1 /*
2 Copyright (c) 2003 Bruno T. C. de Oliveira
3 
4 LICENSE INFORMATION:
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 General Public License for more details.
14 
15 You should have received a copy of the GNU General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 Copyright (c) 2002 Bruno T. C. de Oliveira
19 
20 INFORMA��ES DE LICEN�A:
21 Este programa � um software de livre distribui��o; voc� pode
22 redistribu�-lo e/ou modific�-lo sob os termos da GNU General
23 Public License, conforme publicado pela Free Software Foundation,
24 pela vers�o 2 da licen�a ou qualquer vers�o posterior.
25 
26 Este programa � distribu�do na esperan�a de que ele ser� �til
27 aos seus usu�rios, por�m, SEM QUAISQUER GARANTIAS; sem sequer
28 a garantia impl�cita de COMERCIABILIDADE ou DE ADEQUA��O A
29 QUALQUER FINALIDADE ESPEC�FICA. Consulte a GNU General Public
30 License para obter mais detalhes (uma c�pia acompanha este
31 programa, armazenada no arquivo COPYING).
32 */
33 
34 #include "util.h"
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 
dstrset(char ** ptr,const char * new_value)40 char *dstrset(char **ptr, const char *new_value) {
41    if (*ptr) free(*ptr);
42    return (*ptr = new_value ? sstrdup(new_value) : 0);
43 }
44 
zalloc(int bytes)45 void *zalloc(int bytes) {
46    void *buf;
47 
48    if (bytes <= 0) return 0;
49 
50    if (!(buf = malloc(bytes))) {
51       fprintf(stderr, "*** FATAL ERROR ***\n"
52                       "zalloc failed to allocate memory.\n"
53                       "Request size: %d bytes.\n\nSorry.\n", bytes);
54       abort();
55    }
56 
57    memset(buf, 0, bytes);
58    return buf;
59 }
60 
sstrdup(const char * s)61 char* sstrdup(const char *s) {
62    char *r;
63    if (!s) return 0;
64 
65    if ( !(r = strdup(s)) ) {
66       fprintf(stderr, "*** FATAL ERROR ***\n"
67                       "sstrdup failed to allocate memory.\n");
68       abort();
69    }
70    return r;
71 }
72 
srealloc(void * buf,int newsize)73 void *srealloc(void *buf, int newsize) {
74    if (!buf) return zalloc(newsize);
75    if (!(buf = realloc(buf, newsize))) {
76       fprintf(stderr, "*** FATAL ERROR ***\n"
77                       "srealloc failed to reallocate memory.\n"
78                       "Request size: %d bytes.\n\nSorry.\n", newsize);
79       abort();
80    }
81    return buf;
82 }
83 
minimum(int a,int b)84 int minimum(int a, int b) { return (a < b) ? a : b; }
maximum(int a,int b)85 int maximum(int a, int b) { return (a > b) ? a : b; }
minimum_d(double a,double b)86 double minimum_d(double a, double b) { return (a < b) ? a : b; }
maximum_d(double a,double b)87 double maximum_d(double a, double b) { return (a > b) ? a : b; }
88 
89 
printable_char(int ch)90 int printable_char(int ch) {
91    if (ch < 0 || ch > 255) return 0;     /* not in char range */
92    if (ch <= 31 || ch == 127) return 0;  /* control character */
93    return 1;
94 }
95 
str_fit_ex(const char * orig,int size,int padch)96 char *str_fit_ex(const char *orig, int size, int padch) {
97    char *s; char *p;
98    if (size <= 0) return 0;
99 
100    p = s = zalloc(size + 1);
101    while (p - s < size)
102       *(p++) = (*orig) ? *(orig++) : padch;
103 
104    *p = 0;
105    return s;
106 }
107 
str_fit(const char * orig,int size)108 char *str_fit(const char *orig, int size) {
109    return str_fit_ex(orig, size, ' ');
110 }
111 
timeval_dif(const struct timeval * a,const struct timeval * b)112 float timeval_dif(const struct timeval* a, const struct timeval* b) {
113    long to_remove;
114    float af, bf;
115    if (a->tv_sec > b->tv_sec) to_remove = b->tv_sec;
116    else to_remove = a->tv_sec;
117 
118    af = (float)(a->tv_sec - to_remove) + a->tv_usec / 1000000.0f;
119    bf = (float)(b->tv_sec - to_remove) + b->tv_usec / 1000000.0f;
120    return af - bf;
121 }
122 
fsavestr(const char * str,FILE * f)123 void fsavestr(const char *str, FILE *f) {
124    int len = strlen(str);
125 
126    fwrite(&len, sizeof(int), 1, f);
127    while (*str) fputc(*(str++), f);
128 }
129 
floadstr(FILE * f)130 char *floadstr(FILE *f) {
131    char *str, *p; int len;
132 
133    fread(&len, sizeof(int), 1, f);
134 
135    p = str = zalloc(len + 1);
136    while (len--) *(p++) = fgetc(f);
137 
138    return str;
139 }
140 
interval_intersect(int a0,int a1,int b0,int b1,int * c0,int * c1)141 void interval_intersect(int a0, int a1, int b0, int b1, int *c0, int *c1) {
142    *c0 = maximum(a0, b0);
143    *c1 = minimum(a1, b1);
144 }
145 
interval_intersect_d(double a0,double a1,double b0,double b1,double * c0,double * c1)146 void interval_intersect_d(double a0, double a1, double b0, double b1,
147                           double *c0, double *c1) {
148    *c0 = maximum_d(a0, b0);
149    *c1 = minimum_d(a1, b1);
150 }
151 
sort_two(int v0,int v1,int * r0,int * r1)152 void sort_two(int v0, int v1, int *r0, int *r1) {
153   if (v0 <= v1) {
154      if (r0) *r0 = v0;
155      if (r1) *r1 = v1;
156   }
157   else {
158      if (r0) *r0 = v1;
159      if (r1) *r1 = v0;
160   }
161 }
162 
dsprintf(const char * fmt,...)163 char *dsprintf(const char *fmt, ...) {
164    /* this function was adapted from the example provided in
165     * Linux man page for printf(3) */
166    int n, size = 100;
167    char *p;
168    va_list ap;
169 
170    p = zalloc(size);
171 
172    while (1) {
173       /* Try to print in the allocated space. */
174       va_start(ap, fmt); n = vsnprintf (p, size, fmt, ap); va_end(ap);
175 
176       /* If that worked, return the string. */
177       if (n > -1 && n < size)  return p;
178 
179       /* Else try again with more space. */
180       if (n > -1)    /* glibc 2.1 */
181          size = n+1; /* precisely what is needed */
182       else           /* glibc 2.0 */
183           size *= 2;  /* twice the old size */
184 
185       p = srealloc (p, size);
186    }
187 }
188 
sfree(void * ptr)189 void sfree(void *ptr) {
190    if (ptr) free(ptr);
191 }
192 
zfree(char ** str)193 void zfree(char **str) {
194    if (*str) {
195       free(*str);
196       *str = 0;
197    }
198 }
199 
freadline(FILE * f)200 char *freadline(FILE *f) {
201    return freadline_ex((void*)f, (int(*)(void*)) fgetc);
202 }
203 
freadline_ex(void * fh,int (* readch)(void *))204 char *freadline_ex(void *fh, int (*readch)(void*)) {
205    int size = 64;
206    char *buf;
207    int i;
208    char ch;
209 
210    /* read in the first character */
211    ch = readch(fh);
212    if (ch < 0) return NULL;
213 
214    /* allocate buffer */
215    buf = zalloc(size + 1);
216    i = 0;
217 
218    /* store and read over and over until \n or EOF */
219    while (ch != '\n' && ch != -1) {
220       buf[i++] = ch;
221       if (i >= size) buf = srealloc(buf, 1 + (size += size));
222 
223       ch = readch(fh);
224    }
225 
226    buf[i] = 0; /* we know we can write on buf[i] because we know i <= size,
227                 * (remember that buf has capacity is size + 1) */
228    return buf;
229 }
230 
strtrim(const char * s)231 char *strtrim(const char *s) {
232    char *t, *u;
233    while (*s == ' ' || *s == '\t' || *s == '\n') s++;
234    t = sstrdup(s);
235    u = t + strlen(t) - 1;
236    while (u >= t && (*u == ' ' || *u == '\t' || *u == '\n')) u--;
237    u[1] = 0;
238    return t;
239 }
240 
dstrcat(const char * s,const char * t)241 char *dstrcat(const char *s, const char *t) {
242    char *u = zalloc(1 + (s ? strlen(s) : 0) + (t ? strlen(t) : 0));
243    if (s) strcpy(u, s);
244    if (t) strcat(u, t);
245    return u; /* zalloc zeroes out the buffer, so even if s == t == NULL,
246               * u will be a single '\0', which is a correct result.  */
247 }
248 
chr2hex(int c,char * ret)249 void chr2hex(int c, char* ret) {
250    static char hs[] = "0123456789abcdef";
251 
252    if (c <= 0) c = 0;
253    if (c >= 256) c = 255;
254 
255    ret[0] = hs[c / 16];
256    ret[1] = hs[c % 16];
257    ret[2] = 0;
258 }
259 
hex_digit_val(char c)260 static int hex_digit_val(char c) {
261    if (c >= '0' && c <= '9') return c - '0';
262    else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
263    else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
264    else return 0;
265 }
266 
hex2chr(const char * hex)267 int hex2chr(const char *hex) {
268    return hex_digit_val(hex[0]) * 16 + hex_digit_val(hex[1]);
269 }
270 
271