* about m4 quoting &c., but we have to #include it so that the C
* objects from the lexer are available.
*
- * Copyright (C)1996-1999 Ian Jackson
+ * userv is
+ * Copyright 1996-2017 Ian Jackson <ian@davenant.greenend.org.uk>.
+ * Copyright 2000 Ben Harris <bjh21@cam.ac.uk>
+ * Copyright 2016-2017 Peter Benie <pjb1008@cam.ac.uk>
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with userv; if not, write to the Free Software
- * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * along with userv; if not, see <http://www.gnu.org/licenses/>.
*/
static int parse_file(const char *string, int *didexist);
int v;
p=q=inplace;
- assert(*p++ = '"');
+ assert(*p=='"'); p++;
while (*p && *p != '"') {
if (*p != '\\') { *q++= *p++; continue; }
switch (*++p) {
*q++= v;
continue;
default:
- if (isalpha(*p))
+ if (ISCHAR(isalpha,*p))
return parseerrprint("unknown \\<letter> sequence \\%c in quoted string",*p);
- if (isdigit(*p)) {
+ if (ISCHAR(isdigit,*p)) {
if (!((buf[0]= *p++) && (buf[1]= *p++) && (buf[2]= *p++))) abort();
buf[3]= 0; v= strtoul(buf,&bep,8);
if (bep != buf+3 || (v & ~0xff))
return parseerrprint("invalid \\<octal> sequence \\%s in quoted string",buf);
*q++= v; continue;
- } else if (ispunct(*p)) {
+ } else if (ISCHAR(ispunct,*p)) {
*q++= *p++; continue;
} else {
while (*p==' ' || *p=='\t') p++;
}
}
}
- assert(*p); assert(!*++p);
+ assert(*p); p++; assert(!*p);
*q++= 0;
return tokv_quotedstring;
}
return buf;
} else if (token & tokt_number) {
snyprintf(buf,sizeof(buf),"number %d",lr_min); return buf;
+ } else if (token & tokt_fdrange && token & tokr_word) {
+ snyprintf(buf,sizeof(buf),"fd %s",buf); return buf;
} else if (token & tokt_fdrange && lr_max==-1) {
snyprintf(buf,sizeof(buf),"fdrange %d-",lr_min); return buf;
} else if (token & tokt_fdrange) {
l= strlen(buf); i= sizeof(buf)-l-2; p= yytext; q= buf+l;
while ((c= *p++)) {
if (i-- <= 0) { q--; strcpy(q-3,"..."); break; }
- if (isspace(c)) c= ' ';
- else if (!isprint(c) || iscntrl(c)) c= '?';
+ if (ISCHAR(isspace,c)) c= ' ';
+ else if (!ISCHAR(isprint,c) || ISCHAR(iscntrl,c)) c= '?';
else *q++= c;
}
strcpy(q,"'");
for (;;) { /* loop over lines */
cstate->reportlineno= cstate->lineno;
- do { token= yylex(); } while (token == tokv_lwsp);
+ do { token= yylex(); } while (token == tokv_lwsp || token == tokv_newline);
if (token & tokt_exception) {
return token;
} else if (token & tokt_controlend) {
char *ep;
unsigned long v;
- r= pa_mwsp(); if (r) return r;
mintoken= pa_numberdollar(&min); if (mintoken == tokv_error) return mintoken;
- r= pa_mwsp(); if (r) return r;
maxtoken= pa_numberdollar(&max); if (maxtoken == tokv_error) return maxtoken;
r= pa_mnl(); if (r) return r;
for (pp= pv; *pp; pp++) {
buf= xmalloc(maxlen+2); actrue= 0; c= 0;
while (!actrue && c!=EOF) {
c= getc(file); if (c==EOF) break;
- if (isspace(c)) continue;
+ if (ISCHAR(isspace,c)) continue;
l= maxlen+1; p= buf;
while (l>0 && c!='\n' && c!=EOF) { *p++= c; l--; c= getc(file); }
- if (c=='\n' || c==EOF || isspace(c)) {
- while (p>buf && isspace(p[-1])) --p;
+ if (c=='\n' || c==EOF || ISCHAR(isspace,c)) {
+ while (p>buf && ISCHAR(isspace,p[-1])) --p;
*p= 0; posstrue= 0;
for (pp= pv; !posstrue && *pp; pp++)
if (!strcmp(*pp,buf)) posstrue= 1;
for (;;) {
c= getc(file);
if (c==EOF || c=='\n') break;
- if (!isspace(c)) posstrue= 0;
+ if (!ISCHAR(isspace,c)) posstrue= 0;
}
}
if (posstrue) actrue= 1;
r= paa_pathargs(&rv,&newargs); if (r) return r;
p= strrchr(service,'/'); if (p) p++; else p= service;
- if (!*p || !isalnum(*p)) {
+ if (!*p || !ISCHAR(isalnum,*p)) {
parseerrprint("execute-from-directory requires initial char of service "
"portion to be alphanumeric (service portion was `%s')",
p);
return tokv_error;
}
for (q=p+1; *q; q++) {
- if (!isalnum(*q) && *q != '-') {
+ if (!ISCHAR(isalnum,*q) && *q != '-') {
parseerrprint("execute-from-directory requires service portion to "
"contain only alphanumerics and hyphens (was `%s')",
p);
return parseerrprint("unable to open directory `%s': %s",cpget,strerror(errno));
cp= xstrsave(cpget);
cpl= strlen(cp);
- while ((de= readdir(d))) {
+ while ((errno=0, de= readdir(d))) {
tel= strlen(de->d_name);
if (!tel) continue;
p= de->d_name;
- if (!*p || !isalnum(*p)) continue;
- while ((c= *++p)) if (!(isalnum(c) || c=='-')) break;
+ if (!*p || !ISCHAR(isalnum,*p)) continue;
+ while ((c= *++p)) if (!(ISCHAR(isalnum,c) || c=='-')) break;
if (c) continue;
if (makeroom(&buildbuf,&buildbuflen,cpl+1+tel+1)) {
stringoverflow("pathname in directory");
goto x_err;
}
}
+ if (errno) {
+ parseerrprint("error reading directory `%s': %s",cp,strerror(errno));
+ closedir(d);
+ free(cp);
+ return tokv_error;
+ }
if (closedir(d)) {
parseerrprint("error closing directory `%s': %s",cp,strerror(errno));
free(cp);
return r;
}
+static int oldquote = 0;
+
+int dfg_lookupquotemode(int dtoken) {
+ int r;
+ r= pa_mnl(); if (r) return r;
+ oldquote = dtoken == tokv_word_includelookupquoteold;
+ return r;
+}
+
int df_includelookup(int dtoken) {
static char *buildbuf=0;
int buildbuflen=0;
if (c=='/') {
*q++= ':';
c= '-';
- } else if (!((c >= '0' && c <= '9') ||
+ } else if (oldquote ?
+ !((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') ||
- c == '-' || c == '_')) {
+ c == '-' || c == '_') :
+ (c==':')) {
*q++= ':';
}
*q++= c;