Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/sh/shcomp.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1982-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* David Korn
23
* AT&T Labs
24
*
25
* shell script to shell binary converter
26
*
27
*/
28
29
static const char usage[] =
30
"[-?\n@(#)$Id: shcomp (AT&T Research) 2003-03-02 $\n]"
31
USAGE_LICENSE
32
"[+NAME?shcomp - compile a shell script]"
33
"[+DESCRIPTION?Unless \b-D\b is specified, \bshcomp\b takes a shell script, "
34
"\ainfile\a, and creates a binary format file, \aoutfile\a, that "
35
"\bksh\b can read and execute with the same effect as the original "
36
"script.]"
37
"[+?Since aliases are processed as the script is read, alias definitions "
38
"whose value requires variable expansion will not work correctly.]"
39
"[+?If \b-D\b is specified, all double quoted strings that are preceded by "
40
"\b$\b are output. These are the messages that need to be "
41
"translated to locale specific versions for internationalization.]"
42
"[+?If \aoutfile\a is omitted, then the results will be written to "
43
"standard output. If \ainfile\a is also omitted, the shell script "
44
"will be read from standard input.]"
45
"[D:dictionary?Generate a list of strings that need to be placed in a message "
46
"catalog for internationalization.]"
47
"[n:noexec?Displays warning messages for obsolete or non-conforming "
48
"constructs.] "
49
"[v:verbose?Displays input from \ainfile\a onto standard error as it "
50
"reads it.]"
51
"\n"
52
"\n[infile [outfile]]\n"
53
"\n"
54
"[+EXIT STATUS?]{"
55
"[+0?Successful completion.]"
56
"[+>0?An error occurred.]"
57
"}"
58
"[+SEE ALSO?\bksh\b(1)]"
59
;
60
61
#include <shell.h>
62
#include "defs.h"
63
#include "shnodes.h"
64
#include "sys/stat.h"
65
66
#define CNTL(x) ((x)&037)
67
#define VERSION 3
68
static const char header[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,VERSION,0 };
69
70
int main(int argc, char *argv[])
71
{
72
Sfio_t *in, *out;
73
Shell_t *shp;
74
Namval_t *np;
75
Shnode_t *t;
76
char *cp;
77
int n, nflag=0, vflag=0, dflag=0;
78
error_info.id = argv[0];
79
while(n = optget(argv, usage )) switch(n)
80
{
81
case 'D':
82
dflag=1;
83
break;
84
case 'v':
85
vflag=1;
86
break;
87
case 'n':
88
nflag=1;
89
break;
90
case ':':
91
errormsg(SH_DICT,2,"%s",opt_info.arg);
92
break;
93
case '?':
94
errormsg(SH_DICT,ERROR_usage(2),"%s",opt_info.arg);
95
break;
96
}
97
shp = sh_init(argc,argv,(Shinit_f)0);
98
shp->shcomp = 1;
99
argv += opt_info.index;
100
argc -= opt_info.index;
101
if(error_info.errors || argc>2)
102
errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0));
103
if(cp= *argv)
104
{
105
argv++;
106
in = sh_pathopen(cp);
107
}
108
else
109
in = sfstdin;
110
if(cp= *argv)
111
{
112
struct stat statb;
113
if(!(out = sfopen((Sfio_t*)0,cp,"w")))
114
errormsg(SH_DICT,ERROR_system(1),"%s: cannot create",cp);
115
if(fstat(sffileno(out),&statb) >=0)
116
chmod(cp,(statb.st_mode&~S_IFMT)|S_IXUSR|S_IXGRP|S_IXOTH);
117
}
118
else
119
out = sfstdout;
120
if(dflag)
121
{
122
sh_onoption(SH_DICTIONARY);
123
sh_onoption(SH_NOEXEC);
124
}
125
if(nflag)
126
sh_onoption(SH_NOEXEC);
127
if(vflag)
128
sh_onoption(SH_VERBOSE);
129
if(!dflag)
130
sfwrite(out,header,sizeof(header));
131
shp->inlineno = 1;
132
#if SHOPT_BRACEPAT
133
sh_onoption(SH_BRACEEXPAND);
134
#endif
135
while(1)
136
{
137
stakset((char*)0,0);
138
if(t = (Shnode_t*)sh_parse(shp,in,0))
139
{
140
if((t->tre.tretyp&(COMMSK|COMSCAN))==0 && t->com.comnamp && strcmp(nv_name((Namval_t*)t->com.comnamp),"alias")==0)
141
sh_exec(t,0);
142
if(!dflag && sh_tdump(out,t) < 0)
143
errormsg(SH_DICT,ERROR_exit(1),"dump failed");
144
}
145
else if(sfeof(in))
146
break;
147
if(sferror(in))
148
errormsg(SH_DICT,ERROR_system(1),"I/O error");
149
if(t && ((t->tre.tretyp&COMMSK)==TCOM) && (np=t->com.comnamp) && (cp=nv_name(np)))
150
{
151
if(strcmp(cp,"exit")==0)
152
break;
153
/* check for exec of a command */
154
if(strcmp(cp,"exec")==0)
155
{
156
if(t->com.comtyp&COMSCAN)
157
{
158
if(t->com.comarg->argnxt.ap)
159
break;
160
}
161
else
162
{
163
struct dolnod *ap = (struct dolnod*)t->com.comarg;
164
if(ap->dolnum>1)
165
break;
166
}
167
}
168
}
169
}
170
/* copy any remaining input */
171
sfmove(in,out,SF_UNBOUND,-1);
172
if(in!=sfstdin)
173
sfclose(in);
174
if(out!=sfstdout)
175
sfclose(out);
176
return(0);
177
}
178
179