home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / sed-3.02 / sed / utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-06  |  7.3 KB  |  395 lines

  1. /*  Functions from hack's utils library.
  2.     Copyright (C) 1989, 1990, 1991, 1998
  3.     Free Software Foundation, Inc.
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2, or (at your option)
  8.     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
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  18.  
  19. /* These routines were written as part of a library (by hack), but since most
  20.    people don't have the library, here they are.  */
  21. /* Tweaked by ken */
  22.  
  23. #include "config.h"
  24.  
  25. #include <stdio.h>
  26.  
  27. #include <errno.h>
  28. #ifndef errno
  29.   extern int errno;
  30. #endif
  31.  
  32. #ifndef HAVE_STRING_H
  33. # include <strings.h>
  34. #else
  35. # include <string.h>
  36. #endif /* HAVE_STRING_H */
  37.  
  38. #ifndef HAVE_STDLIB_H
  39. # ifdef RX_MEMDBUG
  40. #  include <sys/types.h>
  41. #  include <malloc.h>
  42. # endif /* RX_MEMDBUG */
  43. #else /* HAVE_STDLIB_H */
  44. # include <stdlib.h>
  45. #endif /* HAVE_STDLIB_H */
  46.  
  47. #include "basicdefs.h"
  48. #include "utils.h"
  49.  
  50. #ifndef HAVE_STDLIB_H
  51. # ifndef RX_MEMDBUG
  52.    VOID *malloc();
  53.    VOID *realloc();
  54. # endif /* RX_MEMDBUG */
  55. #endif /* HAVE_STDLIB_H */
  56.  
  57. const char *myname;
  58.  
  59.  
  60. /* Print an error message and exit */
  61. #if !defined __STDC__ || !__STDC__
  62. # include <varargs.h>
  63. # define VSTART(l,a)    va_start(l)
  64. void
  65. panic(str, va_alist)
  66.   char *str;
  67.   va_dcl
  68. #else /*__STDC__*/
  69. # include <stdarg.h>
  70. # define VSTART(l,a)    va_start(l, a)
  71. void
  72. panic(const char *str, ...)
  73. #endif /* __STDC__ */
  74. {
  75.   va_list iggy;
  76.  
  77.   fprintf(stderr, "%s: ", myname);
  78.   VSTART(iggy, str);
  79. #ifndef HAVE_VPRINTF
  80. # ifndef HAVE_DOPRNT
  81.   fputs(str, stderr);    /* not great, but perhaps better than nothing... */
  82. # else /* HAVE_DOPRNT */
  83.   _doprnt(str, &iggy, stderr);
  84. # endif /* HAVE_DOPRNT */
  85. #else /* HAVE_VFPRINTF */
  86.   vfprintf(stderr, str, iggy);
  87. #endif /* HAVE_VFPRINTF */
  88.   va_end(iggy);
  89.   putc('\n', stderr);
  90.   exit(4);
  91. }
  92.  
  93.  
  94. /* Store information about files opened with ck_fopen
  95.    so that error messages from ck_fread, ck_fwrite, etc. can print the
  96.    name of the file that had the error */
  97.  
  98. struct id
  99.   {
  100.     FILE *fp;
  101.     char *name;
  102.     struct id *link;
  103.   };
  104.  
  105. static struct id *utils_id_s = NULL;
  106. static const char *utils_fp_name P_((FILE *fp));
  107.  
  108. /* Internal routine to get a filename from utils_id_s */
  109. static const char *
  110. utils_fp_name(fp)
  111.   FILE *fp;
  112. {
  113.   struct id *p;
  114.  
  115.   for (p=utils_id_s; p; p=p->link)
  116.     if (p->fp == fp)
  117.       return p->name;
  118.   if (fp == stdin)
  119.     return "{standard input}";
  120.   else if (fp == stdout)
  121.     return "{standard output}";
  122.   else if (fp == stderr)
  123.     return "{standard error}";
  124.   return "{Unknown file pointer}";
  125. }
  126.  
  127. /* Panic on failing fopen */
  128. FILE *
  129. ck_fopen(name, mode)
  130.   const char *name;
  131.   const char *mode;
  132. {
  133.   FILE *fp;
  134.   struct id *p;
  135.  
  136.   if ( ! (fp = fopen(name, mode)) )
  137.     panic("Couldn't open file %s", name);
  138.   for (p=utils_id_s; p; p=p->link)
  139.     {
  140.       if (fp == p->fp)
  141.     {
  142.       FREE(p->name);
  143.       break;
  144.     }
  145.     }
  146.   if (!p)
  147.     {
  148.       p = MALLOC(1, struct id);
  149.       p->link = utils_id_s;
  150.       utils_id_s = p;
  151.     }
  152.   p->name = ck_strdup(name);
  153.   p->fp = fp;
  154.   return fp;
  155. }
  156.  
  157. /* Panic on failing fwrite */
  158. void
  159. ck_fwrite(ptr, size, nmemb, stream)
  160.   const VOID *ptr;
  161.   size_t size;
  162.   size_t nmemb;
  163.   FILE *stream;
  164. {
  165.   if (size && fwrite(ptr, size, nmemb, stream) != nmemb)
  166.     panic("couldn't write %d item%s to %s: %s",
  167.       nmemb, nmemb==1 ? "" : "s", utils_fp_name(stream), strerror(errno));
  168. }
  169.  
  170. /* Panic on failing fread */
  171. size_t
  172. ck_fread(ptr, size, nmemb, stream)
  173.   VOID *ptr;
  174.   size_t size;
  175.   size_t nmemb;
  176.   FILE *stream;
  177. {
  178.   if (size && (nmemb=fread(ptr, size, nmemb, stream)) <= 0 && ferror(stream))
  179.     panic("read error on %s: %s", utils_fp_name(stream), strerror(errno));
  180.   return nmemb;
  181. }
  182.  
  183. /* Panic on failing fflush */
  184. void
  185. ck_fflush(stream)
  186.   FILE *stream;
  187. {
  188.   if (fflush(stream) == EOF)
  189.     panic("Couldn't flush %s", utils_fp_name(stream));
  190. }
  191.  
  192. /* Panic on failing fclose */
  193. void
  194. ck_fclose(stream)
  195.   FILE *stream;
  196. {
  197.   struct id r;
  198.   struct id *prev;
  199.   struct id *cur;
  200.  
  201.   if (!stream)
  202.     return;
  203.   if (fclose(stream) == EOF)
  204.     panic("Couldn't close %s", utils_fp_name(stream));
  205.   r.link = utils_id_s;
  206.   prev = &r;
  207.   while ( (cur = prev->link) )
  208.     {
  209.       if (stream == cur->fp)
  210.     {
  211.       prev->link = cur->link;
  212.       FREE(cur->name);
  213.       FREE(cur);
  214. #ifdef TRUST_THAT_ID_CHAIN_IS_CLEAN
  215.       break;
  216. #endif
  217.     }
  218.       else
  219.     {
  220.       prev = cur;
  221.     }
  222.     }
  223.   utils_id_s = r.link;
  224. }
  225.  
  226.  
  227. /* Panic on failing malloc */
  228. VOID *
  229. ck_malloc(size)
  230.   size_t size;
  231. {
  232.   VOID *ret = malloc(size ? size : 1);
  233.   if (!ret)
  234.     panic("Couldn't allocate memory");
  235.   return ret;
  236. }
  237.  
  238. /* Panic on failing malloc */
  239. VOID *
  240. xmalloc(size)
  241.   size_t size;
  242. {
  243.   return ck_malloc(size);
  244. }
  245.  
  246. /* Panic on failing realloc */
  247. VOID *
  248. ck_realloc(ptr, size)
  249.   VOID *ptr;
  250.   size_t size;
  251. {
  252.   VOID *ret;
  253.  
  254.   if (size == 0)
  255.     {
  256.       FREE(ptr);
  257.       return NULL;
  258.     }
  259.   if (!ptr)
  260.     return ck_malloc(size);
  261.   ret = realloc(ptr, size);
  262.   if (!ret)
  263.     panic("Couldn't re-allocate memory");
  264.   return ret;
  265. }
  266.  
  267. /* Return a malloc()'d copy of a string */
  268. char *
  269. ck_strdup(str)
  270.   const char *str;
  271. {
  272.   char *ret = MALLOC(strlen(str)+1, char);
  273.   return strcpy(ret, str);
  274. }
  275.  
  276. /* Return a malloc()'d copy of a block of memory */
  277. VOID *
  278. ck_memdup(buf, len)
  279.   const VOID *buf;
  280.   size_t len;
  281. {
  282.   VOID *ret = ck_malloc(len);
  283.   return memcpy(ret, buf, len);
  284. }
  285.  
  286. /* Release a malloc'd block of memory */
  287. void
  288. ck_free(ptr)
  289.   VOID *ptr;
  290. {
  291.   if (ptr)
  292.     free(ptr);
  293. }
  294.  
  295.  
  296. /* Implement a variable sized buffer of 'stuff'.  We don't know what it is,
  297. nor do we care, as long as it doesn't mind being aligned by malloc. */
  298.  
  299. struct buffer
  300.   {
  301.     size_t allocated;
  302.     size_t length;
  303.     char *b;
  304.   };
  305.  
  306. #define MIN_ALLOCATE 50
  307.  
  308. struct buffer *
  309. init_buffer()
  310. {
  311.   struct buffer *b = MALLOC(1, struct buffer);
  312.   b->b = MALLOC(MIN_ALLOCATE, char);
  313.   b->allocated = MIN_ALLOCATE;
  314.   b->length = 0;
  315.   return b;
  316. }
  317.  
  318. char *
  319. get_buffer(b)
  320.   struct buffer *b;
  321. {
  322.   return b->b;
  323. }
  324.  
  325. size_t
  326. size_buffer(b)
  327.   struct buffer *b;
  328. {
  329.   return b->length;
  330. }
  331.  
  332. static void resize_buffer P_((struct buffer *b, size_t newlen));
  333.  
  334. static void
  335. resize_buffer(b, newlen)
  336.   struct buffer *b;
  337.   size_t newlen;
  338. {
  339.   char *try = NULL;
  340.   size_t alen = b->allocated;
  341.  
  342.   if (newlen <= alen)
  343.     return;
  344.   alen *= 2;
  345.   if (newlen < alen)
  346.     try = realloc(b->b, alen);    /* Note: *not* the REALLOC() macro! */
  347.   if (!try)
  348.     {
  349.       alen = newlen;
  350.       try = REALLOC(b->b, alen, char);
  351.     }
  352.   b->allocated = alen;
  353.   b->b = try;
  354. }
  355.  
  356. void
  357. add_buffer(b, p, n)
  358.   struct buffer *b;
  359.   const char *p;
  360.   size_t n;
  361. {
  362.   if (b->allocated - b->length < n)
  363.     resize_buffer(b, b->length+n);
  364.   memcpy(b->b + b->length, p, n);
  365.   b->length += n;
  366. }
  367.  
  368. void
  369. add1_buffer(b, c)
  370.   struct buffer *b;
  371.   int c;
  372. {
  373.   /* This special case should be kept cheap;
  374.    *  don't make it just a mere convenience
  375.    *  wrapper for add_buffer() -- even "builtin"
  376.    *  versions of memcpy(a, b, 1) can become
  377.    *  expensive when called too often.
  378.    */
  379.   if (c != EOF)
  380.     {
  381.       if (b->allocated - b->length < 1)
  382.     resize_buffer(b, b->length+1);
  383.       b->b[b->length++] = c;
  384.     }
  385. }
  386.  
  387. void
  388. free_buffer(b)
  389.   struct buffer *b;
  390. {
  391.   if (b)
  392.     FREE(b->b);
  393.   FREE(b);
  394. }
  395.