/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #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 */voidmain(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 inttranslate(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 intlookup( 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 intcompare(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;}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#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;
}