f00b7fadcc
2006/09/29 18:50:22 vq 1.1.1.1.156.1: #i69814# Add/fix option to make directory cache case insensitive. (Make this the default for Windows and Mac OS X.) Added testcase.
300 lines
6.1 KiB
C
300 lines
6.1 KiB
C
/* RCS $Id: dmstring.c,v 1.2 2007-01-18 09:29:40 vg 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 <distribution-root>/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 );
|
|
}
|
|
|
|
|
|
/* Provide "missing" string function. */
|
|
#ifndef HAVE_STRLWR
|
|
char *
|
|
strlwr(char *s)
|
|
{
|
|
char *p;
|
|
for(p=s; *p; p++ )
|
|
*p = tolower(*p);
|
|
return s;
|
|
}
|
|
#endif
|