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