Skip to content

Commit d6ca6c5

Browse files
committed
revise code
Rewrote getword and renamed getLine to getdef, plus other minor tweaks throughout the program.
1 parent a4878d8 commit d6ca6c5

File tree

1 file changed

+64
-139
lines changed

1 file changed

+64
-139
lines changed

chapter06/6-6.c

+64-139
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
/*
22
* Exercise 6-6. Implement a simple version of the #define processor (i.e., no
3-
* arguments) suitable for use with C programs, base on the routines of this
3+
* arguments) suitable for use with C programs, based on the routines of this
44
* section. You may also find getch and ungetch helpful.
5+
*
56
* By Faisal Saadatmand
67
*/
78

9+
#include <ctype.h>
810
#include <stdio.h>
911
#include <stdlib.h>
1012
#include <string.h>
11-
#include <ctype.h>
1213

1314
#define HASHSIZE 101
14-
#define MAXWORD 100
15-
#define MAXLEN 5000
16-
#define BUFSIZE 100
17-
#define NSYMBOLS (sizeof symbol / sizeof symbol[0])
18-
19-
struct key {
20-
char *word;
21-
int count;
22-
};
15+
#define MAXWORD 100
16+
#define MAXLEN 5000
17+
#define BUFSIZE 100
2318

2419
struct nlist { /* table entry: */
2520
struct nlist *next; /* next entry in chain */
@@ -28,139 +23,82 @@ struct nlist { /* table entry: */
2823
};
2924

3025
/* globals */
31-
int buf[BUFSIZE]; /* buffer from ungetch */
32-
int bufp = 0; /* next free position in buf */
26+
int buf[BUFSIZE]; /* buffer from ungetch */
27+
int bufp = 0; /* next free position in buf */
3328
static struct nlist *hashtab[HASHSIZE]; /* pointer table */
3429

35-
struct key symbol[] = { /* array is sorted for binary search */
36-
{ "\"", 0 },
37-
{ "#", 0 },
38-
{ "*", 0 },
39-
{ "/", 0 },
40-
{ "\\", 0 },
41-
{ "_", 0 },
42-
};
43-
4430
/* functions */
45-
struct key *binsearch(char *, struct key *, int);
4631
int getword(char *, int);
47-
int getLine(char *, int);
32+
int getdef(char *, int);
4833
char *strDup(char *);
4934
unsigned hash(char *);
5035
struct nlist *lookup(char *);
5136
struct nlist *install(char *, char *);
5237
void printtab(struct nlist *[], int);
5338
void freetable(struct nlist *[], int);
5439

55-
/* binsearch: find word in tab[0]...tab[n - 1] */
56-
struct key *binsearch(char *word, struct key *tab, int n)
40+
/* getword: get next word or character from input */
41+
int getword(char *word, int lim)
5742
{
58-
int cond;
59-
struct key *low = &tab[0];
60-
struct key *high = &tab[n];
61-
struct key *mid;
43+
int c, getch(void);
44+
void ungetch(int);
45+
char *w = word;
6246

63-
while (low < high) {
64-
mid = low + (high - low) / 2;
65-
if ((cond = strcmp(word, mid->word)) < 0)
66-
high = mid;
67-
else if (cond > 0)
68-
low = mid + 1;
69-
else
70-
return mid;
71-
}
72-
return NULL;
47+
while (isspace(c = getch()))
48+
;
49+
if (c != EOF)
50+
*w++ = c;
51+
if (isalpha(c) || c == '_' || c == '#') {
52+
for ( ; --lim > 0; ++w)
53+
if (!isalnum(*w = getch()) && *w != '_') {
54+
ungetch(*w);
55+
break;
56+
}
57+
} else if (c == '\'') /* skip character constants */
58+
while ((c = getch()) != '\'')
59+
;
60+
else if (c == '\"') { /* skip string constants */
61+
while ((c = getch()) != '\"')
62+
if (c == '\\')
63+
getch();
64+
} else if (c == '/' && (c = getch()) == '*') /* skip comments */
65+
while ((c = getch()) != EOF)
66+
if (c == '*' && (c = getch()) == '/')
67+
break;
68+
*w ='\0';
69+
return c;
7370
}
7471

75-
int getch(void) /* get a (possibly pushed back) character */
72+
/* get a (possibly pushed back) character */
73+
int getch(void)
7674
{
7775
return (bufp > 0) ? buf[--bufp] : getchar();
7876
}
7977

80-
void ungetch(int c) /* push character back on input */
78+
/* push character back on input */
79+
void ungetch(int c)
8180
{
8281
if (bufp >= BUFSIZE)
8382
printf("ungetch: too many characters\n");
8483
else
8584
buf[bufp++] = c;
8685
}
8786

88-
/* getword: get next word or character from input: C program specific (modified
89-
* for define preprocessor control line) */
90-
int getword(char *word, int lim)
91-
{
92-
int c, getch(void);
93-
void ungetch(int);
94-
char *w = word;
95-
struct key *p;
96-
97-
while (isspace(c = getch()))
98-
;
99-
100-
if (c != EOF) {
101-
*w++ = c;
102-
*w = '\0';
103-
} else
104-
return c;
105-
106-
if (!isalpha(c) && (p = binsearch(word, symbol, NSYMBOLS)) == NULL)
107-
return c;
108-
109-
switch (c) {
110-
case '\\': /* handle escape sequences */
111-
c = getch();
112-
break;
113-
case '\"': /* skip words inside string constant */
114-
while ((c = getch()) != '\"')
115-
if (c == EOF)
116-
return c;
117-
break;
118-
case '/': /* skip words inside C comments */
119-
if ((c = getch()) == '*') {
120-
while ((c = getch()))
121-
if (c == '*' && (c = getch()) == '/')
122-
break;
123-
else if (c == EOF)
124-
return c;
125-
} else /* don't skip pointer variables */
126-
ungetch(c);
127-
break;
128-
default:
129-
if (c == '#') {
130-
while (isspace(c = getch()))
131-
;
132-
*w++ = c;
133-
}
134-
135-
for ( ; --lim > 0; w++)
136-
if (!isalnum(*w = getch()) && *w != '_') {
137-
ungetch(*w);
138-
break;
139-
}
140-
break;
141-
}
142-
143-
*w = '\0';
144-
return word[0];
145-
}
146-
147-
/* getLine: get line into s, return length of s -- modified to skip blanks at
148-
* the beginning of the line and not to insert a newline character at the end.
149-
* */
150-
int getLine(char *s, int lim)
87+
/* getdef: copy the rest of the line int s, return length of s. This is a
88+
* modified version of getLine, which skips leading blanks andd does not insert
89+
* a newline character at the end. */
90+
int getdef(char *s, int lim)
15191
{
15292
int c, len;
15393

15494
while (isspace(c = getch()))
15595
;
15696
*s++ = c;
157-
15897
len = 0;
15998
while (--lim > 0 && (c = getchar()) != EOF && c != '\n') {
16099
*s++ = c;
161100
++len;
162101
}
163-
164102
*s = '\0';
165103
return len;
166104
}
@@ -170,8 +108,8 @@ char *strDup(char *s)
170108
{
171109
char *p;
172110

173-
p = (char *) malloc(strlen(s) + 1); /* +1 for '\0' */
174-
if (p != NULL)
111+
p = malloc(strlen(s) + 1); /* +1 for '\0' */
112+
if (p)
175113
strcpy(p, s);
176114
return p;
177115
}
@@ -181,7 +119,7 @@ unsigned hash(char *s)
181119
{
182120
unsigned hashval;
183121

184-
for (hashval = 0; *s != '\0'; s++)
122+
for (hashval = 0; *s; ++s)
185123
hashval = *s + (31 * hashval);
186124
return hashval % HASHSIZE;
187125
}
@@ -191,8 +129,8 @@ struct nlist *lookup(char *s)
191129
{
192130
struct nlist *np;
193131

194-
for (np = hashtab[hash(s)]; np != NULL; np = np->next)
195-
if (strcmp(s, np->name) == 0)
132+
for (np = hashtab[hash(s)]; np; np = np->next)
133+
if (!strcmp(s, np->name))
196134
return np; /* found */
197135
return NULL;
198136
}
@@ -203,19 +141,16 @@ struct nlist *install(char *name, char *defn)
203141
struct nlist *np;
204142
unsigned hashval;
205143

206-
if ((np = lookup(name)) == NULL) { /* not found */
207-
np = (struct nlist *) malloc(sizeof(*np));
208-
if (np == NULL || (np->name = strDup(name)) == NULL)
144+
if (!(np = lookup(name))) { /* not found */
145+
np = malloc(sizeof(*np));
146+
if (!np || !(np->name = strDup(name)))
209147
return NULL; /* no (heap) memory */
210148
hashval = hash(name);
211149
np->next = hashtab[hashval];
212150
hashtab[hashval] = np;
213151
} else /* already there */
214152
free((void *) np->defn); /* free previous definition */
215-
216-
np->defn = strDup(defn); /* copy definition */
217-
218-
if (np->defn == NULL)
153+
if (!(np->defn = strDup(defn))) /* copy definition */
219154
return NULL;
220155
return np;
221156
}
@@ -224,45 +159,35 @@ void printtab(struct nlist *node[], int size)
224159
{
225160
int i;
226161

227-
for (i = 0; i < size; i++)
228-
if (node[i] != NULL)
229-
printf("%i name: %s defn: %s\n",
230-
i, node[i]->name, node[i]->defn);
162+
for (i = 0; i < size; ++i)
163+
if (node[i])
164+
printf("%i name: %s defn: %s\n", i, node[i]->name, node[i]->defn);
231165
}
232166

233167
/* freetable: free table's (and its content's) allocated memory from heap */
234168
void freetable(struct nlist *node[], int size)
235169
{
236170
int i;
237171

238-
for (i = 0; i < size; i++)
239-
if (node[i] != NULL) {
172+
for (i = 0; i < size; ++i)
173+
if (node[i]) {
240174
free(node[i]->name);
241175
free(node[i]->defn);
242176
free(node[i]);
243177
}
244178
}
245179

246-
/* simple define processor (no arguments) */
247180
int main (void)
248181
{
249-
// struct nlist *p;
250182
char word[MAXWORD];
251183
char defn[MAXLEN];
252-
char *name, *keyword = "#define";
253-
int ctrline;
254-
255-
name = word; /* unnecessary. Added for clarity */
184+
const char *keyword = "#define";
256185

257-
ctrline = 0;
258186
while (getword(word, MAXWORD) != EOF)
259-
if (word[0] == '#' && !ctrline) {
260-
if (strcmp(word, keyword) == 0)
261-
ctrline = 1; /* found processor control line */
262-
} else if (ctrline) { /* parse name and definition */
263-
getLine(defn, MAXLEN);
264-
install(name, defn);
265-
ctrline = 0;
187+
if (word[0] == '#' && !strcmp(word, keyword)) { /* found #define */
188+
getword(word, MAXLEN); /* get the name */
189+
getdef(defn, MAXLEN); /* parse definition */
190+
install(word, defn);
266191
}
267192
printf("Hash Table Values:\n");
268193
printtab(hashtab, HASHSIZE);

0 commit comments

Comments
 (0)