summaryrefslogtreecommitdiffstats
path: root/usr.bin/nl/nl.c
diff options
context:
space:
mode:
authortjr <tjr@FreeBSD.org>2004-07-13 02:18:21 +0000
committertjr <tjr@FreeBSD.org>2004-07-13 02:18:21 +0000
commit056d1c10d2eef0deb094b3887b8887e6ad5acb6f (patch)
tree27e77be175520016f7ed3920308a701a9bd2eaf7 /usr.bin/nl/nl.c
parentbdcd057a4e86b77ba0740b0b1a3d82ec00d5d3ea (diff)
downloadFreeBSD-src-056d1c10d2eef0deb094b3887b8887e6ad5acb6f.zip
FreeBSD-src-056d1c10d2eef0deb094b3887b8887e6ad5acb6f.tar.gz
Add support for multibyte characters.
Diffstat (limited to 'usr.bin/nl/nl.c')
-rw-r--r--usr.bin/nl/nl.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/usr.bin/nl/nl.c b/usr.bin/nl/nl.c
index e3a5342..662ce26 100644
--- a/usr.bin/nl/nl.c
+++ b/usr.bin/nl/nl.c
@@ -53,6 +53,7 @@ __RCSID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <wchar.h>
typedef enum {
number_all, /* number all lines */
@@ -107,11 +108,13 @@ static size_t buffersize;
*/
static char *intbuffer;
+/* delimiter characters that indicate the start of a logical page section */
+static char delim[2 * MB_LEN_MAX];
+static int delimlen;
+
/*
* Configurable parameters.
*/
-/* delimiter characters that indicate the start of a logical page section */
-static char delim[2] = { '\\', ':' };
/* line numbering format */
static const char *format = FORMAT_RN;
@@ -141,11 +144,13 @@ main(argc, argv)
int argc;
char *argv[];
{
- int c;
+ int c, n;
long val;
unsigned long uval;
char *ep;
- size_t intbuffersize;
+ size_t intbuffersize, clen;
+ char delim1[MB_LEN_MAX] = { '\\' }, delim2[MB_LEN_MAX] = { ':' };
+ size_t delim1len = 1, delim2len = 1;
(void)setlocale(LC_ALL, "");
@@ -158,16 +163,24 @@ main(argc, argv)
parse_numbering(optarg, BODY);
break;
case 'd':
- if (optarg[0] != '\0')
- delim[0] = optarg[0];
- if (optarg[1] != '\0')
- delim[1] = optarg[1];
- /* at most two delimiter characters */
- if (optarg[2] != '\0') {
- errx(EXIT_FAILURE,
- "invalid delim argument -- %s",
- optarg);
- /* NOTREACHED */
+ clen = mbrlen(optarg, MB_CUR_MAX, NULL);
+ if (clen == (size_t)-1 || clen == (size_t)-2)
+ errc(EXIT_FAILURE, EILSEQ, NULL);
+ if (clen != 0) {
+ memcpy(delim1, optarg, delim1len = clen);
+ clen = mbrlen(optarg + delim1len,
+ MB_CUR_MAX, NULL);
+ if (clen == (size_t)-1 ||
+ clen == (size_t)-2)
+ errc(EXIT_FAILURE, EILSEQ, NULL);
+ if (clen != 0) {
+ memcpy(delim2, optarg + delim1len,
+ delim2len = clen);
+ if (optarg[delim1len + clen] != '\0')
+ errx(EXIT_FAILURE,
+ "invalid delim argument -- %s",
+ optarg);
+ }
}
break;
case 'f':
@@ -251,6 +264,11 @@ main(argc, argv)
/* NOTREACHED */
}
+ /* Generate the delimiter sequence */
+ memcpy(delim, delim1, delim1len);
+ memcpy(delim + delim1len, delim2, delim2len);
+ delimlen = delim1len + delim2len;
+
/* Determine the maximum input line length to operate on. */
if ((val = sysconf(_SC_LINE_MAX)) == -1) /* ignore errno */
val = LINE_MAX;
@@ -290,10 +308,10 @@ filter()
while (fgets(buffer, (int)buffersize, stdin) != NULL) {
for (idx = FOOTER; idx <= NP_LAST; idx++) {
/* Does it look like a delimiter? */
- if (buffer[2 * idx + 0] == delim[0] &&
- buffer[2 * idx + 1] == delim[1]) {
+ if (memcmp(buffer + delimlen * idx, delim,
+ delimlen) == 0) {
/* Was this the whole line? */
- if (buffer[2 * idx + 2] == '\n') {
+ if (buffer[delimlen * (idx + 1)] == '\n') {
section = idx;
adjblank = 0;
if (restart)
OpenPOWER on IntegriCloud