tomwalters@0: /*************************************************************************** tomwalters@0: tomwalters@0: strmatch.c String matching routines to supplement those defined in tomwalters@0: ---------- . tomwalters@0: tomwalters@0: tomwalters@0: Character classification macros defined in tomwalters@0: These return truth values [0,1]. tomwalters@0: tomwalters@0: tomwalters@0: int isalpha(c) c is a letter tomwalters@0: int c; tomwalters@0: tomwalters@0: int isupper(c) c is an uppercase letter tomwalters@0: int c; tomwalters@0: tomwalters@0: int islower(c) c is a lowercase letter tomwalters@0: int c; tomwalters@0: tomwalters@0: int isdigit(c) c is a digit tomwalters@0: int c; tomwalters@0: tomwalters@0: int isxdigit(c) c is a hexadecimal digit, by default [0-9], [A-F], or tomwalters@0: int c; [a-f]. tomwalters@0: tomwalters@0: int isalnum(c) c is an alphanumeric character tomwalters@0: int c; tomwalters@0: tomwalters@0: int isspace(c) c is a space, tab, carriage return, new line, or form tomwalters@0: int c; feed. tomwalters@0: tomwalters@0: int ispunct(c) c is a punctuation character (neither control, tomwalters@0: int c; alphanumeric, nor space) tomwalters@0: tomwalters@0: tomwalters@0: int isprint(c) c is a printing character, by default code 040(8) tomwalters@0: int c; (space) through 0176 (tilde) tomwalters@0: tomwalters@0: tomwalters@0: int isgraph(c) c is a printing character, like isprint except false tomwalters@0: int c; for space. tomwalters@0: tomwalters@0: int iscntrl(c) c is a delete character (0177) or ordinary control tomwalters@0: int c; character (less than 040) except for space characters tomwalters@0: tomwalters@0: tomwalters@0: int isascii(c) c is an ASCII character, code less than 0200 tomwalters@0: int c; tomwalters@0: tomwalters@0: tomwalters@0: Character translation macros defined in tomwalters@0: tomwalters@0: tomwalters@0: int toupper(c) return upper-case letter corresponding to c. tomwalters@0: int c; tomwalters@0: tomwalters@0: int tolower(c) return lower-case letter corresponding to c. tomwalters@0: int c; tomwalters@0: tomwalters@0: int toascii(c) return ascii value corresponding to c. tomwalters@0: int c; tomwalters@0: tomwalters@0: tomwalters@0: String handling routines defined in tomwalters@0: A `span' is the length of a segment of a string, ie a number of characters. tomwalters@0: tomwalters@0: tomwalters@0: char *strcat(s1, s2) Append a copy of string s2 to the end of tomwalters@0: char *s1, *s2; string s1. Return a ptr to s1. tomwalters@0: tomwalters@0: char *strncat(s1, s2, n) Append n chars of s2 to the end of string s1. tomwalters@0: char *s1, *s2; Return a ptr to s1. tomwalters@0: tomwalters@0: int strcmp(s1, s2) Compare strings. Return 0 if equal. tomwalters@0: unsigned char *s1, *s2; Otherwise return difference number of chars. tomwalters@0: tomwalters@0: int strncmp(s1, s2, n) Compare n chars of strings. Return 0 if equal. tomwalters@0: unsigned char *s1, *s2; Otherwise return difference number of chars. tomwalters@0: int n tomwalters@0: tomwalters@0: strcasecmp(s1, s2) As strcmp, but case insensitive. tomwalters@0: char *s1, *s2; tomwalters@0: tomwalters@0: strncasecmp(s1, s2, n) As strncmp, but case insensitive. tomwalters@0: char *s1, *s2; tomwalters@0: tomwalters@0: char *strcpy(s1, s2) Copy s2 to s1, including null char. tomwalters@0: char *s1, *s2; tomwalters@0: tomwalters@0: char *strncpy(s1, s2, n) Copy n chars of s2 to s1. Truncate or pad s2 tomwalters@0: char *s1, *s2; with nulls to make up n chars. If s2 needs to tomwalters@0: int n be truncated, s1 will not be null terminated. tomwalters@0: tomwalters@0: int strlen(s) Return number of chars in s, not including tomwalters@0: char *s; the terminating null character. tomwalters@0: tomwalters@0: char *strstr(s1, s2) Return a ptr to the first occurrence of s2 tomwalters@0: char *s1, *s2; in s1. Otherwise return a null ptr. tomwalters@0: tomwalters@0: char *strchr(s, c) Return a ptr to the first occurrence of c tomwalters@0: char *s; in s. Otherwise return a null ptr. tomwalters@0: int c; tomwalters@0: tomwalters@0: char *strrchr(s, c) Return a ptr to the last occurrence of c tomwalters@0: char *s; in s. Otherwise return a null ptr. tomwalters@0: int c; tomwalters@0: tomwalters@0: char *strpbrk(s1, s2) Return a ptr to the first occurrence of any tomwalters@0: char *s1, *s2; char in s2 in s1. Otherwise return a null ptr. tomwalters@0: tomwalters@0: int strspn(s1, s2) Return the span from the head of s1 which tomwalters@0: char *s1, *s2; consists of chars which are in s2. tomwalters@0: tomwalters@0: int strcspn(s1, s2) Return the span from the head of s1 which tomwalters@0: char *s1, *s2; consists of chars which are not in s2. tomwalters@0: tomwalters@0: char *strtok(s1, s2) See below: tomwalters@0: char *s1, *s2; tomwalters@0: tomwalters@0: The strtok subroutine considers the string s1 to consist of a sequence tomwalters@0: of zero or more text tokens separated by spans of one or more characters tomwalters@0: from the separator string s2. The first call (with pointer s1 speci- tomwalters@0: fied) returns a pointer to the first character of the first token, and tomwalters@0: will have written a null character into s1 immediately following the tomwalters@0: returned token. The function keeps track of its position in the string tomwalters@0: between separate calls, so that subsequent calls (which must be made tomwalters@0: with the first argument a NULL pointer) will work through the string s1 tomwalters@0: immediately following that token. In this way, subsequent calls will tomwalters@0: work through the string s1 until no tokens remain. The separator string tomwalters@0: s2 may be different from call to call. When no token remains in s1, a tomwalters@0: NULL pointer is returned. tomwalters@0: tomwalters@0: tomwalters@0: ***************************************************************************/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: #include tomwalters@0: #include "strmatch.h" tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Test for a NULL pointer to a character or string tomwalters@0: */ tomwalters@0: tomwalters@0: int isnull( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: if ( s == (char *)0 ) return 1 ; tomwalters@0: else return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: Test for an empty string tomwalters@0: */ tomwalters@0: tomwalters@0: tomwalters@0: int isempty( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: if ( *s == '\0' ) return 1 ; tomwalters@0: else return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: Test for NULL string pointer or empty string tomwalters@0: */ tomwalters@0: tomwalters@0: int isnullorempty( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: if ( s == (char *)0 || *s == '\0' ) return 1 ; tomwalters@0: else return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return a pointer to the terminator '\0' at the tail of string `s'. tomwalters@0: */ tomwalters@0: tomwalters@0: char *terminator( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: return ( s + strlen( s ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Test strings s1==s2. Return 1 if true, 0 otherwise. tomwalters@0: */ tomwalters@0: tomwalters@0: int isstr( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: return ( strcmp( s1, s2 ) == 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Test strings s1==s2 up to the length of string s1 (ie allowing truncation). tomwalters@0: Return 1 if true, 0 otherwise. tomwalters@0: */ tomwalters@0: tomwalters@0: int iststr( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: return ( strncmp( s1, s2, strlen( s1 ) ) == 0 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Copy s2 to s1 up to (but not including) the first occurrence of character c tomwalters@0: in s2. Ensure s1 is then null terminated. tomwalters@0: Return s1 or a null ptr if c is not found in s2. tomwalters@0: */ tomwalters@0: tomwalters@0: char *strccpy( s1, s2, c ) tomwalters@0: char *s1, *s2 ; tomwalters@0: char c ; tomwalters@0: { tomwalters@0: char *s ; tomwalters@0: tomwalters@0: if ( ( s = strchr( s2, c ) ) == (char *)0 ) return (char *)0 ; tomwalters@0: strncpy( s1, s2, (int)( s - s2 ) ) ; tomwalters@0: *( s1 + ( s - s2 ) ) == '\0' ; tomwalters@0: return ( s1 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return a ptr to the first occurrence of any char in s1 which is not in s2. tomwalters@0: Otherwise return a null ptr. (This complements strpbrk() in the Unix string tomwalters@0: library). tomwalters@0: */ tomwalters@0: tomwalters@0: char *strcbrk(s1, s2) tomwalters@0: char *s1, *s2; tomwalters@0: { tomwalters@0: int spn ; tomwalters@0: tomwalters@0: if ( ( spn = strspn( s1, s2 ) ) == strlen( s1 ) ) tomwalters@0: return ( (char *)0 ) ; tomwalters@0: return ( (char *)( s1 + spn ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the span from the head of s1 to the first occurrence of any char in s2. tomwalters@0: Otherwise (if no such char found) return -1. tomwalters@0: */ tomwalters@0: tomwalters@0: int strspnbrk(s1, s2) tomwalters@0: char *s1, *s2; tomwalters@0: { tomwalters@0: int spn ; tomwalters@0: tomwalters@0: if ( ( spn = strcspn( s1, s2 ) ) == strlen( s1 ) ) tomwalters@0: return ( -1 ) ; tomwalters@0: return ( spn ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the span from the head of s1 to the first occurrence of any char not tomwalters@0: in s2. Otherwise (if no such char found) return -1. tomwalters@0: */ tomwalters@0: tomwalters@0: int strcspnbrk(s1, s2) tomwalters@0: char *s1, *s2; tomwalters@0: { tomwalters@0: int spn ; tomwalters@0: tomwalters@0: if ( ( spn = strspn( s1, s2 ) ) == strlen( s1 ) ) tomwalters@0: return ( -1 ) ; tomwalters@0: return ( spn ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Compare the heads of strings s1 and s2 up to the length of string s1. tomwalters@0: Return 0 if equal, otherwise return difference number of chars. tomwalters@0: */ tomwalters@0: tomwalters@0: int strtcmp( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: return ( strncmp( s1, s2, strlen( s1 ) ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Compare the tails of strings s1 and s2 back to the length of string s2. tomwalters@0: Return 0 if equal, otherwise return difference number of chars. tomwalters@0: */ tomwalters@0: tomwalters@0: int strtrcmp( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: int i, j ; tomwalters@0: tomwalters@0: if ( ( i = strlen( s1 ) ) >= ( j = strlen( s2 ) ) ) tomwalters@0: return ( strcmp( s1+i-j, s2 ) ) ; tomwalters@0: return ( i-j ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the span (number of chars) over which the head of string s1 equals the tomwalters@0: head of string s2. tomwalters@0: */ tomwalters@0: tomwalters@0: int streqspn( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: int spn=0 ; tomwalters@0: tomwalters@0: while ( !isempty(s1) && *s1++ == *s2++ ) spn++ ; tomwalters@0: return spn ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the span (number of chars) of a at the head of string s. tomwalters@0: = [-][.] tomwalters@0: where either, but not both, of the digit strings may be empty. tomwalters@0: */ tomwalters@0: tomwalters@0: int strnumspn( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: int j0=0, j1, j2 ; tomwalters@0: tomwalters@0: if ( *s == '-' ) j0++ ; /* span of '-' */ tomwalters@0: j1 = strspn( s+j0, "0123456789" ) ; /* span of digits left of point */ tomwalters@0: if ( *( s+j0+j1 ) == '.' ) j1++ ; /* span of '.' */ tomwalters@0: j2 = strspn( s+j0+j1, "0123456789" ) ; /* span of digits right of point */ tomwalters@0: if ( *( s+j0+j1+j2 ) == '.' ) j2++ ; tomwalters@0: tomwalters@0: if ( j1>0 || j2>0 ) tomwalters@0: return ( j0+j1+j2 ) ; tomwalters@0: return 0 ; /* zero span means no number */ tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Test for a . tomwalters@0: */ tomwalters@0: tomwalters@0: int isnumber( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: if ( strnumspn( s ) > 0 ) return 1 ; tomwalters@0: else return 0 ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return a ptr to the first char after a at the head of string s. tomwalters@0: */ tomwalters@0: tomwalters@0: char *strnumptr( s ) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: return ( s + strnumspn( s ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return a ptr to the first occurrence of any number char in s. tomwalters@0: (where a number char includes '-' and '.' as well as any digit). tomwalters@0: */ tomwalters@0: tomwalters@0: char *strpnum(s) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: return ( strpbrk( s, "-.0123456789" ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* tomwalters@0: Return a ptr to the first occurrence of any char in s not a number char. tomwalters@0: (where a number char includes '-' and '.' as well as any digit). tomwalters@0: */ tomwalters@0: tomwalters@0: char *strcnum(s) tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: return ( strcbrk( s, "-.0123456789" ) ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Separate string `s1' into two string tokens at the first occurrence of a tomwalters@0: separator character `s2'. (Given as a string of one char). tomwalters@0: Numbers at the head of `s1' are skipped. (This skips leading hyphens or points tomwalters@0: which are part of a number, and so allows negative numbers with splitting tomwalters@0: hyphens, real numbers with splitting decimal point, etc.). tomwalters@0: Four possible outcomes, depending upon form of `s1': tomwalters@0: 1. Null or empty. - return NULL ptr, (missing 1st and 2nd tokens). tomwalters@0: 2. No separator char. - return ptr to empty string, (empty 2nd token). tomwalters@0: 3. Separator is last char. - return NULL ptr, (missing 2nd token). tomwalters@0: 4. Separator within `s1'. - return ptr to 2nd token, (two correct tokens). tomwalters@0: String `s1' is unchanged at the end. tomwalters@0: */ tomwalters@0: tomwalters@0: char *strpsep( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: char *s ; tomwalters@0: tomwalters@0: if ( isnullorempty( s1 ) ) tomwalters@0: return ( (char *)0 ) ; tomwalters@0: tomwalters@0: s1 = strnumptr( s1 ) ; /* skip leading numbers */ tomwalters@0: tomwalters@0: if ( ( s = strpbrk( s1, s2 ) ) == (char *)0 ) tomwalters@0: return ( s1 + strlen( s1 ) ) ; /* ptr to empty string at end s1 */ tomwalters@0: tomwalters@0: if ( isempty( ( s2 = s+1 ) ) ) tomwalters@0: return ( (char *)0 ) ; /* separator is last char */ tomwalters@0: tomwalters@0: return ( s2 ) ; tomwalters@0: } tomwalters@0: tomwalters@0: /* Replace above last 4 lines of routine, and also mod strsep, to get proper tomwalters@0: string separator tomwalters@0: if ( ( s2 = strcbrk( s, s2 ) ) == (char *)0 ) tomwalters@0: return ( (char *)0 ) ; tomwalters@0: while ( --s2 > s && isnumber( s2 ) ) ; tomwalters@0: return ( ++s2 ) ; tomwalters@0: */ tomwalters@0: tomwalters@0: /* tomwalters@0: Separate string `s1' into two string tokens. tomwalters@0: strsep() is the same as strpsep() except that, in the event of two correct tomwalters@0: tokens, insert '\0' at the separator. tomwalters@0: String `s1' is thus separated and becomes the first token. tomwalters@0: */ tomwalters@0: tomwalters@0: char *strsep( s1, s2 ) tomwalters@0: char *s1, *s2 ; tomwalters@0: { tomwalters@0: char *s = strpsep( s1, s2 ) ; /* ptr to 2nd token */ tomwalters@0: tomwalters@0: if ( isnullorempty( s ) ) tomwalters@0: return s ; tomwalters@0: tomwalters@0: *(s-1) = '\0' ; /* insert '\0' and return 2nd token */ tomwalters@0: return ( s ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Compare the head of string `s' with null-terminated list of strings `list'. tomwalters@0: Return the longest matching string from `list'. tomwalters@0: Return a NULL pointer if no match is found, or if the (possibly abbreviated) tomwalters@0: head of string `s' is ambiguous (ie. matches more than once in the list). tomwalters@0: */ tomwalters@0: tomwalters@0: char *listcmp( list, s ) tomwalters@0: char **list ; tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: int i, j = (-1) ; tomwalters@0: tomwalters@0: for ( i=0; list[i] != (char *)0 ; i++) tomwalters@0: if ( strtcmp( s, list[i] ) == 0 ) { tomwalters@0: if ( j >= 0 ) return (char *)0 ; /* ambiguous match */ tomwalters@0: else j = i; tomwalters@0: } tomwalters@0: if ( j < 0 ) return (char *)0 ; /* match not found */ tomwalters@0: return ( list[j] ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Compare the tail of string `s' with null-terminated list of strings `list'. tomwalters@0: Return the longest matching string from `list'. tomwalters@0: Return a NULL pointer if no match is found, or if the (possibly abbreviated) tomwalters@0: tail of string `s' is ambiguous (ie. matches more than once in the list). tomwalters@0: */ tomwalters@0: tomwalters@0: char *listrcmp( list, s ) tomwalters@0: char **list ; tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: int i, j = (-1), k, maxlen = 0 ; tomwalters@0: tomwalters@0: for ( i=0; list[i] != (char *)0 ; i++) tomwalters@0: if ( strtrcmp( s, list[i] ) == 0 && ( k = strlen( list[i] ) ) > maxlen ) { tomwalters@0: maxlen = k ; tomwalters@0: j = i ; tomwalters@0: } tomwalters@0: if ( j < 0 ) return (char *)0 ; /* match not found */ tomwalters@0: return ( list[j] ) ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Compare the head of string `s' with null-terminated list of strings `list'. tomwalters@0: Find the string in `list' having the longest matching span with the head of tomwalters@0: `s' (which is possibly abbreviated). tomwalters@0: Return the list index of the matching string. tomwalters@0: Return (-1) if there is no match in the list (all spans are zero). tomwalters@0: Return (-2) if the longest matching span is ambiguous (ie occurs more tomwalters@0: than once in the list). tomwalters@0: */ tomwalters@0: tomwalters@0: int listindex( list, s ) tomwalters@0: char **list ; tomwalters@0: char *s ; tomwalters@0: { tomwalters@0: int i, j, jmax = 0, index = (-1) ; tomwalters@0: tomwalters@0: for ( i=0; list[i] != (char *)0 ; i++) { tomwalters@0: if ( ( j = streqspn( s, list[i] ) ) > jmax ) { tomwalters@0: jmax = j ; tomwalters@0: index = i ; tomwalters@0: } tomwalters@0: else if ( j > 0 && j == jmax ) tomwalters@0: index = (-2) ; tomwalters@0: } tomwalters@0: return index ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return the length of the null-terminated list of strings `list', ie. the tomwalters@0: number of strings it contains. tomwalters@0: */ tomwalters@0: tomwalters@0: listsize( list ) tomwalters@0: char **list ; tomwalters@0: { tomwalters@0: int i ; tomwalters@0: tomwalters@0: for ( i = 0 ; list[i] != (char *)0 ; i++ ) tomwalters@0: ; tomwalters@0: return i ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: For each string in list1, find the index of the matching string in list2 tomwalters@0: and store it in the index array, (which must be at least the size of list1). tomwalters@0: The string match allows for abbreviations in the list1 strings. tomwalters@0: Return the number of matching strings found. (If this is less than the size tomwalters@0: of list1 then list1 contains an unknown or an ambiguous string). tomwalters@0: */ tomwalters@0: tomwalters@0: mapindices( list1, list2, index ) tomwalters@0: char **list1, **list2 ; tomwalters@0: int *index ; tomwalters@0: { tomwalters@0: int i, j, n = 0 ; tomwalters@0: tomwalters@0: for ( i = 0 ; list1[i] != (char *)0 ; i++ ) tomwalters@0: if ( ( j = listindex( list2, list1[i] ) ) >= 0 ) tomwalters@0: index[n++] = j ; tomwalters@0: tomwalters@0: return n ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Split the given string `str' into tokens at occurrences of separator char c. tomwalters@0: Store pointers to each token in `list', and null-terminate each token tomwalters@0: by overwriting the separator char with null. tomwalters@0: The list must contain at most n pointers. tomwalters@0: Return the number of tokens, or 0 if an error. tomwalters@0: */ tomwalters@0: tomwalters@0: tokens( str, list, n, c ) tomwalters@0: char *str ; tomwalters@0: char **list ; tomwalters@0: int n ; tomwalters@0: char c ; tomwalters@0: { tomwalters@0: int i ; tomwalters@0: char *s ; tomwalters@0: tomwalters@0: if ( isempty( str ) || *str == c || n <= 0 ) return 0 ; tomwalters@0: list[0] = str ; tomwalters@0: tomwalters@0: for ( i = 1 ; i < n && ( s = strchr( str, c ) ) != (char *)0 ; i++ ) { tomwalters@0: *s = '\0' ; tomwalters@0: str = s + 1 ; tomwalters@0: if ( isempty( str ) || *str == c ) return 0 ; tomwalters@0: list[i] = str ; tomwalters@0: } tomwalters@0: tomwalters@0: if ( i == n && strchr( str, c ) != (char *)0 ) return 0 ; tomwalters@0: tomwalters@0: return i ; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* tomwalters@0: Return ASCII string of integer i. (Inverse of atoi()). tomwalters@0: */ tomwalters@0: tomwalters@0: char *itoa( i ) tomwalters@0: int i ; tomwalters@0: { tomwalters@0: char s[64], *s1 ; tomwalters@0: tomwalters@0: sprintf( s, "%d", i ) ; tomwalters@0: s1 = (char *)malloc( strlen( s ) + 1 ) ; tomwalters@0: strcpy( s1, s ) ; tomwalters@0: return s1 ; tomwalters@0: }