home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / m / makedrawf / Source / c / general < prev    next >
Text File  |  1995-05-11  |  3KB  |  143 lines

  1. /* general.c
  2.  *
  3.  * Routines used in both mouth.c and stomach.c.
  4.  *  - error handling
  5.  *  - xmalloc(), xfree()
  6.  *  - cistreq(), copy_string()
  7.  */
  8.  
  9. #include <ctype.h>
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #include "mkdrawf.h"
  16.  
  17. #define max_n_errors 100
  18.  
  19. char *prog_name="[mkdrawf?]";
  20. static int return_code=0;
  21.  
  22. int line_number=0;
  23.  
  24. static int n_errors=0;
  25. static int n_warnings=0;
  26.  
  27. /* |no_filenames!=0| iff we should not display filenames in error messages.
  28.  * This happens if "-e" is given on the command line. It's used when we're
  29.  * reporting errors via throwback.
  30.  */
  31. int no_filenames=0;
  32.  
  33. /* Report on any errors and warnings. Say nothing if there were none.
  34.  * Return the return code to be used.
  35.  */
  36. int final_report(void) {
  37.   if (n_warnings || n_errors)
  38.     fprintf(stderr,"%s: %d warning%s, %d error%s.\n",
  39.       input_file_name,
  40.       n_warnings,(n_warnings==1)?"":"s",
  41.       n_errors,(n_errors==1)?"":"s");
  42. #ifdef PROFILE
  43.   _fmapstore("$.tmp.MDFcounts");
  44. #endif
  45.   return return_code;
  46. }
  47.  
  48. /* Begin an error message.
  49.  */
  50. static void err_head(char *s) {
  51.   if (no_filenames)
  52.     fprintf(stderr,"Line %d: %s: ",line_number,s);
  53.   else
  54. #ifdef VERBOSE_ERRORS
  55.   fprintf(stderr,"%s, line %d of file %s: %s:\n",
  56.                  prog_name,line_number,input_file_name,s);
  57. #else
  58.   fprintf(stderr,"`%s', line %d: %s: ",input_file_name,line_number,s);
  59. #endif
  60. }
  61.  
  62. void warn(char *s, ...) {
  63.   va_list ap;
  64.   va_start(ap,s);
  65.   err_head("warning");
  66.   vfprintf(stderr,s,ap);
  67.   va_end(ap);
  68.   fprintf(stderr,".\n");
  69.   return_code=4;
  70.   ++n_warnings;
  71. }
  72.  
  73. /* Fatal errors.
  74.  */
  75. void error(char *s, ...) {
  76.   va_list ap;
  77.   va_start(ap,s);
  78.   err_head("fatal error");
  79.   vfprintf(stderr,s,ap);
  80.   va_end(ap);
  81.   fprintf(stderr,".\n");
  82.   final_report();
  83.   exit(12);
  84. }
  85.  
  86. /* Recoverable-from errors. Not necessarily really minor.
  87.  * If we get too many of these, we'll exit via |error()|.
  88.  */
  89. void minor(char *s, ...) {
  90.   va_list ap;
  91.   va_start(ap,s);
  92.   err_head("error");
  93.   vfprintf(stderr,s,ap);
  94.   va_end(ap);
  95.   fprintf(stderr,".\n");
  96.   return_code=8;
  97.   if (++n_errors>=max_n_errors) error("Too many errors");
  98. }
  99.  
  100.  
  101. /* Allocate some memory, and fall over and die if we couldn't
  102.  * get enough.
  103.  */
  104. void *xmalloc(uint n, char *s) {
  105.   void *p=malloc(n);
  106.   if (!p) error("Out of memory for %s",s);
  107. #ifdef DEBUG_MEMORY
  108.   fprintf(stderr,"Allocated %d bytes for %s, at 0x%X\n",n,s,(int)p);
  109. #endif
  110.   return p;
  111. }
  112.  
  113. /* We use an instrumented |free()| when debugging; otherwise the usual
  114.  * one is just fine.
  115.  */
  116. #ifdef DEBUG_MEMORY
  117. void xfree(void *p) {
  118.   fprintf(stderr,"Freeing memory at 0x%X, might be %d bytes\n",(int)p,
  119.           /* For at least some versions of the ShCL the #bytes is right */
  120.           ((int*)p)[-1]&~0xF0000000);
  121.   free(p);
  122. }
  123. #endif
  124.  
  125. /* |cistreq(s1,s2)| returns non-zero iff s1==s2 when they're
  126.  * considered as caseless strings.
  127.  * This is used for comparing font names and sprite names.
  128.  */
  129. int cistreq(const char *s1, const char *s2) {
  130.   char c1,c2;
  131.   do { c1=tolower(*s1++); c2=tolower(*s2++); } while (c1==c2 && c1);
  132.   return (!c1 && !c2);
  133. }
  134.  
  135. /* |copy_string(s)| returns a new string equal to |s| but in new storage.
  136.  */
  137. char *copy_string(const char *s) {
  138.   int l=strlen(s);
  139.   char *t=xmalloc(l+1,"a string");
  140.   memcpy(t,s,l+1);
  141.   return t;
  142. }
  143.