Download raw body.
Implement -E for rs(1)
Hello,
It looks like -E was never added to rs(1) for some reason even though
the man page and the code make reference to it. I recently had need to
have rs -E work, so I took a stab at implementing it.
Here is what it does:
$ echo ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz | ./rs -E 4
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m
n o p q r s t u v w x y z
Comments on the patch? Should the code also handle allocating less
memory when only a single char is necessary requested (I did start on
that but it was less simple)?
Index: rs.c
===================================================================
RCS file: /cvs/src/usr.bin/rs/rs.c,v
retrieving revision 1.30
diff -u -r1.30 rs.c
--- rs.c 3 Dec 2015 12:23:15 -0000 1.30
+++ rs.c 23 Nov 2023 00:39:30 -0000
@@ -81,7 +81,7 @@
char isep = ' ', osep = ' ';
int owidth = 80, gutter = 2;
-int mbsavis(char **, const char *);
+int mbsavis(char **, const char *, int);
void usage(void);
void getargs(int, char *[]);
@@ -120,10 +120,11 @@
getfile(void)
{
const char delim[2] = { isep, '\0' };
- char *p;
+ char *p, *f;
struct entry *ep;
int multisep = (flags & ONEISEPONLY ? 0 : 1);
int nullpad = flags & NULLPAD;
+ int oneperchar = flags & ONEPERCHAR;
struct entry *padto;
curline = NULL;
@@ -139,6 +140,8 @@
flags |= ONEPERLINE;
if (flags & ONEPERLINE)
icols = 1;
+ else if (oneperchar)
+ icols = mbsavis(&f, curline, 0);
else /* count cols on first line */
for (p = curline; *p != '\0'; p++) {
if (*p == isep && multisep)
@@ -151,7 +154,7 @@
p = curline;
do {
if (flags & ONEPERLINE) {
- ep->w = mbsavis(&ep->s, curline);
+ ep->w = mbsavis(&ep->s, curline, 0);
if (maxwidth < ep->w)
maxwidth = ep->w;
INCR(ep); /* prepare for next entry */
@@ -160,14 +163,17 @@
}
p = curline;
while (p != NULL && *p != '\0') {
- if (*p == isep) {
+ if (oneperchar) {
+ ep->w = mbsavis(&ep->s, p, 1);
+ p += ep->w;
+ } else if (*p == isep) {
p++;
if (multisep)
continue;
ep->s = ""; /* empty column */
ep->w = 0;
} else
- ep->w = mbsavis(&ep->s, strsep(&p, delim));
+ ep->w = mbsavis(&ep->s, strsep(&p, delim), 0);
if (maxwidth < ep->w)
maxwidth = ep->w;
INCR(ep); /* prepare for next entry */
Index: utf8.c
===================================================================
RCS file: /cvs/src/usr.bin/rs/utf8.c,v
retrieving revision 1.1
diff -u -r1.1 utf8.c
--- utf8.c 3 Dec 2015 12:23:15 -0000 1.1
+++ utf8.c 23 Nov 2023 00:39:30 -0000
@@ -20,7 +20,7 @@
#include <wchar.h>
int
-mbsavis(char** outp, const char *mbs)
+mbsavis(char** outp, const char *mbs, int nchars)
{
const char *src; /* Iterate mbs. */
char *dst; /* Iterate *outp. */
@@ -28,13 +28,16 @@
int total_width; /* Display width of the whole string. */
int width; /* Display width of a single Unicode char. */
int len; /* Length in bytes of UTF-8 encoded string. */
+ int count; /* Count of chars read. */
len = strlen(mbs);
if ((*outp = malloc(len + 1)) == NULL)
err(1, NULL);
if (MB_CUR_MAX == 1) {
+ len = (nchars && nchars < len) ? nchars : len;
memcpy(*outp, mbs, len + 1);
+ (*outp)[len] = '\0';
return len;
}
@@ -55,6 +58,7 @@
while (len-- > 0)
*dst++ = *src++;
}
+ if (nchars > 0 && count++ >= nchars) break;
}
*dst = '\0';
return total_width;
------------------------------------------------------------------------
Thanks,
Andy
[resent]
Implement -E for rs(1)