cref.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:3k
源码类别:

VC书籍

开发平台:

C/C++

  1. /*
  2. This version of xref uses the Text and Ring interfaces.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include "assert.h"
  9. #include "fmt.h"
  10. #include "mem.h"
  11. #include "table.h"
  12. #include "integer.h"
  13. #include "ring.h"
  14. #include "text.h"
  15. static char rcsid[] = "$Id: cref.c,v 1.3 1997/07/30 22:41:03 drh Exp $";
  16. Text_T getword(Text_T *line, Text_T first, Text_T rest) {
  17. int i, j;
  18. assert(line);
  19. if ((i = Text_upto(*line, 1, 0, first)) > 0) {
  20. Text_T word = Text_sub(*line, j = Text_many(*line, i, 0, rest), i);
  21. *line = Text_sub(*line, j, 0);
  22. return word;
  23. } else
  24. return Text_null;
  25. }
  26. Text_T first, rest;
  27. int textcmp(const void *x, const void *y) {
  28. return Text_cmp(*(Text_T *)x, *(Text_T *)y);
  29. }
  30. int compare(const void *x, const void *y) {
  31. return textcmp(*(Text_T **)x, *(Text_T **)y);
  32. }
  33. unsigned texthash(const void *x) {
  34. int i;
  35. unsigned h = 0;
  36. const Text_T *t = x;
  37. for (i = 0; i < t->len; i++)
  38. h = (h<<1) + t->str[i];
  39. return h;
  40. }
  41. void print(Table_T files) {
  42. int i;
  43. void **array = Table_toArray(files, NULL);
  44. qsort(array, Table_length(files), 2*sizeof (*array), compare);
  45. for (i = 0; array[i]; i += 2) {
  46. Ring_T ring = array[i+1];
  47. Text_T *filename = array[i];
  48. if (filename->len > 0)
  49. Fmt_print("t%T:", filename);
  50. while (Ring_length(ring) > 0) {
  51. Integer_T line = Ring_remhi(ring);
  52. Fmt_print(" %D", line);
  53. FREE(line);
  54. }
  55. Fmt_print("n");
  56. FREE(filename);
  57. Ring_free(&ring);
  58. }
  59. FREE(array);
  60. Table_free(&files);
  61. }
  62. Text_T *copy(Text_T t) {
  63. Text_T *p;
  64. NEW(p);
  65. *p = t;
  66. return p;
  67. }
  68. void cref(char *name, FILE *fp, Table_T identifiers) {
  69. char buf[512];
  70. Text_T filename = { 0, "" };
  71. int linenum;
  72. if (name)
  73. filename = Text_put(name);
  74. for (linenum = 1; fgets(buf, sizeof buf, fp) != NULL; linenum++) {
  75. Text_T id, line = Text_put(buf);
  76. while ((id = getword(&line, first, rest)).len > 0) {
  77. Ring_T ring;
  78. Table_T files;
  79. files = Table_get(identifiers, &id);
  80. if (files == NULL) {
  81. files = Table_new(0, textcmp, texthash);
  82. Table_put(identifiers, copy(id), files);
  83. }
  84. ring = Table_get(files, &filename);
  85. if (ring == NULL) {
  86. ring = Ring_new();
  87. Table_put(files, copy(filename), ring);
  88. Ring_addlo(ring, Integer_new(linenum));
  89. } else if (Integer_get(Ring_get(ring, 0)) != linenum)
  90. Ring_addlo(ring, Integer_new(linenum));
  91. }
  92. }
  93. }
  94. int main(int argc, char *argv[]) {
  95. int i;
  96. Table_T identifiers = Table_new(10000, textcmp, texthash);
  97. Text_save_T mark = Text_save();
  98. Fmt_register('T', Text_fmt);
  99. Fmt_register('D', Integer_fmt);
  100. first = Text_cat(Text_cat(Text_ucase, Text_lcase), Text_box("_", 1));
  101. rest  = Text_cat(first, Text_digits);
  102. for (i = 1; i < argc; i++) {
  103. FILE *fp = fopen(argv[i], "r");
  104. if (fp == NULL)
  105. fprintf(stderr, "%s: can't open '%s' (%s)n", argv[0], argv[i], strerror(errno));
  106. else {
  107. cref(argv[i], fp, identifiers);
  108. fclose(fp);
  109. }
  110. }
  111. if (argc == 1)
  112. cref(NULL, stdin, identifiers);
  113. {
  114. int i;
  115. void **array = Table_toArray(identifiers, NULL);
  116. qsort(array, Table_length(identifiers), 2*sizeof (*array), compare);
  117. for (i = 0; array[i]; i += 2) {
  118. Fmt_print("%T", array[i]);
  119. print(array[i+1]);
  120. FREE(array[i]);
  121. }
  122. FREE(array);
  123. Table_free(&identifiers);
  124. }
  125. Text_restore(&mark);
  126. return EXIT_SUCCESS;
  127. }