home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / m4 / part01 / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-27  |  4.9 KB  |  292 lines

  1. /*
  2.  * misc.c
  3.  * Facility: m4 macro processor
  4.  * by: oz
  5.  */
  6.  
  7. #include "mdef.h"
  8. #include "extr.h" 
  9.  
  10. extern char *malloc();
  11.  
  12. /*
  13.  * indx - find the index of second str in the
  14.  *        first str.
  15.  */
  16. indx(s1, s2)
  17. char *s1;
  18. char *s2;
  19. {
  20.         register char *t;
  21.         register char *p;
  22.         register char *m;
  23.  
  24.         for (p = s1; *p; p++) {
  25.                 for (t = p, m = s2; *m && *m == *t; m++, t++)
  26.                         ;
  27.                 if (!*m)
  28.                         return(p - s1);
  29.         }
  30.         return (-1);
  31. }
  32.  
  33. /*
  34.  *  putback - push character back onto input
  35.  *
  36.  */
  37. putback (c)
  38. char c;
  39. {
  40.         if (bp < endpbb)
  41.                 *bp++ = c;
  42.         else
  43.                 error("m4: too many characters pushed back");
  44. }
  45.  
  46. /*
  47.  *  pbstr - push string back onto input
  48.  *          putback is replicated to improve
  49.  *          performance.
  50.  *
  51.  */
  52. pbstr(s)
  53. register char *s;
  54. {
  55.         register char *es;
  56.     register char *zp;
  57.  
  58.     es = s;
  59.     zp = bp;
  60.  
  61.         while (*es)
  62.                 es++;
  63.         es--;
  64.         while (es >= s)
  65.                 if (zp < endpbb)
  66.                         *zp++ = *es--;
  67.         if ((bp = zp) == endpbb)
  68.                 error("m4: too many characters pushed back");
  69. }
  70.  
  71. /*
  72.  *  pbnum - convert number to string, push back on input.
  73.  *
  74.  */
  75. pbnum (n)
  76. int n;
  77. {
  78.         register int num;
  79.  
  80.         num = (n < 0) ? -n : n;
  81.         do {
  82.                 putback(num % 10 + '0');
  83.         }
  84.         while ((num /= 10) > 0);
  85.  
  86.         if (n < 0) putback('-');
  87. }
  88.  
  89. /*
  90.  *  chrsave - put single char on string space
  91.  *
  92.  */
  93. chrsave (c)
  94. char c;
  95. {
  96. /***        if (sp < 0)
  97.                 putc(c, active);
  98.         else ***/ if (ep < endest)
  99.                 *ep++ = c;
  100.         else
  101.                 error("m4: string space overflow");
  102. }
  103.  
  104. /*
  105.  * getdiv - read in a diversion file, and
  106.  *          trash it.
  107.  */
  108. getdiv(ind) {
  109.         register int c;
  110.         register FILE *dfil;
  111.  
  112.         if (active == outfile[ind])
  113.                 error("m4: undivert: diversion still active.");
  114.         (void) fclose(outfile[ind]);
  115.         outfile[ind] = NULL;
  116.         m4temp[UNIQUE] = ind + '0';
  117.         if ((dfil = fopen(m4temp, "r")) == NULL)
  118.                 error("m4: cannot undivert.");
  119.         else
  120.                 while((c = getc(dfil)) != EOF)
  121.                         putc(c, active);
  122.         (void) fclose(dfil);
  123.  
  124. #if vms
  125.         if (remove(m4temp))
  126. #else
  127.     if (unlink(m4temp) == -1)
  128. #endif
  129.                 error("m4: cannot unlink.");
  130. }
  131.  
  132. /*
  133.  * Very fatal error. Close all files
  134.  * and die hard.
  135.  */
  136. error(s)
  137. char *s;
  138. {
  139.         killdiv();
  140.         fprintf(stderr,"%s\n",s);
  141.         exit(1);
  142. }
  143.  
  144. /*
  145.  * Interrupt handling
  146.  */
  147. static char *msg = "\ninterrupted.";
  148.  
  149. onintr() {
  150.         error(msg);
  151. }
  152.  
  153. /*
  154.  * killdiv - get rid of the diversion files
  155.  *
  156.  */
  157. killdiv() {
  158.         register int n;
  159.  
  160.         for (n = 0; n < MAXOUT; n++)
  161.                 if (outfile[n] != NULL) {
  162.                         (void) fclose (outfile[n]);
  163.                         m4temp[UNIQUE] = n + '0';
  164. #if vms
  165.             (void) remove (m4temp);
  166. #else
  167.                         (void) unlink (m4temp);
  168. #endif
  169.                 }
  170. }
  171.  
  172. /*
  173.  * save a string somewhere..
  174.  *
  175.  */
  176. char *strsave(s)
  177. char *s;
  178. {
  179.     register int n;
  180.         char *p;
  181.  
  182.         if ((p = malloc (n = strlen(s)+1)) != NULL)
  183.                 (void) memcpy(p, s, n);
  184.         return (p);
  185. }
  186.  
  187. usage() {
  188.         fprintf(stderr, "Usage: m4 [-Dname[=val]] [-Uname]\n");
  189.         exit(1);
  190. }
  191.  
  192. #ifdef GETOPT
  193. /*
  194.  * H. Spencer getopt - get option letter from argv
  195.  * 
  196.  *
  197. #include <stdio.h>
  198.  *
  199.  */
  200.  
  201. char    *optarg;    /* Global argument pointer. */
  202. int    optind = 0;    /* Global argv index. */
  203.  
  204. static char    *scan = NULL;    /* Private scan pointer. */
  205.  
  206. extern char    *index();
  207.  
  208. int
  209. getopt(argc, argv, optstring)
  210. int argc;
  211. char *argv[];
  212. char *optstring;
  213. {
  214.     register char c;
  215.     register char *place;
  216.  
  217.     optarg = NULL;
  218.  
  219.     if (scan == NULL || *scan == '\0') {
  220.         if (optind == 0)
  221.             optind++;
  222.     
  223.         if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
  224.             return(EOF);
  225.         if (strcmp(argv[optind], "--")==0) {
  226.             optind++;
  227.             return(EOF);
  228.         }
  229.     
  230.         scan = argv[optind]+1;
  231.         optind++;
  232.     }
  233.  
  234.     c = *scan++;
  235.     place = index(optstring, c);
  236.  
  237.     if (place == NULL || c == ':') {
  238.         fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
  239.         return('?');
  240.     }
  241.  
  242.     place++;
  243.     if (*place == ':') {
  244.         if (*scan != '\0') {
  245.             optarg = scan;
  246.             scan = NULL;
  247.         } else {
  248.             optarg = argv[optind];
  249.             optind++;
  250.         }
  251.     }
  252.  
  253.     return(c);
  254. }
  255.    
  256. #endif
  257.  
  258. #ifdef DUFFCP
  259. /*
  260.  * This code uses Duff's Device (tm Tom Duff)
  261.  * to unroll the copying loop:
  262.  * while (count-- > 0)
  263.  *    *to++ = *from++;
  264.  */
  265.  
  266. #define COPYBYTE     *to++ = *from++
  267.  
  268. memcpy(to, from, count)
  269. register char *from, *to;
  270. register int count;
  271. {
  272.     if (count > 0) {
  273.         register int loops = (count+8-1) >> 3;    /* div 8 round up */
  274.  
  275.         switch (count&(8-1)) {            /* mod 8 */
  276.         case 0: do {
  277.             COPYBYTE;
  278.         case 7:    COPYBYTE;
  279.         case 6:    COPYBYTE;
  280.         case 5:    COPYBYTE;
  281.         case 4:    COPYBYTE;
  282.         case 3:    COPYBYTE;
  283.         case 2:    COPYBYTE;
  284.         case 1:    COPYBYTE;
  285.             } while (--loops > 0);
  286.         }
  287.  
  288.     }
  289. }
  290.  
  291. #endif
  292.