From: ori@eigenstate.org
To: 9front@9front.org
Subject: Re: [9front] [PATCH] awk: add %q format for quoted strings (see quote(2))
Date: Tue, 24 Aug 2021 00:31:32 -0400 [thread overview]
Message-ID: <3863D6C11096E789A36452D1407D8DAB@eigenstate.org> (raw)
In-Reply-To: <133E5FC5E7881988426C146233AB5F7D@eigenstate.org>
Quoth ori@eigenstate.org:
> Quoth james palmer <james@biobuf.link>:
> > this one comes in handy for building bulk rename scripts.
> > patch for git/import attached.
> >
> > - james
> >
>
> I think it makes sense to add this, though I'm
> not sure how much we want to diverge from upstream.
>
> Ape would get this by accident, but it's a superset
> of what posix needs.
>
> going the other way would also be neat:
>
> ls -l | awk -Q {print $NF}
>
Here's a proof of concept -- though, I don't like how it
totally ignores FS.
diff fb2e0a1987b33083e3e08fa0659f99534c56d6aa uncommitted
--- a/sys/src/cmd/awk/awk.h
+++ b/sys/src/cmd/awk/awk.h
@@ -49,6 +49,7 @@
extern int donefld; /* 1 if record broken into fields */
extern int donerec; /* 1 if record is valid (no fld has changed */
extern char inputFS[]; /* FS at time of input, for field splitting */
+extern int quotefld; /* if we use quotes instead of FS for splitting */
extern int dbg;
--- a/sys/src/cmd/awk/lib.c
+++ b/sys/src/cmd/awk/lib.c
@@ -38,6 +38,7 @@
Cell **fldtab; /* pointers to Cells */
char inputFS[100] = " ";
+int quotefld;
#define MAXFLD 200
int nfields = MAXFLD; /* last allocated slot for $i */
@@ -242,7 +243,49 @@
dprint( ("command line set %s to |%s|\n", s, p) );
}
+char *unquoted(char *t, char **et)
+{
+ int quoting;
+ char *h, *s;
+ quoting = 0;
+ /* unquoting only shrinks s */
+ while (*t == ' ' || *t == '\t' || *t == '\n')
+ t++;
+ s = strdup(t);
+ h = s;
+ if (s == nil)
+ FATAL("out of space in tostring on %s", s);
+ while(*t!='\0'){
+ if(!quoting && (*t == ' ' || *t == '\t' || *t == '\n'))
+ break;
+ if(*t != '\''){
+ *s++ = *t++;
+ continue;
+ }
+ /* *t is a quote */
+ if(!quoting){
+ quoting = 1;
+ t++;
+ continue;
+ }
+ /* quoting and we're on a quote */
+ if(t[1] != '\''){
+ /* end of quoted section; absorb closing quote */
+ t++;
+ quoting = 0;
+ continue;
+ }
+ /* doubled quote; fold one quote into two */
+ t++;
+ *s++ = *t++;
+
+ }
+ *s = 0;
+ *et = t;
+ return h;
+}
+
void fldbld(void) /* create fields from current record */
{
/* this relies on having fields[] the same length as $0 */
@@ -265,7 +308,21 @@
}
fr = fields;
i = 0; /* number of fields accumulated here */
- if (strlen(inputFS) > 1) { /* it's a regular expression */
+ if (quotefld){ /* it's quoted text */
+ for (i = 0; ; ) {
+ while (*r == ' ' || *r == '\t' || *r == '\n')
+ r++;
+ if (*r == 0)
+ break;
+ i++;
+ if (i > nfields)
+ growfldtab(i);
+ if (freeable(fldtab[i]))
+ xfree(fldtab[i]->sval);
+ fldtab[i]->sval = unquoted(r, &r);
+ fldtab[i]->tval = FLD | STR;
+ }
+ }else if (strlen(inputFS) > 1) { /* it's a regular expression */
i = refldbld(r, inputFS);
} else if (*inputFS == ' ') { /* default whitespace */
for (i = 0; ; ) {
--- a/sys/src/cmd/awk/main.c
+++ b/sys/src/cmd/awk/main.c
@@ -51,7 +51,7 @@
void main(int argc, char *argv[])
{
- char *fs = nil, *marg;
+ char *fs = nil, qs = 0, *marg;
int temp;
setfcr(getfcr() & ~FPINVAL);
@@ -103,6 +103,9 @@
if (fs == nil || *fs == '\0')
WARNING("field separator FS is empty");
break;
+ case 'Q':
+ qs = 1;
+ break;
case 'v': /* -v a=1 to be done NOW. one -v for each */
if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1]))
setclvar(argv[1]);
@@ -158,6 +161,8 @@
dprint( ("argc=%d, argv[0]=%s\n", argc, argv[0]) );
arginit(argc, argv);
yyparse();
+ if (qs)
+ quotefld = 1;
if (fs)
*FS = qstring(fs, '\0');
dprint( ("exitstatus=%s\n", exitstatus) );
prev parent reply other threads:[~2021-08-24 9:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-11 21:24 james palmer
2021-08-12 21:29 ` Steve Simon
2021-08-18 13:23 ` james palmer
2021-08-24 9:45 ` [9front] " Pavel Renev
2021-08-13 6:43 ` unobe
2021-08-18 13:10 ` james palmer
2021-08-23 16:55 ` ori
2021-08-24 4:31 ` ori [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3863D6C11096E789A36452D1407D8DAB@eigenstate.org \
--to=ori@eigenstate.org \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).