-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f93d072
commit 057e707
Showing
10 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
BINARY=undef | ||
|
||
include ../../Exercise_incl.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# include <stdio.h> | ||
|
||
int getline (char *line, int lim) | ||
{ | ||
int c; | ||
char *l0 = line; | ||
|
||
while (--lim > 0 && (c = getchar()) != EOF && c != '\n') | ||
*line++ = c; | ||
*line = '\0'; | ||
|
||
return c == EOF ? -1 : line - l0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# ifndef GETLINE_H | ||
# define GETLINE_H | ||
|
||
int getline (char *line, int lim); | ||
|
||
# endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# include <stdio.h> | ||
# include <stdlib.h> | ||
# include <string.h> | ||
|
||
struct nlist { /* table entry: */ | ||
struct nlist *next; /* next entry in chain */ | ||
char *name; /* defined name */ | ||
char *defn; /* replacement text */ | ||
}; | ||
|
||
#define HASHSIZE 101 | ||
|
||
static struct nlist *hashtab[HASHSIZE]; /* pointer table */ | ||
|
||
/* hash: form hash value for string s */ | ||
unsigned hash (char *s) | ||
{ | ||
unsigned hashval; | ||
|
||
for (hashval = 0; *s != '\0'; s++) | ||
hashval = *s + 31 * hashval; | ||
return hashval % HASHSIZE; | ||
} | ||
|
||
/* lookup: look for s in hashtab */ | ||
struct nlist *lookup (char *s) | ||
{ | ||
struct nlist *np; | ||
|
||
for (np = hashtab[hash(s)]; np != NULL; np = np->next) | ||
if (strcmp(s, np->name) == 0) | ||
return np; /* found */ | ||
return NULL; /* not found */ | ||
} | ||
|
||
/* make a duplicate of s */ | ||
char *strdup (char *s) | ||
{ | ||
char *p; | ||
|
||
p = (char *) malloc(strlen(s)+1); /* +1 for '\0' */ | ||
if (p != NULL) | ||
strcpy(p, s); | ||
return p; | ||
} | ||
|
||
/* install: put (name, defn) in hashtab */ | ||
struct nlist *install (char *name, char *defn) | ||
{ | ||
struct nlist *np; | ||
unsigned hashval; | ||
|
||
if ((np = lookup(name)) == NULL) { /* not found */ | ||
np = (struct nlist *) malloc(sizeof(*np)); | ||
if (np == NULL || (np->name = strdup(name)) == NULL) | ||
return NULL; | ||
hashval = hash(name); | ||
np->next = hashtab[hashval]; | ||
hashtab[hashval] = np; | ||
} else /* already there */ | ||
free((void *) np->defn); /*free previous defn */ | ||
if ((np->defn = strdup(defn)) == NULL) | ||
return NULL; | ||
return np; | ||
} | ||
|
||
/* free_node: free the memory taken by nlist, including internal strings */ | ||
void free_node (struct nlist *np) | ||
{ | ||
free(np->name); | ||
free(np->defn); | ||
free(np); | ||
} | ||
|
||
/* undef: remove name from hashtab */ | ||
int undef (char *name) | ||
{ | ||
struct nlist *np, *prev; | ||
|
||
if ((np = hashtab[hash(name)]) != NULL) { | ||
if (strcmp(np->name, name) == 0) { | ||
hashtab[hash(name)] = np->next; | ||
free_node(np); | ||
return 1; | ||
} else { | ||
for (prev = np, np = np->next; np != NULL; prev = np, np = np->next) | ||
if (strcmp(name, np->name) == 0) { | ||
prev->next = np->next; | ||
free_node(np); | ||
return 1; | ||
} | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/* print_hashtab: print hash table content */ | ||
void print_hashtab (void) | ||
{ | ||
int i; | ||
struct nlist *np; | ||
|
||
for (i = 0; i < HASHSIZE; i++) | ||
for (np = hashtab[i]; np != NULL; np = np->next) | ||
printf("[%d] '%s': '%s'\n", i, np->name, np->defn); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# ifndef HASHTAB_H | ||
# define HASHTAB_H | ||
|
||
/* lookup: look for s in hashtab */ | ||
struct nlist *lookup (char *s); | ||
/* install: put (name, defn) in hashtab */ | ||
struct nlist *install (char *name, char *defn); | ||
/* undef: remove name from hashtab */ | ||
int undef (char *name); | ||
/* print_hashtab: print hash table content */ | ||
void print_hashtab (void); | ||
|
||
# endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# include <stdio.h> | ||
# include <string.h> | ||
# include "getline.h" | ||
# include "hashtab.h" | ||
|
||
# define BUFSIZE 1024 | ||
|
||
int main () | ||
{ | ||
char line[BUFSIZE], name[BUFSIZE], defn[BUFSIZE]; | ||
|
||
while (getline(line, BUFSIZE) != -1) | ||
if (line[0] == '+') { | ||
int li = 2, ni = 0, di = 0; | ||
while (line[li] != ' ' && line[li] != '\0') | ||
name[ni++] = line[li++]; | ||
if (line[li] == '\0') { | ||
printf("ERROR! unexpected end of line while reading definition"); | ||
return 0; | ||
} | ||
name[ni] = '\0'; | ||
li++; | ||
while (line[li] != '\0') | ||
defn[di++] = line[li++]; | ||
defn[di] = '\0'; | ||
install(name, defn); | ||
} | ||
else if (line[0] == '-') { | ||
int li = 2, ni = 0; | ||
while (line[li] != '\0') | ||
name[ni++] = line[li++]; | ||
name[ni] = '\0'; | ||
undef(name); | ||
} else { | ||
printf("unrecognised operation '%c', should be '+' or '-'.\n", line[0]); | ||
return 0; | ||
} | ||
|
||
print_hashtab(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
+ some other | ||
+ some different | ||
+ some last one | ||
+ any any single time |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[5] 'some': 'last one' | ||
[91] 'any': 'any single time' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
+ once once upon a time | ||
+ this this one is safe | ||
+ delme you should not see this! | ||
+ delete this one should also be deleted | ||
+ fun fun fun fun | ||
- delme | ||
+ not ton | ||
- delete | ||
+ end . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[32] 'this': 'this one is safe' | ||
[52] 'fun': 'fun fun fun' | ||
[63] 'once': 'once upon a time' | ||
[76] 'end': '.' | ||
[86] 'not': 'ton' |