add new | syntax.
syntax will change.
This commit is contained in:
parent
02f38ca68c
commit
9aa1c92f74
19 changed files with 281 additions and 83 deletions
|
|
@ -11,10 +11,8 @@ void atouch(char*);
|
||||||
void bufcpy(Bufblock *, char *, int);
|
void bufcpy(Bufblock *, char *, int);
|
||||||
Envy *buildenv(Job*, int);
|
Envy *buildenv(Job*, int);
|
||||||
void catchnotes(void);
|
void catchnotes(void);
|
||||||
char *charin(char *, char *);
|
|
||||||
int chgtime(char*);
|
int chgtime(char*);
|
||||||
void clrmade(Node*);
|
void clrmade(Node*);
|
||||||
char *copyq(char*, Rune, Bufblock*);
|
|
||||||
void delete(char*);
|
void delete(char*);
|
||||||
void delword(Word*);
|
void delword(Word*);
|
||||||
int dorecipe(Node*);
|
int dorecipe(Node*);
|
||||||
|
|
@ -24,24 +22,23 @@ void dumpn(char*, Node*);
|
||||||
void dumpr(char*, Rule*);
|
void dumpr(char*, Rule*);
|
||||||
void dumpv(char*);
|
void dumpv(char*);
|
||||||
void dumpw(char*, Word*);
|
void dumpw(char*, Word*);
|
||||||
int escapetoken(Biobuf*, Bufblock*, int, int);
|
|
||||||
void execinit(void);
|
void execinit(void);
|
||||||
int execsh(char*, char*, Bufblock*, Envy*);
|
int execsh(char*, char*, Bufblock*, Envy*, Shell*, Word*);
|
||||||
void Exit(void);
|
void Exit(void);
|
||||||
char *expandquote(char*, Rune, Bufblock*);
|
|
||||||
void expunge(int, char*);
|
void expunge(int, char*);
|
||||||
void freebuf(Bufblock*);
|
void freebuf(Bufblock*);
|
||||||
void front(char*);
|
void front(char*);
|
||||||
Node *graph(char*);
|
Node *graph(char*);
|
||||||
void growbuf(Bufblock *);
|
void growbuf(Bufblock *);
|
||||||
void initenv(void);
|
void initenv(void);
|
||||||
|
void initshell(void);
|
||||||
void insert(Bufblock *, int);
|
void insert(Bufblock *, int);
|
||||||
void ipop(void);
|
void ipop(void);
|
||||||
void ipush(void);
|
void ipush(void);
|
||||||
void killchildren(char*);
|
void killchildren(char*);
|
||||||
void *Malloc(int);
|
void *Malloc(int);
|
||||||
char *maketmp(int*);
|
char *maketmp(int*);
|
||||||
int match(char*, char*, char*);
|
int match(char*, char*, char*, Shell*);
|
||||||
char *membername(char*, int, char*);
|
char *membername(char*, int, char*);
|
||||||
void mk(char*);
|
void mk(char*);
|
||||||
ulong mkmtime(char*);
|
ulong mkmtime(char*);
|
||||||
|
|
@ -56,17 +53,21 @@ void nproc(void);
|
||||||
void nrep(void);
|
void nrep(void);
|
||||||
int outofdate(Node*, Arc*, int);
|
int outofdate(Node*, Arc*, int);
|
||||||
void parse(char*, int, int);
|
void parse(char*, int, int);
|
||||||
int pipecmd(char*, Envy*, int*);
|
int pipecmd(char*, Envy*, int*, Shell*, Word*);
|
||||||
|
void popshell(void);
|
||||||
void prusage(void);
|
void prusage(void);
|
||||||
|
void pushshell(void);
|
||||||
void rcopy(char**, Resub*, int);
|
void rcopy(char**, Resub*, int);
|
||||||
void readenv(void);
|
void readenv(void);
|
||||||
void *Realloc(void*, int);
|
void *Realloc(void*, int);
|
||||||
void rinsert(Bufblock *, Rune);
|
void rinsert(Bufblock *, Rune);
|
||||||
char *rulecnt(void);
|
char *rulecnt(void);
|
||||||
void run(Job*);
|
void run(Job*);
|
||||||
|
char *setshell(Word*);
|
||||||
void setvar(char*, void*);
|
void setvar(char*, void*);
|
||||||
|
int shargv(Word*, int, char***);
|
||||||
char *shname(char*);
|
char *shname(char*);
|
||||||
void shprint(char*, Envy*, Bufblock*);
|
void shprint(char*, Envy*, Bufblock*, Shell*);
|
||||||
Word *stow(char*);
|
Word *stow(char*);
|
||||||
void subst(char*, char*, char*);
|
void subst(char*, char*, char*);
|
||||||
void symdel(char*, int);
|
void symdel(char*, int);
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ applyrules(char *target, char *cnt)
|
||||||
if(regexec(r->pat, node->name, rmatch, NREGEXP) == 0)
|
if(regexec(r->pat, node->name, rmatch, NREGEXP) == 0)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if(!match(node->name, r->target, stem)) continue;
|
if(!match(node->name, r->target, stem, r->shellt)) continue;
|
||||||
}
|
}
|
||||||
if(cnt[r->rule] >= nreps) continue;
|
if(cnt[r->rule] >= nreps) continue;
|
||||||
cnt[r->rule]++;
|
cnt[r->rule]++;
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ assline(Biobuf *bp, Bufblock *buf)
|
||||||
case '\'':
|
case '\'':
|
||||||
case '"':
|
case '"':
|
||||||
rinsert(buf, c);
|
rinsert(buf, c);
|
||||||
if (escapetoken(bp, buf, 1, c) == 0)
|
if (shellt->escapetoken(bp, buf, 1, c) == 0)
|
||||||
Exit();
|
Exit();
|
||||||
break;
|
break;
|
||||||
case '`':
|
case '`':
|
||||||
|
|
@ -87,14 +87,14 @@ bquote(Biobuf *bp, Bufblock *buf)
|
||||||
insert(buf,0);
|
insert(buf,0);
|
||||||
buf->current = buf->start+start;
|
buf->current = buf->start+start;
|
||||||
execinit();
|
execinit();
|
||||||
execsh(0, buf->current, buf, envy);
|
execsh(0, buf->current, buf, envy, shellt, shellcmd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(c == '\n')
|
if(c == '\n')
|
||||||
break;
|
break;
|
||||||
if(c == '\'' || c == '"' || c == '\\'){
|
if(c == '\'' || c == '"' || c == '\\'){
|
||||||
insert(buf, c);
|
insert(buf, c);
|
||||||
if(!escapetoken(bp, buf, 1, c))
|
if(!shellt->escapetoken(bp, buf, 1, c))
|
||||||
return 0;
|
return 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ main(int argc, char **argv)
|
||||||
* instead of sharing them
|
* instead of sharing them
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
initshell();
|
||||||
Binit(&bout, 1, OWRITE);
|
Binit(&bout, 1, OWRITE);
|
||||||
buf = newbuf();
|
buf = newbuf();
|
||||||
whatif = 0;
|
whatif = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "mk.h"
|
#include "mk.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
match(char *name, char *template, char *stem)
|
match(char *name, char *template, char *stem, Shell *sh)
|
||||||
{
|
{
|
||||||
Rune r;
|
Rune r;
|
||||||
int n;
|
int n;
|
||||||
|
|
@ -24,7 +24,7 @@ match(char *name, char *template, char *stem)
|
||||||
strncpy(stem, name, n);
|
strncpy(stem, name, n);
|
||||||
stem[n] = 0;
|
stem[n] = 0;
|
||||||
if(*template == '&')
|
if(*template == '&')
|
||||||
return !charin(stem, "./");
|
return !sh->charin(stem, "./");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,14 +192,14 @@ update(int fake, Node *node)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pcmp(char *prog, char *p, char *q)
|
pcmp(char *prog, char *p, char *q, Shell *sh, Word *shcmd)
|
||||||
{
|
{
|
||||||
char buf[3*NAMEBLOCK];
|
char buf[3*NAMEBLOCK];
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
Bflush(&bout);
|
Bflush(&bout);
|
||||||
snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q);
|
snprint(buf, sizeof buf, "%s '%s' '%s'\n", prog, p, q);
|
||||||
pid = pipecmd(buf, 0, 0);
|
pid = pipecmd(buf, 0, 0, sh, shcmd);
|
||||||
while(waitup(-3, &pid) >= 0)
|
while(waitup(-3, &pid) >= 0)
|
||||||
;
|
;
|
||||||
return(pid? 2:1);
|
return(pid? 2:1);
|
||||||
|
|
@ -219,7 +219,7 @@ outofdate(Node *node, Arc *arc, int eval)
|
||||||
if(sym == 0 || eval){
|
if(sym == 0 || eval){
|
||||||
if(sym == 0)
|
if(sym == 0)
|
||||||
str = strdup(buf);
|
str = strdup(buf);
|
||||||
ret = pcmp(arc->prog, node->name, arc->n->name);
|
ret = pcmp(arc->prog, node->name, arc->n->name, arc->r->shellt, arc->r->shellcmd);
|
||||||
if(sym)
|
if(sym)
|
||||||
sym->value = (void *)ret;
|
sym->value = (void *)ret;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,18 @@ typedef struct Envy
|
||||||
|
|
||||||
extern Envy *envy;
|
extern Envy *envy;
|
||||||
|
|
||||||
|
typedef struct Shell
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
char *termchars; /* used in parse.c to isolate assignment attribute */
|
||||||
|
int iws; /* inter-word separator in environment */
|
||||||
|
char *(*charin)(char*, char*); /* search for unescaped characters */
|
||||||
|
char *(*expandquote)(char*, Rune, Bufblock*); /* extract escaped token */
|
||||||
|
int (*escapetoken)(Biobuf*, Bufblock*, int, int); /* input escaped token */
|
||||||
|
char *(*copyq)(char*, Rune, Bufblock*); /* check for quoted strings */
|
||||||
|
int (*matchname)(char*); /* does name match */
|
||||||
|
} Shell;
|
||||||
|
|
||||||
typedef struct Rule
|
typedef struct Rule
|
||||||
{
|
{
|
||||||
char *target; /* one target */
|
char *target; /* one target */
|
||||||
|
|
@ -40,6 +52,8 @@ typedef struct Rule
|
||||||
char *prog; /* to use in out of date */
|
char *prog; /* to use in out of date */
|
||||||
struct Rule *chain; /* hashed per target */
|
struct Rule *chain; /* hashed per target */
|
||||||
struct Rule *next;
|
struct Rule *next;
|
||||||
|
Shell *shellt; /* shell to use with this rule */
|
||||||
|
Word *shellcmd;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
extern Rule *rules, *metarules, *patrule;
|
extern Rule *rules, *metarules, *patrule;
|
||||||
|
|
@ -143,11 +157,10 @@ extern int mkinline;
|
||||||
extern char *infile;
|
extern char *infile;
|
||||||
extern int nreps;
|
extern int nreps;
|
||||||
extern char *explain;
|
extern char *explain;
|
||||||
extern char *termchars;
|
extern Shell *shellt;
|
||||||
extern int IWS;
|
extern Word *shellcmd;
|
||||||
extern char *shell;
|
|
||||||
extern char *shellname;
|
extern Shell shshell, rcshell;
|
||||||
extern char *shflags;
|
|
||||||
|
|
||||||
#define SYNERR(l) (fprint(2, "mk: %s:%d: syntax error; ", infile, ((l)>=0)?(l):mkinline))
|
#define SYNERR(l) (fprint(2, "mk: %s:%d: syntax error; ", infile, ((l)>=0)?(l):mkinline))
|
||||||
#define RERR(r) (fprint(2, "mk: %s:%d: rule error; ", (r)->file, (r)->line))
|
#define RERR(r) (fprint(2, "mk: %s:%d: rule error; ", (r)->file, (r)->line))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,12 @@
|
||||||
a: b
|
|$PLAN9/bin/rc
|
||||||
cp b a
|
use-rc:V:
|
||||||
|
for(i in a b c)
|
||||||
|
echo $i
|
||||||
|
|
||||||
|
|/bin/sh
|
||||||
|
use-sh:V:
|
||||||
|
for i in a b c
|
||||||
|
do
|
||||||
|
echo $i
|
||||||
|
done
|
||||||
|
|
||||||
c:V:
|
|
||||||
echo hello world
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ parse(char *f, int fd, int varoverride)
|
||||||
int newfd;
|
int newfd;
|
||||||
Biobuf in;
|
Biobuf in;
|
||||||
Bufblock *buf;
|
Bufblock *buf;
|
||||||
|
char *err;
|
||||||
|
|
||||||
if(fd < 0){
|
if(fd < 0){
|
||||||
fprint(2, "open %s: %r\n", f);
|
fprint(2, "open %s: %r\n", f);
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
|
pushshell();
|
||||||
ipush();
|
ipush();
|
||||||
infile = strdup(f);
|
infile = strdup(f);
|
||||||
mkinline = 1;
|
mkinline = 1;
|
||||||
|
|
@ -52,7 +54,7 @@ parse(char *f, int fd, int varoverride)
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
execinit();
|
execinit();
|
||||||
pid=pipecmd(p, envy, &newfd);
|
pid=pipecmd(p, envy, &newfd, shellt, shellcmd);
|
||||||
if(newfd < 0){
|
if(newfd < 0){
|
||||||
fprint(2, "warning: skipping missing program file %s: %r\n", p);
|
fprint(2, "warning: skipping missing program file %s: %r\n", p);
|
||||||
} else
|
} else
|
||||||
|
|
@ -93,6 +95,14 @@ cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
|
||||||
if(attr)
|
if(attr)
|
||||||
symlook(head->s, S_NOEXPORT, (void *)"");
|
symlook(head->s, S_NOEXPORT, (void *)"");
|
||||||
break;
|
break;
|
||||||
|
case 'S':
|
||||||
|
if((err = setshell(tail)) != nil){
|
||||||
|
SYNERR(hline);
|
||||||
|
fprint(2, "%s\n", err);
|
||||||
|
Exit();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SYNERR(hline);
|
SYNERR(hline);
|
||||||
fprint(2, "expected one of :<=\n");
|
fprint(2, "expected one of :<=\n");
|
||||||
|
|
@ -103,6 +113,7 @@ cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
|
||||||
close(fd);
|
close(fd);
|
||||||
freebuf(buf);
|
freebuf(buf);
|
||||||
ipop();
|
ipop();
|
||||||
|
popshell();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -114,7 +125,7 @@ addrules(Word *head, Word *tail, char *body, int attr, int hline, char *prog)
|
||||||
/* tuck away first non-meta rule as default target*/
|
/* tuck away first non-meta rule as default target*/
|
||||||
if(target1 == 0 && !(attr®EXP)){
|
if(target1 == 0 && !(attr®EXP)){
|
||||||
for(w = head; w; w = w->next)
|
for(w = head; w; w = w->next)
|
||||||
if(charin(w->s, "%&"))
|
if(shellt->charin(w->s, "%&"))
|
||||||
break;
|
break;
|
||||||
if(w == 0)
|
if(w == 0)
|
||||||
target1 = wdup(head);
|
target1 = wdup(head);
|
||||||
|
|
@ -133,7 +144,11 @@ rhead(char *line, Word **h, Word **t, int *attr, char **prog)
|
||||||
int n;
|
int n;
|
||||||
Word *w;
|
Word *w;
|
||||||
|
|
||||||
p = charin(line,":=<");
|
if(*line == '|'){
|
||||||
|
sep = 'S'; /* shell */
|
||||||
|
p = line+1;
|
||||||
|
}else{
|
||||||
|
p = shellt->charin(line,":=<");
|
||||||
if(p == 0)
|
if(p == 0)
|
||||||
return('?');
|
return('?');
|
||||||
sep = *p;
|
sep = *p;
|
||||||
|
|
@ -142,10 +157,11 @@ rhead(char *line, Word **h, Word **t, int *attr, char **prog)
|
||||||
sep = '|';
|
sep = '|';
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
*attr = 0;
|
*attr = 0;
|
||||||
*prog = 0;
|
*prog = 0;
|
||||||
if(sep == '='){
|
if(sep == '='){
|
||||||
pp = charin(p, termchars); /* termchars is shell-dependent */
|
pp = shellt->charin(p, shellt->termchars); /* termchars is shell-dependent */
|
||||||
if (pp && *pp == '=') {
|
if (pp && *pp == '=') {
|
||||||
while (p != pp) {
|
while (p != pp) {
|
||||||
n = chartorune(&r, p);
|
n = chartorune(&r, p);
|
||||||
|
|
@ -219,7 +235,7 @@ rhead(char *line, Word **h, Word **t, int *attr, char **prog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*h = w = stow(line);
|
*h = w = stow(line);
|
||||||
if(*w->s == 0 && sep != '<' && sep != '|') {
|
if(*w->s == 0 && sep != '<' && sep != '|' && sep != 'S') {
|
||||||
SYNERR(mkinline-1);
|
SYNERR(mkinline-1);
|
||||||
fprint(2, "no var on left side of assignment/rule\n");
|
fprint(2, "no var on left side of assignment/rule\n");
|
||||||
Exit();
|
Exit();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
#include "mk.h"
|
#include "mk.h"
|
||||||
|
|
||||||
char *termchars = "'= \t"; /*used in parse.c to isolate assignment attribute*/
|
|
||||||
char *shflags = "-I"; /* rc flag to force non-interactive mode */
|
|
||||||
int IWS = '\1'; /* inter-word separator in env - not used in plan 9 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file contains functions that depend on rc's syntax. Most
|
* This file contains functions that depend on rc's syntax. Most
|
||||||
* of the routines extract strings observing rc's escape conventions
|
* of the routines extract strings observing rc's escape conventions
|
||||||
|
|
@ -38,7 +34,7 @@ squote(char *cp)
|
||||||
* characters in quotes and variable generators are escaped
|
* characters in quotes and variable generators are escaped
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
charin(char *cp, char *pat)
|
rccharin(char *cp, char *pat)
|
||||||
{
|
{
|
||||||
Rune r;
|
Rune r;
|
||||||
int n, vargen;
|
int n, vargen;
|
||||||
|
|
@ -82,7 +78,7 @@ charin(char *cp, char *pat)
|
||||||
* others are just inserted into the receiving buffer.
|
* others are just inserted into the receiving buffer.
|
||||||
*/
|
*/
|
||||||
char*
|
char*
|
||||||
expandquote(char *s, Rune r, Bufblock *b)
|
rcexpandquote(char *s, Rune r, Bufblock *b)
|
||||||
{
|
{
|
||||||
if (r != '\'') {
|
if (r != '\'') {
|
||||||
rinsert(b, r);
|
rinsert(b, r);
|
||||||
|
|
@ -108,7 +104,7 @@ expandquote(char *s, Rune r, Bufblock *b)
|
||||||
* rc; the others are just inserted into the receiving buffer.
|
* rc; the others are just inserted into the receiving buffer.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
|
rcescapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
|
||||||
{
|
{
|
||||||
int c, line;
|
int c, line;
|
||||||
|
|
||||||
|
|
@ -155,7 +151,7 @@ copysingle(char *s, Bufblock *buf)
|
||||||
* s points to char after opening quote, q.
|
* s points to char after opening quote, q.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
copyq(char *s, Rune q, Bufblock *buf)
|
rccopyq(char *s, Rune q, Bufblock *buf)
|
||||||
{
|
{
|
||||||
if(q == '\'') /* copy quoted string */
|
if(q == '\'') /* copy quoted string */
|
||||||
return copysingle(s, buf);
|
return copysingle(s, buf);
|
||||||
|
|
@ -173,3 +169,26 @@ copyq(char *s, Rune q, Bufblock *buf)
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rcmatchname(char *name)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if((p = strchr(name, '/')) != nil)
|
||||||
|
name = p+1;
|
||||||
|
if(name[0] == 'r' && name[1] == 'c')
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Shell rcshell = {
|
||||||
|
"rc",
|
||||||
|
"'= \t",
|
||||||
|
'\1',
|
||||||
|
rccharin,
|
||||||
|
rcexpandquote,
|
||||||
|
rcescapetoken,
|
||||||
|
rccopyq,
|
||||||
|
rcmatchname,
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, ch
|
||||||
}
|
}
|
||||||
if(r == 0)
|
if(r == 0)
|
||||||
r = (Rule *)Malloc(sizeof(Rule));
|
r = (Rule *)Malloc(sizeof(Rule));
|
||||||
|
r->shellt = shellt;
|
||||||
|
r->shellcmd = shellcmd;
|
||||||
r->target = head;
|
r->target = head;
|
||||||
r->tail = tail;
|
r->tail = tail;
|
||||||
r->recipe = body;
|
r->recipe = body;
|
||||||
|
|
@ -42,7 +44,7 @@ addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, ch
|
||||||
}
|
}
|
||||||
if(!reuse)
|
if(!reuse)
|
||||||
r->next = 0;
|
r->next = 0;
|
||||||
if((attr®EXP) || charin(head, "%&")){
|
if((attr®EXP) || shellt->charin(head, "%&")){
|
||||||
r->attr |= META;
|
r->attr |= META;
|
||||||
if(reuse)
|
if(reuse)
|
||||||
return;
|
return;
|
||||||
|
|
@ -72,7 +74,8 @@ addrule(char *head, Word *tail, char *body, Word *ahead, int attr, int hline, ch
|
||||||
void
|
void
|
||||||
dumpr(char *s, Rule *r)
|
dumpr(char *s, Rule *r)
|
||||||
{
|
{
|
||||||
Bprint(&bout, "%s: start=%ld\n", s, r);
|
Bprint(&bout, "%s: start=%ld shelltype=%s shellcmd=%s\n",
|
||||||
|
s, r, r->shellt->name, wtos(r->shellcmd, ' '));
|
||||||
for(; r; r = r->next){
|
for(; r; r = r->next){
|
||||||
Bprint(&bout, "\tRule %ld: %s[%d] attr=%x next=%ld chain=%ld alltarget='%s'",
|
Bprint(&bout, "\tRule %ld: %s[%d] attr=%x next=%ld chain=%ld alltarget='%s'",
|
||||||
r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets, ' '));
|
r, r->file, r->line, r->attr, r->next, r->chain, wtos(r->alltargets, ' '));
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ sched(void)
|
||||||
events[slot].job = j;
|
events[slot].job = j;
|
||||||
buf = newbuf();
|
buf = newbuf();
|
||||||
e = buildenv(j, slot);
|
e = buildenv(j, slot);
|
||||||
shprint(j->r->recipe, e, buf);
|
shprint(j->r->recipe, e, buf, j->r->shellt);
|
||||||
if(!tflag && (nflag || !(j->r->attr&QUIET)))
|
if(!tflag && (nflag || !(j->r->attr&QUIET)))
|
||||||
Bwrite(&bout, buf->start, (long)strlen(buf->start));
|
Bwrite(&bout, buf->start, (long)strlen(buf->start));
|
||||||
freebuf(buf);
|
freebuf(buf);
|
||||||
|
|
@ -82,7 +82,7 @@ sched(void)
|
||||||
flags = 0;
|
flags = 0;
|
||||||
else
|
else
|
||||||
flags = "-e";
|
flags = "-e";
|
||||||
events[slot].pid = execsh(flags, j->r->recipe, 0, e);
|
events[slot].pid = execsh(flags, j->r->recipe, 0, e, j->r->shellt, j->r->shellcmd);
|
||||||
usage();
|
usage();
|
||||||
nrunning++;
|
nrunning++;
|
||||||
if(DEBUG(D_EXEC))
|
if(DEBUG(D_EXEC))
|
||||||
|
|
@ -145,7 +145,7 @@ again: /* rogue processes */
|
||||||
if(buf[0]){
|
if(buf[0]){
|
||||||
e = buildenv(j, slot);
|
e = buildenv(j, slot);
|
||||||
bp = newbuf();
|
bp = newbuf();
|
||||||
shprint(j->r->recipe, e, bp);
|
shprint(j->r->recipe, e, bp, j->r->shellt);
|
||||||
front(bp->start);
|
front(bp->start);
|
||||||
fprint(2, "mk: %s: exit status=%s", bp->start, buf);
|
fprint(2, "mk: %s: exit status=%s", bp->start, buf);
|
||||||
freebuf(bp);
|
freebuf(bp);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
#include "mk.h"
|
#include "mk.h"
|
||||||
|
|
||||||
char *termchars = "\"'= \t"; /*used in parse.c to isolate assignment attribute*/
|
|
||||||
char *shflags = 0;
|
|
||||||
int IWS = ' '; /* inter-word separator in env */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file contains functions that depend on the shell's syntax. Most
|
* This file contains functions that depend on the shell's syntax. Most
|
||||||
* of the routines extract strings observing the shell's escape conventions.
|
* of the routines extract strings observing the shell's escape conventions.
|
||||||
|
|
@ -34,8 +30,8 @@ squote(char *cp, int c)
|
||||||
/*
|
/*
|
||||||
* search a string for unescaped characters in a pattern set
|
* search a string for unescaped characters in a pattern set
|
||||||
*/
|
*/
|
||||||
char *
|
static char *
|
||||||
charin(char *cp, char *pat)
|
shcharin(char *cp, char *pat)
|
||||||
{
|
{
|
||||||
Rune r;
|
Rune r;
|
||||||
int n, vargen;
|
int n, vargen;
|
||||||
|
|
@ -82,8 +78,8 @@ charin(char *cp, char *pat)
|
||||||
* extract an escaped token. Possible escape chars are single-quote,
|
* extract an escaped token. Possible escape chars are single-quote,
|
||||||
* double-quote,and backslash.
|
* double-quote,and backslash.
|
||||||
*/
|
*/
|
||||||
char*
|
static char*
|
||||||
expandquote(char *s, Rune esc, Bufblock *b)
|
shexpandquote(char *s, Rune esc, Bufblock *b)
|
||||||
{
|
{
|
||||||
Rune r;
|
Rune r;
|
||||||
|
|
||||||
|
|
@ -110,8 +106,8 @@ expandquote(char *s, Rune esc, Bufblock *b)
|
||||||
* Input an escaped token. Possible escape chars are single-quote,
|
* Input an escaped token. Possible escape chars are single-quote,
|
||||||
* double-quote and backslash.
|
* double-quote and backslash.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
escapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
|
shescapetoken(Biobuf *bp, Bufblock *buf, int preserve, int esc)
|
||||||
{
|
{
|
||||||
int c, line;
|
int c, line;
|
||||||
|
|
||||||
|
|
@ -168,8 +164,8 @@ copysingle(char *s, Rune q, Bufblock *buf)
|
||||||
* check for quoted strings. backquotes are handled here; single quotes above.
|
* check for quoted strings. backquotes are handled here; single quotes above.
|
||||||
* s points to char after opening quote, q.
|
* s points to char after opening quote, q.
|
||||||
*/
|
*/
|
||||||
char *
|
static char *
|
||||||
copyq(char *s, Rune q, Bufblock *buf)
|
shcopyq(char *s, Rune q, Bufblock *buf)
|
||||||
{
|
{
|
||||||
if(q == '\'' || q == '"') /* copy quoted string */
|
if(q == '\'' || q == '"') /* copy quoted string */
|
||||||
return copysingle(s, q, buf);
|
return copysingle(s, q, buf);
|
||||||
|
|
@ -187,3 +183,24 @@ copyq(char *s, Rune q, Bufblock *buf)
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
shmatchname(char *name)
|
||||||
|
{
|
||||||
|
USED(name);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Shell shshell = {
|
||||||
|
"sh",
|
||||||
|
"\"'= \t", /*used in parse.c to isolate assignment attribute*/
|
||||||
|
' ', /* inter-word separator in env */
|
||||||
|
shcharin,
|
||||||
|
shexpandquote,
|
||||||
|
shescapetoken,
|
||||||
|
shcopyq,
|
||||||
|
shmatchname,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
76
src/cmd/mk/shell.c
Normal file
76
src/cmd/mk/shell.c
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
#include "mk.h"
|
||||||
|
|
||||||
|
static Shell *shells[] = {
|
||||||
|
&shshell,
|
||||||
|
&rcshell
|
||||||
|
};
|
||||||
|
|
||||||
|
Shell *shellt;
|
||||||
|
Word *shellcmd;
|
||||||
|
|
||||||
|
typedef struct Shellstack Shellstack;
|
||||||
|
struct Shellstack
|
||||||
|
{
|
||||||
|
Shell *t;
|
||||||
|
Word *w;
|
||||||
|
Shellstack *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
Shellstack *shellstack;
|
||||||
|
|
||||||
|
char*
|
||||||
|
setshell(Word *w)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(w->s == nil)
|
||||||
|
return "shell name not found on line";
|
||||||
|
|
||||||
|
for(i=0; i<nelem(shells); i++)
|
||||||
|
if(shells[i]->matchname(w->s))
|
||||||
|
break;
|
||||||
|
if(i == nelem(shells))
|
||||||
|
return "cannot determine shell type";
|
||||||
|
shellt = shells[i];
|
||||||
|
shellcmd = w;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
initshell(void)
|
||||||
|
{
|
||||||
|
shellcmd = stow(shells[0]->name);
|
||||||
|
shellt = shells[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pushshell(void)
|
||||||
|
{
|
||||||
|
Shellstack *s;
|
||||||
|
|
||||||
|
/* save */
|
||||||
|
s = Malloc(sizeof *s);
|
||||||
|
s->t = shellt;
|
||||||
|
s->w = shellcmd;
|
||||||
|
s->next = shellstack;
|
||||||
|
shellstack = s;
|
||||||
|
|
||||||
|
initshell(); /* reset to defaults */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
popshell(void)
|
||||||
|
{
|
||||||
|
Shellstack *s;
|
||||||
|
|
||||||
|
if(shellstack == nil){
|
||||||
|
fprint(2, "internal shellstack error\n");
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
s = shellstack;
|
||||||
|
shellstack = s->next;
|
||||||
|
shellt = s->t;
|
||||||
|
shellcmd = s->w;
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
|
@ -40,7 +40,7 @@ getfields(char *str, char **args, int max, int mflag, char *set)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
shprint(char *s, Envy *env, Bufblock *buf)
|
shprint(char *s, Envy *env, Bufblock *buf, Shell *sh)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
Rune r;
|
Rune r;
|
||||||
|
|
@ -52,7 +52,7 @@ shprint(char *s, Envy *env, Bufblock *buf)
|
||||||
else {
|
else {
|
||||||
rinsert(buf, r);
|
rinsert(buf, r);
|
||||||
s += n;
|
s += n;
|
||||||
s = copyq(s, r, buf); /*handle quoted strings*/
|
s = sh->copyq(s, r, buf); /*handle quoted strings*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
insert(buf, 0);
|
insert(buf, 0);
|
||||||
|
|
|
||||||
22
src/cmd/mk/sys.std.h
Normal file
22
src/cmd/mk/sys.std.h
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <utf.h>
|
||||||
|
#include <fmt.h>
|
||||||
|
#include <bio.h>
|
||||||
|
#include <regexp9.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define OREAD O_RDONLY
|
||||||
|
#define OWRITE O_WRONLY
|
||||||
|
#define ORDWR O_RDWR
|
||||||
|
#define nil 0
|
||||||
|
#define nelem(x) sizeof((x)/sizeof((x)[0]))
|
||||||
|
#define seek lseek
|
||||||
|
#define remove unlink
|
||||||
|
#define exits(x) exit(x && *(char*)x ? 1 : 0)
|
||||||
|
#define USED(x) if(x){}else
|
||||||
|
#define create(name, mode, perm) open(name, mode|O_CREAT, perm)
|
||||||
|
#define ERRMAX 256
|
||||||
|
|
@ -51,7 +51,7 @@ readenv(void)
|
||||||
* to exec immediately after this.
|
* to exec immediately after this.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
exportenv(Envy *e)
|
exportenv(Envy *e, Shell *sh)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char **p;
|
char **p;
|
||||||
|
|
@ -61,7 +61,7 @@ exportenv(Envy *e)
|
||||||
for(i = 0; e->name; e++, i++) {
|
for(i = 0; e->name; e++, i++) {
|
||||||
p = (char**) Realloc(p, (i+2)*sizeof(char*));
|
p = (char**) Realloc(p, (i+2)*sizeof(char*));
|
||||||
if(e->values)
|
if(e->values)
|
||||||
snprint(buf, sizeof buf, "%s=%s", e->name, wtos(e->values, IWS));
|
snprint(buf, sizeof buf, "%s=%s", e->name, wtos(e->values, sh->iws));
|
||||||
else
|
else
|
||||||
snprint(buf, sizeof buf, "%s=", e->name);
|
snprint(buf, sizeof buf, "%s=", e->name);
|
||||||
p[i] = strdup(buf);
|
p[i] = strdup(buf);
|
||||||
|
|
@ -102,9 +102,29 @@ expunge(int pid, char *msg)
|
||||||
int mypid;
|
int mypid;
|
||||||
|
|
||||||
int
|
int
|
||||||
execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
|
shargv(Word *cmd, int extra, char ***pargv)
|
||||||
{
|
{
|
||||||
char *p;
|
char **argv;
|
||||||
|
int i, n;
|
||||||
|
Word *w;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for(w=cmd; w; w=w->next)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
argv = Malloc((n+extra+1)*sizeof(argv[0]));
|
||||||
|
i = 0;
|
||||||
|
for(w=cmd; w; w=w->next)
|
||||||
|
argv[i++] = w->s;
|
||||||
|
argv[n] = 0;
|
||||||
|
*pargv = argv;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
execsh(char *args, char *cmd, Bufblock *buf, Envy *e, Shell *sh, Word *shellcmd)
|
||||||
|
{
|
||||||
|
char *p, **argv;
|
||||||
int tot, n, pid, in[2], out[2];
|
int tot, n, pid, in[2], out[2];
|
||||||
|
|
||||||
if(buf && pipe(out) < 0){
|
if(buf && pipe(out) < 0){
|
||||||
|
|
@ -138,11 +158,11 @@ execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
|
||||||
close(in[0]);
|
close(in[0]);
|
||||||
close(in[1]);
|
close(in[1]);
|
||||||
if (e)
|
if (e)
|
||||||
exportenv(e);
|
exportenv(e, sh);
|
||||||
if(shflags)
|
n = shargv(shellcmd, 1, &argv);
|
||||||
execl(shell, shellname, shflags, args, 0);
|
argv[n++] = args;
|
||||||
else
|
argv[n] = 0;
|
||||||
execl(shell, shellname, args, 0);
|
execvp(argv[0], argv);
|
||||||
mkperror(shell);
|
mkperror(shell);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -180,9 +200,11 @@ execsh(char *args, char *cmd, Bufblock *buf, Envy *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
pipecmd(char *cmd, Envy *e, int *fd)
|
pipecmd(char *cmd, Envy *e, int *fd, Shell *sh, Word *shellcmd)
|
||||||
{
|
{
|
||||||
int pid, pfd[2];
|
int pid, pfd[2];
|
||||||
|
int n;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
if(DEBUG(D_EXEC))
|
if(DEBUG(D_EXEC))
|
||||||
fprint(1, "pipecmd='%s'\n", cmd);/**/
|
fprint(1, "pipecmd='%s'\n", cmd);/**/
|
||||||
|
|
@ -203,11 +225,12 @@ pipecmd(char *cmd, Envy *e, int *fd)
|
||||||
close(pfd[1]);
|
close(pfd[1]);
|
||||||
}
|
}
|
||||||
if(e)
|
if(e)
|
||||||
exportenv(e);
|
exportenv(e, sh);
|
||||||
if(shflags)
|
n = shargv(shellcmd, 2, &argv);
|
||||||
execl(shell, shellname, shflags, "-c", cmd, 0);
|
argv[n++] = "-c";
|
||||||
else
|
argv[n++] = cmd;
|
||||||
execl(shell, shellname, "-c", cmd, 0);
|
argv[n] = 0;
|
||||||
|
execvp(argv[0], argv);
|
||||||
mkperror(shell);
|
mkperror(shell);
|
||||||
_exit(1);
|
_exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ expandvar(char **s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cp++;
|
cp++;
|
||||||
end = charin(cp , "}");
|
end = shellt->charin(cp , "}");
|
||||||
if(end == 0){
|
if(end == 0){
|
||||||
SYNERR(-1);
|
SYNERR(-1);
|
||||||
fprint(2, "missing '}': %s\n", begin);
|
fprint(2, "missing '}': %s\n", begin);
|
||||||
|
|
@ -128,7 +128,7 @@ extractpat(char *s, char **r, char *term, char *end)
|
||||||
char *cp;
|
char *cp;
|
||||||
Word *w;
|
Word *w;
|
||||||
|
|
||||||
cp = charin(s, term);
|
cp = shellt->charin(s, term);
|
||||||
if(cp){
|
if(cp){
|
||||||
*r = cp;
|
*r = cp;
|
||||||
if(cp == s)
|
if(cp == s)
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ nextword(char **s)
|
||||||
case '\\':
|
case '\\':
|
||||||
case '\'':
|
case '\'':
|
||||||
case '"':
|
case '"':
|
||||||
cp = expandquote(cp, r, b);
|
cp = shellt->expandquote(cp, r, b);
|
||||||
if(cp == 0){
|
if(cp == 0){
|
||||||
fprint(2, "missing closing quote: %s\n", *s);
|
fprint(2, "missing closing quote: %s\n", *s);
|
||||||
Exit();
|
Exit();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue