aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2009-07-15 02:48:37 -0400
committerRuss Cox <rsc@swtch.com>2009-07-15 02:48:37 -0400
commit3cd77ae67905c839ba2078e119f981d4f2284c7a (patch)
tree960af29766218ca12f282764b68716ded766da09 /cmd
parent9bea9069bf3bc282c6b7d129926d4a0f1b40c66b (diff)
downloadplan9port-3cd77ae67905c839ba2078e119f981d4f2284c7a.tar.gz
plan9port-3cd77ae67905c839ba2078e119f981d4f2284c7a.tar.bz2
plan9port-3cd77ae67905c839ba2078e119f981d4f2284c7a.zip
getflags: import from 4e, with usage
fixes #6 http://bitbucket.org/rsc/plan9port/issue/6/ http://codereview.appspot.com/95043
Diffstat (limited to 'cmd')
-rw-r--r--cmd/getflags.c82
-rw-r--r--cmd/usage.c72
2 files changed, 154 insertions, 0 deletions
diff --git a/cmd/getflags.c b/cmd/getflags.c
new file mode 100644
index 00000000..bb0edf28
--- /dev/null
+++ b/cmd/getflags.c
@@ -0,0 +1,82 @@
+#include <u.h>
+#include <libc.h>
+
+void
+usage(void)
+{
+ print("status=usage\n");
+ exits(0);
+}
+
+char*
+findarg(char *flags, Rune r)
+{
+ char *p;
+ Rune rr;
+
+ for(p=flags; p!=(char*)1; p=strchr(p, ',')+1){
+ chartorune(&rr, p);
+ if(rr == r)
+ return p;
+ }
+ return nil;
+}
+
+int
+countargs(char *p)
+{
+ int n;
+
+ n = 1;
+ while(*p == ' ')
+ p++;
+ for(; *p && *p != ','; p++)
+ if(*p == ' ' && *(p-1) != ' ')
+ n++;
+ return n;
+}
+
+void
+main(int argc, char *argv[])
+{
+ char *flags, *p, buf[512];
+ int i, n;
+ Fmt fmt;
+
+ quotefmtinstall();
+ argv0 = argv[0]; /* for sysfatal */
+
+ flags = getenv("flagfmt");
+ if(flags == nil){
+ fprint(2, "$flagfmt not set\n");
+ print("exit 'missing flagfmt'");
+ exits(0);
+ }
+
+ fmtfdinit(&fmt, 1, buf, sizeof buf);
+ for(p=flags; p!=(char*)1; p=strchr(p, ',')+1)
+ fmtprint(&fmt, "flag%.1s=()\n", p);
+ ARGBEGIN{
+ default:
+ if((p = findarg(flags, ARGC())) == nil)
+ usage();
+ p += runelen(ARGC());
+ if(*p == ',' || *p == 0){
+ fmtprint(&fmt, "flag%C=1\n", ARGC());
+ break;
+ }
+ n = countargs(p);
+ fmtprint(&fmt, "flag%C=(", ARGC());
+ for(i=0; i<n; i++)
+ fmtprint(&fmt, "%s%q", i ? " " : "", EARGF(usage()));
+ fmtprint(&fmt, ")\n");
+ }ARGEND
+
+ fmtprint(&fmt, "*=(");
+ for(i=0; i<argc; i++)
+ fmtprint(&fmt, "%s%q", i ? " " : "", argv[i]);
+ fmtprint(&fmt, ")\n");
+ fmtprint(&fmt, "status=''\n");
+ fmtfdflush(&fmt);
+ exits(0);
+}
diff --git a/cmd/usage.c b/cmd/usage.c
new file mode 100644
index 00000000..b064feaf
--- /dev/null
+++ b/cmd/usage.c
@@ -0,0 +1,72 @@
+#include <u.h>
+#include <libc.h>
+
+void
+main(int argc, char **argv)
+{
+ Fmt fmt;
+ char buf[512];
+ char *argv0, *args, *flags, *p, *p0;
+ int single;
+ Rune r;
+
+ argv0 = getenv("0");
+ if(argv0 == nil) {
+ if(argc > 1)
+ argv0 = argv[1];
+ else
+ argv0 = "unknown-program-name";
+ }
+ if((p = strrchr(argv0, '/')) != nil)
+ argv0 = p+1;
+ flags = getenv("flagfmt");
+ args = getenv("args");
+
+ if(argv0 == nil){
+ fprint(2, "aux/usage: $0 not set\n");
+ exits("$0");
+ }
+ if(flags == nil)
+ flags = "";
+ if(args == nil)
+ args = "";
+
+ fmtfdinit(&fmt, 2, buf, sizeof buf);
+ fmtprint(&fmt, "usage: %s", argv0);
+ if(flags[0]){
+ single = 0;
+ for(p=flags; *p; ){
+ p += chartorune(&r, p);
+ if(*p == ',' || *p == 0){
+ if(!single){
+ fmtprint(&fmt, " [-");
+ single = 1;
+ }
+ fmtprint(&fmt, "%C", r);
+ if(*p == ',')
+ p++;
+ continue;
+ }
+ while(*p == ' ')
+ p++;
+ if(single){
+ fmtprint(&fmt, "]");
+ single = 0;
+ }
+ p0 = p;
+ p = strchr(p0, ',');
+ if(p == nil)
+ p = "";
+ else
+ *p++ = 0;
+ fmtprint(&fmt, " [-%C %s]", r, p0);
+ }
+ if(single)
+ fmtprint(&fmt, "]");
+ }
+ if(args)
+ fmtprint(&fmt, " %s", args);
+ fmtprint(&fmt, "\n");
+ fmtfdflush(&fmt);
+ exits("usage");
+}