ack/util/cmisc/cclash.c
ceriel 3bc3818955 Adapted to use General C Identifier processing Module (GCIPM).
Also changed so that output for "cid" or "cpp" is in alphabetical order.
1986-11-11 13:42:42 +00:00

301 lines
4.5 KiB
C

/*
cclash: find clashing names within C programs
Flags:
-c : produce oldname=newname line for each clashing id
(useful input for cid)
-l<num> : check identifiers of <num> or more characters
(default <num> = 8)
-m : output a #define for each clashing id
Author: Erik Baalbergen
Date: Nov 8, 1985
Revised: Dec 10, 1985
C keywords are not listed
Revised: Aug 27, 1986
Skip C numeric constants
Revised: Wed Jul 23 13:27:16 MDT 1986
by Ceriel Jacobs,
replaced "stoi" by "atoi"
Revised: Tue Nov 11 13:32:31 MET 1986
by Ceriel Jacobs,
to produce lists for "cid" or preprocessor in
alphabetical order.
*/
#include <stdio.h>
#define DEF_LENGTH 8
struct idf {
struct idf *id_next;
char *id_name;
struct idf *id_same;
char *id_key;
};
#define ACT_LISTONLY 0
#define ACT_MAPFILE 1
#define ACT_CID 2
int maxlen = DEF_LENGTH;
int action = ACT_LISTONLY;
extern char *ProgName;
char * keywords[] = {
"asm",
"auto",
"break",
"case",
"char",
"continue",
"default",
"do",
"double",
"else",
"entry",
"extern",
"float",
"for",
"fortran",
"goto",
"if",
"int",
"long",
"register",
"return",
"short",
"sizeof",
"static",
"struct",
"switch",
"typedef",
"union",
"unsigned",
"while",
0
};
struct idf *maplist = 0;
DefineKeys()
{
register char **pkey = &keywords[0];
register char *id;
while (id = *pkey++)
if (strlen(id) >= maxlen)
InsertId(id, 1);
}
DoOption(str)
char *str;
{
switch (str[1]) {
case 'c':
action = ACT_CID;
break;
case 'l':
if ((maxlen = atoi(&str[2])) <= 0) {
fprintf(stderr, "%s: option \"-l%s\" ignored\n",
ProgName, &str[2]);
maxlen = DEF_LENGTH;
}
break;
case 'm':
action = ACT_MAPFILE;
break;
default:
fprintf(stderr, "%s: bad option \"%s\"\n", ProgName, str);
break;
}
}
#define HASHSIZE 257
struct idf *hash_tab[HASHSIZE];
char *Malloc(), *Salloc();
InsertId(id, key)
char *id;
{
int hash_val = EnHash(id);
register struct idf *idp = hash_tab[hash_val];
register struct idf *p = 0;
while (idp && strncmp(idp->id_name, id, maxlen)) {
p = idp;
idp = idp->id_next;
}
if (idp == 0) {
idp = (struct idf *) Malloc(sizeof(struct idf));
idp->id_next = 0;
if (!p) hash_tab[hash_val] = idp;
else p->id_next = idp;
idp->id_name = Salloc(id);
idp->id_same = 0;
}
p = idp;
while (p && strcmp(p->id_name, id)) {
idp = p;
p = p->id_same;
}
if (p == 0) {
p = (struct idf *) Malloc(sizeof(struct idf));
p->id_next = 0;
p->id_same = 0;
p->id_name = Salloc(id);
idp->id_same = p;
}
if (key)
p->id_key = id;
}
char *
Malloc(n)
unsigned n;
{
char *mem, *malloc();
if ((mem = malloc(n)) == 0) {
fprintf(stderr, "%s: out of memory\n", ProgName);
exit(1);
}
return mem;
}
char *
Salloc(str)
char *str;
{
char *strcpy();
if (str == 0)
str = "";
return strcpy(Malloc(strlen(str) + 1), str);
}
EnHash(id)
char *id;
{
register unsigned hash_val = 0;
register n = maxlen;
while (n-- && *id)
hash_val = 31 * hash_val + *id++;
return hash_val % (unsigned) HASHSIZE;
}
BeginOfProgram() { }
EndOfProgram()
{
register int i;
register struct idf *idp, *p;
for (i = 0; i < HASHSIZE; i++) {
for (idp = hash_tab[i]; idp; idp = idp->id_next) {
if (idp->id_same == 0)
continue;
switch (action) {
register n;
case ACT_LISTONLY:
n = 0;
if (idp->id_key == 0) {
printf(idp->id_name);
n++;
}
for (p = idp->id_same; p; p = p->id_same)
if (p->id_key == 0) {
printf("%s%s",
n ? " " : "",
p->id_name
);
n++;
}
if (n)
printf("\n");
break;
case ACT_CID:
case ACT_MAPFILE:
for (p = idp->id_same; p;) {
register struct idf *q = p->id_same;
if (p->id_key == 0)
saveline(p);
p = q;
}
if (idp->id_key == 0)
saveline(idp);
break;
}
}
}
switch(action) {
case ACT_CID:
case ACT_MAPFILE:
for (idp = maplist; idp; idp = idp->id_same) {
mapline(idp->id_name);
}
}
}
saveline(p)
register struct idf *p;
{
register struct idf *idp = maplist, *idp1 = 0;
while (idp && strcmp(idp->id_name, p->id_name) < 0) {
idp1 = idp;
idp = idp->id_same;
}
p->id_same = idp;
if (idp1 == 0) {
maplist = p;
}
else {
idp1->id_same = p;
}
}
mapline(nm)
char *nm;
{
static map_count = 0;
switch (action) {
case ACT_MAPFILE:
printf("#define %s _%d_%s\n", nm, ++map_count, nm);
break;
case ACT_CID:
printf("%s=_%d_%s\n", nm, ++map_count, nm);
break;
}
}
CheckId(id, s)
char *id;
{
if (s >= maxlen)
InsertId(id, 0);
}