00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define UTIL_H_IMPLEMENTATION
00026 #include "util.h"
00027 #include <ctype.h>
00028 #include <stdlib.h>
00029 #ifdef HAVE_MALLOC_H
00030 #include <malloc.h>
00031 #endif
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <errno.h>
00035 #ifdef HAVE_UNISTD_H
00036 #include <unistd.h>
00037 #endif
00038 #ifdef HAVE_IO_H
00039 #include <io.h>
00040 #endif
00041 #include <sys/stat.h>
00042 #include <fcntl.h>
00043
00044 #define MAXSTRLEN 256
00045
00046 ichar *
00047 istrdup(const ichar *s)
00048 { ichar *dup = malloc((istrlen(s)+1)*sizeof(ichar));
00049 ichar *d = dup;
00050
00051 while(*s)
00052 *d++ = *s++;
00053 *d = 0;
00054
00055 return dup;
00056 }
00057
00058
00059 ichar *
00060 istrcpy(ichar *d, const ichar *s)
00061 { ichar *r = d;
00062
00063 while(*s)
00064 *d++ = *s++;
00065 *d = 0;
00066
00067 return r;
00068 }
00069
00070
00071 int
00072 istrcaseeq(const ichar *s1, const ichar *s2)
00073 { ichar c;
00074
00075 while ((c = *s1++) != '\0')
00076 { if (tolower(*(ichar const *)s2++) != tolower(c))
00077 return FALSE;
00078 }
00079
00080 return *s2 == '\0';
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 int
00096 istrncaseeq(const ichar *s1, const ichar *s2, int len)
00097 { while(--len >= 0 && tolower(*s1) == tolower(*s2))
00098 s1++, s2++;
00099
00100 if ( len < 0 )
00101 return TRUE;
00102
00103 return FALSE;
00104 }
00105
00106
00107 int
00108 istrprefix(const ichar *pref, const ichar *s)
00109 { while(*pref && *pref == *s)
00110 pref++, s++;
00111
00112 if ( *pref == 0 )
00113 return TRUE;
00114
00115 return FALSE;
00116 }
00117
00118
00119 ichar *
00120 istrchr(const ichar *s, int c)
00121 { for( ; *s; s++ )
00122 { if ( c == *s )
00123 return (ichar *)s;
00124 }
00125
00126 return NULL;
00127 }
00128
00129
00130 ichar *
00131 istrupper(ichar *s)
00132 { ichar *r = s;
00133
00134 for( ; *s; s++)
00135 *s = toupper(*s);
00136
00137 return r;
00138 }
00139
00140
00141 ichar *
00142 istrlower(ichar *s)
00143 { ichar *r = s;
00144
00145 for( ; *s; s++)
00146 *s = tolower(*s);
00147
00148 return r;
00149 }
00150
00151
00152 int
00153 istrhash(const ichar *t, int tsize)
00154 { unsigned int value = 0;
00155 unsigned int shift = 5;
00156
00157 while(*t)
00158 { unsigned int c = *t++;
00159
00160 c -= 'a';
00161 value ^= c << (shift & 0xf);
00162 shift ^= c;
00163 }
00164
00165 value = value ^ (value >> 16);
00166
00167 return value % tsize;
00168 }
00169
00170
00171 int
00172 istrcasehash(const ichar *t, int tsize)
00173 { unsigned int value = 0;
00174 unsigned int shift = 5;
00175
00176 while(*t)
00177 { unsigned int c = tolower(*t++);
00178
00179 c -= 'a';
00180 value ^= c << (shift & 0xf);
00181 shift ^= c;
00182 }
00183
00184 value = value ^ (value >> 16);
00185
00186 return value % tsize;
00187 }
00188
00189
00190 int
00191 istrtol(const ichar *s, long *val)
00192 { long v;
00193 char *e;
00194
00195 if ( *s )
00196 { v = strtol((const char *)s, &e, 10);
00197 if ( !e[0] && errno != ERANGE )
00198 { *val = v;
00199 return TRUE;
00200 }
00201 }
00202
00203 return FALSE;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 icharbuf *
00213 new_icharbuf()
00214 { icharbuf *buf = sgml_malloc(sizeof(*buf));
00215
00216 buf->allocated = 0;
00217 buf->size = 0;
00218 buf->data = NULL;
00219
00220 return buf;
00221 }
00222
00223
00224 void
00225 free_icharbuf(icharbuf *buf)
00226 { if ( buf->data )
00227 sgml_free(buf->data);
00228
00229 sgml_free(buf);
00230 }
00231
00232
00233 void
00234 __add_icharbuf(icharbuf *buf, int chr)
00235 { if ( buf->size == buf->allocated )
00236 { buf->allocated = (buf->allocated ? buf->allocated*2 : 128);
00237
00238 if ( buf->data )
00239 buf->data = sgml_realloc(buf->data, buf->allocated);
00240 else
00241 buf->data = sgml_malloc(buf->allocated);
00242 }
00243
00244 buf->data[buf->size++] = chr;
00245 }
00246
00247
00248 void
00249 del_icharbuf(icharbuf *buf)
00250 { if ( buf->size > 0 )
00251 buf->size--;
00252 }
00253
00254
00255 void
00256 terminate_icharbuf(icharbuf *buf)
00257 { add_icharbuf(buf, '\0');
00258 buf->size--;
00259 }
00260
00261
00262 void
00263 empty_icharbuf(icharbuf *buf)
00264 { buf->size = 0;
00265 }
00266
00267
00268
00269
00270
00271
00272 int
00273 ostrlen(const ochar *s)
00274 { int len =0;
00275
00276 while(*s++)
00277 len++;
00278
00279 return len;
00280 }
00281
00282
00283 ochar *
00284 ostrdup(const ochar *s)
00285 { ochar *dup = sgml_malloc((ostrlen(s)+1)*sizeof(ochar));
00286 ochar *d = dup;
00287
00288 while(*s)
00289 *d++ = *s++;
00290 *d = 0;
00291
00292 return dup;
00293 }
00294
00295
00296
00297
00298
00299
00300 ocharbuf *
00301 new_ocharbuf()
00302 { ocharbuf *buf = sgml_malloc(sizeof(*buf));
00303
00304 buf->allocated = 0;
00305 buf->size = 0;
00306 buf->data = NULL;
00307
00308 return buf;
00309 }
00310
00311
00312 void
00313 free_ocharbuf(ocharbuf *buf)
00314 { if ( buf->data )
00315 sgml_free(buf->data);
00316
00317 sgml_free(buf);
00318 }
00319
00320
00321 void
00322 __add_ocharbuf(ocharbuf *buf, int chr)
00323 { if ( buf->size == buf->allocated )
00324 { buf->allocated = (buf->allocated ? buf->allocated*2 : 128);
00325
00326 if ( buf->data )
00327 buf->data = sgml_realloc(buf->data, buf->allocated);
00328 else
00329 buf->data = sgml_malloc(buf->allocated);
00330 }
00331
00332 buf->data[buf->size++] = chr;
00333 }
00334
00335
00336 void
00337 del_ocharbuf(ocharbuf *buf)
00338 { if ( buf->size > 0 )
00339 buf->size--;
00340 }
00341
00342
00343 void
00344 terminate_ocharbuf(ocharbuf *buf)
00345 { add_ocharbuf(buf, '\0');
00346 buf->size--;
00347 }
00348
00349
00350 void
00351 empty_ocharbuf(ocharbuf *buf)
00352 { buf->size = 0;
00353 }
00354
00355
00356
00357
00358
00359 #define RINGSIZE 16
00360 static char *ring[RINGSIZE];
00361 static int ringp;
00362
00363 char *
00364 str2ring(const char *in)
00365 { char *copy = strdup(in);
00366
00367 if ( ring[ringp] )
00368 sgml_free(ring[ringp]);
00369 ring[ringp++] = copy;
00370 if ( ringp == RINGSIZE )
00371 ringp = 0;
00372
00373 if ( !copy )
00374 sgml_nomem();
00375
00376 return copy;
00377 }
00378
00379
00380 char *ringallo(size_t size)
00381 { char *result = malloc(size);
00382
00383 if ( ring[ringp] != 0 )
00384 sgml_free(ring[ringp]);
00385 ring[ringp++] = result;
00386 if ( ringp == RINGSIZE )
00387 ringp = 0;
00388
00389 return result;
00390 }
00391
00392
00393
00394
00395
00396
00397 char const *
00398 str_summary(char const *s, int len)
00399 { char *buf;
00400 size_t l = strlen(s);
00401
00402 if ( l < (size_t)len )
00403 return s;
00404 buf = ringallo(len + 10);
00405 strncpy(buf, s, len-5);
00406 strcpy(&buf[len-5], " ... ");
00407 strcpy(&buf[len], &s[l-5]);
00408
00409 return buf;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 #ifndef O_BINARY
00425 #define O_BINARY 0
00426 #endif
00427
00428 ichar *
00429 load_sgml_file_to_charp(const char *file, int normalise_rsre, int *length)
00430 { int fd;
00431
00432 if ( (fd = open(file, O_RDONLY|O_BINARY)) >= 0 )
00433 { struct stat buf;
00434
00435 if ( fstat(fd, &buf) == 0 )
00436 { long len = buf.st_size;
00437 char *r = sgml_malloc(len+1);
00438
00439 if ( r )
00440 { char *s = r;
00441
00442 while(len>0)
00443 { int n;
00444
00445 if ( (n=read(fd, s, len)) < 0 )
00446 { close(fd);
00447 sgml_free(r);
00448 return NULL;
00449 } else if ( n == 0 )
00450 break;
00451 len -= n;
00452 s += n;
00453 }
00454
00455 len = s-r;
00456 *s = '\0';
00457 close(fd);
00458
00459 if ( normalise_rsre )
00460 { int nl;
00461 int last_is_lf;
00462
00463 last_is_lf = (s > 0 && s[-1] == '\n');
00464
00465 for(s=r, nl=0; *s; s++)
00466 { if ( *s == '\n' && s>r && s[-1] != '\r' )
00467 nl++;
00468 }
00469
00470 if ( nl > 0 )
00471 { char *r2 = sgml_malloc(len+nl+1);
00472 char *t;
00473
00474 for(s=r, t=r2; *s; s++)
00475 { if ( *s == '\n' )
00476 { if ( s>r && s[-1] != '\r' )
00477 *t++ = CR;
00478 *t++ = LF;
00479 } else
00480 *t++ = *s;
00481 }
00482 len = t-r2;
00483 *t = '\0';
00484 sgml_free(r);
00485 r = r2;
00486 }
00487
00488 if ( last_is_lf )
00489 r[--len] = '\0';
00490 }
00491
00492 if ( length )
00493 *length = len;
00494
00495 return (ichar *)r;
00496 }
00497 }
00498 }
00499
00500 return NULL;
00501 }
00502
00503
00504
00505
00506
00507
00508 #ifdef _WINDOWS
00509 #include <windows.h>
00510 #endif
00511
00512 void
00513 sgml_nomem()
00514 { fprintf(stderr, "SGML: Fatal: out of memory\n");
00515
00516 #ifdef _WINDOWS
00517 MessageBox(NULL, "SGML: Fatal: out of memory", "SGML", MB_OK|MB_TASKMODAL);
00518 #endif
00519
00520 exit(1);
00521 }
00522
00523
00524 void *
00525 sgml_malloc(size_t size)
00526 { void *mem;
00527
00528 if ( size == 0 )
00529 return NULL;
00530
00531 if ( (mem = malloc(size)) )
00532 return mem;
00533
00534 sgml_nomem();
00535 return NULL;
00536 }
00537
00538
00539 void *
00540 sgml_realloc(void *old, size_t size)
00541 { void *mem;
00542
00543 if ( old )
00544 { if ( (mem = realloc(old, size)) )
00545 return mem;
00546 } else
00547 { if ( (mem = malloc(size)) )
00548 return mem;
00549 }
00550
00551 sgml_nomem();
00552 return NULL;
00553 }
00554
00555
00556 void *
00557 sgml_calloc(size_t n, size_t size)
00558 { void *mem;
00559
00560 if ( (mem=calloc(n, size)) )
00561 return mem;
00562
00563 sgml_nomem();
00564 return NULL;
00565 }
00566
00567
00568 void
00569 sgml_free(void *mem)
00570 { if ( mem )
00571 free(mem);
00572 }