13e12c5d1SDavid du Colombier #include "common.h"
23e12c5d1SDavid du Colombier
3219b2ee8SDavid du Colombier /*
4219b2ee8SDavid du Colombier * WARNING! This turns all upper case names into lower case
5219b2ee8SDavid du Colombier * local ones.
6219b2ee8SDavid du Colombier */
7219b2ee8SDavid du Colombier
83e12c5d1SDavid du Colombier /* predeclared */
93e12c5d1SDavid du Colombier static String *getdbfiles(void);
107dd7cddfSDavid du Colombier static int translate(char*, char**, String*, String*);
117dd7cddfSDavid du Colombier static int lookup(String**, String*, String*);
123e12c5d1SDavid du Colombier static int compare(String*, char*);
13219b2ee8SDavid du Colombier static char* mklower(char*);
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier static int debug;
167dd7cddfSDavid du Colombier static int from;
177dd7cddfSDavid du Colombier static char *namefiles = "namefiles";
183e12c5d1SDavid du Colombier #define DEBUG if(debug)
193e12c5d1SDavid du Colombier
203e12c5d1SDavid du Colombier /* loop through the names to be translated */
213e12c5d1SDavid du Colombier void
main(int argc,char * argv[])223e12c5d1SDavid du Colombier main(int argc, char *argv[])
233e12c5d1SDavid du Colombier {
247dd7cddfSDavid du Colombier String *s;
253e12c5d1SDavid du Colombier String *alias; /* the alias for the name */
267dd7cddfSDavid du Colombier char **names; /* names of this system */
273e12c5d1SDavid du Colombier String *files; /* list of files to search */
283e12c5d1SDavid du Colombier int i, rv;
297dd7cddfSDavid du Colombier char *p;
303e12c5d1SDavid du Colombier
313e12c5d1SDavid du Colombier ARGBEGIN {
323e12c5d1SDavid du Colombier case 'd':
333e12c5d1SDavid du Colombier debug = 1;
343e12c5d1SDavid du Colombier break;
357dd7cddfSDavid du Colombier case 'f':
367dd7cddfSDavid du Colombier from = 1;
377dd7cddfSDavid du Colombier break;
387dd7cddfSDavid du Colombier case 'n':
397dd7cddfSDavid du Colombier namefiles = ARGF();
407dd7cddfSDavid du Colombier break;
413e12c5d1SDavid du Colombier } ARGEND
427dd7cddfSDavid du Colombier if (chdir(UPASLIB) < 0) {
433e12c5d1SDavid du Colombier perror("translate(chdir):");
443e12c5d1SDavid du Colombier exit(1);
453e12c5d1SDavid du Colombier }
463e12c5d1SDavid du Colombier
473e12c5d1SDavid du Colombier /* get environmental info */
487dd7cddfSDavid du Colombier names = sysnames_read();
493e12c5d1SDavid du Colombier files = getdbfiles();
503e12c5d1SDavid du Colombier alias = s_new();
513e12c5d1SDavid du Colombier
523e12c5d1SDavid du Colombier /* loop through the names to be translated (from standard input) */
533e12c5d1SDavid du Colombier for(i=0; i<argc; i++) {
547dd7cddfSDavid du Colombier s = unescapespecial(s_copy(mklower(argv[i])));
557dd7cddfSDavid du Colombier if(strchr(s_to_c(s), '!') == 0)
567dd7cddfSDavid du Colombier rv = translate(s_to_c(s), names, files, alias);
573e12c5d1SDavid du Colombier else
587dd7cddfSDavid du Colombier rv = -1;
597dd7cddfSDavid du Colombier if(from){
607dd7cddfSDavid du Colombier if (rv >= 0 && *s_to_c(alias) != '\0'){
617dd7cddfSDavid du Colombier p = strchr(s_to_c(alias), '\n');
627dd7cddfSDavid du Colombier if(p)
637dd7cddfSDavid du Colombier *p = 0;
647dd7cddfSDavid du Colombier p = strchr(s_to_c(alias), '!');
657dd7cddfSDavid du Colombier if(p) {
667dd7cddfSDavid du Colombier *p = 0;
677dd7cddfSDavid du Colombier print("%s", s_to_c(alias));
687dd7cddfSDavid du Colombier } else {
697dd7cddfSDavid du Colombier p = strchr(s_to_c(alias), '@');
707dd7cddfSDavid du Colombier if(p)
717dd7cddfSDavid du Colombier print("%s", p+1);
727dd7cddfSDavid du Colombier else
737dd7cddfSDavid du Colombier print("%s", s_to_c(alias));
747dd7cddfSDavid du Colombier }
757dd7cddfSDavid du Colombier }
767dd7cddfSDavid du Colombier } else {
777dd7cddfSDavid du Colombier if (rv < 0 || *s_to_c(alias) == '\0')
787dd7cddfSDavid du Colombier print("local!%s\n", s_to_c(s));
797dd7cddfSDavid du Colombier else {
807dd7cddfSDavid du Colombier /* this must be a write, not a print */
817dd7cddfSDavid du Colombier write(1, s_to_c(alias), strlen(s_to_c(alias)));
827dd7cddfSDavid du Colombier }
837dd7cddfSDavid du Colombier }
847dd7cddfSDavid du Colombier s_free(s);
853e12c5d1SDavid du Colombier }
863e12c5d1SDavid du Colombier exits(0);
873e12c5d1SDavid du Colombier }
883e12c5d1SDavid du Colombier
893e12c5d1SDavid du Colombier /* get the list of dbfiles to search */
903e12c5d1SDavid du Colombier static String *
getdbfiles(void)913e12c5d1SDavid du Colombier getdbfiles(void)
923e12c5d1SDavid du Colombier {
93*dc5a79c1SDavid du Colombier Sinstack *sp;
943e12c5d1SDavid du Colombier String *files = s_new();
957dd7cddfSDavid du Colombier char *nf;
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier if(from)
987dd7cddfSDavid du Colombier nf = "fromfiles";
997dd7cddfSDavid du Colombier else
1007dd7cddfSDavid du Colombier nf = namefiles;
1013e12c5d1SDavid du Colombier
1023e12c5d1SDavid du Colombier /* system wide aliases */
103*dc5a79c1SDavid du Colombier if ((sp = s_allocinstack(nf)) != 0){
104*dc5a79c1SDavid du Colombier while(s_rdinstack(sp, files))
1053e12c5d1SDavid du Colombier s_append(files, " ");
106*dc5a79c1SDavid du Colombier s_freeinstack(sp);
1073e12c5d1SDavid du Colombier }
1083e12c5d1SDavid du Colombier
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier DEBUG print("files are %s\n", s_to_c(files));
1113e12c5d1SDavid du Colombier
1123e12c5d1SDavid du Colombier return files;
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier
1153e12c5d1SDavid du Colombier /* loop through the translation files */
1163e12c5d1SDavid du Colombier static int
translate(char * name,char ** namev,String * files,String * alias)1173e12c5d1SDavid du Colombier translate(char *name, /* name to translate */
1187dd7cddfSDavid du Colombier char **namev, /* names of this system */
1197dd7cddfSDavid du Colombier String *files, /* names of system alias files */
1203e12c5d1SDavid du Colombier String *alias) /* where to put the alias */
1213e12c5d1SDavid du Colombier {
1223e12c5d1SDavid du Colombier String *file = s_new();
1237dd7cddfSDavid du Colombier String **fullnamev;
1247dd7cddfSDavid du Colombier int n, rv;
1253e12c5d1SDavid du Colombier
1267dd7cddfSDavid du Colombier rv = -1;
1277dd7cddfSDavid du Colombier
1287dd7cddfSDavid du Colombier DEBUG print("translate(%s, %s, %s)\n", name,
1293e12c5d1SDavid du Colombier s_to_c(files), s_to_c(alias));
1303e12c5d1SDavid du Colombier
1313e12c5d1SDavid du Colombier /* create the full name to avoid loops (system!name) */
1327dd7cddfSDavid du Colombier for(n = 0; namev[n]; n++)
1337dd7cddfSDavid du Colombier ;
1347dd7cddfSDavid du Colombier fullnamev = (String**)malloc(sizeof(String*)*(n+2));
1357dd7cddfSDavid du Colombier n = 0;
1367dd7cddfSDavid du Colombier fullnamev[n++] = s_copy(name);
1377dd7cddfSDavid du Colombier for(; *namev; namev++){
1387dd7cddfSDavid du Colombier fullnamev[n] = s_copy(*namev);
1397dd7cddfSDavid du Colombier s_append(fullnamev[n], "!");
1407dd7cddfSDavid du Colombier s_append(fullnamev[n], name);
1417dd7cddfSDavid du Colombier n++;
1427dd7cddfSDavid du Colombier }
1437dd7cddfSDavid du Colombier fullnamev[n] = 0;
1443e12c5d1SDavid du Colombier
1453e12c5d1SDavid du Colombier /* look at system-wide names */
1463e12c5d1SDavid du Colombier s_restart(files);
1473e12c5d1SDavid du Colombier while (s_parse(files, s_restart(file)) != 0) {
1487dd7cddfSDavid du Colombier if (lookup(fullnamev, file, alias)==0) {
1497dd7cddfSDavid du Colombier rv = 0;
1507dd7cddfSDavid du Colombier goto out;
1513e12c5d1SDavid du Colombier }
1523e12c5d1SDavid du Colombier }
1533e12c5d1SDavid du Colombier
1547dd7cddfSDavid du Colombier out:
1557dd7cddfSDavid du Colombier for(n = 0; fullnamev[n]; n++)
1567dd7cddfSDavid du Colombier s_free(fullnamev[n]);
1577dd7cddfSDavid du Colombier s_free(file);
1587dd7cddfSDavid du Colombier free(fullnamev);
1597dd7cddfSDavid du Colombier return rv;
1607dd7cddfSDavid du Colombier }
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier /*
1637dd7cddfSDavid du Colombier * very dumb conversion to bang format
1647dd7cddfSDavid du Colombier */
1657dd7cddfSDavid du Colombier static String*
attobang(String * token)1667dd7cddfSDavid du Colombier attobang(String *token)
1677dd7cddfSDavid du Colombier {
1687dd7cddfSDavid du Colombier char *p;
1697dd7cddfSDavid du Colombier String *tok;
1707dd7cddfSDavid du Colombier
1717dd7cddfSDavid du Colombier p = strchr(s_to_c(token), '@');
1727dd7cddfSDavid du Colombier if(p == 0)
1737dd7cddfSDavid du Colombier return token;
1747dd7cddfSDavid du Colombier
1757dd7cddfSDavid du Colombier p++;
1767dd7cddfSDavid du Colombier tok = s_copy(p);
1777dd7cddfSDavid du Colombier s_append(tok, "!");
1787dd7cddfSDavid du Colombier s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
1797dd7cddfSDavid du Colombier
1807dd7cddfSDavid du Colombier return tok;
1813e12c5d1SDavid du Colombier }
1823e12c5d1SDavid du Colombier
1833e12c5d1SDavid du Colombier /* Loop through the entries in a translation file looking for a match.
1843e12c5d1SDavid du Colombier * Return 0 if found, -1 otherwise.
1853e12c5d1SDavid du Colombier */
1863e12c5d1SDavid du Colombier static int
lookup(String ** namev,String * file,String * alias)1877dd7cddfSDavid du Colombier lookup(
1887dd7cddfSDavid du Colombier String **namev,
1893e12c5d1SDavid du Colombier String *file,
1903e12c5d1SDavid du Colombier String *alias) /* returned String */
1913e12c5d1SDavid du Colombier {
1923e12c5d1SDavid du Colombier String *line = s_new();
1933e12c5d1SDavid du Colombier String *token = s_new();
1947dd7cddfSDavid du Colombier String *bangtoken;
1957dd7cddfSDavid du Colombier int i, rv = -1;
1967dd7cddfSDavid du Colombier char *name = s_to_c(namev[0]);
197*dc5a79c1SDavid du Colombier Sinstack *sp;
1983e12c5d1SDavid du Colombier
1997dd7cddfSDavid du Colombier DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
2003e12c5d1SDavid du Colombier s_to_c(file), s_to_c(alias));
2013e12c5d1SDavid du Colombier
2023e12c5d1SDavid du Colombier s_reset(alias);
203*dc5a79c1SDavid du Colombier if ((sp = s_allocinstack(s_to_c(file))) == 0)
2043e12c5d1SDavid du Colombier return -1;
2053e12c5d1SDavid du Colombier
2063e12c5d1SDavid du Colombier /* look for a match */
207*dc5a79c1SDavid du Colombier while (s_rdinstack(sp, s_restart(line))!=0) {
2083e12c5d1SDavid du Colombier DEBUG print("line is %s\n", s_to_c(line));
2093e12c5d1SDavid du Colombier s_restart(token);
2103e12c5d1SDavid du Colombier if (s_parse(s_restart(line), token)==0)
2113e12c5d1SDavid du Colombier continue;
212*dc5a79c1SDavid du Colombier if (compare(token, "#include")==0){
213*dc5a79c1SDavid du Colombier if(s_parse(line, s_restart(token))!=0) {
214*dc5a79c1SDavid du Colombier if(lookup(namev, line, alias) == 0)
215*dc5a79c1SDavid du Colombier break;
216*dc5a79c1SDavid du Colombier }
217*dc5a79c1SDavid du Colombier continue;
218*dc5a79c1SDavid du Colombier }
2193e12c5d1SDavid du Colombier if (compare(token, name)!=0)
2203e12c5d1SDavid du Colombier continue;
2213e12c5d1SDavid du Colombier /* match found, get the alias */
2223e12c5d1SDavid du Colombier while(s_parse(line, s_restart(token))!=0) {
2237dd7cddfSDavid du Colombier bangtoken = attobang(token);
2247dd7cddfSDavid du Colombier
2253e12c5d1SDavid du Colombier /* avoid definition loops */
2267dd7cddfSDavid du Colombier for(i = 0; namev[i]; i++)
2277dd7cddfSDavid du Colombier if(compare(bangtoken, s_to_c(namev[i]))==0) {
2283e12c5d1SDavid du Colombier s_append(alias, "local");
2293e12c5d1SDavid du Colombier s_append(alias, "!");
2303e12c5d1SDavid du Colombier s_append(alias, name);
2317dd7cddfSDavid du Colombier break;
2323e12c5d1SDavid du Colombier }
2337dd7cddfSDavid du Colombier
2347dd7cddfSDavid du Colombier if(namev[i] == 0)
2357dd7cddfSDavid du Colombier s_append(alias, s_to_c(token));
2367dd7cddfSDavid du Colombier s_append(alias, "\n");
2377dd7cddfSDavid du Colombier
2387dd7cddfSDavid du Colombier if(bangtoken != token)
2397dd7cddfSDavid du Colombier s_free(bangtoken);
2403e12c5d1SDavid du Colombier }
2413e12c5d1SDavid du Colombier rv = 0;
2423e12c5d1SDavid du Colombier break;
2433e12c5d1SDavid du Colombier }
2443e12c5d1SDavid du Colombier s_free(line);
2453e12c5d1SDavid du Colombier s_free(token);
246*dc5a79c1SDavid du Colombier s_freeinstack(sp);
2473e12c5d1SDavid du Colombier return rv;
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier
2503e12c5d1SDavid du Colombier #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
251219b2ee8SDavid du Colombier
252219b2ee8SDavid du Colombier /* compare two Strings (case insensitive) */
2533e12c5d1SDavid du Colombier static int
compare(String * s1,char * p2)2543e12c5d1SDavid du Colombier compare(String *s1,
2553e12c5d1SDavid du Colombier char *p2)
2563e12c5d1SDavid du Colombier {
2573e12c5d1SDavid du Colombier char *p1 = s_to_c(s1);
2583e12c5d1SDavid du Colombier int rv;
2593e12c5d1SDavid du Colombier
2603e12c5d1SDavid du Colombier DEBUG print("comparing %s to %s\n", p1, p2);
2613e12c5d1SDavid du Colombier while((rv = lower(*p1) - lower(*p2)) == 0) {
2623e12c5d1SDavid du Colombier if (*p1 == '\0')
2633e12c5d1SDavid du Colombier break;
2643e12c5d1SDavid du Colombier p1++;
2653e12c5d1SDavid du Colombier p2++;
2663e12c5d1SDavid du Colombier }
2673e12c5d1SDavid du Colombier return rv;
2683e12c5d1SDavid du Colombier }
269219b2ee8SDavid du Colombier
2707dd7cddfSDavid du Colombier static char*
mklower(char * name)271219b2ee8SDavid du Colombier mklower(char *name)
272219b2ee8SDavid du Colombier {
273219b2ee8SDavid du Colombier char *p;
274219b2ee8SDavid du Colombier char c;
275219b2ee8SDavid du Colombier
276219b2ee8SDavid du Colombier for(p = name; *p; p++){
277219b2ee8SDavid du Colombier c = *p;
278219b2ee8SDavid du Colombier *p = lower(c);
279219b2ee8SDavid du Colombier }
280219b2ee8SDavid du Colombier return name;
281219b2ee8SDavid du Colombier }
282