home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / emacs / src / vms-pp.c < prev    next >
C/C++ Source or Header  |  1991-01-08  |  7KB  |  243 lines

  1. /* vms_pp - preprocess emacs files in such a way that they can be
  2.  *          compiled on VMS without warnings.
  3.  * Copyright (C) 1986 Free Software Foundation, Inc.
  4.    
  5. This file is part of GNU Emacs.
  6.  
  7. GNU Emacs is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11.  
  12. GNU Emacs is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU Emacs; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.  *
  22.  * Usage:
  23.  *    vms_pp infile outfile
  24.  * implicit inputs:
  25.  *    The file "vms_pp.trans" has the names and their translations.
  26.  * description:
  27.  *    Vms_pp takes the input file and scans it, replacing the long
  28.  *    names with shorter names according to the table read in from
  29.  *    vms_pp.trans. The line is then written to the output file.
  30.  *
  31.  *    Additionally, the "#undef foo" construct is replaced with:
  32.  *        #ifdef foo
  33.  *        #undef foo
  34.  *        #endif
  35.  *
  36.  *    The construct #if defined(foo) is replaced with
  37.  *        #ifdef foo
  38.  *        #define foo_VAL 1
  39.  *        #else
  40.  *        #define foo_VAL 0
  41.  *        #endif
  42.  *        #define defined(XX) XX_val
  43.  *        #if defined(foo)
  44.  *
  45.  *    This last contruction only works on single line #if's and takes
  46.  *    advantage of a questionable C pre-processor trick. If there are
  47.  *    comments within the #if, that contain "defined", then this will
  48.  *    bomb.
  49.  */
  50. #include <stdio.h>
  51.  
  52. #define Max_table 100
  53. #define Table_name "vms_pp.trans"
  54. #define Word_member \
  55. "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$"
  56.  
  57. static   FILE *in,*out;            /* read from, write to */
  58. struct item {                /* symbol table entries */
  59.   char *name;
  60.   char *value;
  61. };
  62. static struct item name_table[Max_table]; /* symbol table */
  63. static int defined_defined = 0;        /* small optimization */
  64.  
  65. main(argc,argv) int argc; char **argv; {
  66.   char buffer[1024];
  67.  
  68.   if(argc != 3) {            /* check argument count */
  69.     fprintf(stderr,"usage: vms_pp infile outfile");
  70.     exit();
  71.   }
  72.   init_table();                /* read in translation table */
  73.  
  74. /* open input and output files
  75.  */
  76.   if((in = fopen(argv[1],"r")) == NULL) {
  77.     fprintf(stderr,"vms_pp: unable to open file '%s'",argv[1]);
  78.     exit();
  79.   }
  80.   if((out = fopen(argv[2],"w")) == NULL) {
  81.     fprintf(stderr,"vms_pp: unable to create file '%s'",argv[2]);
  82.     exit();
  83.   }
  84.  
  85.   while(fgets(buffer,1023,in) != NULL) { /* loop through buffer until end */
  86.     process_line(buffer);        /* process the line */
  87.     fputs(buffer,out);            /* write out the line */
  88.   }
  89. }
  90.  
  91. /* buy - allocate and copy a string
  92.  */
  93. static char *buy(str) char *str; {
  94.   char *temp;
  95.  
  96.   if(!(temp = malloc(strlen(str)+1))) {
  97.     fprintf(stderr,"vms_pp: can't allocate memory");
  98.     exit();
  99.   }
  100.   strcpy(temp,str);
  101.   return temp;
  102. }
  103.  
  104. /* gather_word - return a buffer full of the next word
  105.  */
  106. static char *gather_word(ptr,word) char *ptr, *word;{
  107.   for(; strchr(Word_member,*ptr); ptr++,word++)
  108.     *word = *ptr;
  109.   *word = 0;
  110.   return ptr;
  111. }
  112.  
  113. /* skip_white - skip white space
  114.  */
  115. static char *skip_white(ptr) char *ptr; {
  116.   while(*ptr == ' ' || *ptr == '\t')
  117.     ptr++;
  118.   return ptr;
  119. }
  120.  
  121. /* init_table - initialize translation table.
  122.  */
  123. init_table() {
  124.   char buf[256],*ptr,word[128];
  125.   FILE *in;
  126.   int i;
  127.  
  128.   if((in = fopen(Table_name,"r")) == NULL) { /* open file */
  129.     fprintf(stderr,"vms_pp: can't open '%s'",Table_name);
  130.     exit();
  131.   }
  132.   for(i = 0; fgets(buf,255,in) != NULL;) { /* loop through lines */
  133.     ptr = skip_white(buf);
  134.     if(*ptr == '!')            /* skip comments */
  135.       continue;
  136.     ptr = gather_word(ptr,word);    /* get long word */
  137.     if(*word == 0) {            /* bad entry */
  138.       fprintf(stderr,"vms_pp: bad input line '%s'\n",buf);
  139.       continue;
  140.     }
  141.     name_table[i].name = buy(word);    /* set up the name */
  142.     ptr = skip_white(ptr);        /* skip white space */
  143.     ptr = gather_word(ptr,word);    /* get equivalent name */
  144.     if(*word == 0) {            /* bad entry */
  145.       fprintf(stderr,"vms_pp: bad input line '%s'\n",buf);
  146.       continue;
  147.     }
  148.     name_table[i].value = buy(word);    /* and the equivalent name */
  149.     i++;                /* increment to next position */
  150.   }
  151.   for(; i < Max_table; i++)        /* mark rest as unused */
  152.     name_table[i].name = 0;
  153. }
  154.  
  155. /* process_line - do actual line processing
  156.  */
  157. process_line(buf) char *buf; {
  158.   char *in_ptr,*out_ptr;
  159.   char word[128],*ptr;
  160.   int len;
  161.  
  162.   check_pp(buf);            /* check for preprocessor lines */
  163.  
  164.   for(in_ptr = out_ptr = buf; *in_ptr;) {
  165.     if(!strchr(Word_member,*in_ptr))    /* non alpha-numeric? just copy */
  166.       *out_ptr++ = *in_ptr++;
  167.     else {
  168.       in_ptr = gather_word(in_ptr,word); /* get the 'word' */
  169.       if(strlen(word) > 31)        /* length is too long */
  170.     replace_word(word);        /* replace the word */
  171.       for(ptr = word; *ptr; ptr++,out_ptr++) /* copy out the word */
  172.       *out_ptr = *ptr;
  173.     }
  174.   }
  175.   *out_ptr = 0;
  176. }
  177.  
  178. /* check_pp - check for preprocessor lines
  179.  */
  180. check_pp(buf) char *buf; {
  181.   char *ptr,*p;
  182.   char word[128];
  183.  
  184.   ptr = skip_white(buf);        /* skip white space */
  185.   if(*ptr != '#')            /* is this a preprocessor line? */
  186.     return;                /* no, just return */
  187.  
  188.   ptr = skip_white(++ptr);        /* skip white */
  189.   ptr = gather_word(ptr,word);        /* get command word */
  190.   if(!strcmp("undef",word)) {        /* undef? */
  191.     ptr = skip_white(ptr);
  192.     ptr = gather_word(ptr,word);    /* get the symbol to undef */
  193.     fprintf(out,"#ifdef %s\n",word);
  194.     fputs(buf,out);
  195.     strcpy(buf,"#endif");
  196.     return;
  197.   }
  198.   if(!strcmp("if",word)) {        /* check for if */
  199.     for(;;) {
  200.       ptr = strchr(ptr,'d');        /* look for d in defined */
  201.       if(!ptr)                /* are we done? */
  202.     return;
  203.       if(strchr(Word_member,*(ptr-1))){    /* at beginning of word? */
  204.     ptr++; continue;        /* no, continue looking */
  205.       }
  206.       ptr = gather_word(ptr,word);    /* get the word */
  207.       if(strcmp(word,"defined"))    /* skip if not defined */
  208.     continue;
  209.       ptr = skip_white(ptr);        /* skip white */
  210.       if(*ptr != '(')            /* look for open paren */
  211.     continue;            /* error, continue */
  212.       ptr++;                /* skip paren */
  213.       ptr = skip_white(ptr);        /* more white skipping */
  214.       ptr = gather_word(ptr,word);    /* get the thing to test */
  215.       if(!*word)            /* null word is bad */
  216.     continue;
  217.       fprintf(out,"#ifdef %s\n",word);    /* generate the code */
  218.       fprintf(out,"#define %s_VAL 1\n",word);
  219.       fprintf(out,"#else\n");
  220.       fprintf(out,"#define %s_VAL 0\n",word);
  221.       fprintf(out,"#endif\n");
  222.       if(!defined_defined) {
  223.     fprintf(out,"#define defined(XXX) XXX/**/_VAL\n");
  224.     defined_defined = 1;
  225.       }
  226.     }
  227.   }
  228. }
  229.  
  230. /* replace_word - look the word up in the table, and replace it
  231.  *          if a match is found.
  232.  */
  233. replace_word(word) char *word; {
  234.   int i;
  235.  
  236.   for(i = 0; i < Max_table && name_table[i].name; i++)
  237.     if(!strcmp(word,name_table[i].name)) {
  238.       strcpy(word,name_table[i].value);
  239.       return;
  240.     }
  241.   fprintf(stderr,"couldn't find '%s'\n",word);
  242. }
  243.