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