X-Git-Url: https://git.deb.at/?a=blobdiff_plain;f=misc.c;h=22ebc800ef941cab85154079e42be606c7a2efb1;hb=2f465ba5e73ba05745d23f0fca9d5bdb1b350d8c;hp=eae1e90178b37ee344fa4f16766936118b6a4137;hpb=12a57d9405d7910566d5ff888d743d29b0716554;p=pkg%2Fabook.git diff --git a/misc.c b/misc.c index eae1e90..22ebc80 100644 --- a/misc.c +++ b/misc.c @@ -2,24 +2,25 @@ /* * $Id$ * - * by JH + * by JH * * Copyright (C) Jaakko Heinonen + * getaline() Copyright (C) Lars Wirzenius + * sprintf and snprintf copyright is owned by various people */ -#define ABOOK_SRC 1 -/*#undef ABOOK_SRC*/ - #include #include #include #include #include #include -#include "misc.h" -#ifdef ABOOK_SRC -# include "abook.h" +#ifdef HAVE_CONFIG_H +# include "config.h" #endif +#include +#include "misc.h" +#include "xmalloc.h" #ifndef DEBUG # define NDEBUG 1 @@ -29,39 +30,13 @@ #include -char * -revstr(char *str) -{ - char *s, *s2; - - s = s2 = strdup(str); - - while( *str ) - str++; - - while( *s ) - *--str = *s++; - - free(s2); - return str; -} - -char * -strupper(char *str) -{ - char *tmp = str; - - while( ( *str = toupper( *str ) ) ) - str++; - - return tmp; -} - char * strlower(char *str) { char *tmp = str; + assert(str != NULL); + while( ( *str = tolower ( *str ) ) ) str++; @@ -75,12 +50,12 @@ strtrim(char *s) assert(s != NULL); - for(t = s; ISSPACE(*t); t++); + for(t = s; isspace(*t); t++); memmove(s, t, strlen(t)+1); for (tt = t = s; *t != '\0'; t++) - if(!ISSPACE(*t)) + if(!isspace(*t)) tt = t+1; *tt = '\0'; @@ -105,17 +80,14 @@ strtrim(char *s) #endif char * -mkstr (const char *format, ... ) +strdup_printf (const char *format, ... ) { MY_VA_LOCAL_DECL; - int size = 100; - char *buffer = -#ifdef ABOOK_SRC - (char *) abook_malloc (size); -#else - (char *) malloc (size); -#endif - + size_t size = 100; + char *buffer = xmalloc (size); + + assert(format != NULL); + for(;;) { int n; MY_VA_START(format); @@ -123,17 +95,15 @@ mkstr (const char *format, ... ) format, ap); MY_VA_END; - if (n > -1) + if (n > -1 && n < size) return buffer; - size *= 2; - - buffer = -#ifdef ABOOK_SRC - (char *) abook_realloc (buffer, size); -#else - (char *) realloc (buffer, size); -#endif + if (n > -1) + size = n + 1; + else + size *= 2; + + buffer = xrealloc(buffer, size); } } @@ -141,12 +111,11 @@ mkstr (const char *format, ... ) char* strconcat (const char *str, ...) { - int l; + unsigned long l; MY_VA_LOCAL_DECL; char *s, *concat; - if(str == NULL) - return NULL; + assert(str != NULL); l = 1 + strlen (str); MY_VA_START(str); @@ -156,13 +125,8 @@ strconcat (const char *str, ...) MY_VA_SHIFT(s, char*); } MY_VA_END; - - concat = (char *) -#ifdef ABOOK_SRC - abook_malloc(l); -#else - malloc(l); -#endif + + concat = xmalloc(l); strcpy (concat, str); MY_VA_START(str); @@ -178,7 +142,7 @@ strconcat (const char *str, ...) int -safe_strcmp(const char *s1, const char * s2) +safe_strcmp(const char *s1, const char *s2) { if (s1 == NULL && s2 == NULL) return 0; if (s1 == NULL) return -1; @@ -187,25 +151,65 @@ safe_strcmp(const char *s1, const char * s2) return strcmp(s1, s2); } +int +safe_strcoll(const char *s1, const char *s2) +{ +#ifdef HAVE_STRCOLL + if (s1 == NULL && s2 == NULL) return 0; + if (s1 == NULL) return -1; + if (s2 == NULL) return 1; + + return strcoll(s1, s2); +#else /* fall back to strcmp */ + return safe_strcmp(s1, s2); +#endif +} + char * my_getcwd() { char *dir = NULL; - int size = 100; + size_t size = 100; + + if( (dir = xmalloc(size)) == NULL) + return NULL; + + *dir = 0; - dir = malloc(size); - while( getcwd(dir, size) == NULL && errno == ERANGE ) - dir = realloc(dir, size *=2); + if( (dir = xrealloc(dir, size *=2)) == NULL) + return NULL; return dir; } -#define INITIAL_SIZE 128 -#ifndef ABOOK_SRC -# define abook_malloc(X) malloc(X) -# define abook_realloc(X, XX) realloc(X, XX) -#endif +/* + * getaline() + * + * Copyright (c) 1994 Lars Wirzenius + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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. + */ char * getaline(FILE *f) @@ -229,7 +233,7 @@ getaline(FILE *f) len = 0; size = thres; - buf = abook_malloc(size); + buf = xmalloc(size); while (fgets(buf+len, size-len, f) != NULL) { len += strlen(buf+len); @@ -237,7 +241,8 @@ getaline(FILE *f) break; /* the whole line has been read */ for (inc = size, p = NULL; inc > mininc; inc /= 2) - if ((p = abook_realloc(buf, size + inc)) != NULL) + if ((p = xrealloc_inc(buf, size, inc)) != + NULL) break; size += inc; @@ -245,7 +250,7 @@ getaline(FILE *f) } if (len == 0) { - free(buf); + xfree(buf); return NULL; /* nothing read (eof or error) */ } @@ -253,7 +258,7 @@ getaline(FILE *f) buf[--len] = '\0'; if (size - len > mucho) { /* a plenitude of unused memory? */ - p = abook_realloc(buf, len+1); + p = xrealloc_inc(buf, len, 1); if (p != NULL) { buf = p; size = len+1; @@ -263,6 +268,24 @@ getaline(FILE *f) return buf; } +int +strwidth(const char *s) +{ + assert(s); + return mbswidth(s, 0); +} + +int +bytes2width(const char *s, int width) +{ + assert(s); +#ifdef HANDLE_MULTIBYTE + return mbsnbytes(s, strlen(s), width, 0); +#else + return width; +#endif +} + /************************************************************** * Original: * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 @@ -293,9 +316,9 @@ getaline(FILE *f) * original. Also, there is now a builtin-test, just compile with: * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm * and run snprintf for results. - * + * * Thomas Roessler 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. + * The PGP code was using unsigned hexadecimal formats. * Unfortunately, unsigned formats simply didn't work. * * Michael Elkins 03/05/98 for mutt 0.90.8 @@ -344,7 +367,7 @@ getaline(FILE *f) /*int snprintf (char *str, size_t count, const char *fmt, ...);*/ /*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ -static void dopr (char *buffer, size_t maxlen, const char *format, +static void dopr (char *buffer, size_t maxlen, const char *format, va_list args); static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, char *value, int flags, int min, int max); @@ -397,7 +420,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) int flags; int cflags; size_t currlen; - + state = DP_S_DEFAULT; currlen = flags = cflags = min = 0; max = -1; @@ -405,20 +428,20 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) while (state != DP_S_DONE) { - if ((ch == '\0') || (currlen >= maxlen)) + if ((ch == '\0') || (currlen >= maxlen)) state = DP_S_DONE; - switch(state) + switch(state) { case DP_S_DEFAULT: - if (ch == '%') + if (ch == '%') state = DP_S_FLAGS; - else + else dopr_outch (buffer, &currlen, maxlen, ch); ch = *format++; break; case DP_S_FLAGS: - switch (ch) + switch (ch) { case '-': flags |= DP_F_MINUS; @@ -446,49 +469,49 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) } break; case DP_S_MIN: - if (isdigit((unsigned char)ch)) + if (isdigit((unsigned char)ch)) { min = 10*min + char_to_int (ch); ch = *format++; - } - else if (ch == '*') + } + else if (ch == '*') { min = va_arg (args, int); ch = *format++; state = DP_S_DOT; - } - else + } + else state = DP_S_DOT; break; case DP_S_DOT: - if (ch == '.') + if (ch == '.') { state = DP_S_MAX; ch = *format++; - } - else + } + else state = DP_S_MOD; break; case DP_S_MAX: - if (isdigit((unsigned char)ch)) + if (isdigit((unsigned char)ch)) { if (max < 0) max = 0; max = 10*max + char_to_int (ch); ch = *format++; - } - else if (ch == '*') + } + else if (ch == '*') { max = va_arg (args, int); ch = *format++; state = DP_S_MOD; - } - else + } + else state = DP_S_MOD; break; case DP_S_MOD: /* Currently, we don't support Long Long, bummer */ - switch (ch) + switch (ch) { case 'h': cflags = DP_C_SHORT; @@ -508,11 +531,11 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) state = DP_S_CONV; break; case DP_S_CONV: - switch (ch) + switch (ch) { case 'd': case 'i': - if (cflags == DP_C_SHORT) + if (cflags == DP_C_SHORT) value = va_arg (args, short int); else if (cflags == DP_C_LONG) value = va_arg (args, long int); @@ -581,7 +604,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) break; case 's': strvalue = va_arg (args, char *); - if (max < 0) + if (max < 0) max = maxlen; /* ie, no max */ fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); break; @@ -590,19 +613,19 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); break; case 'n': - if (cflags == DP_C_SHORT) + if (cflags == DP_C_SHORT) { short int *num; num = va_arg (args, short int *); *num = currlen; - } - else if (cflags == DP_C_LONG) + } + else if (cflags == DP_C_LONG) { long int *num; num = va_arg (args, long int *); *num = currlen; - } - else + } + else { int *num; num = va_arg (args, int *); @@ -632,9 +655,9 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) break; /* some picky compilers need this */ } } - if (currlen < maxlen - 1) + if (currlen < maxlen - 1) buffer[currlen] = '\0'; - else + else buffer[maxlen - 1] = '\0'; } @@ -643,7 +666,7 @@ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, { int padlen, strln; /* amount to pad */ int cnt = 0; - + if (value == 0) { value = ""; @@ -651,23 +674,23 @@ static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, for (strln = 0; value[strln]; ++strln); /* strlen */ padlen = min - strln; - if (padlen < 0) + if (padlen < 0) padlen = 0; - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justify */ - while ((padlen > 0) && (cnt < max)) + while ((padlen > 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); --padlen; ++cnt; } - while (*value && (cnt < max)) + while (*value && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, *value++); ++cnt; } - while ((padlen < 0) && (cnt < max)) + while ((padlen < 0) && (cnt < max)) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; @@ -687,7 +710,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, int spadlen = 0; /* amount to space pad */ int zpadlen = 0; /* amount to zero pad */ int caps = 0; - + if (max < 0) max = 0; @@ -706,7 +729,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, if (flags & DP_F_SPACE) signvalue = ' '; } - + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ do { @@ -727,7 +750,7 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, zpadlen = MAX(zpadlen, spadlen); spadlen = 0; } - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) spadlen = -spadlen; /* Left Justifty */ #ifdef DEBUG_SNPRINTF @@ -736,18 +759,18 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, #endif /* Spaces */ - while (spadlen > 0) + while (spadlen > 0) { dopr_outch (buffer, currlen, maxlen, ' '); --spadlen; } /* Sign */ - if (signvalue) + if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); /* Zeros */ - if (zpadlen > 0) + if (zpadlen > 0) { while (zpadlen > 0) { @@ -757,9 +780,9 @@ static void fmtint (char *buffer, size_t *currlen, size_t maxlen, } /* Digits */ - while (place > 0) + while (place > 0) dopr_outch (buffer, currlen, maxlen, convert[--place]); - + /* Left Justified spaces */ while (spadlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); @@ -786,7 +809,7 @@ static long double pow10 (int exp) result *= 10; exp--; } - + return result; } @@ -812,12 +835,12 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, int iplace = 0; int fplace = 0; int padlen = 0; /* amount to pad */ - int zpadlen = 0; + int zpadlen = 0; int caps = 0; long intpart; long fracpart; - - /* + + /* * AIX manpage says the default is 0, but Solaris says the default * is 6, and sprintf on AIX defaults to 6 */ @@ -841,8 +864,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, intpart = ufvalue; - /* - * Sorry, we only support 9 digits past the decimal because of our + /* + * Sorry, we only support 9 digits past the decimal because of our * conversion method */ if (max > 9) @@ -882,18 +905,18 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, fconvert[fplace] = 0; /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); zpadlen = max - fplace; if (zpadlen < 0) zpadlen = 0; - if (padlen < 0) + if (padlen < 0) padlen = 0; - if (flags & DP_F_MINUS) + if (flags & DP_F_MINUS) padlen = -padlen; /* Left Justifty */ - if ((flags & DP_F_ZERO) && (padlen > 0)) + if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) + if (signvalue) { dopr_outch (buffer, currlen, maxlen, signvalue); --padlen; @@ -910,10 +933,10 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, dopr_outch (buffer, currlen, maxlen, ' '); --padlen; } - if (signvalue) + if (signvalue) dopr_outch (buffer, currlen, maxlen, signvalue); - while (iplace > 0) + while (iplace > 0) dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); /* @@ -922,7 +945,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, */ dopr_outch (buffer, currlen, maxlen, '.'); - while (fplace > 0) + while (fplace > 0) dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); while (zpadlen > 0) @@ -931,7 +954,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, --zpadlen; } - while (padlen < 0) + while (padlen < 0) { dopr_outch (buffer, currlen, maxlen, ' '); ++padlen; @@ -968,7 +991,7 @@ int snprintf (va_alist) va_dcl char *fmt; #endif VA_LOCAL_DECL; - + VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); @@ -1000,7 +1023,7 @@ int main (void) "%3.2f", NULL }; - double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, 4.136, 0}; char *int_fmt[] = { "%-1.5d", @@ -1028,7 +1051,7 @@ int main (void) sprintf (buf2, fp_fmt[x], fp_nums[y]); if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", fp_fmt[x], buf1, buf2); fail++; } @@ -1042,7 +1065,7 @@ int main (void) sprintf (buf2, int_fmt[x], int_nums[y]); if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", int_fmt[x], buf1, buf2); fail++; }