diff options
Diffstat (limited to 'src/common.c')
-rw-r--r-- | src/common.c | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..054dae4 --- /dev/null +++ b/src/common.c @@ -0,0 +1,376 @@ +/* + * common.c -- miscellanious helper functions. + * + * Copyright (c) 2003, WiseGuys Internet B.V. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * - Neither the name of the WiseGuys Internet B.V. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include "common.h" + +extern void wgmem_error( const char *fmt, ... ) +{ + va_list ap; + + fprintf(stderr, "MEMERROR : "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(-1); +} + + +extern void *wg_malloc( size_t size ) +{ + void *result; + if ( !size ) { + wgmem_error( "Error mallocing 0 bytes.\n" ); + } + + result = malloc( size ); + if ( !result ) { + wgmem_error( "Error while mallocing %u bytes.\n", size ); + } + + return result; +} + +extern void *wg_calloc( size_t nmemb, size_t size ) +{ + void *result; + if ( !size || !nmemb ) { + wgmem_error( "Error callocing 0 bytes.\n" ); + } + + result = calloc( nmemb, size ); + if ( !result ) { + wgmem_error( "Error while callocing %u elements of %u bytes.\n", nmemb, size); + } + + return result; +} + +extern void *wg_zalloc( size_t size ) +{ + void *result; + + if (!size) { + wgmem_error( "Error zallocing 0 bytes.\n" ); + } + + result = calloc(1, size); + if ( !result ) { + wgmem_error( "Error while zallocing %u bytes.\n", size ); + } + + return result; +} + +extern char* wg_strdup( const char *s ) +{ + char *result = strdup( s ); + + if ( !result ) { + wgmem_error( "Error while strduping %u bytes.\n", strlen(s) ); + } + + return( result ); +} + +extern void* wg_realloc( void *ptr, size_t size ) +{ + void *result; + + if (!size) { + wgmem_error( "Error reallocing 0 bytes.\n" ); + } + + result = realloc( ptr, size ); + if ( !result ) { + wgmem_error( "Error while reallocing %u bytes.\n", size ); + } + + return( result ); +} + +extern void wg_free( void *mem ) +{ + if ( mem ) { + free(mem); + } +} + +extern char *wg_getline( char *line, int size, FILE *fp ) +{ + char *p; + + if ( fgets(line, size, fp) == NULL ) { + return NULL; + } + + /** kill term null **/ + if ( (p = strpbrk( line, "\n\r" )) ) { + *p = '\0'; + } + + return line; +} + + + +/* + * wg_split: split a line into segments, using whitespace-sequences as separators. + * + * ARGUMENTS: + * - result: + * + * After the split, this array contains pointers to the start of each + * detected segment. Must be preallocated and at least as large as + * maxsegments. The pointers point into the dest buffer. + * + * - dest: + * + * String into which result points as an index. Must be preallocated, and + * at least as big as src. You can use src as dest, but in that case src + * is overwritten! + * + * - src: + * + * The string to split. Sequences of whitespace are treated as separators, unless + * escaped. There are two ways to escape: by using single quotes (anything + * between single quotes is treated as one segment), or by using a backslash + * to escape the next character. The backslash escape works inside quotation + * as well. + * + * Example: + * + * "It\'s very\ easy 'to use WiseGuys\' wg_split()' function" is split into: + * + * "It's" + * "very easy" + * "to use WiseGuys' wg_split()" + * "function" + * + * - maxsegments: + * + * The maximum number of segments. If the splitter runs out of segments, + * the remainder of the string is stored in the last segment. + * + * RETURN VALUE: + * The number of segments found. + */ +unsigned int wg_split( char **result, char *dest, char *src, int maxsegments ) +{ + char *p = src; + char *w = dest; + int cnt = 0; + int state=0; + + if ( maxsegments == 0 ) { + return 0; + } + + maxsegments--; + + while (cnt < maxsegments && *p) { + + switch (state) { + case 0: + /*** Skip spaces ***/ + while ( isspace((int) *p) ) { + p++; + } + state = 1; + + case 1: + /*** Start segment ***/ + result[cnt] = w; + cnt++; + state = 2; + + case 2: + /*** Unquoted segment ***/ + while (*p) { + if ( isspace((int) *p) ) { + *w++ = '\0'; + p++; + state = 0; + break; + } + else if ( *p == '\'' ) { + /*** Start quotation ***/ + p++; + state = 3; + break; + } + else if ( *p == '\\' && p[1] ) { + /*** Escape ***/ + p++; + *w++ = *p++; + } + else { + *w++ = *p++; + } + } + break; + + case 3: + /*** Inside quotes ***/ + while (*p) { + if (*p == '\'') { + p++; + break; + } + else if ( *p == '\\' && p[1] ) { + /*** Escape ***/ + p++; + *w++ = *p++; + } + else { + *w++ = *p++; + } + } + state = 2; + break; + + } + } + + if ( !*p ) { + *w = '\0'; + return cnt; + } + + /*** We ran out of segments; copy the remainder of the string into last segment ***/ + result[cnt++] = w; + while (*p) { + *w++ = *p++; + } + *w = '\0'; + return cnt; +} + + +extern void wg_timerstart(wgtimer_t *t) +{ + gettimeofday( &(t->start), NULL ); +} + + + +extern uint4 wg_timerstop(wgtimer_t *t) +{ + uint4 result; + gettimeofday( &(t->stop), NULL ); + result = (t->stop.tv_sec - t->start.tv_sec) * 1000000 + + (t->stop.tv_usec - t->start.tv_usec); + + t->start.tv_sec = t->stop.tv_sec; + t->start.tv_usec = t->stop.tv_usec; + + return result; +} + + +/** + * wg_strgmov -- a guarded strcpy() variation + * + * copies src to dest (including terminating zero), and returns + * pointer to position of terminating zero in dest. The function is + * guaranteed not to write past destlimit. If the copy couldn't be + * finished, the function returns NULL after restoring the first + * character in dest for your convenience (since this is usually a zero). + */ +char *wg_strgmov( char *dest, const char *src, const char *destlimit ) +{ + char tmp, *w; + + if ( !dest || dest >= destlimit ) { + return NULL; + } + + tmp = *dest; + w = dest; + + while ( *src ) { + + *w++ = *src++; + + if ( w == destlimit ) { + /*** restore old situation ***/ + *dest = tmp; + return NULL; + } + } + + *w = '\0'; + return w; + +} + +/* + * wg_trim() -- remove whitespace surrounding a string. + * + * Example: " bla bla bla " becomes "bla bla bla" after trimming. + * + * ARGUMENTS + * - dest : After the trim, this will point to the trimmed string. + * Must be preallocated and at least as big as src. You can + * use src as dest. + * - src : Points to the string to be trimmed. + * + * RETURNS: + * dest + */ +char *wg_trim( char *dest, const char *src ) +{ + char *lastnonspace = &dest[-1]; + const char *p = src; + char *w = dest; + + while ( isspace((int)*p) ) { + p++; + } + while (*p) { + if ( !isspace((int)*p) ) { + lastnonspace = w; + } + *w++ = *p++; + } + lastnonspace[1] = '\0'; + + return dest; +} + |