util.c

00001 /*  $Id: util.c,v 1.2 2005/03/07 20:31:23 kifer Exp $
00002 
00003     Part of SWI-Prolog
00004 
00005     Author:        Jan Wielemaker
00006     E-mail:        jan@swi.psy.uva.nl
00007     WWW:           http://www.swi-prolog.org
00008     Copyright (C): 1985-2002, University of Amsterdam
00009 
00010     This library is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU Lesser General Public
00012     License as published by the Free Software Foundation; either
00013     version 2.1 of the License, or (at your option) any later version.
00014 
00015     This library is distributed in the hope that it will be useful,
00016     but WITHOUT ANY WARRANTY; without even the implied warranty of
00017     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018     Lesser General Public License for more details.
00019 
00020     You should have received a copy of the GNU Lesser General Public
00021     License along with this library; if not, write to the Free Software
00022     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 int
00085 istreq(const ichar *s1, const ichar *s2)
00086 { while(*s1 && *s1 == *s2)
00087     s1++, s2++;
00088   
00089   if ( *s1 == 0 && *s2 == 0 )
00090     return TRUE;
00091   
00092   return FALSE;
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++);     /* case insensitive */
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                  *    INPUT CHARACTER BUFFER    *
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                  *      OUTPUT CHARACTERS       *
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                  *    OUTPUT CHARACTER BUFFER   *
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                  *         BUFFER RING          *
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                *              MISC            *
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                  *            FILES             *
00416                  *******************************/
00417 
00418 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
00419 Load a file into memory. This would be so  easy if we didn't had to deal
00420 with &#RE/&#RS handling that forces us to create the proper record start
00421 and end.
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);                  /* I/O error */
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';                      /* ensure closing EOS */
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';            /* delete last LF */
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                  *           ALLOCATION         *
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 }

Generated on Wed Jul 26 13:30:46 2006 for XSB by  doxygen 1.4.5