diff options
author | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
commit | f08fdedcee12c06e3ce9ac9bec363915978e8289 (patch) | |
tree | d67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/fmtquote.c | |
parent | 5993a8f2756bc455101a8c9ce95347d5050e7883 (diff) | |
download | plan9port-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.c | 162 |
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; +} |