aboutsummaryrefslogtreecommitdiff
path: root/6.2
diff options
context:
space:
mode:
Diffstat (limited to '6.2')
-rw-r--r--6.2/Makefile13
-rw-r--r--6.2/getch.c23
-rw-r--r--6.2/getch.h2
-rw-r--r--6.2/main.c28
-rw-r--r--6.2/tree.c67
-rw-r--r--6.2/tree.h20
-rw-r--r--6.2/word.c63
-rw-r--r--6.2/word.h1
8 files changed, 217 insertions, 0 deletions
diff --git a/6.2/Makefile b/6.2/Makefile
new file mode 100644
index 0000000..d3991c3
--- /dev/null
+++ b/6.2/Makefile
@@ -0,0 +1,13 @@
+objects = main.o getch.o word.o tree.o
+CC = gcc
+CFLAGS = -Wvla -Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -fsanitize=address
+
+words : $(objects)
+ $(CC) $(CFLAGS) -o words $(objects)
+
+main.o : word.h tree.h
+word.o : getch.h
+
+.PHONY : clean
+clean :
+ rm words $(objects)
diff --git a/6.2/getch.c b/6.2/getch.c
new file mode 100644
index 0000000..2b86efe
--- /dev/null
+++ b/6.2/getch.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <error.h>
+#include <errno.h>
+#include "getch.h"
+
+#define MAXBUFF 100
+
+char buff[MAXBUFF];
+static size_t top;
+
+void ungetch(char c)
+{
+ if (top < MAXBUFF)
+ buff[top++] = c;
+ else
+ error(EXIT_FAILURE, ENOBUFS , "getch");
+}
+
+char getch(void)
+{
+ return (top > 0) ? buff[--top] : getchar();
+}
diff --git a/6.2/getch.h b/6.2/getch.h
new file mode 100644
index 0000000..cbfe8ad
--- /dev/null
+++ b/6.2/getch.h
@@ -0,0 +1,2 @@
+void ungetch(char c);
+char getch(void);
diff --git a/6.2/main.c b/6.2/main.c
new file mode 100644
index 0000000..57b562a
--- /dev/null
+++ b/6.2/main.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "word.h"
+#include "tree.h"
+
+#define MAXWORD 100
+#define DEFLEN 6
+
+int main(int argc, char *argv[])
+{
+ struct tnode *root;
+ char word[MAXWORD];
+ int bar;
+
+ bar = (--argc && (**++argv == '-')) ? atoi(argv[0]+1) : DEFLEN;
+ root = NULL;
+ while (getword(word, MAXWORD) != EOF)
+ if ((isalpha(word[0]) || (word[0] == '#' && isalpha(word[1]))) &&
+ strlen(word) > (size_t) bar)
+ root = naddtree(root, word, bar, NO);
+
+ ntreeprint(root);
+ treefree(root);
+
+ return 0;
+}
diff --git a/6.2/tree.c b/6.2/tree.c
new file mode 100644
index 0000000..5e061a4
--- /dev/null
+++ b/6.2/tree.c
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "tree.h"
+
+struct tnode *naddtree(struct tnode *p, char *w, int bar, int prevmatch)
+{
+ int cond;
+
+ if (p == NULL) {
+ p = talloc();
+ p->word = sneed_strdup(w);
+ p->count = 1;
+ p->match = prevmatch;
+ p->left = p->right = NULL;
+ } else {
+ if ((!strncmp(p->word, w, bar) && strcmp(p->word, w)))
+ p->match = prevmatch = YES;
+
+ if ((cond = strcmp(w, p->word)) == 0) {
+ p->count++;
+ } else if (cond < 0) {
+ p->left = naddtree(p->left, w, bar, prevmatch);
+ } else if (cond > 0) {
+ p->right = naddtree(p->right, w, bar, prevmatch);
+ }
+ }
+
+ return p;
+}
+
+void ntreeprint(struct tnode *p)
+{
+ if (p != NULL) {
+ ntreeprint(p->left);
+ if (p->match)
+ printf("%4d %s\n", p->count, p->word);
+ ntreeprint(p->right);
+ }
+}
+
+void treefree(struct tnode *p) {
+ if (p != NULL) {
+ if (p->left != NULL)
+ treefree(p->left);
+ if (p->right != NULL)
+ treefree(p->right);
+ free(p->word);
+ free(p);
+ }
+}
+
+struct tnode *talloc(void)
+{
+ return (struct tnode *) malloc(sizeof(struct tnode));
+}
+
+char *sneed_strdup(char *s)
+{
+ char *p;
+
+ p = (char *) malloc(strlen(s) + 1);
+ if (p != NULL)
+ strcpy(p, s);
+
+ return p;
+}
diff --git a/6.2/tree.h b/6.2/tree.h
new file mode 100644
index 0000000..e976495
--- /dev/null
+++ b/6.2/tree.h
@@ -0,0 +1,20 @@
+#ifndef TREE_H
+
+struct tnode {
+ char *word;
+ int count;
+ int match;
+ struct tnode *left;
+ struct tnode *right;
+};
+
+enum { NO, YES };
+
+#define TREE_H
+#endif
+
+struct tnode *naddtree(struct tnode *p, char *w, int bar, int prevmatch);
+void ntreeprint(struct tnode *p);
+void treefree(struct tnode *p);
+struct tnode *talloc(void);
+char *sneed_strdup(char *s);
diff --git a/6.2/word.c b/6.2/word.c
new file mode 100644
index 0000000..1c5503a
--- /dev/null
+++ b/6.2/word.c
@@ -0,0 +1,63 @@
+#include <stdio.h>
+#include <ctype.h>
+#include "getch.h"
+#include "word.h"
+
+char scomment(void);
+
+int getword(char *word, int lim)
+{
+ char *w = word;
+
+ while (isblank(*w = getch()) || *w == '"' || *w == '/') {
+ if (*w == '"') {
+ while ((*w = getch()) != '"' && *w != EOF)
+ ;
+ if (*w == EOF)
+ ungetch(*w);
+ } else if (*w == '/' && !scomment()) {
+ break;
+ }
+ }
+
+ if (isalpha(*w)) {
+ while ((isalnum(*w) || *w == '_') && --lim > 0)
+ *++w = getch();
+ ungetch(*w--);
+ } else if (*w == '#') {
+ --lim;
+ do {
+ *++w = getch();
+ } while (isalpha(*w) && --lim > 0);
+ ungetch(*w--);
+ }
+
+ *++w = '\0';
+ return word[0];
+}
+
+char scomment(void)
+{
+ char c;
+
+ switch (c = getch()) {
+ case '/' :
+ while ((c = getch()) != EOF && c != '\n')
+ ;
+ if (c == EOF)
+ ungetch(c);
+
+ return '/';
+ case '*' :
+ while ((c = getch()) != EOF && !(c == '*' && (c = getch()) == '/'))
+ if (c == '*')
+ ungetch(c);
+ if (c == EOF)
+ ungetch(c);
+
+ return '*';
+ default:
+ ungetch(c);
+ return 0;
+ }
+}
diff --git a/6.2/word.h b/6.2/word.h
new file mode 100644
index 0000000..5714c50
--- /dev/null
+++ b/6.2/word.h
@@ -0,0 +1 @@
+int getword(char *word, int len);