version 1.1, 2019/03/29 15:55:28 |
version 1.2, 2019/03/29 18:09:43 |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <err.h> |
#include <err.h> |
#include <fcntl.h> |
#include <fcntl.h> |
|
#include <getopt.h> |
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
Line 54 static size_t stacki; |
|
Line 55 static size_t stacki; |
|
|
|
/* |
/* |
* Count one instance of a parent-child relation. |
* Count one instance of a parent-child relation. |
|
* Before the special call table_add(NULL, NULL), |
|
* mark relations to not be counted; |
|
* in that phase, child can be NULL as a wildcard. |
*/ |
*/ |
static void |
static void |
table_add(const char *parent, const char *child) |
table_add(const char *parent, const char *child) |
{ |
{ |
size_t i; |
static int init_done; |
|
size_t i; |
|
|
|
if (parent == NULL && child == NULL) { |
|
init_done = 1; |
|
return; |
|
} |
|
|
/* If the table entry already exists, increment its count. */ |
/* If the table entry already exists, increment its count. */ |
|
|
for (i = 0; i < tablei; i++) { |
for (i = 0; i < tablei; i++) { |
if (strcmp(parent, table[i].parent) == 0 && |
if (strcmp(parent, table[i].parent) == 0 && |
strcmp(child, table[i].child) == 0) { |
(child == NULL || table[i].child == NULL || |
table[i].count++; |
strcmp(child, table[i].child) == 0)) { |
|
assert(init_done); |
|
if (table[i].count != -1) |
|
table[i].count++; |
return; |
return; |
} |
} |
} |
} |
Line 83 table_add(const char *parent, const char *child) |
|
Line 96 table_add(const char *parent, const char *child) |
|
|
|
if ((table[tablei].parent = strdup(parent)) == NULL) |
if ((table[tablei].parent = strdup(parent)) == NULL) |
err(1, NULL); |
err(1, NULL); |
if ((table[tablei].child = strdup(child)) == NULL) |
if (child == NULL) |
|
table[tablei].child = NULL; |
|
else if ((table[tablei].child = strdup(child)) == NULL) |
err(1, NULL); |
err(1, NULL); |
table[tablei++].count = 1; |
table[tablei++].count = init_done ? 1 : -1; |
} |
} |
|
|
/* |
/* |
Line 232 parse_file(int fd, char *fname) |
|
Line 247 parse_file(int fd, char *fname) |
|
poff++; |
poff++; |
} else if (b[poff] != '!' && b[poff] != '?') { |
} else if (b[poff] != '!' && b[poff] != '?') { |
table_add(stacki > 0 ? |
table_add(stacki > 0 ? |
stack[stacki - 1] : "", |
stack[stacki - 1] : "ROOT", |
b + poff); |
b + poff); |
stack_push(b + poff); |
stack_push(b + poff); |
} |
} |
Line 258 main(int argc, char *argv[]) |
|
Line 273 main(int argc, char *argv[]) |
|
char *fname; |
char *fname; |
size_t fsz, i; |
size_t fsz, i; |
ssize_t rsz; |
ssize_t rsz; |
int fd; |
int ch, fd, show_all; |
|
|
fd = -1; |
show_all = 0; |
fname = NULL; |
while ((ch = getopt(argc, argv, "a")) != -1) { |
|
switch (ch) { |
|
case 'a': |
|
show_all = 1; |
|
break; |
|
default: |
|
return 1; |
|
} |
|
} |
|
|
|
/* Exclude relations that are already fully implemented. */ |
|
if (show_all == 0) { |
|
table_add("para", NULL); |
|
} |
|
table_add(NULL, NULL); |
|
|
/* Loop over input files. */ |
/* Loop over input files. */ |
|
fd = -1; |
|
fname = NULL; |
while ((rsz = getline(&fname, &fsz, stdin)) != -1) { |
while ((rsz = getline(&fname, &fsz, stdin)) != -1) { |
if (fname[rsz - 1] == '\n') |
if (fname[rsz - 1] == '\n') |
fname[--rsz] = '\0'; |
fname[--rsz] = '\0'; |
Line 282 main(int argc, char *argv[]) |
|
Line 313 main(int argc, char *argv[]) |
|
|
|
/* Dump results. */ |
/* Dump results. */ |
for (i = 0; i < tablei; i++) |
for (i = 0; i < tablei; i++) |
printf("%d\t%s\t%s\n", table[i].count, |
if (table[i].count != -1) |
table[i].parent, table[i].child); |
printf("%d\t%s\t%s\n", table[i].count, |
|
table[i].parent, table[i].child); |
return 0; |
return 0; |
} |
} |