version 1.3, 2019/04/03 08:39:53 |
version 1.4, 2019/04/03 09:49:49 |
|
|
* Typical usage: |
* Typical usage: |
* statistics < filenames.txt | sort -n |
* statistics < filenames.txt | sort -n |
* statistics < filenames.txt | grep '\<listitem\>' | sort -n |
* statistics < filenames.txt | grep '\<listitem\>' | sort -n |
|
* |
|
* Relations already fully implemented are excluded by default. |
|
* The option -a shows all relations. |
|
* |
|
* If two arguments (parent and child) are given, a histogram |
|
* of the number of children of the kind in each parent is given |
|
* in addition to the normal output. |
|
* |
|
* Example usage: |
|
* statistics tgroup colspec < filenames.txt | grep colspec |
*/ |
*/ |
|
|
struct entry { |
struct entry { |
Line 52 static char **stack; |
|
Line 62 static char **stack; |
|
static size_t stacksz; |
static size_t stacksz; |
static size_t stacki; |
static size_t stacki; |
|
|
|
static const int nchildsz = 8; |
|
struct nchild { |
|
char *parent; |
|
char *child; |
|
int freq[nchildsz]; |
|
int count; |
|
}; |
|
|
|
static struct nchild nchild; |
|
static char *fname; |
|
|
|
|
/* |
/* |
* Count one instance of a parent-child relation. |
* Count one instance of a parent-child relation. |
* Before the special call table_add(NULL, NULL), |
* Before the special call table_add(NULL, NULL), |
Line 70 table_add(const char *parent, const char *child) |
|
Line 91 table_add(const char *parent, const char *child) |
|
return; |
return; |
} |
} |
|
|
|
/* Optional parent-child histogram. */ |
|
|
|
if (init_done && parent != NULL && child != NULL && |
|
nchild.parent != NULL && nchild.child != NULL && |
|
strcmp(parent, nchild.parent) == 0 && |
|
strcmp(child, nchild.child) == 0) { |
|
if (nchild.count < nchildsz) { |
|
nchild.freq[nchild.count]++; |
|
if (nchild.count > 0) |
|
nchild.freq[nchild.count - 1]--; |
|
} else if (nchild.count == nchildsz) |
|
puts(fname); |
|
nchild.count++; |
|
} |
|
|
/* 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++) { |
Line 109 table_add(const char *parent, const char *child) |
|
Line 145 table_add(const char *parent, const char *child) |
|
static void |
static void |
stack_push(const char *name) |
stack_push(const char *name) |
{ |
{ |
|
if (nchild.parent != NULL && strcmp(name, nchild.parent) == 0) |
|
nchild.count = 0; |
|
|
if (stacki == stacksz) { |
if (stacki == stacksz) { |
stacksz += 8; |
stacksz += 8; |
stack = reallocarray(stack, stacksz, sizeof(*stack)); |
stack = reallocarray(stack, stacksz, sizeof(*stack)); |
Line 283 parse_file(int fd, char *fname) |
|
Line 322 parse_file(int fd, char *fname) |
|
int |
int |
main(int argc, char *argv[]) |
main(int argc, char *argv[]) |
{ |
{ |
char *fname; |
|
size_t fsz, i; |
size_t fsz, i; |
ssize_t rsz; |
ssize_t rsz; |
int ch, fd, show_all; |
int ch, fd, show_all; |
Line 298 main(int argc, char *argv[]) |
|
Line 336 main(int argc, char *argv[]) |
|
return 1; |
return 1; |
} |
} |
} |
} |
|
argc -= optind; |
|
argv += optind; |
|
|
|
if (argc > 1) { |
|
nchild.parent = argv[0]; |
|
nchild.child = argv[1]; |
|
} |
|
|
/* Exclude relations that are already fully implemented. */ |
/* Exclude relations that are already fully implemented. */ |
if (show_all == 0) { |
if (show_all == 0) { |
table_add("para", NULL); |
table_add("para", NULL); |
Line 329 main(int argc, char *argv[]) |
|
Line 374 main(int argc, char *argv[]) |
|
if (table[i].count != -1) |
if (table[i].count != -1) |
printf("%d\t%s\t%s\n", table[i].count, |
printf("%d\t%s\t%s\n", table[i].count, |
table[i].parent, table[i].child); |
table[i].parent, table[i].child); |
|
|
|
/* Optional parent-child histogram. */ |
|
if (nchild.parent != NULL) { |
|
printf("%s %s", nchild.parent, nchild.child); |
|
for (i = 0; i < nchildsz; i++) |
|
printf(" %d", nchild.freq[i]); |
|
putchar('\n'); |
|
} |
return 0; |
return 0; |
} |
} |