aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/fmtquote.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:04:08 +0000
committerrsc <devnull@localhost>2003-11-23 18:04:08 +0000
commitf08fdedcee12c06e3ce9ac9bec363915978e8289 (patch)
treed67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/fmtquote.c
parent5993a8f2756bc455101a8c9ce95347d5050e7883 (diff)
downloadplan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.gz
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.bz2
plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.zip
Plan 9's rc.
not a clear win over byron's, but at least it has the right syntax.
Diffstat (limited to 'src/cmd/rc/fmtquote.c')
-rw-r--r--src/cmd/rc/fmtquote.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/cmd/rc/fmtquote.c b/src/cmd/rc/fmtquote.c
new file mode 100644
index 00000000..e6b91e34
--- /dev/null
+++ b/src/cmd/rc/fmtquote.c
@@ -0,0 +1,162 @@
+/*
+ * The authors of this software are Rob Pike and Ken Thompson.
+ * Copyright (c) 2002 by Lucent Technologies.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+#include <u.h>
+#include <libc.h>
+#include "fmt.h"
+#include "fmtdef.h"
+
+extern int (*doquote)(int);
+
+/*
+ * How many bytes of output UTF will be produced by quoting (if necessary) this string?
+ * How many runes? How much of the input will be consumed?
+ * The parameter q is filled in by _quotesetup.
+ * The string may be UTF or Runes (s or r).
+ * Return count does not include NUL.
+ * Terminate the scan at the first of:
+ * NUL in input
+ * count exceeded in input
+ * count exceeded on output
+ * *ninp is set to number of input bytes accepted.
+ * nin may be <0 initially, to avoid checking input by count.
+ */
+void
+__quotesetup(char *s, int nin, int nout, Quoteinfo *q, int sharp)
+{
+ int c;
+
+ q->quoted = 0;
+ q->nbytesout = 0;
+ q->nrunesout = 0;
+ q->nbytesin = 0;
+ q->nrunesin = 0;
+ if(sharp || nin==0 || *s=='\0'){
+ if(nout < 2)
+ return;
+ q->quoted = 1;
+ q->nbytesout = 2;
+ q->nrunesout = 2;
+ }
+ for(; nin!=0; nin-=1){
+ c = *s;
+
+ if(c == '\0')
+ break;
+ if(q->nrunesout+1 > nout)
+ break;
+
+ if((c <= L' ') || (c == L'\'') || (doquote!=nil && doquote(c))){
+ if(!q->quoted){
+ if(1+q->nrunesout+1+1 > nout) /* no room for quotes */
+ break;
+ q->nrunesout += 2; /* include quotes */
+ q->nbytesout += 2; /* include quotes */
+ q->quoted = 1;
+ }
+ if(c == '\'') {
+ q->nbytesout++;
+ q->nrunesout++; /* quotes reproduce as two characters */
+ }
+ }
+
+ /* advance input */
+ s++;
+ q->nbytesin++;
+ q->nrunesin++;
+
+ /* advance output */
+ q->nbytesout++;
+ q->nrunesout++;
+ }
+}
+
+static int
+qstrfmt(char *sin, Quoteinfo *q, Fmt *f)
+{
+ int r;
+ char *t, *s, *m, *me;
+ ulong fl;
+ int nc, w;
+
+ m = sin;
+ me = m + q->nbytesin;
+
+ w = f->width;
+ fl = f->flags;
+ if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)
+ return -1;
+ t = f->to;
+ s = f->stop;
+ FMTCHAR(f, t, s, '\'');
+ for(nc = q->nrunesin; nc > 0; nc--){
+ r = *(uchar*)m++;
+ FMTCHAR(f, t, s, r);
+ if(r == '\'')
+ FMTCHAR(f, t, s, r);
+ }
+
+ FMTCHAR(f, t, s, '\'');
+ f->nfmt += t - (char *)f->to;
+ f->to = t;
+ if(fl & FmtLeft && __fmtpad(f, w - q->nbytesout) < 0)
+ return -1;
+ return 0;
+}
+
+int
+__quotestrfmt(int runesin, Fmt *f)
+{
+ int outlen;
+ char *s;
+ Quoteinfo q;
+
+ f->flags &= ~FmtPrec; /* ignored for %q %Q, so disable for %s %S in easy case */
+ s = va_arg(f->args, char *);
+ if(!s)
+ return __fmtcpy(f, "<nil>", 5, 5);
+
+ if(f->flush)
+ outlen = 0x7FFFFFFF; /* if we can flush, no output limit */
+ else
+ outlen = (char*)f->stop - (char*)f->to;
+
+ __quotesetup(s, -1, outlen, &q, f->flags&FmtSharp);
+
+ if(!q.quoted)
+ return __fmtcpy(f, s, q.nrunesin, q.nbytesin);
+ return qstrfmt(s, &q, f);
+}
+
+int
+quotestrfmt(Fmt *f)
+{
+ return __quotestrfmt(0, f);
+}
+
+void
+quotefmtinstall(void)
+{
+ fmtinstall('q', quotestrfmt);
+}
+
+int
+__needsquotes(char *s, int *quotelenp)
+{
+ Quoteinfo q;
+
+ __quotesetup(s, -1, 0x7FFFFFFF, &q, 0);
+ *quotelenp = q.nbytesout;
+
+ return q.quoted;
+}