diff options
author | sinanmohd <sinan@firemail.cc> | 2023-05-09 18:52:09 +0530 |
---|---|---|
committer | sinanmohd <sinan@firemail.cc> | 2023-05-10 08:25:12 +0530 |
commit | 73526f53e58c476507c44fd94412b04244ab0930 (patch) | |
tree | a8e49d8c9b7985d869b43c4be31fbc06ab1f7476 /6.5 | |
parent | 3f761f64d02480c81177e39af2f00f0e76b6f113 (diff) |
6.5 initial commit
Diffstat (limited to '6.5')
-rw-r--r-- | 6.5/Makefile | 13 | ||||
-rw-r--r-- | 6.5/getch.c | 23 | ||||
-rw-r--r-- | 6.5/getch.h | 2 | ||||
-rw-r--r-- | 6.5/hash.c | 115 | ||||
-rw-r--r-- | 6.5/hash.h | 18 | ||||
-rw-r--r-- | 6.5/main.c | 34 | ||||
-rw-r--r-- | 6.5/test.c | 5 | ||||
-rw-r--r-- | 6.5/word.c | 58 | ||||
-rw-r--r-- | 6.5/word.h | 3 |
9 files changed, 271 insertions, 0 deletions
diff --git a/6.5/Makefile b/6.5/Makefile new file mode 100644 index 0000000..c99e8b9 --- /dev/null +++ b/6.5/Makefile @@ -0,0 +1,13 @@ +objects = main.o hash.o word.o getch.o +CC = gcc +CFLAGS = -Wvla -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -fsanitize=address + +hash : $(objects) + $(CC) $(CFLAGS) -o hash $(objects) + +main.o : word.h hash.h +word.o : getch.h + +.PHONY : clean +clean: + rm hash $(objects) diff --git a/6.5/getch.c b/6.5/getch.c new file mode 100644 index 0000000..a473190 --- /dev/null +++ b/6.5/getch.c @@ -0,0 +1,23 @@ +#include <stdio.h> +#include <stdlib.h> +#include <error.h> +#include <errno.h> +#include "getch.h" + +#define MAXBUFF 100 + +int gtop; +char buff[MAXBUFF]; + +char getch(void) +{ + return (gtop > 0) ? buff[--gtop] : getchar(); +} + +void ungetch(char c) +{ + if (gtop < MAXBUFF) + buff[gtop++] = c; + else + error(EXIT_FAILURE, ENOBUFS, "getch"); +} diff --git a/6.5/getch.h b/6.5/getch.h new file mode 100644 index 0000000..b0e086b --- /dev/null +++ b/6.5/getch.h @@ -0,0 +1,2 @@ +char getch(void); +void ungetch(char c); diff --git a/6.5/hash.c b/6.5/hash.c new file mode 100644 index 0000000..1e29bd7 --- /dev/null +++ b/6.5/hash.c @@ -0,0 +1,115 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include "hash.h" + +void nlfree(struct nlist *p); +uint32_t hash(char *s, uint32_t hashsize); +struct nlist *lookup(struct nlist *hashtab[], uint32_t hashsize, char *s); +void pnl(struct nlist *np); + +uint32_t hash(char *s, uint32_t hashsize) +{ + uint32_t hashval; + + for (hashval = 0; *s != '\0'; ++s) + hashval = *s + 31*hashval; + + return hashval % hashsize; +} + +struct nlist *lookup(struct nlist *hashtab[], uint32_t hashsize, char *s) +{ + struct nlist *np; + + for (np = hashtab[hash(s, hashsize)]; np != NULL; np = np->next) + if (!strcmp(s, np->name)) + return np; + + return NULL; +} + +struct nlist *install(struct nlist *hashtab[], uint32_t hashsize, + char *name, char *defn) +{ + struct nlist *np; + uint32_t hashval; + + if ((np = lookup(hashtab, hashsize, name)) == NULL) { + np = (struct nlist *) malloc(sizeof(*np)); + if (np == NULL || (np->name = strdup(name)) == NULL) { + nlfree(np); + return NULL; + } + + hashval = hash(name, hashsize); + np->next = hashtab[hashval]; + hashtab[hashval] = np; + } else { + free(np->defn); + } + + if ((np->defn = strdup(defn)) == NULL) { + undef(hashtab, hashsize, name); + return NULL; + } + + return np; +} + +void undef(struct nlist *hashtab[], uint32_t hashsize, char *name) +{ + struct nlist *cur, *last; + uint32_t hashval = hash(name, hashsize); + + for (cur = hashtab[hashval], last = NULL; cur !=NULL; last = cur, + cur = cur->next) { + if (!strcmp(cur->name, name)) { + if (last == NULL) + hashtab[hashval] = cur->next; + else + last->next = cur->next; + + cur->next = NULL; + nlfree(cur); + return; + } + } +} + +void pnl(struct nlist *np) +{ + if (np != NULL) { + pnl(np->next); + printf("%10s %s\n", np->name, np->defn); + } +} + +void phashtab(struct nlist *hashtab[], int lim) +{ + int i; + + for (i = 0; i < lim; ++i) + pnl(hashtab[i]); +} + +void nlfree(struct nlist *p) +{ + if (p != NULL ) { + nlfree(p->next); + if (p->defn != NULL) + free(p->defn); + if (p->name != NULL) + free(p->name); + free(p); + } +} + +void hashfree(struct nlist *hashtab[], int lim) +{ + int i; + + for (i = 0; i < lim; ++i) + nlfree(hashtab[i]); +} diff --git a/6.5/hash.h b/6.5/hash.h new file mode 100644 index 0000000..b32e0d4 --- /dev/null +++ b/6.5/hash.h @@ -0,0 +1,18 @@ +#include <stdint.h> + +#ifndef HASH_H + +struct nlist { + struct nlist *next; + char *name; + char *defn; +}; + +#define HASH_H +#endif + +struct nlist *install(struct nlist *hashtab[], uint32_t hashsize, + char *name, char *defn); +void undef(struct nlist *hashtab[], uint32_t hashsize, char *name); +void phashtab(struct nlist *hastab[], int hashsize); +void hashfree(struct nlist *hastab[], int hashsize); diff --git a/6.5/main.c b/6.5/main.c new file mode 100644 index 0000000..90bc87e --- /dev/null +++ b/6.5/main.c @@ -0,0 +1,34 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "word.h" +#include "hash.h" + +#define MAXWORD 100 +#define HASHSIZE 100 + +struct nlist *hashtab[HASHSIZE]; + +int main(void) +{ + char word[MAXWORD]; + char *name; + + while (getword(word, MAXWORD) != EOF) { + if (!strcmp(word, "#define")) { + getword(word, MAXWORD); + name = strdup(word); + getword(word, MAXWORD); + install(hashtab, HASHSIZE, name, word); + free(name); + } else if (!strcmp(word, "#undef")) { + getword(word, MAXWORD); + undef(hashtab, HASHSIZE, word); + } + } + + phashtab(hashtab, HASHSIZE); + hashfree(hashtab, HASHSIZE); + + return 0; +} diff --git a/6.5/test.c b/6.5/test.c new file mode 100644 index 0000000..d905c15 --- /dev/null +++ b/6.5/test.c @@ -0,0 +1,5 @@ +#define sneed feed +#define chuck seek +#define based soy +#define soy based +#undef chuck diff --git a/6.5/word.c b/6.5/word.c new file mode 100644 index 0000000..045eaf7 --- /dev/null +++ b/6.5/word.c @@ -0,0 +1,58 @@ +// #include <stdio.h> +// #include <stdlib.h> +// #include <stdint.h> +#include <ctype.h> +// #include <string.h> +// #include <error.h> +// #include <errno.h> +#include "getch.h" +#include "word.h" + +// #define MAXBUFF 100 +// +// uint32_t top; +// char *wstack[MAXBUFF]; + +char getword(char *word, int lim) +{ + char *w = word; + + // if (top > 0) + // return *wstack[--top]; + + while (isblank(*w = getch())) + ; + + if (isalpha(*w)) { + while ((isalnum(*++w = getch()) || *w == '_') && --lim > 0) + ; + ungetch(*w--); + } else if (*w == '#') { + --lim; + do { + *++w = getch(); + } while (isalpha(*w) && --lim > 0); + ungetch(*w--); + } + + *++w = '\0'; + return word[0]; +} +// +// void ungetword(char *word) +// { +// if (top < MAXBUFF) { +// if ((wstack[top++] = strdup(word)) == NULL) +// error(EXIT_FAILURE, ENOBUFS, "ungetword"); +// } else { +// error(EXIT_FAILURE, ENOBUFS, "ungetword"); +// } +// } +// +// void wordfree(void) +// { +// uint32_t i; +// +// for (i = 0; i < top; ++i) +// free(wstack[i]); +// } diff --git a/6.5/word.h b/6.5/word.h new file mode 100644 index 0000000..fcd8240 --- /dev/null +++ b/6.5/word.h @@ -0,0 +1,3 @@ +char getword(char *word, int lim); +// void ungetword(char *word); +// void wordfree(void); |