blob: 781da33c685b810f1f85e95478b7807708c19ac5 [file] [log] [blame]
/*% cyntax % && cc -go # %
* getflags: process flags for command files
* Usage: ifs='' eval `{getflags [-s] flagfmt [arg ...]} # rc
* Usage: IFS= eval `getflags -b [-s] flagfmt [arg...]` # Bourne shell
* -b means give Bourne-shell compatible output
*/
#include <u.h>
#include <libc.h>
#include "getflags.h"
/* predefine functions */
void bourneprint(int, char *[]);
void bournearg(char *);
void rcprint(int, char *[]);
void usmsg(char *);
int count(int, char *);
void rcarg(char *);
void
main(int argc, char *argv[])
{
int bourne;
argc=getflags(argc, argv, "b");
if(argc<2) usage("flagfmt [arg ...]");
bourne=flag['b']!=0;
flag['b']=0;
if((argc=getflags(argc-1, argv+1, argv[1]))<0){
usmsg(argv[1]);
exits(0);
}
if(bourne) bourneprint(argc, argv);
else rcprint(argc, argv);
exits(0);
}
void
bourneprint(int argc, char *argv[])
{
register int c, i, n;
for(c=0;c!=NFLAG;c++) if(flag[c]){
print("FLAG%c=", c); /* bug -- c could be a bad char */
n=count(c, argv[1]);
if(n==0)
print("1\n");
else{
print("'");
bournearg(flag[c][0]);
for(i=1;i!=n;i++){
print(" ");
bournearg(flag[c][i]);
}
print("'\n");
}
}
print("set --");
for(c=1;c!=argc;c++){
print(" ");
bournearg(argv[c+1]);
}
print("\n");
}
void
bournearg(char *s)
{
for(;*s;s++)
if(*s=='\'')
print("'\\''");
else
print("%c", *s);
}
void
rcprint(int argc, char *argv[])
{
int c, i, n;
for(c=0;c!=NFLAG;c++) if(flag[c]){
print("FLAG%c=", c); /* bug -- c could be a bad char */
n=count(c, argv[1]);
if(n==0)
print("''");
else if(n==1)
rcarg(flag[c][0]);
else{
print("(");
rcarg(flag[c][0]);
for(i=1;i!=n;i++){
print(" ");
rcarg(flag[c][i]);
}
print(")");
}
print("\n");
}
print("*=");
if(argc==1) print("()");
else if(argc==2) rcarg(argv[2]);
else{
print("(");
rcarg(argv[2]);
for(c=2;c!=argc;c++){
print(" ");
rcarg(argv[c+1]);
}
print(")");
}
print("\n");
}
void
usmsg(char *flagarg)
{
char *s, *t, c;
int count, nflag=0;
print("echo Usage: $0'");
for(s=flagarg;*s;){
c=*s;
if(*s++==' ') continue;
if(*s==':')
count = strtol(s+1, &s, 10);
else count=0;
if(count==0){
if(nflag==0) print(" [-");
nflag++;
print("%c", c);
}
if(*s=='['){
int depth=1;
s++;
for(;*s!='\0' && depth>0; s++)
if (*s==']') depth--;
else if (*s=='[') depth++;
}
}
if(nflag) print("]");
for(s=flagarg;*s;){
c=*s;
if(*s++==' ') continue;
if(*s==':')
count = strtol(s+1, &s, 10);
else count=0;
if(count!=0){
print(" [-");
print("%c", c);
if(*s=='['){
int depth=1;
s++;
t=s;
for(;*s!='\0' && depth>0; s++)
if (*s==']') depth--;
else if (*s=='[') depth++;
print(" ");
write(1, t, s - t);
}
else
while(count--) print(" arg");
print("]");
}
else if(*s=='['){
int depth=1;
s++;
for(;*s!='\0' && depth>0; s++)
if (*s==']') depth--;
else if (*s=='[') depth++;
}
}
print("' $usage;\n");
print("exit 'usage'\n");
}
int
count(int flag, char *flagarg)
{
char *s, c;
int n;
for(s=flagarg;*s;){
c=*s;
if(*s++==' ') continue;
if(*s==':')
n = strtol(s+1, &s, 10);
else n=0;
if(*s=='['){
int depth=1;
s++;
for(;*s!='\0' && depth>0; s++)
if (*s==']') depth--;
else if (*s=='[') depth++;
}
if(c==flag) return n;
}
return -1; /* never happens */
}
void
rcarg(char *s)
{
if(*s=='\0' || strpbrk(s, "\n \t#;&|^$=`'{}()<>?")){
print("\'");
for(;*s;s++)
if(*s=='\'') print("''");
else print("%c", *s);
print("\'");
}
else print("%s", s);
}