cclash.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /*
  7. cclash: find clashing names within C programs
  8. Flags:
  9. -c : produce oldname=newname line for each clashing id
  10. (useful input for cid)
  11. -l<num> : check identifiers of <num> or more characters
  12. (default <num> = 8)
  13. -m : output a #define for each clashing id
  14. Author: Erik Baalbergen
  15. Date: Nov 8, 1985
  16. Revised: Dec 10, 1985
  17. C keywords are not listed
  18. Revised: Aug 27, 1986
  19. Skip C numeric constants
  20. Revised: Wed Jul 23 13:27:16 MDT 1986
  21. by Ceriel Jacobs,
  22. replaced "stoi" by "atoi"
  23. Revised: Tue Nov 11 13:32:31 MET 1986
  24. by Ceriel Jacobs,
  25. to produce lists for "cid" or preprocessor in
  26. alphabetical order.
  27. */
  28. #include <stdio.h>
  29. #define DEF_LENGTH 8
  30. struct idf {
  31. struct idf *id_next;
  32. char *id_name;
  33. struct idf *id_same;
  34. char id_key;
  35. };
  36. #define ACT_LISTONLY 0
  37. #define ACT_MAPFILE 1
  38. #define ACT_CID 2
  39. int maxlen = DEF_LENGTH;
  40. int action = ACT_LISTONLY;
  41. extern char *ProgName;
  42. char * keywords[] = {
  43. "asm",
  44. "auto",
  45. "break",
  46. "case",
  47. "char",
  48. "continue",
  49. "default",
  50. "do",
  51. "double",
  52. "else",
  53. "entry",
  54. "extern",
  55. "float",
  56. "for",
  57. "fortran",
  58. "goto",
  59. "if",
  60. "int",
  61. "long",
  62. "register",
  63. "return",
  64. "short",
  65. "sizeof",
  66. "static",
  67. "struct",
  68. "switch",
  69. "typedef",
  70. "union",
  71. "unsigned",
  72. "while",
  73. 0
  74. };
  75. struct idf *maplist = 0;
  76. DefineKeys()
  77. {
  78. register char **pkey = &keywords[0];
  79. register char *id;
  80. while (id = *pkey++)
  81. if (strlen(id) >= maxlen)
  82. InsertId(id, 1);
  83. }
  84. DoOption(str)
  85. char *str;
  86. {
  87. switch (str[1]) {
  88. case 'c':
  89. action = ACT_CID;
  90. break;
  91. case 'l':
  92. if ((maxlen = atoi(&str[2])) <= 0) {
  93. fprintf(stderr, "%s: option \"-l%s\" ignored\n",
  94. ProgName, &str[2]);
  95. maxlen = DEF_LENGTH;
  96. }
  97. break;
  98. case 'm':
  99. action = ACT_MAPFILE;
  100. break;
  101. default:
  102. fprintf(stderr, "%s: bad option \"%s\"\n", ProgName, str);
  103. break;
  104. }
  105. }
  106. #define HASHSIZE 257
  107. struct idf *hash_tab[HASHSIZE];
  108. char *Malloc(), *Salloc();
  109. InsertId(id, key)
  110. char *id;
  111. {
  112. int hash_val = EnHash(id);
  113. register struct idf *idp = hash_tab[hash_val];
  114. register struct idf *p = 0;
  115. while (idp && strncmp(idp->id_name, id, maxlen)) {
  116. p = idp;
  117. idp = idp->id_next;
  118. }
  119. if (idp == 0) {
  120. idp = (struct idf *) Malloc(sizeof(struct idf));
  121. idp->id_next = 0;
  122. if (!p) hash_tab[hash_val] = idp;
  123. else p->id_next = idp;
  124. idp->id_name = Salloc(id);
  125. idp->id_same = 0;
  126. }
  127. p = idp;
  128. while (p && strcmp(p->id_name, id)) {
  129. idp = p;
  130. p = p->id_same;
  131. }
  132. if (p == 0) {
  133. p = (struct idf *) Malloc(sizeof(struct idf));
  134. p->id_next = 0;
  135. p->id_same = 0;
  136. p->id_name = Salloc(id);
  137. idp->id_same = p;
  138. }
  139. p->id_key = key;
  140. }
  141. char *
  142. Malloc(n)
  143. unsigned n;
  144. {
  145. char *mem, *malloc();
  146. if ((mem = malloc(n)) == 0) {
  147. fprintf(stderr, "%s: out of memory\n", ProgName);
  148. exit(1);
  149. }
  150. return mem;
  151. }
  152. char *
  153. Salloc(str)
  154. char *str;
  155. {
  156. char *strcpy();
  157. if (str == 0)
  158. str = "";
  159. return strcpy(Malloc((unsigned)strlen(str) + 1), str);
  160. }
  161. EnHash(id)
  162. char *id;
  163. {
  164. register unsigned hash_val = 0;
  165. register n = maxlen;
  166. while (n-- && *id)
  167. hash_val = 31 * hash_val + *id++;
  168. return hash_val % (unsigned) HASHSIZE;
  169. }
  170. BeginOfProgram() { DefineKeys(); }
  171. EndOfProgram()
  172. {
  173. register int i;
  174. register struct idf *idp, *p;
  175. for (i = 0; i < HASHSIZE; i++) {
  176. for (idp = hash_tab[i]; idp; idp = idp->id_next) {
  177. if (idp->id_same == 0)
  178. continue;
  179. switch (action) {
  180. register n;
  181. case ACT_LISTONLY:
  182. n = 0;
  183. if (idp->id_key == 0) {
  184. printf(idp->id_name);
  185. n++;
  186. }
  187. for (p = idp->id_same; p; p = p->id_same)
  188. if (p->id_key == 0) {
  189. printf("%s%s",
  190. n ? " " : "",
  191. p->id_name
  192. );
  193. n++;
  194. }
  195. if (n)
  196. printf("\n");
  197. break;
  198. case ACT_CID:
  199. case ACT_MAPFILE:
  200. for (p = idp->id_same; p;) {
  201. register struct idf *q = p->id_same;
  202. if (p->id_key == 0)
  203. saveline(p);
  204. p = q;
  205. }
  206. if (idp->id_key == 0)
  207. saveline(idp);
  208. break;
  209. }
  210. }
  211. }
  212. switch(action) {
  213. case ACT_CID:
  214. case ACT_MAPFILE:
  215. for (idp = maplist; idp; idp = idp->id_same) {
  216. mapline(idp->id_name);
  217. }
  218. }
  219. }
  220. saveline(p)
  221. register struct idf *p;
  222. {
  223. register struct idf *idp = maplist, *idp1 = 0;
  224. while (idp && strcmp(idp->id_name, p->id_name) < 0) {
  225. idp1 = idp;
  226. idp = idp->id_same;
  227. }
  228. p->id_same = idp;
  229. if (idp1 == 0) {
  230. maplist = p;
  231. }
  232. else {
  233. idp1->id_same = p;
  234. }
  235. }
  236. mapline(nm)
  237. char *nm;
  238. {
  239. static map_count = 0;
  240. switch (action) {
  241. case ACT_MAPFILE:
  242. printf("#define %s _%d_%s\n", nm, ++map_count, nm);
  243. break;
  244. case ACT_CID:
  245. printf("%s=_%d_%s\n", nm, ++map_count, nm);
  246. break;
  247. }
  248. }
  249. CheckId(id, s)
  250. char *id;
  251. {
  252. if (s >= maxlen)
  253. InsertId(id, 0);
  254. }