1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
25 * shell script to shell binary converter
29 static const char usage
[] =
30 "[-?\n@(#)$Id: shcomp (AT&T Research) 2003-03-02 $\n]"
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 "
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 "
49 "[v:verbose?Displays input from \ainfile\a onto standard error as it "
52 "\n[infile [outfile]]\n"
55 "[+0?Successful completion.]"
56 "[+>0?An error occurred.]"
58 "[+SEE ALSO?\bksh\b(1)]"
66 #define CNTL(x) ((x)&037)
68 static const char header
[6] = { CNTL('k'),CNTL('s'),CNTL('h'),0,VERSION
,0 };
70 int main(int argc
, char *argv
[])
77 int n
, nflag
=0, vflag
=0, dflag
=0;
78 error_info
.id
= argv
[0];
79 while(n
= optget(argv
, usage
)) switch(n
)
91 errormsg(SH_DICT
,2,"%s",opt_info
.arg
);
94 errormsg(SH_DICT
,ERROR_usage(2),"%s",opt_info
.arg
);
97 shp
= sh_init(argc
,argv
,(Shinit_f
)0);
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));
106 in
= sh_pathopen(cp
);
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
);
122 sh_onoption(SH_DICTIONARY
);
123 sh_onoption(SH_NOEXEC
);
126 sh_onoption(SH_NOEXEC
);
128 sh_onoption(SH_VERBOSE
);
130 sfwrite(out
,header
,sizeof(header
));
133 sh_onoption(SH_BRACEEXPAND
);
138 if(t
= (Shnode_t
*)sh_parse(shp
,in
,0))
140 if((t
->tre
.tretyp
&(COMMSK
|COMSCAN
))==0 && t
->com
.comnamp
&& strcmp(nv_name((Namval_t
*)t
->com
.comnamp
),"alias")==0)
142 if(!dflag
&& sh_tdump(out
,t
) < 0)
143 errormsg(SH_DICT
,ERROR_exit(1),"dump failed");
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
)))
151 if(strcmp(cp
,"exit")==0)
153 /* check for exec of a command */
154 if(strcmp(cp
,"exec")==0)
156 if(t
->com
.comtyp
&COMSCAN
)
158 if(t
->com
.comarg
->argnxt
.ap
)
163 struct dolnod
*ap
= (struct dolnod
*)t
->com
.comarg
;
170 /* copy any remaining input */
171 sfmove(in
,out
,SF_UNBOUND
,-1);