diff options
Diffstat (limited to 'support/texlab/crates/bibutils_sys/src/str.c')
-rw-r--r-- | support/texlab/crates/bibutils_sys/src/str.c | 1126 |
1 files changed, 0 insertions, 1126 deletions
diff --git a/support/texlab/crates/bibutils_sys/src/str.c b/support/texlab/crates/bibutils_sys/src/str.c deleted file mode 100644 index 75b76bce70..0000000000 --- a/support/texlab/crates/bibutils_sys/src/str.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * str.c - * - * Version: 2018-09-21 - * - * Copyright (c) Chris Putnam 1999-2019 - * - * Source code released under the GPL version 2 - * - * - * routines for dynamically allocated strings - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> -#include "is_ws.h" -#include "str.h" -#include "msvc_fix.h" - -/* Do not use asserts in STR_NOASSERT defined */ -#ifdef STR_NOASSERT -#define NDEBUG -#endif -#include <assert.h> - -#define str_initlen (64) - -#ifndef STR_SMALL - -#define str_clear_status( s ) s->status = STR_OK; -#define handle_memerr( s, f ) s->status = STR_MEMERR; -#define return_if_memerr( s ) \ -{ \ - if ( s->status != STR_OK ) return; \ -} -#define return_zero_if_memerr( s ) \ -{ \ - if ( s->status != STR_OK ) return 0; \ -} -#define return_after_delim_if_memerr( s, p, delim, finalstep ) \ -{ \ - if ( s->status != STR_OK ) { \ - while ( p && *p && !strchr( delim, *p ) ) p++; \ - if ( p && *p && finalstep ) p++; \ - return p; \ - } \ -} - -#else - -#define str_clear_status( s ) {} -#define handle_memerr( s, f ) \ -{ \ - fprintf( stderr,"Error. Cannot allocate memory in %s.\n", f ); \ - exit( EXIT_FAILURE ); \ -} -#define return_if_memerr( s ) {} -#define return_zero_if_memerr( s ) {} -#define return_after_delim_if_memerr( s, p, delim, finalstep ) {} - -#endif - - -/* Clear memory in resize/free if STR_PARANOIA defined */ - -#ifndef STR_PARANOIA - -static void -str_realloc( str *s, unsigned long minsize ) -{ - unsigned long size; - char *newptr; - - assert( s ); - return_if_memerr( s ); - - size = 2 * s->dim; - if (size < minsize) size = minsize; - - newptr = (char *) realloc( s->data, sizeof( *(s->data) )*size ); - if ( !newptr ) handle_memerr( s, __FUNCTION__ ); - - s->data = newptr; - s->dim = size; -} - -/* define as a no-op */ -#define str_nullify( s ) - -#else - -static void -str_realloc( str *s, unsigned long minsize ) -{ - unsigned long size; - char *newptr; - - assert( s ); - return_if_memerr( s ); - - size = 2 * s->dim; - if ( size < minsize ) size = minsize; - - newptr = (char *) malloc( sizeof( *(s->data) ) * size ); - if ( !newptr ) handle_memerr( s, __FUNCTION__ ); - - if ( s->data ) { - str_nullify( s ); - free( s->data ); - } - s->data = newptr; - s->dim = size; -} - -static inline void -str_nullify( str *s ) -{ - memset( s->data, 0, s->dim ); -} - -#endif - -void -str_init( str *s ) -{ - assert( s ); - s->dim = 0; - s->len = 0; - s->data = NULL; - str_clear_status( s ); -} - -void -str_initstr( str *s, str *from ) -{ - assert( s ); - assert( from ); - str_init( s ); - str_strcpy( s, from ); -} - -void -str_initstrc( str *s, const char *initstr ) -{ - assert( s ); - assert( initstr ); - str_init( s ); - str_strcpyc( s, initstr ); -} - -void -str_initstrsc( str *s, ... ) -{ - const char *c; - va_list ap; - str_init( s ); - va_start( ap, s ); - do { - c = va_arg( ap, const char * ); - if ( c ) str_strcatc( s, c ); - } while ( c ); - va_end( ap ); -} - -void -strs_init( str *s, ... ) -{ - str *s2; - va_list ap; - str_init( s ); - va_start( ap, s ); - do { - s2 = va_arg( ap, str * ); - if ( s2 ) str_init( s2 ); - } while ( s2 ); - va_end( ap ); -} - -int -str_memerr( str *s ) -{ -#ifndef STR_SMALL - return s->status == STR_MEMERR; -#else - return 0; -#endif -} - -void -str_mergestrs( str *s, ... ) -{ - va_list ap; - const char *cp; - str_clear_status( s ); - str_empty( s ); - va_start( ap, s ); - do { - cp = va_arg( ap, const char * ); - if ( cp ) str_strcatc( s, cp ); - } while ( cp ); - va_end( ap ); -} - -static void -str_initalloc( str *s, unsigned long minsize ) -{ - unsigned long size = str_initlen; - assert( s ); - if ( minsize > str_initlen ) size = minsize; - s->data = (char *) malloc( sizeof( *(s->data) ) * size ); - if ( !s->data ) { - fprintf(stderr,"Error. Cannot allocate memory in str_initalloc, requested %lu characters.\n", size ); - exit( EXIT_FAILURE ); - } - s->data[0]='\0'; - s->dim=size; - s->len=0; - str_clear_status( s ); -} - -str * -str_new( void ) -{ - str *s = (str *) malloc( sizeof( *s ) ); - if ( s ) - str_initalloc( s, str_initlen ); - return s; -} - -void -str_free( str *s ) -{ - assert( s ); - if ( s->data ) { - str_nullify( s ); - free( s->data ); - } - s->dim = 0; - s->len = 0; - s->data = NULL; -} - -void -strs_free( str *s, ... ) -{ - str *s2; - va_list ap; - str_free( s ); - va_start( ap, s ); - do { - s2 = va_arg( ap, str * ); - if ( s2 ) str_free( s2 ); - } while ( s2 ); - va_end( ap ); -} - -void -str_delete( str *s ) -{ - assert( s ); - str_free( s ); - free( s ); -} - -void -str_empty( str *s ) -{ - assert( s ); - str_clear_status( s ); - if ( s->data ) { - str_nullify( s ); - s->data[0] = '\0'; - } - s->len = 0; -} - -void -strs_empty( str *s, ... ) -{ - str *s2; - va_list ap; - str_empty( s ); - va_start( ap, s ); - do { - s2 = va_arg( ap, str * ); - if ( s2 ) str_empty( s2 ); - } while ( s2 ); - va_end( ap ); -} - -void -str_addchar( str *s, char newchar ) -{ - assert( s ); - - return_if_memerr( s ); - - if ( newchar=='\0' ) return; /* appending '\0' is a null operation */ - - if ( !s->data || s->dim==0 ) - str_initalloc( s, str_initlen ); - if ( s->len + 2 > s->dim ) - str_realloc( s, s->len*2 ); - - s->data[s->len++] = newchar; - s->data[s->len] = '\0'; -} - -/* str_addutf8 - * - * Add potential multibyte character to s starting at pointer p. - * Multibyte Unicode characters have the high bit set. - * - * Since we can progress more than one byte at p, return the - * properly updated pointer p. - */ -const char * -str_addutf8( str *s, const char *p ) -{ - if ( ! ((*p) & 128 ) ) { - str_addchar( s, *p ); - p++; - } else { - while ( ((*p) & 128) ) { - str_addchar( s, *p ); - p++; - } - } - return p; -} - -char * -str_cstr( str *s ) -{ - assert( s ); - return s->data; -} - -void -str_fprintf( FILE *fp, str *s ) -{ - assert( s ); - if ( s->data ) fprintf( fp, "%s", s->data ); -} - -void -str_prepend( str *s, const char *addstr ) -{ - unsigned long lenaddstr, i; - - assert( s && addstr ); - - return_if_memerr( s ); - - lenaddstr = strlen( addstr ); - if ( lenaddstr==0 ) return; /* appending an empty string is a null op */ - - if ( !s->data || !s->dim ) - str_initalloc( s, lenaddstr+1 ); - else { - if ( s->len + lenaddstr + 1 > s->dim ) - str_realloc( s, s->len + lenaddstr + 1 ); - for ( i=s->len+lenaddstr-1; i>=lenaddstr; i-- ) - s->data[i] = s->data[i-lenaddstr]; - } - strncpy( s->data, addstr, lenaddstr ); - s->len += lenaddstr; - s->data[ s->len ] = '\0'; -} - -static inline void -str_strcat_ensurespace( str *s, unsigned long n ) -{ - unsigned long m = s->len + n + 1; - if ( !s->data || !s->dim ) - str_initalloc( s, m ); - else if ( s->len + n + 1 > s->dim ) - str_realloc( s, m ); -} - -static inline void -str_strcat_internal( str *s, const char *addstr, unsigned long n ) -{ - return_if_memerr( s ); - str_strcat_ensurespace( s, n ); - strncat( &(s->data[s->len]), addstr, n ); - s->len += n; - s->data[s->len]='\0'; -} - -void -str_strcat( str *s, str *from ) -{ - assert ( s && from ); - if ( !from->data ) return; - else str_strcat_internal( s, from->data, from->len ); -} - -void -str_strcatc( str *s, const char *from ) -{ - unsigned long n; - assert( s && from ); - n = strlen( from ); - str_strcat_internal( s, from, n ); -} - -void -str_segcat( str *s, char *startat, char *endat ) -{ - unsigned long n; - char *p; - - assert( s && startat && endat ); - assert( (size_t) startat < (size_t) endat ); - - return_if_memerr( s ); - - if ( startat==endat ) return; - - n = 0; - p = startat; - while ( p!=endat ) { - n++; - p++; - } - - str_strcat_internal( s, startat, n ); -} - -void -str_indxcat( str *s, char *p, unsigned long start, unsigned long stop ) -{ - unsigned long i; - - assert( s && p ); - assert( start <= stop ); - - return_if_memerr( s ); - - for ( i=start; i<stop; ++i ) - str_addchar( s, p[i] ); -} - -/* str_cpytodelim() - * term = string of characters to be used as terminators - * finalstep = set to non-zero to position return value past the - * terminating character - */ -const char * -str_cpytodelim( str *s, const char *p, const char *delim, unsigned char finalstep ) -{ - assert( s ); - - str_empty( s ); - return str_cattodelim( s, p, delim, finalstep ); -} - -/* str_cpytodelim() - * term = string of characters to be used as terminators - * finalstep = set to non-zero to position return value past the - * terminating character - */ -const char * -str_cattodelim( str *s, const char *p, const char *delim, unsigned char finalstep ) -{ - assert( s ); - - return_after_delim_if_memerr( s, p, delim, finalstep ); - - while ( p && *p && !strchr( delim, *p ) ) { - str_addchar( s, *p ); - p++; - } - if ( p && *p && finalstep ) p++; - return p; -} - -static inline void -str_strcpy_ensurespace( str *s, unsigned long n ) -{ - unsigned long m = n + 1; - if ( !s->data || !s->dim ) - str_initalloc( s, m ); - else if ( m > s->dim ) - str_realloc( s, m ); -} - -static inline void -str_strcpy_internal( str *s, const char *p, unsigned long n ) -{ - return_if_memerr( s ); - - str_strcpy_ensurespace( s, n ); - strncpy( s->data, p, n ); - s->data[n] = '\0'; - s->len = n; -} - -void -str_strcpy( str *s, str *from ) -{ - assert( s ); - assert( from ); - if ( s==from ) return; - else if ( !from || from->len==0 ) str_empty( s ); - else str_strcpy_internal( s, from->data, from->len ); -} - -void -str_strcpyc( str *s, const char *from ) -{ - unsigned long n; - assert( s && from ); - n = strlen( from ); - str_strcpy_internal( s, from, n ); -} - -/* str_segcpy( s, start, end ); - * - * copies [start,end) into s - */ -void -str_segcpy( str *s, char *startat, char *endat ) -{ - unsigned long n; - char *p; - - assert( s && startat && endat ); - assert( ((size_t) startat) <= ((size_t) endat) ); - - return_if_memerr( s ); - - if ( startat==endat ) { - str_empty( s ); - return; - } - - n = 0; - p = startat; - while ( p!=endat ) { - p++; - n++; - } - - str_strcpy_internal( s, startat, n ); -} - -/* - * str_indxcpy( s, in, start, stop ); - * - * copies in[start,stop) (excludes stop) into s - */ -void -str_indxcpy( str *s, char *p, unsigned long start, unsigned long stop ) -{ - unsigned long i; - - assert( s && p ); - assert( start <= stop ); - - return_if_memerr( s ); - - if ( start == stop ) { - str_empty( s ); - return; - } - str_strcpy_ensurespace( s, stop-start+1 ); - for ( i=start; i<stop; ++i ) - s->data[i-start] = p[i]; - s->len = stop-start; - s->data[s->len] = '\0'; -} - -str * -str_strdup( str *from ) -{ - str *s = str_new(); - if ( s ) - str_strcpy( s, from ); - return s; -} - -str * -str_strdupc( const char *from ) -{ - str *s = str_new(); - if ( s ) - str_strcpyc( s, from ); - return s; -} - -void -str_segdel( str *s, char *p, char *q ) -{ - str tmp1, tmp2; - char *r; - - assert( s ); - - return_if_memerr( s ); - - r = &(s->data[s->len]); - str_init( &tmp1 ); - str_init( &tmp2 ); - str_segcpy( &tmp1, s->data, p ); - str_segcpy( &tmp2, q, r ); - str_empty( s ); - if ( tmp1.data ) str_strcat( s, &tmp1 ); - if ( tmp2.data ) str_strcat( s, &tmp2 ); - str_free( &tmp2 ); - str_free( &tmp1 ); -} - -/* - * str_findreplace() - * - * if replace is "" or NULL, then delete find - */ - -int -str_findreplace( str *s, const char *find, const char *replace ) -{ - long diff; - size_t findstart, searchstart; - size_t p1, p2; - size_t find_len, rep_len, curr_len; - char empty[2] = ""; - unsigned long minsize; - char *p; - int n = 0; - - assert( s && find ); - - return_zero_if_memerr( s ); - - if ( !s->data || !s->dim ) return 0; - if ( !replace ) replace = empty; - - find_len = strlen( find ); - rep_len = strlen( replace ); - diff = rep_len - find_len; - if ( diff < 0 ) diff = 0; - - searchstart=0; - while ((p=strstr(s->data + searchstart,find))!=NULL) { - curr_len = strlen(s->data); - findstart=(size_t) p - (size_t) s->data; - minsize = curr_len + diff + 1; - if (s->dim <= minsize) str_realloc( s, minsize ); - if ( find_len > rep_len ) { - p1 = findstart + rep_len; - p2 = findstart + find_len; - while( s->data[p2] ) - s->data[p1++]=s->data[p2++]; - s->data[p1]='\0'; - n++; - } else if ( find_len < rep_len ) { - for ( p1=curr_len; p1>=findstart+find_len; p1-- ) - s->data[p1+diff] = s->data[p1]; - n++; - } - for (p1=0; p1<rep_len; p1++) - s->data[findstart+p1]=replace[p1]; - searchstart = findstart + rep_len; - s->len += rep_len - find_len; - } - return n; -} - - -/* str_fget() - * returns 0 if we're done, 1 if we're not done - * extracts line by line (regardless of end characters) - * and feeds from buf.... - */ -int -str_fget( FILE *fp, char *buf, int bufsize, int *pbufpos, str *outs ) -{ - int bufpos = *pbufpos, done = 0; - char *ok; - assert( fp && outs ); - str_empty( outs ); - while ( !done ) { - while ( buf[bufpos] && buf[bufpos]!='\r' && buf[bufpos]!='\n' ) - str_addchar( outs, buf[bufpos++] ); - if ( buf[bufpos]=='\0' ) { - ok = fgets( buf, bufsize, fp ); - bufpos=*pbufpos=0; - if ( !ok && feof(fp) ) { /* end-of-file */ - buf[bufpos] = 0; - if ( outs->len==0 ) return 0; /*nothing in out*/ - else return 1; /*one last out */ - } - } else if ( buf[bufpos]=='\r' || buf[bufpos]=='\n' ) done=1; - } - if ( ( buf[bufpos]=='\n' && buf[bufpos+1]=='\r') || - ( buf[bufpos]=='\r' && buf[bufpos+1]=='\n') ) bufpos+=2; - else if ( buf[bufpos]=='\n' || buf[bufpos]=='\r' ) bufpos+=1; - *pbufpos = bufpos; - return 1; -} - -void -str_toupper( str *s ) -{ - unsigned long i; - assert( s ); - for ( i=0; i<s->len; ++i ) - s->data[i] = toupper( (unsigned char)s->data[i] ); -} - -void -str_tolower( str *s ) -{ - unsigned long i; - assert( s ); - for ( i=0; i<s->len; ++i ) - s->data[i] = tolower( (unsigned char)s->data[i] ); -} - -/* str_swapstrings( s1, s2 ) - * be sneaky and swap internal string data from one - * string to another - */ -void -str_swapstrings( str *s1, str *s2 ) -{ - char *tmpp; - int tmp; - - assert( s1 && s2 ); - - /* swap dimensioning info */ - tmp = s1->dim; - s1->dim = s2->dim; - s2->dim = tmp; - - /* swap length info */ - tmp = s1->len; - s1->len = s2->len; - s2->len = tmp; - - /* swap data */ - tmpp = s1->data; - s1->data = s2->data; - s2->data = tmpp; -} - -void -str_trimstartingws( str *s ) -{ - char *p, *q; - int n; - - assert( s ); - - if ( s->len==0 || !is_ws( s->data[0] ) ) return; - - n = 0; - p = s->data; - while ( is_ws( *p ) ) p++; - - q = s->data; - while ( *p ) { - *q++ = *p++; - n++; - } - *q = '\0'; - - s->len = n; -} - -void -str_trimendingws( str *s ) -{ - assert( s ); - while ( s->len > 0 && is_ws( s->data[s->len-1] ) ) { - s->data[s->len-1] = '\0'; - s->len--; - } -} - -int -str_match_first( str *s, char ch ) -{ - assert( s ); - if ( !s->len ) return 0; - if ( s->data[0] == ch ) return 1; - return 0; -} - -int -str_match_end( str *s, char ch ) -{ - assert( s ); - if ( !s->len ) return 0; - if ( s->data[ s->len - 1 ] == ch ) return 1; - return 0; -} - -void -str_trimbegin( str *s, unsigned long n ) -{ - char *p, *q; - - assert( s ); - - if ( n==0 ) return; - if ( s->len==0 ) return; - if ( n >= s->len ) { - str_empty( s ); - return; - } - - p = s->data; - while ( n-- > 0 ) p++; - - n = 0; - q = s->data; - while ( *p ) { - *q++ = *p++; - n++; - } - *q = '\0'; - - s->len = n; -} - -void -str_trimend( str *s, unsigned long n ) -{ - assert( s ); - - if ( n==0 ) return; - if ( n >= s->len ) { - str_empty( s ); - return; - } - - s->len -= n; - s->data[ s->len ] = '\0'; -} - -void -str_pad( str *s, unsigned long len, char ch ) -{ - unsigned long i; - assert( s ); - for ( i=s->len; i<len; i++ ) - str_addchar( s, ch ); -} - -void -str_copyposlen( str *s, str *in, unsigned long pos, unsigned long len ) -{ - unsigned long i, max; - assert( s ); - str_empty( s ); - max = pos+len; - if ( max > in->len ) max = in->len; - for ( i=pos; i<max; ++i ) - str_addchar( s, in->data[i] ); -} - -static void -str_check_case( str *s, int *lowercase, int *uppercase ) -{ - int i; - assert( s ); - *lowercase = 0; - *uppercase = 0; - if ( s->len < 1 ) return; - for ( i=0; i<s->len && !( *lowercase && *uppercase ); ++i ) { - if ( isalpha( (unsigned char)s->data[i] ) ) { - if ( isupper( (unsigned char)s->data[i] ) ) *uppercase += 1; - else if ( islower( (unsigned char)s->data[i] ) ) *lowercase += 1; - } - } -} - -int -str_is_mixedcase( str *s ) -{ - int lowercase, uppercase; - str_check_case( s, &lowercase, &uppercase ); - if ( lowercase > 0 && uppercase > 0 ) return 1; - return 0; -} - -int -str_is_lowercase( str *s ) -{ - int lowercase, uppercase; - str_check_case( s, &lowercase, &uppercase ); - if ( lowercase > 0 && uppercase == 0 ) return 1; - return 0; -} - -int -str_is_uppercase( str *s ) -{ - int lowercase, uppercase; - str_check_case( s, &lowercase, &uppercase ); - if ( lowercase == 0 && uppercase > 0 ) return 1; - return 0; -} - -void -str_stripws( str *s ) -{ - unsigned long len = 0; - char *p, *q; - assert( s ); - if ( s->len ) { - p = q = s->data; - while ( *p ) { - if ( !is_ws( *p ) ) { - *q = *p; - q++; - len++; - } - p++; - } - *q = '\0'; - } - s->len = len; -} - -int -str_strcmp( const str *s, const str *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 && t->len == 0 ) return 0; - if ( s->len == 0 ) return strcmp( "", t->data ); - if ( t->len == 0 ) return strcmp( s->data, "" ); - return strcmp( s->data, t->data ); -} - -int -str_strcmpc( const str *s, const char *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 ) return strcmp( "", t ); - return strcmp( s->data, t ); -} - -int -str_strncmp( const str *s, const str *t, size_t n ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 && t->len == 0 ) return 0; - if ( s->len == 0 ) return strncmp( "", t->data, n ); - if ( t->len == 0 ) return strncmp( s->data, "", n ); - return strncmp( s->data, t->data, n ); -} - -int -str_strncmpc( const str *s, const char *t, size_t n ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 ) return strncmp( "", t, n ); - return strncmp( s->data, t, n ); -} - -int -str_strcasecmp( const str *s, const str *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 && t->len == 0 ) return 0; - if ( s->len == 0 ) return strcasecmp( "", t->data ); - if ( t->len == 0 ) return strcasecmp( s->data, "" ); - return strcasecmp( s->data, t->data ); -} - -int -str_strcasecmpc( const str *s, const char *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 ) return strcasecmp( "", t ); - return strcasecmp( s->data, t ); -} - -char * -str_strstr( const str *s, const str *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 && t->len == 0 ) return strstr( "", "" ); - if ( s->len == 0 ) return strstr( "", t->data ); - if ( t->len == 0 ) return strstr( s->data, "" ); - return strstr( s->data, t->data ); -} - -char * -str_strstrc( const str *s, const char *t ) -{ - assert( s ); - assert( t ); - if ( s->len == 0 ) return strstr( "", t ); - return strstr( s->data, t ); -} - -void -str_reverse( str *s ) -{ - unsigned long i, max; - char tmp; - assert( s ); - max = s->len / 2; - for ( i=0; i<max; ++i ) { - tmp = s->data[ i ]; - s->data[ i ] = s->data[ s->len - 1 - i ]; - s->data[ s->len - 1 - i ] = tmp; - } -} - -int -str_fgetline( str *s, FILE *fp ) -{ - int ch, eol = 0; - assert( s ); - assert( fp ); - str_empty( s ); - if ( feof( fp ) ) return 0; - while ( !feof( fp ) && !eol ) { - ch = fgetc( fp ); - if ( ch == EOF ) { - if ( s->len ) return 1; - else return 0; - } - else if ( ch == '\n' ) eol = 1; - else if ( ch == '\r' ) { - ch = fgetc( fp ); - if ( ch != '\n' ) ungetc( ch, fp ); - eol = 1; - } else { - str_addchar( s, (char) ch ); - } - } - return 1; -} - -/* - * s = "Hi!\0", s.len = 3 - * - * str_char( s, 0 ) = 'H' str_revchar( s, 0 ) = '!' - * str_char( s, 1 ) = 'i' str_revchar( s, 1 ) = 'i' - * str_char( s, 2 ) = '!' str_revchar( s, 2 ) = 'H' - * str_char( s, 3 ) = '\0' str_revchar( s, 3 ) = '\0' - */ -char -str_char( str *s, unsigned long n ) -{ - assert( s ); - if ( s->len==0 || n >= s->len ) return '\0'; - return s->data[ n ]; -} - -char -str_revchar( str *s, unsigned long n ) -{ - assert( s ); - if ( s->len==0 || n >= s->len ) return '\0'; - return s->data[ s->len - n - 1]; -} - -void -str_makepath( str *path, const char *dirname, const char *filename, char sep ) -{ - assert( path ); - if ( dirname ) str_strcpyc( path, dirname ); - else str_empty( path ); - - if ( path->len && path->data[path->len-1]!=sep ) - str_addchar( path, sep ); - - if ( filename ) str_strcatc( path, filename ); -} - -void -str_fill( str *s, unsigned long n, char fillchar ) -{ - unsigned long i; - assert( s ); - str_clear_status( s ); - if ( !s->data || s->dim==0 ) - str_initalloc( s, n+1 ); - if ( n + 1 > s->dim ) - str_realloc( s, n+1 ); - for ( i=0; i<n; ++i ) - s->data[i] = fillchar; - s->data[n] = '\0'; - s->len = n; -} - -int -str_has_value( str *s ) -{ - if ( !s || s->len==0 ) return 0; - return 1; -} - -int -str_is_empty( str *s ) -{ - if ( !s || s->len==0 ) return 1; - return 0; -} - -unsigned long -str_strlen( str *s ) -{ - if ( !s ) return 0; - else return s->len; -} |