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

VC书籍

开发平台:

C/C++

  1. /*
  2. This version of xref uses the Text, Array, and MP interfaces,
  3. and stores the line numbers in 3-byte MP_Ts in Array_Ts.
  4. It's slow, because it expands Array_Ts one element at a time.
  5. getword picks off the identifiers right-to-left.
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <errno.h>
  11. #include "assert.h"
  12. #include "fmt.h"
  13. #include "mem.h"
  14. #include "mp.h"
  15. #include "table.h"
  16. #include "array.h"
  17. #include "text.h"
  18. static char rcsid[] = "$Id: iref.c,v 1.3 1997/07/30 22:41:04 drh Exp $";
  19. Text_T getword(Text_T *line, Text_T first, Text_T rest) {
  20. int i, j;
  21. assert(line);
  22. if ((i = Text_rupto(*line, 1, 0, first)) > 0) {
  23. Text_T word = Text_sub(*line, j = Text_rmany(*line, 1, i + 1, rest), i + 1);
  24. *line = Text_sub(*line, 1, j);
  25. return word;
  26. } else
  27. return Text_null;
  28. }
  29. Text_T first, rest;
  30. int textcmp(const void *x, const void *y) {
  31. return Text_cmp(*(Text_T *)x, *(Text_T *)y);
  32. }
  33. int compare(const void *x, const void *y) {
  34. return textcmp(*(Text_T **)x, *(Text_T **)y);
  35. }
  36. unsigned texthash(const void *x) {
  37. int i;
  38. unsigned h = 0;
  39. const Text_T *t = x;
  40. for (i = 0; i < t->len; i++)
  41. h = (h<<1) + t->str[i];
  42. return h;
  43. }
  44. void print(Table_T files) {
  45. int i;
  46. void **array = Table_toArray(files, NULL);
  47. qsort(array, Table_length(files), 2*sizeof (*array), compare);
  48. for (i = 0; array[i]; i += 2) {
  49. int j;
  50. Text_T *filename = array[i];
  51. if (filename->len > 0)
  52. Fmt_print("t%T:", filename);
  53. for (j = 0; j < Array_length(array[i+1]); j++)
  54. Fmt_print(" %D", Array_get(array[i+1], j), 10);
  55. Fmt_print("n");
  56. FREE(filename);
  57. Array_free((Array_T *)&array[i+1]);
  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 iref(char *name, FILE *fp, Table_T identifiers) {
  69. char buf[512];
  70. Text_T filename = { 0, "" };
  71. unsigned char linenum[3];
  72. if (name)
  73. filename = Text_put(name);
  74. MP_fromint(linenum, 1);
  75. while (fgets(buf, sizeof buf, fp) != NULL) {
  76. Text_T id, line = Text_put(buf);
  77. while ((id = getword(&line, first, rest)).len > 0) {
  78. Array_T array;
  79. Table_T files;
  80. files = Table_get(identifiers, &id);
  81. if (files == NULL) {
  82. files = Table_new(0, textcmp, texthash);
  83. Table_put(identifiers, copy(id), files);
  84. }
  85. array = Table_get(files, &filename);
  86. if (array == NULL) {
  87. array = Array_new(1, 3);
  88. Table_put(files, copy(filename), array);
  89. Array_put(array, 0, linenum);
  90. } else if (MP_cmp(Array_get(array, Array_length(array)-1), linenum) != 0) {
  91. Array_resize(array, Array_length(array) + 1);
  92. Array_put(array, Array_length(array) - 1, linenum);
  93. }
  94. }
  95. MP_addi(linenum, linenum, 1);
  96. }
  97. }
  98. int main(int argc, char *argv[]) {
  99. int i;
  100. Table_T identifiers = Table_new(10000, textcmp, texthash);
  101. Text_save_T mark = Text_save();
  102. Fmt_register('T', Text_fmt);
  103. Fmt_register('D', MP_fmt);
  104. MP_set(24);
  105. first = Text_cat(Text_cat(Text_ucase, Text_lcase), Text_box("_", 1));
  106. rest  = Text_cat(first, Text_digits);
  107. for (i = 1; i < argc; i++) {
  108. FILE *fp = fopen(argv[i], "r");
  109. if (fp == NULL)
  110. fprintf(stderr, "%s: can't open '%s' (%s)n", argv[0], argv[i], strerror(errno));
  111. else {
  112. iref(argv[i], fp, identifiers);
  113. fclose(fp);
  114. }
  115. }
  116. if (argc == 1)
  117. iref(NULL, stdin, identifiers);
  118. {
  119. int i;
  120. void **array = Table_toArray(identifiers, NULL);
  121. qsort(array, Table_length(identifiers), 2*sizeof (*array), compare);
  122. for (i = 0; array[i]; i += 2) {
  123. Fmt_print("%T", array[i]);
  124. print(array[i+1]);
  125. FREE(array[i]);
  126. }
  127. FREE(array);
  128. Table_free(&identifiers);
  129. }
  130. Text_restore(&mark);
  131. return EXIT_SUCCESS;
  132. }