Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d6ca6c5

Browse files
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‎

Lines changed: 64 additions & 139 deletions
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-
structkey*binsearch(char *word, structkey*tab, int n)
40+
/* getword: get next word or character from input */
41+
intgetword(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 = (structnlist*) 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)

AltStyle によって変換されたページ (->オリジナル) /