123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- #include "common.h"
- /*
- * WARNING! This turns all upper case names into lower case
- * local ones.
- */
- /* predeclared */
- static String *getdbfiles(void);
- static int translate(char*, char**, String*, String*);
- static int lookup(String**, String*, String*);
- static int compare(String*, char*);
- static char* mklower(char*);
- static int debug;
- static int from;
- static char *namefiles = "namefiles";
- #define DEBUG if(debug)
- /* loop through the names to be translated */
- void
- main(int argc, char *argv[])
- {
- String *s;
- String *alias; /* the alias for the name */
- char **names; /* names of this system */
- String *files; /* list of files to search */
- int i, rv;
- char *p;
- ARGBEGIN {
- case 'd':
- debug = 1;
- break;
- case 'f':
- from = 1;
- break;
- case 'n':
- namefiles = ARGF();
- break;
- } ARGEND
- if (chdir(UPASLIB) < 0) {
- perror("translate(chdir):");
- exit(1);
- }
- /* get environmental info */
- names = sysnames_read();
- files = getdbfiles();
- alias = s_new();
- /* loop through the names to be translated (from standard input) */
- for(i=0; i<argc; i++) {
- s = unescapespecial(s_copy(mklower(argv[i])));
- if(strchr(s_to_c(s), '!') == 0)
- rv = translate(s_to_c(s), names, files, alias);
- else
- rv = -1;
- if(from){
- if (rv >= 0 && *s_to_c(alias) != '\0'){
- p = strchr(s_to_c(alias), '\n');
- if(p)
- *p = 0;
- p = strchr(s_to_c(alias), '!');
- if(p) {
- *p = 0;
- print("%s", s_to_c(alias));
- } else {
- p = strchr(s_to_c(alias), '@');
- if(p)
- print("%s", p+1);
- else
- print("%s", s_to_c(alias));
- }
- }
- } else {
- if (rv < 0 || *s_to_c(alias) == '\0')
- print("local!%s\n", s_to_c(s));
- else {
- /* this must be a write, not a print */
- write(1, s_to_c(alias), strlen(s_to_c(alias)));
- }
- }
- s_free(s);
- }
- exits(0);
- }
- /* get the list of dbfiles to search */
- static String *
- getdbfiles(void)
- {
- Sinstack *sp;
- String *files = s_new();
- char *nf;
- if(from)
- nf = "fromfiles";
- else
- nf = namefiles;
- /* system wide aliases */
- if ((sp = s_allocinstack(nf)) != 0){
- while(s_rdinstack(sp, files))
- s_append(files, " ");
- s_freeinstack(sp);
- }
- DEBUG print("files are %s\n", s_to_c(files));
- return files;
- }
- /* loop through the translation files */
- static int
- translate(char *name, /* name to translate */
- char **namev, /* names of this system */
- String *files, /* names of system alias files */
- String *alias) /* where to put the alias */
- {
- String *file = s_new();
- String **fullnamev;
- int n, rv;
- rv = -1;
- DEBUG print("translate(%s, %s, %s)\n", name,
- s_to_c(files), s_to_c(alias));
- /* create the full name to avoid loops (system!name) */
- for(n = 0; namev[n]; n++)
- ;
- fullnamev = (String**)malloc(sizeof(String*)*(n+2));
- n = 0;
- fullnamev[n++] = s_copy(name);
- for(; *namev; namev++){
- fullnamev[n] = s_copy(*namev);
- s_append(fullnamev[n], "!");
- s_append(fullnamev[n], name);
- n++;
- }
- fullnamev[n] = 0;
- /* look at system-wide names */
- s_restart(files);
- while (s_parse(files, s_restart(file)) != 0) {
- if (lookup(fullnamev, file, alias)==0) {
- rv = 0;
- goto out;
- }
- }
- out:
- for(n = 0; fullnamev[n]; n++)
- s_free(fullnamev[n]);
- s_free(file);
- free(fullnamev);
- return rv;
- }
- /*
- * very dumb conversion to bang format
- */
- static String*
- attobang(String *token)
- {
- char *p;
- String *tok;
- p = strchr(s_to_c(token), '@');
- if(p == 0)
- return token;
- p++;
- tok = s_copy(p);
- s_append(tok, "!");
- s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
- return tok;
- }
- /* Loop through the entries in a translation file looking for a match.
- * Return 0 if found, -1 otherwise.
- */
- static int
- lookup(
- String **namev,
- String *file,
- String *alias) /* returned String */
- {
- String *line = s_new();
- String *token = s_new();
- String *bangtoken;
- int i, rv = -1;
- char *name = s_to_c(namev[0]);
- Sinstack *sp;
- DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
- s_to_c(file), s_to_c(alias));
- s_reset(alias);
- if ((sp = s_allocinstack(s_to_c(file))) == 0)
- return -1;
- /* look for a match */
- while (s_rdinstack(sp, s_restart(line))!=0) {
- DEBUG print("line is %s\n", s_to_c(line));
- s_restart(token);
- if (s_parse(s_restart(line), token)==0)
- continue;
- if (compare(token, "#include")==0){
- if(s_parse(line, s_restart(token))!=0) {
- if(lookup(namev, line, alias) == 0)
- break;
- }
- continue;
- }
- if (compare(token, name)!=0)
- continue;
- /* match found, get the alias */
- while(s_parse(line, s_restart(token))!=0) {
- bangtoken = attobang(token);
- /* avoid definition loops */
- for(i = 0; namev[i]; i++)
- if(compare(bangtoken, s_to_c(namev[i]))==0) {
- s_append(alias, "local");
- s_append(alias, "!");
- s_append(alias, name);
- break;
- }
- if(namev[i] == 0)
- s_append(alias, s_to_c(token));
- s_append(alias, "\n");
- if(bangtoken != token)
- s_free(bangtoken);
- }
- rv = 0;
- break;
- }
- s_free(line);
- s_free(token);
- s_freeinstack(sp);
- return rv;
- }
- #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
- /* compare two Strings (case insensitive) */
- static int
- compare(String *s1,
- char *p2)
- {
- char *p1 = s_to_c(s1);
- int rv;
- DEBUG print("comparing %s to %s\n", p1, p2);
- while((rv = lower(*p1) - lower(*p2)) == 0) {
- if (*p1 == '\0')
- break;
- p1++;
- p2++;
- }
- return rv;
- }
- static char*
- mklower(char *name)
- {
- char *p;
- char c;
- for(p = name; *p; p++){
- c = *p;
- *p = lower(c);
- }
- return name;
- }
|