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

VC书籍

开发平台:

C/C++

  1. /*
  2. This version of xref, which is derived from cref, uses the Str and Seq
  3. interfaces, and it uses Atom_Ts are used for the line numbers.
  4. This version is a possible solution to exercise 11.5.
  5. Also, this version of getword picks off the identifiers from
  6. right to left.
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include "assert.h"
  13. #include "atom.h"
  14. #include "fmt.h"
  15. #include "mem.h"
  16. #include "table.h"
  17. #include "seq.h"
  18. #include "str.h"
  19. static char rcsid[] = "$Id: kref.c,v 1.3 1997/07/30 22:41:04 drh Exp $";
  20. int getword(char *line, int *i, char *first, char *rest) {
  21. int j;
  22. assert(line);
  23. assert(i);
  24. assert(first);
  25. assert(rest);
  26. if ((j = Str_rupto(line, 1, *i, first)) > 0)
  27. j = Str_rmany(line, 1, *i = j + 1, rest);
  28. return j;
  29. }
  30. char *first, *rest;
  31. int compare(const void *x, const void *y) {
  32. return Str_cmp(*(char **)x, 1, 0, *(char **)y, 1, 0);
  33. }
  34. unsigned strhash(const void *x) {
  35. const char *str = x;
  36. unsigned h = 0;
  37. while (*str)
  38. h = (h<<1) + *str++;
  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. Seq_T seq = array[i+1];
  47. char *filename = array[i];
  48. if (*filename)
  49. Fmt_print("t%S:", filename, 1, 0);
  50. while (Seq_length(seq) > 0)
  51. Fmt_print(" %S", Seq_remhi(seq), 1, 0);
  52. Fmt_print("n");
  53. FREE(filename);
  54. Seq_free(&seq);
  55. }
  56. FREE(array);
  57. Table_free(&files);
  58. }
  59. void kref(char *name, FILE *fp, Table_T identifiers) {
  60. char buf[512], *filename = "";
  61. int linenum;
  62. if (name)
  63. filename = name;
  64. for (linenum = 1; fgets(buf, sizeof buf, fp) != NULL; linenum++) {
  65. int i, j;
  66. for (i = 0; (j = getword(buf, &i, first, rest)) > 0; i = j) {
  67. char *id = Str_sub(buf, j, i);
  68. const char *ln = Atom_int(linenum);
  69. Seq_T seq;
  70. Table_T files;
  71. files = Table_get(identifiers, id);
  72. if (files == NULL) {
  73. files = Table_new(0,
  74. (int (*)(const void *, const void *))strcmp, strhash);
  75. Table_put(identifiers, id, files);
  76. } else
  77. FREE(id);
  78. seq = Table_get(files, filename);
  79. if (seq == NULL) {
  80. seq = Seq_new(0);
  81. Table_put(files, Str_dup(filename, 1, 0, 1), seq);
  82. Seq_addlo(seq, (void *)ln);
  83. } else if (Seq_get(seq, 0) != ln)
  84. Seq_addlo(seq, (void *)ln);
  85. }
  86. }
  87. }
  88. int main(int argc, char *argv[]) {
  89. int i;
  90. Table_T identifiers = Table_new(5000,
  91. (int (*)(const void *, const void *))strcmp, strhash);
  92. Fmt_register('S', Str_fmt);
  93. first = Str_catv("abcdefghijklmnopqrstuvwxyz", 1, 0,
  94. "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1, 0, "_", 1, 0, NULL);
  95. rest  = Str_cat(first, 1, 0, "0123456789", 1, 0);
  96. for (i = 1; i < argc; i++) {
  97. FILE *fp = fopen(argv[i], "r");
  98. if (fp == NULL)
  99. fprintf(stderr, "%s: can't open '%s' (%s)n", argv[0], argv[i], strerror(errno));
  100. else {
  101. kref(argv[i], fp, identifiers);
  102. fclose(fp);
  103. }
  104. }
  105. if (argc == 1)
  106. kref(NULL, stdin, identifiers);
  107. {
  108. int i;
  109. void **array = Table_toArray(identifiers, NULL);
  110. qsort(array, Table_length(identifiers), 2*sizeof (*array), compare);
  111. for (i = 0; array[i]; i += 2) {
  112. Fmt_print("%S", array[i], 1, 0);
  113. print(array[i+1]);
  114. FREE(array[i]);
  115. }
  116. FREE(array);
  117. Table_free(&identifiers);
  118. }
  119. return EXIT_SUCCESS;
  120. }