home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / linuxdoc-sgml-1.1 / sgmls-1.1 / sgmlsasp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  5.3 KB  |  279 lines

  1. /* sgmlsasp.c
  2.    Translate sgmls output using ASP replacement file.
  3.  
  4.    Written by James Clark (jjc@jclark.com). */
  5.  
  6. #include "sgmlsasp.h"
  7. #include "sgmls.h"
  8. #include "replace.h"
  9. #include "getopt.h"
  10.  
  11. /* Non-zero if general (non-entity) names should be folded to upper case. */
  12. int fold_general_names = 1;
  13.  
  14. static char *program_name;
  15. static char last_char = '\n';
  16.  
  17. static void output_begin_line P((void));
  18. static void output_data P((struct sgmls_data *, int));
  19. static void output_pi P((char *, unsigned));
  20. static void output_token P((char *));
  21. static void output_attribute P((struct sgmls_attribute *));
  22. static void output_data_char P((int));
  23. static void output_replacement
  24.   P((struct replacement *, struct sgmls_attribute *));
  25. static void do_file P((FILE *, struct replacement_table *));
  26. static void usage P((void));
  27. static void input_error P((int, char *, unsigned long));
  28.  
  29. #define output_char(c) (last_char = (c), putchar(c))
  30.  
  31. int main(argc, argv)
  32.      int argc;
  33.      char **argv;
  34. {
  35.   struct replacement_table *tablep;
  36.   int i;
  37.   int opt;
  38.   program_name = argv[0];
  39.  
  40.   while ((opt = getopt(argc, argv, "n")) != EOF)
  41.     switch (opt) {
  42.     case 'n':
  43.       fold_general_names = 0;
  44.       break;
  45.     case '?':
  46.       usage();
  47.     default:
  48.       assert(0);
  49.     }
  50.   if (argc - optind <= 0)
  51.     usage();
  52.   tablep = make_replacement_table();
  53.   for (i = optind; i < argc; i++)
  54.     load_replacement_file(tablep, argv[i]);
  55.   (void)sgmls_set_errhandler(input_error);
  56.   do_file(stdin, tablep);
  57.   exit(0);
  58. }
  59.  
  60. static
  61. void usage()
  62. {
  63.   fprintf(stderr, "usage: %s [-n] replacement_file...\n", program_name);
  64.   exit(1);
  65. }
  66.  
  67. static
  68. void input_error(num, str, lineno)
  69.      int num;
  70.      char *str;
  71.      unsigned long lineno;
  72. {
  73.   error("Error at input line %lu: %s", lineno, str);
  74. }
  75.  
  76. static
  77. void do_file(fp, tablep)
  78.      FILE *fp;
  79.      struct replacement_table *tablep;
  80. {
  81.   struct sgmls *sp;
  82.   struct sgmls_event e;
  83.  
  84.   sp = sgmls_create(fp);
  85.   while (sgmls_next(sp, &e))
  86.     switch (e.type) {
  87.     case SGMLS_EVENT_DATA:
  88.       output_data(e.u.data.v, e.u.data.n);
  89.       break;
  90.     case SGMLS_EVENT_ENTITY:
  91.       /* XXX what should we do here? */
  92.       break;
  93.     case SGMLS_EVENT_PI:
  94.       output_pi(e.u.pi.s, e.u.pi.len);
  95.       break;
  96.     case SGMLS_EVENT_START:
  97.       output_replacement(lookup_replacement(tablep,
  98.                         START_ELEMENT, e.u.start.gi),
  99.              e.u.start.attributes);
  100.       sgmls_free_attributes(e.u.start.attributes);
  101.       break;
  102.     case SGMLS_EVENT_END:
  103.       output_replacement(lookup_replacement(tablep, END_ELEMENT, e.u.end.gi),
  104.              0);
  105.       break;
  106.     case SGMLS_EVENT_SUBSTART:
  107.       break;
  108.     case SGMLS_EVENT_SUBEND:
  109.       break;
  110.     case SGMLS_EVENT_APPINFO:
  111.       break;
  112.     case SGMLS_EVENT_CONFORMING:
  113.       break;
  114.     default:
  115.       abort();
  116.     }
  117.   sgmls_free(sp);
  118. }
  119.  
  120. static
  121. void output_data(v, n)
  122. struct sgmls_data *v;
  123. int n;
  124. {
  125.   int i;
  126.  
  127.   for (i = 0; i < n; i++) {
  128.     char *s = v[i].s;
  129.     int len = v[i].len;
  130.     for (; len > 0; len--, s++)
  131.       output_data_char(*s);
  132.   }
  133. }
  134.  
  135. static
  136. void output_pi(s, len)
  137.      char *s;
  138.      unsigned len;
  139. {
  140.   for (; len > 0; len--, s++)
  141.     output_data_char(*s);
  142. }
  143.  
  144. static
  145. void output_replacement(repl, attributes)
  146. struct replacement *repl;
  147. struct sgmls_attribute *attributes;
  148. {
  149.   struct replacement_item *p;
  150.   struct sgmls_attribute *a;
  151.   int i;
  152.  
  153.   if (!repl)
  154.     return;
  155.   if (repl->flags & NEWLINE_BEGIN)
  156.     output_begin_line();
  157.   
  158.   for (p = repl->items; p; p = p->next)
  159.     switch (p->type) {
  160.     case DATA_REPL:
  161.       for (i = 0; i < p->u.data.n; i++)
  162.     output_char(p->u.data.s[i]);
  163.       break;
  164.     case ATTR_REPL:
  165.       for (a = attributes; a; a = a->next)
  166.     if (strcmp(a->name, p->u.attr) == 0) {
  167.       output_attribute(a);
  168.       break;
  169.     }
  170.       break;
  171.     default:
  172.       abort();
  173.     }
  174.  
  175.   if (repl->flags & NEWLINE_END)
  176.     output_begin_line();
  177. }
  178.  
  179. static
  180. void output_attribute(p)
  181. struct sgmls_attribute *p;
  182. {
  183.   switch (p->type) {
  184.   case SGMLS_ATTR_IMPLIED:
  185.     break;
  186.   case SGMLS_ATTR_CDATA:
  187.     output_data(p->value.data.v, p->value.data.n);
  188.     break;
  189.   case SGMLS_ATTR_TOKEN:
  190.     {
  191.       char **token = p->value.token.v;
  192.       int n = p->value.token.n;
  193.       
  194.       if (n > 0) {
  195.     int i;
  196.     output_token(token[0]);
  197.     for (i = 1; i < n; i++) {
  198.       output_char(' ');
  199.       output_token(token[i]);
  200.     }
  201.       }
  202.     }
  203.     break;
  204.   case SGMLS_ATTR_ENTITY:
  205.     {
  206.       struct sgmls_entity **v = p->value.entity.v;
  207.       int n = p->value.entity.n;
  208.       int i;
  209.  
  210.       for (i = 0; i < n; i++) {
  211.     if (i > 0)
  212.       output_char(' ');
  213.     output_token(v[i]->is_internal
  214.              ? v[i]->u.internal.name
  215.              : v[i]->u.external.name);
  216.       }
  217.     }
  218.     break;
  219.   case SGMLS_ATTR_NOTATION:
  220.     if (p->value.notation)
  221.       output_token(p->value.notation->name);
  222.     break;
  223.   default:
  224.     abort();
  225.   }
  226. }
  227.  
  228. static
  229. void output_token(s)
  230.      char *s;
  231. {
  232.   for (; *s; s++)
  233.     output_char(*s);
  234. }
  235.  
  236. static
  237. void output_data_char(c)
  238.      int c;
  239. {
  240.   if (c != RSCHAR) {
  241.     if (c == RECHAR)
  242.       c = '\n';
  243.     output_char(c);
  244.   }
  245. }
  246.  
  247. static
  248. void output_begin_line()
  249. {
  250.   if (last_char != '\n')
  251.     output_char('\n');
  252. }
  253.  
  254. NO_RETURN
  255. #ifdef VARARGS
  256. void error(va_alist) va_dcl
  257. #else
  258. void error(char *message,...)
  259. #endif
  260. {
  261. #ifdef VARARGS
  262.      char *message;
  263. #endif
  264.      va_list ap;
  265.      
  266.      fprintf(stderr, "%s: ", program_name);
  267. #ifdef VARARGS
  268.      va_start(ap);
  269.      message = va_arg(ap, char *);
  270. #else
  271.      va_start(ap, message);
  272. #endif
  273.      vfprintf(stderr, message, ap);
  274.      va_end(ap);
  275.      fputc('\n', stderr);
  276.      fflush(stderr);
  277.      exit(EXIT_FAILURE);
  278. }
  279.