tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Proposal to drop MKCATPAGES
On Mon, Oct 26, 2020 at 05:39:30PM +0700, Robert Elz wrote:
> | Also if inserting newlines is an intended use case, I kinda think it
> | ought to accept \n in there, which it currently doesn't.
>
> That would be "C string quoting" which is $'\n' which isn't yet in POSIX
> but should be coming sometime, it is supported by most (Bournish) shells
I was thinking in lam itself, like this:
(after all, sed has something similar)
I made it specifically recognize only \n and \t (and not \\ or
anything else) to minimize the chances of it breaking anything.
Index: lam.1
===================================================================
RCS file: /cvsroot/src/usr.bin/lam/lam.1,v
retrieving revision 1.14
diff -u -r1.14 lam.1
--- lam.1 26 Oct 2020 04:09:32 -0000 1.14
+++ lam.1 26 Oct 2020 04:12:48 -0000
@@ -91,6 +91,9 @@
This option may appear after the last file.
(A capitalized version appearing before the last file is not carried
over past the last file.)
+Instances of the sequences "\en" and "\et" are replaced with hard
+newlines and tabs, respectively.
+(No other escapes are recognized.)
.It Fl t Ar c
The input line terminator is
.Ar c
Index: lam.c
===================================================================
RCS file: /cvsroot/src/usr.bin/lam/lam.c,v
retrieving revision 1.8
diff -u -r1.8 lam.c
--- lam.c 4 Sep 2011 20:28:09 -0000 1.8
+++ lam.c 26 Oct 2020 04:12:48 -0000
@@ -74,6 +74,7 @@
static char *gatherline(struct openfile *);
static void getargs(char *[]);
static char *pad(struct openfile *);
+static const char *getseparator(const char *arg);
int
main(int argc, char *argv[])
@@ -128,7 +129,7 @@
switch (tolower((unsigned char) *c)) {
case 's':
if (*++p || (p = *++av))
- ip->sepstring = p;
+ ip->sepstring = getseparator(p);
else
error("Need string after -%s", c);
S = (*c == 'S' ? 1 : 0);
@@ -216,6 +217,50 @@
return (lp);
}
+static const char *
+getseparator(const char *arg)
+{
+ size_t i, j;
+ int seen;
+ char *p;
+
+ seen = 0;
+ for (i = 0; arg[i] != '\0'; i++) {
+ /*
+ * React only specifically to \n and \t; leave
+ * anything else alone.
+ */
+ if (arg[i] == '\\' && (arg[i+1] == 'n' || arg[i+1] == 't')) {
+ seen = 1;
+ }
+ }
+ if (!seen) {
+ warnx("blah");
+ return arg;
+ }
+
+ /* sufficient: length of result is at most strlen(arg) - 1 */
+ p = malloc(strlen(arg));
+ if (p == NULL) {
+ err(1, "malloc");
+ }
+ for (i = j = 0; arg[i] != '\0'; i++) {
+ if (arg[i] == '\\' && arg[i+1] == 'n') {
+ p[j++] = '\n';
+ /* skip the \\ */
+ i++;
+ } else if (arg[i] == '\\' && arg[i+1] == 't') {
+ p[j++] = '\t';
+ /* skip the \\ */
+ i++;
+ } else {
+ p[j++] = arg[i];
+ }
+ }
+ p[j] = '\0';
+ return p;
+}
+
static void
error(const char *msg, const char *s)
{
--
David A. Holland
dholland%netbsd.org@localhost
Home |
Main Index |
Thread Index |
Old Index