/* RCS $Id: dmstring.c,v 1.1.1.1 2000-09-22 15:33:25 hr Exp $ -- -- SYNOPSIS -- String handling code -- -- DESCRIPTION -- Routines to handle string manipulation. This code is not specific -- to dmake and has/and will be used in other programs. The string -- "" is considered the NULL string, if NIL(char) is received instead -- undefined results may occurr. (In reality NIL(char) is checked for -- but in general it is not safe to assume NIL(char) == NULL) -- -- AUTHOR -- Dennis Vadura, dvadura@dmake.wticorp.com -- -- WWW -- http://dmake.wticorp.com/ -- -- COPYRIGHT -- Copyright (c) 1996,1997 by WTI Corp. All rights reserved. -- -- This program is NOT free software; you can redistribute it and/or -- modify it under the terms of the Software License Agreement Provided -- in the file /readme/license.txt. -- -- LOG -- Use cvs log to obtain detailed change logs. */ #include "extern.h" PUBLIC char * DmStrJoin( src, data, n, fr )/* =============================== Join data to src according to value of n. n = -1 - return strcat( src, data ) n >= 0 - return strncat( src, data, n ) FREE original src if fr == TRUE, else leave it alone */ char *src; char *data; int n; int fr; { char *t; int l; int flag = FALSE; DB_ENTER( "DmStrJoin" ); if( src == NIL(char) ) { src = ""; flag = TRUE; } if( data == NIL(char) ) data = ""; DB_PRINT( "str", ("Joining [%s] [%s] %d", src, data, n) ); if( n == -1 ) n = strlen( data ); l = strlen( src ) + n + 1; if( (t = MALLOC( l, char )) == NIL(char) ) No_ram(); strcpy( t, src ); if (n) strncat( t, data, n ); t[ l-1 ] = '\0'; if( !flag && fr ) FREE( src ); DB_PRINT( "str", ("Result [%s]", t) ); DB_RETURN( t ); } PUBLIC char * DmStrAdd( src, data, fr )/* =========================== append data to src with space in between if src is not NIL(char) or "" and free both src and data if fr == TRUE, otherwise leave them be */ char *src; char *data; int fr; { char *t; int l; int sflag; int dflag; DB_ENTER( "DmStrAdd" ); sflag = dflag = fr; if( src == NIL(char) ) { src = ""; sflag = FALSE; } if( data == NIL(char) ) { data = ""; dflag = FALSE; } DB_PRINT( "str", ("Adding [%s] [%s] %d", src, data, fr) ); l = strlen(src) + strlen(data) + 1; if( *src ) l++; if( (t = MALLOC( l, char )) == NIL(char) ) No_ram(); strcpy( t, src ); if( *data ) { if( *src ) strcat( t, " " ); strcat( t, data ); } if( sflag ) FREE( src ); if( dflag ) FREE( data ); DB_PRINT( "str", ("Result [%s]", t) ); DB_RETURN( t ); } PUBLIC char * DmStrApp( src1, src2 )/* ======================== Append two strings together, and return the result with a space between the two strings. FREE the first string if it is not NIL and always leave the second string be. */ char *src1; char *src2; { src2 = DmStrAdd( src1, src2, FALSE ); if( src1 != NIL(char) ) FREE( src1 ); return( src2 ); } PUBLIC char * DmStrDup( str )/* ================= Duplicate the contents of a string, by using malloc */ char *str; { char *t; if( str == NIL(char) ) return( NIL(char) ); if( (t = MALLOC( strlen( str )+1, char )) == NIL(char) ) No_ram(); strcpy( t, str ); return( t ); } PUBLIC char * DmStrDup2( str )/* ================== This function is used solely to properly quote command line arguments when they are reinserted int MAKEMACROS so that they can be used further in a processing line. */ char *str; { char *t; size_t size; size_t alloced; char *tmp; char *dest; int seen_equal = 0; if(str == NIL(char)) return(NIL(char)); size = strlen(str) + 1; alloced = size + 2; /* for two quotes */ for(tmp = str; *tmp; tmp++) if(*tmp == '"') alloced++; if((t = MALLOC(alloced, char)) == NIL(char)) No_ram(); for(tmp = str, dest = t; *tmp; tmp++, dest++) { if(*tmp == '=' && !seen_equal) { seen_equal = 1; *dest++ = *tmp; *dest = '"'; continue; } if(*tmp == '"') *dest++ = '\\'; *dest = *tmp; } if(!seen_equal) Fatal("DmStrDup2 invoked without argument of form x=y\n"); *dest++ = '"'; *dest = 0; return t; } PUBLIC char * DmStrPbrk( s1, s2 )/* ==================== find first occurence of char in s2 in string s1. Returns a pointer to the first occurrence. NOTE '\0' is considered part of s2 and a pointer to it is returned if no other chars match. */ char *s1; char *s2; { register char *t; if( s1 == NIL(char) || s2 == NIL(char) ) return( "" ); for( t=s1; *t && (strchr( s2, *t ) == NIL(char)); t++ ); return( t ); } PUBLIC char * DmStrSpn( s1, s2 )/* ==================== return pointer to first char in s1 that does not belong to s2. Returns the pointer if match found, else returns pointer to null char in s1. (ie. "" ) */ char *s1; char *s2; { register char *t; if( s1 == NIL(char) || s2 == NIL(char) ) return( "" ); for( t=s1; *t && (strchr( s2, *t ) != NIL(char)); t++ ); return( t ); } PUBLIC char * DmStrStr( s1, s2 )/* ==================== find first occurrence in s1 of s2 */ char *s1; char *s2; { register char *s; register char *p; register char *r; if( s1 != NIL(char) && s2 != NIL(char) ) for( s=s1; *s; s++ ) if( *s == *s2 ) { for( r=s+1, p = s2+1; *p && (*r == *p); r++, p++ ); if( !*p ) return( s ); } return( NIL(char) ); } PUBLIC char * DmSubStr( s, e )/* ================== Return the string between the two pointers s and e, not including the char that e points to. NOTE: This routine assumes that s and e point into the same string. */ char *s; char *e; { char save; int len = e-s; if( len < 0 || len > strlen(s) ) Fatal( "Internal Error: SubStr fails consistency test" ); save = *e; *e = '\0'; s = DmStrDup( s ); *e = save; return( s ); }