lolamontes69

K+R Exercise6_6

Sep 25th, 2014
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.93 KB | None | 0 0
  1. /* Implement a simple version of the #define processor (i.e., no arguements)
  2.  * suitable for use with C programs, based on the routines of this section. You
  3.  * may also find getch and ungetch helpful.
  4.  *
  5.  * Implemented including the undef() method
  6.  *
  7.  * */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <ctype.h>
  12. #include <string.h>
  13.  
  14. #define HASHSIZE 101
  15. #define MAXWORD 100
  16. #define MAXTOKEN 100
  17. #define BUFSIZE 100
  18.  
  19.  
  20. struct nlist {      /* table entry: */
  21.     struct nlist *next;   /* next entry in chain */
  22.     char *name;           /* defined name        */
  23.     char *defn;           /* replacement text    */
  24. };
  25.  
  26.  
  27. static struct nlist *hashtab[HASHSIZE];  /* pointer table */
  28.  
  29. struct nlist *lookup(char *);
  30. char *strdup1(char *);
  31.  
  32. struct nlist *install(char *name, char *defn);
  33.  
  34. int getch(void);
  35. void ungetch(int c);
  36.  
  37. void errormessage(void);
  38. void undef(char *name);
  39. char temptoken[MAXTOKEN];
  40.  
  41. char buf[BUFSIZE];
  42. int bufp = 0;
  43. int flag = 0;
  44.  
  45.  
  46. main()
  47. {
  48.     int i;
  49.     char word[MAXWORD];
  50.     char nm[MAXTOKEN];
  51.     char dn[MAXTOKEN];
  52.     char *name=nm;
  53.     char *defn=dn;
  54.     char *temp=temptoken;
  55.     struct nlist *res;
  56.  
  57.     while((i = getword(word, MAXWORD)) != EOF) {
  58.         if(!flag) {
  59.             if(strcmp(word, "#define")==0)   /* can compare string to char array */
  60.                 flag++;
  61.             else if(strcmp(word, "#undef")==0)
  62.                 flag=4;
  63.         }
  64.         else if(flag==1) {
  65.             if(isalnum(word[0])) {
  66.                 temp = word;
  67.                 strcpy(name, temp);
  68.                 flag++;
  69.             } else
  70.                 errormessage();
  71.         } else if(flag==2) {
  72.             temp = word;
  73.             strcpy(defn, temp);
  74.             flag++;
  75.         } else if(flag==4) {
  76.             undef(word);
  77.             flag = 0;
  78.         }
  79.         if(flag==3) {
  80.             install(name, defn);
  81.             flag = 0;
  82.             printf("installed name %s defn %s\n",name,defn);
  83.         }
  84.  
  85.     }
  86.     printf("query here > ");
  87.     while((i = getword(word, MAXWORD)) != EOF) {
  88.         res = lookup(word);
  89.         if(res==NULL) printf("%s not in lookup\n",word);
  90.         else printf("defn for %s is %s\n",word,res->defn);
  91.         printf("\nquery here > ");
  92.     }
  93.  
  94.     puts(" ");
  95.     return 0;
  96. }
  97.  
  98. void errormessage(void)
  99. {
  100.     puts("error: invalid data");
  101.     exit(0);
  102. }
  103.  
  104.  
  105. /* getword: get nextword or character from input */
  106. int getword(char *word, int lim)
  107. {
  108.     int c, getch(void);
  109.     void ungetch(int);
  110.     char *w = word;
  111.  
  112.     while(isspace(c=getch()))
  113.         ;
  114.     if(c!=EOF)
  115.         *w++ = c;
  116.     if(!isalnum(c) && c!='#') {
  117.         *w = '\0';
  118.         return c;
  119.     }
  120.     for( ; --lim > 0; w++)
  121.         if(!isalnum(*w=getch()) && *w!='#') {
  122.             ungetch(*w);      
  123.             break;
  124.         }
  125.     *w = '\0';
  126.     return word[0];
  127. }
  128.  
  129. /* hash: form hash value for string s (a value between 0 and HASHSIZE) */
  130. unsigned hash(char *s)
  131. {
  132.     unsigned hashval;
  133.  
  134.     for(hashval =0; *s != '\0'; s++)
  135.         hashval = *s + 31 * hashval;      /* whatever s points to is incremented */
  136.     return hashval % HASHSIZE;            /* by (31 * hasval)  */
  137. }
  138.  
  139.  
  140. /* lookup: look for s in hashtab */
  141. struct nlist *lookup(char *s)
  142. {
  143.     struct nlist *np;
  144.                          /* iterate through hashtab to s if s is there */
  145.                          /* np->next is the pointer to the next struct */
  146.     for(np = hashtab[hash(s)]; np != NULL; np = np->next)
  147.         if(strcmp(s, np->name)==0)
  148.             return np;   /* found */
  149.     return NULL;         /* not found */
  150. }
  151.  
  152.  
  153. /* install: put(name, defn) in hashtab */
  154. struct nlist *install(char *name, char *defn)
  155. {
  156.     struct nlist *np;
  157.     unsigned hashval;
  158.  
  159.     if((np = lookup(name)) == NULL) { /* not found */
  160.         np = (struct nlist *) malloc(sizeof(*np));
  161.         if(np==NULL || (np->name = strdup1(name)) == NULL)
  162.             return NULL;
  163.         hashval = hash(name);
  164.         np->next = hashtab[hashval];
  165.         hashtab[hashval] = np;
  166.     } else        /* already there */
  167.         free((void *) np->defn); /* free previous defn */
  168.     if((np->defn = strdup1(defn))==NULL)
  169.         return NULL;
  170.     return np;
  171. }
  172.  
  173. void undef(char *name)
  174. {
  175.     struct nlist *np;
  176.  
  177.     if((np = lookup(name)) == NULL)
  178.         printf("undef error: %s not found in lookup\n",name);
  179.     else {
  180.         np->name = "";
  181.         np->defn = "";
  182.         printf("%s uninstalled from lookup\n",name);
  183.     }
  184. }
  185.  
  186.  
  187. /* strdup1: make a duplicate of s */
  188. char *strdup1(char *s)
  189. {
  190.     char *p;
  191.  
  192.     p=(char *) malloc(strlen(s)+1); /* +1 for '\0' */
  193.     if(p!=NULL)
  194.         strcpy(p, s);
  195.     return p;
  196. }
  197.  
  198.  
  199. /* get a (possibly pushed-back) character */
  200. int getch(void)
  201. {
  202.     return (bufp > 0) ? buf[--bufp] : getchar();
  203. }
  204.  
  205.  
  206. /* push character back on input */
  207. void ungetch(int c)
  208. {
  209.     if(bufp >= BUFSIZE)
  210.         printf("ungetch: too many characters\n");
  211.     else
  212.         buf[bufp++] = c;
  213. }
Advertisement
Add Comment
Please, Sign In to add comment