X-Git-Url: https://git.deb.at/w?p=pkg%2Fabook.git;a=blobdiff_plain;f=misc.c;h=0f96b7a878316948c11d98a70259865d5e70ac55;hp=225d1563f9e048b981bff605bb7283e6ad9c189e;hb=HEAD;hpb=49aa0214d72eb609845e292772819de414034c55 diff --git a/misc.c b/misc.c index 225d156..0f96b7a 100644 --- a/misc.c +++ b/misc.c @@ -2,24 +2,26 @@ /* * $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 "abook.h" +#include "misc.h" +#include "xmalloc.h" #ifndef DEBUG # define NDEBUG 1 @@ -29,39 +31,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 +51,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'; @@ -88,6 +64,41 @@ strtrim(char *s) return s; } +int +is_number(char *p) +{ + if(!p || !*p || (*p == '-' && !*++p)) + return 0; + + for(; *p; p++) + if(!isdigit(*p)) + return 0; + + return 1; +} + +#ifndef HAVE_STRCASESTR +char * +strcasestr(const char *haystack, const char *needle) +{ + int i; + int k; + + assert(haystack != NULL); + assert(needle != NULL); + + for(i=0; i mininc; inc /= 2) - if ((p = abook_realloc(buf, size + inc)) != NULL) + if ((p = xrealloc_inc(buf, size, inc)) != + NULL) break; size += inc; @@ -248,7 +286,7 @@ getaline(FILE *f) } if (len == 0) { - free(buf); + xfree(buf); return NULL; /* nothing read (eof or error) */ } @@ -256,7 +294,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; @@ -266,6 +304,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 @@ -296,9 +352,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 @@ -347,7 +403,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); @@ -400,7 +456,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; @@ -408,20 +464,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; @@ -449,49 +505,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; @@ -511,11 +567,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); @@ -584,7 +640,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; @@ -593,19 +649,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 *); @@ -635,9 +691,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'; } @@ -646,7 +702,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 = ""; @@ -654,23 +710,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; @@ -690,7 +746,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; @@ -709,7 +765,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 { @@ -730,7 +786,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 @@ -739,18 +795,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) { @@ -760,9 +816,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, ' '); @@ -789,7 +845,7 @@ static long double pow10 (int exp) result *= 10; exp--; } - + return result; } @@ -815,12 +871,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 */ @@ -844,8 +900,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) @@ -885,18 +941,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; @@ -913,10 +969,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]); /* @@ -925,7 +981,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) @@ -934,7 +990,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; @@ -971,7 +1027,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 ); @@ -1003,7 +1059,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", @@ -1031,7 +1087,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++; } @@ -1045,7 +1101,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++; } @@ -1056,3 +1112,189 @@ int main (void) #endif /* SNPRINTF_TEST */ #endif /* !HAVE_SNPRINTF */ + + + + +/* + * List handling functions + */ + +void +abook_list_append(abook_list **list, char *str) +{ + abook_list *tmp; + + if(!str) + return; + + for(tmp = *list; tmp && tmp->next; tmp = tmp->next) + ; + + if(tmp) { + tmp->next = xmalloc(sizeof(abook_list)); + tmp = tmp->next; + } else + tmp = *list = xmalloc(sizeof(abook_list)); + + tmp->data = xstrdup(str); + tmp->next = NULL; +} + +void +abook_list_free(abook_list **list) +{ + abook_list *prev = NULL, *tmp = *list; + + if(!list) + return; + + while(tmp) { + xfree(tmp->data); + prev = tmp; + tmp = tmp->next; + xfree(prev); + } + + *list = NULL; +} + +abook_list * +csv_to_abook_list(char *str) +{ + char *start, *p = str, *end; + abook_list *list = NULL; + + if(!str) + return NULL; + + SKIPWS(p); + start = end = p; + + while(*p) { + if(!strchr(", ", *p)) { + end = ++p; + continue; + } + + if((*p == ',') && (end - start)) { + abook_list_append(&list, xstrndup(start, end - start)); + p++; + SKIPWS(p); + start = end = p; + continue; + } + + p++; + } + if(end - start) + abook_list_append(&list, xstrndup(start, end - start)); + + return list; +} + +char * +abook_list_to_csv(abook_list *list) +{ + abook_list *tmp; + char *res = NULL; + + for(tmp = list; tmp; tmp = tmp->next) { + if(tmp == list) + res = xstrdup(tmp->data); + else { + res = xrealloc(res, strlen(res)+strlen(tmp->data)+2); + strcat(res, ","); + strcat(res, tmp->data); + } + } + + return res; +} + +void +abook_list_rotate(abook_list **list, enum rotate_dir dir) +{ + abook_list *tmp = *list; + + if(!tmp || !tmp->next) + return; + + switch(dir) { + case ROTATE_LEFT: + for(; tmp && tmp->next; tmp = tmp->next) + ; + + tmp->next = *list; + tmp = *list; + *list = (*list)->next; + tmp->next = NULL; + break; + case ROTATE_RIGHT: + for(; tmp && tmp->next && tmp->next->next; + tmp = tmp->next) + ; + + tmp->next->next = *list; + *list = tmp->next; + tmp->next = NULL; + break; + default: + assert(0); + } +} + +/* if str == NULL, deleting the list element */ +void +abook_list_replace(abook_list **list, int index, char *str) +{ + abook_list *cur, *prev; + int i = 0; + + cur = prev = *list; + + if((index == 0) && !str) { + *list = cur->next; + free(cur->data); + free(cur); + return; + } + + while(1) { + if(!cur) + return; + + if(i == index) + break; + + prev = cur; + cur = cur->next; + i++; + } + + if(str) { + free(cur->data); + cur->data = xstrdup(str); + } else { + prev->next = cur->next; + free(cur->data); + free(cur); + } +} + +abook_list * +abook_list_get(abook_list *list, int index) +{ + int i = 0; + + while(1) { + if(!list) + return NULL; + + if(i == index) + return list; + + i++; + list = list->next; + } +}