/************************************************************************************************** $Header: /pub/cvsroot/yencode/lib/string.c,v 1.10 2002/03/12 02:01:43 bboy Exp $ Copyright (C) 2002 Don Moore This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at Your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **************************************************************************************************/ #include "misc.h" /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ BYTESTR Given a number, returns a textual, abbreviated string describing the number of bytes it represents. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char * bytestr(u_int64_t number) { char numbuf[80]; if (number > 99999) { number = (number + 500) / 1000; if (number > 9999) { number = (number + 500) / 1000; if (number > 9999) { number = (number + 500) / 1000; if (number > 9999) { number = (number + 500) / 1000; snprintf(numbuf, sizeof(numbuf), "%lluT", number); } else snprintf(numbuf, sizeof(numbuf), "%lluG", number); } else snprintf(numbuf, sizeof(numbuf), "%lluM", number); } else snprintf(numbuf, sizeof(numbuf), "%lluk", number); } else snprintf(numbuf, sizeof(numbuf), "%llu", number); return (xstrdup(numbuf)); } /*--- bytestr() ---------------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Given a string such as "10MB" returns the size represented, in bytes. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ size_t human_file_size(const char *str) { size_t numeric = 0; /* Numeric part of `str' */ register char *c; /* Ptr to first nonalpha char */ numeric = (size_t)strtoul(str, (char **)NULL, 10); for (c = (char *)str; *c && isdigit(*c); c++) /* DONOTHING */; if (!*c) return (numeric); /* I am using values like 1000 instead of 1024, since that's what most people expect */ switch (tolower(*c)) { case 'k': return (numeric * 1000); case 'm': return (numeric * 1000000); case 'g': return (numeric * 1000000000); default: /* Silently ignore unknown quantifiers */ break; } return (numeric); } /*--- human_file_size() -------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Removes leading and trailing whitespace from a string. Converts tabs and newlines to spaces. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char * strtrim(char *str) { if (!str) return (str); while (isspace(str[0]) || iscntrl(str[0])) memmove(str, str+1, strlen(str)); while (isspace(str[strlen(str)-1]) || iscntrl(str[strlen(str)-1])) str[strlen(str)-1] = '\0'; return (str); } /*--- strtrim() ---------------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CONFTRIM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ char * conftrim(char *str) { register char *ibuf, *obuf; if (!str) return (NULL); /* Strip comments */ for (ibuf = obuf = str; *ibuf; ) { if (*ibuf == '#') { if (obuf > str && obuf[-1] == '\\') obuf[-1] = '#'; else *(obuf++) = '\0'; ibuf++; } else *(obuf++) = *(ibuf++); } for (ibuf = obuf = str; *ibuf; ) { while (*ibuf && (isspace(*ibuf) || iscntrl(*ibuf))) ibuf++; if (*ibuf && (obuf != str)) *(obuf++) = ' '; while (*ibuf && (!isspace(*ibuf) && !iscntrl(*ibuf))) *(obuf++) = *(ibuf++); } *obuf = '\0'; return (str); } /*--- conftrim() --------------------------------------------------------------------------------*/ /************************************************************************************************** COMMAFMT Copies the numeric value of N into buffer 'buf' of size 'bufsiz', inserting commas where appropriate. **************************************************************************************************/ static size_t commafmt(char *buf, size_t bufsiz, unsigned long N) { int len = 1, posn = 1, sign = 1; char *ptr = buf + bufsiz - 1; if (2 > bufsiz) { ABORT:*buf = '\0'; return 0; } *ptr-- = '\0'; --bufsiz; if (0L > N) { sign = -1; N = -N; } for ( ; len <= bufsiz; ++len, ++posn) { *ptr-- = (char)((N % 10L) + '0'); if (0L == (N /= 10L)) break; if (0 == (posn % 3)) { *ptr-- = ','; ++len; } if (len >= bufsiz) goto ABORT; } if (0 > sign) { if (0 == bufsiz) goto ABORT; *ptr-- = '-'; ++len; } strcpy(buf, ++ptr); return (size_t)len; } /*--- commafmt() --------------------------------------------------------------------------------*/ /************************************************************************************************** COMMA1-3 Making printf life easy for Don at the expense of repetition and a few hundred bytes of RAM. **************************************************************************************************/ char *comma(u_int64_t num) { static char cbuf[81]; commafmt(cbuf, 80, num); return (cbuf); } char *comma1(u_int64_t num) { static char cbuf[81]; commafmt(cbuf, 80, num); return (cbuf); } char *comma2(u_int64_t num) { static char cbuf[81]; commafmt(cbuf, 80, num); return (cbuf); } char *comma3(u_int64_t num) { static char cbuf[81]; commafmt(cbuf, 80, num); return (cbuf); } /*--- comma1-3() --------------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ NUMERIC_WIDTH Given a number, returns the maximum numeric width. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ int numeric_width(unsigned long num) { char numbuf[80]; snprintf(numbuf, sizeof(numbuf), "%lu", num); return (strlen(numbuf)); } /*--- numeric_width() ---------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ SDPRINTF A dynamic sprintf; grows the buffer as it adds lines. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void sdprintf(unsigned char **dest, const char *fmt, ...) { char msg[BUFSIZ]; va_list ap; unsigned char *d = *dest; register int msglen, destlen; va_start(ap, fmt); msglen = vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); destlen = (d) ? strlen(d) : 0; d = xrealloc(d, destlen + msglen + 1); memcpy(d + destlen, msg, msglen); d[destlen + msglen] = '\0'; *dest = d; } /*--- sdprintf() --------------------------------------------------------------------------------*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ESCDUMP For debugging, dumps a buffer with characters escaped. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ void escdump(const unsigned char *buf, size_t len) { register size_t ct; for (ct = 0; ct < len; ct++) { switch (buf[ct]) { case '\r': printf("\033[1m\\r\033[0m"); break; case '\n': printf("\033[1m\\n\033[0m\n"); break; case '\t': printf("\033[1m\\t\033[0m"); break; default: if (isprint(buf[ct])) putc(buf[ct], stdout); else printf("\033[1m\\%03o[0m", buf[ct]); break; } } fflush(stdout); } /*--- escdump() ---------------------------------------------------------------------------------*/ /* vi:set ts=3: */