lolamontes69

K+R Exercise6_2

Sep 25th, 2014
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.80 KB | None | 0 0
  1. /* Write a program that read a C program and prints in alphabetical order
  2. each group of variable names that are identical in the first 6 characters,
  3. but different somewhere thereafter. Don't count words within strings and
  4. comments. Make 6 a parameter that can be set from the command line
  5.  
  6. A group can contain 1 item.
  7. The request doesn't ask for all groups of more than one item.
  8. Note skips included filenames too.
  9. */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14. #include <string.h>
  15.  
  16. #define MAXWORD 100
  17. #define BUFSIZE 100
  18.  
  19. struct key {
  20.     char *word;
  21.     int count;
  22. } keytab[] = {
  23.     "#define",0,
  24.     "#elif",0,
  25.     "#else",0,
  26.     "#endif",0,
  27.     "#error",0,
  28.     "#if",0,
  29.     "#ifdef",0,
  30.     "#ifndef",0,
  31.     "#include",0,
  32.     "#line",0,
  33.     "#pragma",0,
  34.     "#undef",0,
  35.     "auto",0,
  36.     "break",0,
  37.     "case",0,
  38.     "char",0,
  39.     "const",0,
  40.     "continue",0,
  41.     "default",0,
  42.     "do",0,
  43.     "double",0,
  44.     "else",0,
  45.     "enum",0,
  46.     "extern",0,
  47.     "float",0,
  48.     "for",0,
  49.     "goto",0,
  50.     "if",0,
  51.     "int",0,
  52.     "long",0,
  53.     "register",0,
  54.     "return",0,
  55.     "short",0,
  56.     "signed",0,
  57.     "sizeof",0,
  58.     "static",0,
  59.     "struct",0,
  60.     "switch",0,
  61.     "typedef",0,
  62.     "union",0,
  63.     "unsigned",0,
  64.     "void",0,
  65.     "volatile",0,
  66.     "while",0
  67. };
  68.  
  69. struct tnode {            /* the tree node:       */
  70.     char *word;           /* points to the text   */
  71.     int count;            /* nunber of occurances */
  72.     struct tnode *left;   /* left child           */
  73.     struct tnode *right;  /* right child          */
  74. };
  75.  
  76.  
  77. #define NKEYS (sizeof keytab / sizeof(keytab[0])) /* space req between NKEYS ()*/
  78. char buf[BUFSIZE];
  79. int bufp = 0;
  80. int incflag=1;             /* used to skip included filenames */
  81.  
  82. char incheck[]="#include"; /* used to skip included filenames */
  83.  
  84.  
  85. struct tnode *addtree(struct tnode *, char *);
  86. void treeprint(struct tnode *);
  87.  
  88. int getword(char *, int);
  89. int binsearch(char *, struct key *, int);
  90. int escapecom(char *w);
  91.  
  92. int strlen1(char *s);
  93.  
  94. /* count C keywords */
  95. main(int argc, char *argv[])
  96. {
  97.     int n, c, type=0, j=6;
  98.     char word[MAXWORD];
  99.     struct tnode *root;
  100.  
  101.     while(--argc>0 && (*++argv)[0] == '-') {
  102.         while(c = *++argv[0])
  103.             type=c;
  104.             switch(type) {
  105.             case 'c':
  106.                 break;
  107.             default:
  108.                 puts("error: invalid flag");
  109.                 return -1;
  110.             }
  111.             c = *++argv[0];
  112.             j=0;
  113.             while(isdigit(**argv)) {
  114.                 j = (j*10)+(**argv-'0');
  115.                 (argv[0]++);
  116.             }
  117.     }
  118.     root = NULL; /* pointer to NULL */
  119.     while(getword(word,MAXWORD)!=EOF)
  120.         if(isalpha(word[0]) || word[0]=='#') {
  121.             n=binsearch(word,keytab,NKEYS);
  122.             if(n<0 && !incflag) {
  123.                 if(strlen1(word)>=j)
  124.                     root = addtree(root, word);
  125.             }
  126.             else if(incflag && n>=0) {
  127.                 if(strcmp(incheck, word)!=0) /* used to skip included filenames */
  128.                     incflag=0;
  129.             }
  130.         }
  131.     treeprint(root);
  132.     return 0;
  133. }
  134.  
  135. /* binsearch: find word in tab[0]...tab[n-1] */
  136. int binsearch(char *word, struct key tab[], int n)
  137. {
  138.     int cond;
  139.     int low, high, mid;
  140.  
  141.     low  = 0;
  142.     high = n-1;
  143.     while(low <= high) {
  144.         mid = (low+high)/2;
  145.         if((cond=strcmp(word,tab[mid].word)) < 0)  /* do a binary search amongst keywords */
  146.             high = mid-1;                          /* to see if word is amongst them      */
  147.         else if(cond>0)                            /* if so it returns its index          */
  148.             low=mid+1;
  149.         else
  150.             return mid;
  151.     }
  152.     return -1;
  153. }
  154.  
  155.  
  156. struct tnode *talloc(void);
  157. char *strdup1(char *);
  158.  
  159. /* addtree: add a node with w, at or below p */
  160. struct tnode *addtree(struct tnode *p, char *w)
  161. {
  162.     int cond;
  163.  
  164.     if(p == NULL) {    /* a new word has arrived */
  165.        p=talloc();     /* make a new node        */
  166.        p->word  = strdup1(w);
  167.        p->count = 1;
  168.        p->left  = p->right = NULL;
  169.     } else if ((cond = strcmp(w, p->word)) == 0)
  170.         p->count++;    /* repeated word */
  171.     else if(cond < 0)  /* less than into left subtree */
  172.         p->left  = addtree(p->left, w);
  173.     else               /* greater than into right subtree */
  174.         p->right = addtree(p->right, w);
  175.     return p;
  176. }
  177.  
  178.  
  179. /* getword: get nextword or character from input */
  180. int getword(char *word, int lim)
  181. {
  182.     int c, getch(void);
  183.     void ungetch(int);
  184.     char *w = word;
  185.  
  186.     while(isspace(c=getch()))
  187.         ;
  188.     if(c!=EOF)
  189.         *w++ = c;
  190.     if(!isalpha(c) && c!='\'' && c!='"' && c!='_' && c!='/' && c!='#') {
  191.         *w = '\0';
  192.         return c;
  193.     }
  194.     if(c=='#') {
  195.         while((c=getch())==' ') /* skip any spaces between '#' and keyword */
  196.             ;
  197.         *w++=c;
  198.     }
  199.     if(c=='"')
  200.         while((c=getch()) != '"' && c!='\n' && c!=EOF)
  201.             ;
  202.     else if(c=='\'')
  203.         while((c=getch()) != '\'' && c!='\n' && c!=EOF)
  204.             ;
  205.     else if(c=='/') escapecom(w);
  206.     for( ; --lim > 0; w++)
  207.         if(!isalnum(*w=getch()) && *w!='_') {
  208.                                       /* This adds to word and breaks on non-alnum*/
  209.             ungetch(*w);              /* so continue with underscores */
  210.             break;
  211.         }
  212.     *w = '\0';
  213.     return word[0];
  214. }
  215.  
  216. /* get a (possibly pushed-back) character */
  217. int getch(void)
  218. {
  219.     return (bufp > 0) ? buf[--bufp] : getchar();
  220. }
  221.  
  222. /* push character back on input */
  223. void ungetch(int c)
  224. {
  225.     if(bufp >= BUFSIZE)
  226.         printf("ungetch: too many characters\n");
  227.     else
  228.         buf[bufp++] = c;
  229. }
  230.  
  231. /* escapecom: see if a comment if so escape commented data */
  232. int escapecom(char *w)
  233. {
  234.     char c;
  235.    
  236.     c = getch();
  237.     if(c!='*') {
  238.         *w--;
  239.         while(c==' ')
  240.             c=getch(); /* skip spaces then */
  241.         *w++=c;        /* add char to word */
  242.         return 0;
  243.     }
  244.     while(1) {
  245.         while((c=getch())!='*' && c!=EOF) /* skip chars until valid end of comment */
  246.             ;
  247.         if((c=getch())=='/' || c==EOF)
  248.             return 0;
  249.     }
  250. }
  251.  
  252. /* treeprint: in-order print of tree p */
  253. void treeprint(struct tnode *p)
  254. {
  255.     if(p!=NULL) {
  256.         treeprint(p->left);
  257.         printf("%4d %s\n", p->count, p->word);
  258.         treeprint(p->right);
  259.     }
  260. }
  261.  
  262. /* talloc: make a tnode */
  263. struct tnode *talloc(void)
  264. {
  265.     return (struct tnode *) malloc(sizeof(struct tnode));
  266. }
  267.  
  268. char *strdup1(char *s) /* make a duplicate of s */
  269. {
  270.     char *p;
  271.  
  272.     p=(char *) malloc(strlen(s)+1); /* +1 for '\0' */
  273.     if(p!=NULL)
  274.         strcpy(p, s);
  275.     return p;
  276. }
  277.  
  278. int strlen1(char *s)
  279. {
  280.     int i;
  281.  
  282.     i=0;
  283.     while(s[i] != '\0')
  284.         ++i;
  285.     return i;
  286. }
Advertisement
Add Comment
Please, Sign In to add comment