home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / cpp114.zoo / src / generic.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-20  |  3.7 KB  |  196 lines

  1. /*
  2. generic -- a pseudo-template code processor
  3.  
  4.              WARNING   WARNING   WARNING
  5. This code is basically a hack.  Only a bare minimum of error checking is
  6. done.  Use caution.
  7.  
  8. Usage:
  9.              parm 1 ---\    /--- parm 2
  10.                  vvvvv vvv
  11.     generic fred.zg joebob:1 alice:257 harvey:17
  12.             ^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^
  13.             \--------|---------/
  14.               parameter groups
  15.  
  16. Output file name is input file name without the trailing 'g'.
  17.  
  18. If there is a line in the input file beginning with "@0", it is removed
  19. and all lines above it appear only once in the output.  All other lines
  20. appear once per parameter group.  A '@' followed by a digit from 1 to 9
  21. is replaced by the corresponding parameter from the current parameter
  22. group.  The text "@@" is replaced by a single '@'.  All other text
  23. passes through unchanged.
  24.  
  25. Example:
  26.  
  27. Input file:
  28. --------------------
  29. This is a test.
  30. @0
  31. This is @1 a @2.
  32. --------------------
  33.  
  34. Command:
  35. generic fred.zg only:test not:drill
  36.  
  37. Output:
  38. --------------------
  39. This is a test.
  40. This is only a test.
  41. This is not a drill.
  42. --------------------
  43. */
  44.  
  45. #include <stdio.h>
  46. #include <stddef.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <ctype.h>
  50.  
  51. #ifdef NO_FGETPOS
  52. /* no fgetpos()/fsetpos(); define them in terms of fseek()/ftell() */
  53. #include <unistd.h>    /* for SEEK_SET, which really should have been
  54.                #define'd in <stdio.h> */
  55. typedef long fpos_t;
  56. #define    fgetpos(f, p)    (*(p) = ftell(f))
  57. #define    fsetpos(f, p)    fseek(f, *(p), SEEK_SET)
  58. #endif
  59.  
  60. #define LINEBUF 1024
  61.  
  62. char *line = 0;
  63. size_t size;
  64. FILE *inf, *outf;
  65. char *parms[9];
  66. fpos_t seekpoint;
  67.  
  68.  
  69. #ifdef __STDC__
  70. int getline(void);
  71. void set_parms(char *);
  72. void process_line(void);
  73. #endif
  74.  
  75.  
  76. int getline()
  77. {
  78.   register char *s, *t;
  79.   ptrdiff_t dp;
  80.  
  81.   if (!line)
  82.     line = malloc(size = LINEBUF);
  83.   s = line;
  84.   if (!fgets(s, size, inf)) {
  85.     return 0;
  86.   }
  87.   t = s + strlen(s);
  88.   for (;;) {
  89.     if (t[-1] != '\n') {
  90.       if (size - (t - s) < LINEBUF) {
  91.     dp = t - s;
  92.     size += LINEBUF;
  93.     s = (char *)realloc(s, size);
  94.     t = s + dp;
  95.       }
  96.       if (!fgets(t, (int)(size - (t - s)), inf)) {
  97.     *t = '\0';
  98.     break;
  99.       }
  100.       t += strlen(t);
  101.     } else
  102.       break;
  103.   }
  104.   *t = '\0';
  105.   line = s;
  106.   return 1;
  107. }
  108.  
  109. void set_parms(s) register char *s;
  110. {
  111.   register char *t;
  112.   register int i;
  113.  
  114.   for (i = 0; i <9; i++)
  115.     parms[i] = 0;
  116.   for (i = 0; i < 9 && *s; i++) {
  117.     t = strchr(s, ':');
  118.     if (!t)
  119.       t = s + strlen(s);
  120.     *t = '\0';
  121.     parms[i] = s;
  122.     s = t + 1;
  123.   }
  124. }
  125.  
  126. void process_line()
  127. {
  128.   register char *s, *t;
  129.  
  130.   s = line;
  131.   if (*s == '@' && s[1] == '0') {
  132.     fgetpos(inf, &seekpoint);
  133.     return;
  134.   }
  135.   for (;;) {
  136.     t = strchr(s, '@');
  137.     if (!t) {
  138.       fputs(s, outf);
  139.       return;
  140.     }
  141.     *t++ = '\0';
  142.     fputs(s, outf);
  143.     if (*t == '@') {
  144.       fputc('@', outf);
  145.       s = t + 1;
  146.       continue;
  147.     }
  148.     if (!isdigit(*t) || *t == '0') {
  149.       fputc('@', outf);
  150.       s = t;
  151.       continue;
  152.     }
  153.     if (parms[*t - '1'])
  154.       fputs(parms[*t - '1'], outf);
  155.     s = t + 1;
  156.   }
  157. }
  158.  
  159. main(argc, argv) int argc; char *argv[];
  160. {
  161.   char buf[512];
  162.   register char *s = buf;
  163.   register int i;
  164.  
  165.   if (argc < 3) {
  166.     fprintf(stderr, "usage: %s infile parmlist [parmlist ...]\n", argv[0]);
  167.     exit(1);
  168.   }
  169.   if (!(inf = fopen(argv[1], "r"))) {
  170.     fprintf(stderr, "%s: cannot open input file %s\n", argv[0], argv[1]);
  171.     exit(1);
  172.   }
  173.   fgetpos(inf, &seekpoint);
  174.   strcpy(buf, argv[1]);
  175.   s += strlen(s) - 1;
  176.   if (*s == 'g')
  177.     *s = '\0';
  178.   else {
  179.     *++s = 'g';
  180.     *++s = '\0';
  181.   }
  182.   if (!(outf = fopen(buf, "w"))) {
  183.     fprintf(stderr, "%s: cannot open output file %s\n", argv[0], buf);
  184.     exit(1);
  185.   }
  186.   for (i = 2; i < argc; i++) {
  187.     set_parms(argv[i]);
  188.     while (getline())
  189.       process_line();
  190.     fsetpos(inf, &seekpoint);
  191.   }
  192.   fclose(inf);
  193.   fclose(outf);
  194.   return 0;
  195. }
  196.