cclash.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /* $Header$ */
  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. if (key)
  140. p->id_key = id;
  141. }
  142. char *
  143. Malloc(n)
  144. unsigned n;
  145. {
  146. char *mem, *malloc();
  147. if ((mem = malloc(n)) == 0) {
  148. fprintf(stderr, "%s: out of memory\n", ProgName);
  149. exit(1);
  150. }
  151. return mem;
  152. }
  153. char *
  154. Salloc(str)
  155. char *str;
  156. {
  157. char *strcpy();
  158. if (str == 0)
  159. str = "";
  160. return strcpy(Malloc(strlen(str) + 1), str);
  161. }
  162. EnHash(id)
  163. char *id;
  164. {
  165. register unsigned hash_val = 0;
  166. register n = maxlen;
  167. while (n-- && *id)
  168. hash_val = 31 * hash_val + *id++;
  169. return hash_val % (unsigned) HASHSIZE;
  170. }
  171. BeginOfProgram() { }
  172. EndOfProgram()
  173. {
  174. register int i;
  175. register struct idf *idp, *p;
  176. for (i = 0; i < HASHSIZE; i++) {
  177. for (idp = hash_tab[i]; idp; idp = idp->id_next) {
  178. if (idp->id_same == 0)
  179. continue;
  180. switch (action) {
  181. register n;
  182. case ACT_LISTONLY:
  183. n = 0;
  184. if (idp->id_key == 0) {
  185. printf(idp->id_name);
  186. n++;
  187. }
  188. for (p = idp->id_same; p; p = p->id_same)
  189. if (p->id_key == 0) {
  190. printf("%s%s",
  191. n ? " " : "",
  192. p->id_name
  193. );
  194. n++;
  195. }
  196. if (n)
  197. printf("\n");
  198. break;
  199. case ACT_CID:
  200. case ACT_MAPFILE:
  201. for (p = idp->id_same; p;) {
  202. register struct idf *q = p->id_same;
  203. if (p->id_key == 0)
  204. saveline(p);
  205. p = q;
  206. }
  207. if (idp->id_key == 0)
  208. saveline(idp);
  209. break;
  210. }
  211. }
  212. }
  213. switch(action) {
  214. case ACT_CID:
  215. case ACT_MAPFILE:
  216. for (idp = maplist; idp; idp = idp->id_same) {
  217. mapline(idp->id_name);
  218. }
  219. }
  220. }
  221. saveline(p)
  222. register struct idf *p;
  223. {
  224. register struct idf *idp = maplist, *idp1 = 0;
  225. while (idp && strcmp(idp->id_name, p->id_name) < 0) {
  226. idp1 = idp;
  227. idp = idp->id_same;
  228. }
  229. p->id_same = idp;
  230. if (idp1 == 0) {
  231. maplist = p;
  232. }
  233. else {
  234. idp1->id_same = p;
  235. }
  236. }
  237. mapline(nm)
  238. char *nm;
  239. {
  240. static map_count = 0;
  241. switch (action) {
  242. case ACT_MAPFILE:
  243. printf("#define %s _%d_%s\n", nm, ++map_count, nm);
  244. break;
  245. case ACT_CID:
  246. printf("%s=_%d_%s\n", nm, ++map_count, nm);
  247. break;
  248. }
  249. }
  250. CheckId(id, s)
  251. char *id;
  252. {
  253. if (s >= maxlen)
  254. InsertId(id, 0);
  255. }