summaryrefslogtreecommitdiffstats
path: root/usr.bin/nl
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
parentbdcd057a4e86b77ba0740b0b1a3d82ec00d5d3ea (diff)
downloadFreeBSD-src-056d1c10d2eef0deb094b3887b8887e6ad5acb6f.zip
FreeBSD-src-056d1c10d2eef0deb094b3887b8887e6ad5acb6f.tar.gz
Add support for multibyte characters.
Diffstat (limited to 'usr.bin/nl')
-rw-r--r--usr.bin/nl/nl.117
-rw-r--r--usr.bin/nl/nl.c52
2 files changed, 47 insertions, 22 deletions
diff --git a/usr.bin/nl/nl.1 b/usr.bin/nl/nl.1
index 846de61..be7fbe1 100644
--- a/usr.bin/nl/nl.1
+++ b/usr.bin/nl/nl.1
@@ -34,7 +34,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd September 20, 2001
+.Dd July 13, 2004
.Dt NL 1
.Os
.Sh NAME
@@ -223,6 +223,17 @@ The default
.Ar width
is 6.
.El
+.Sh ENVIRONMENT
+The
+.Ev LANG,
+.Ev LC_ALL,
+.Ev LC_CTYPE
+and
+.Ev LC_COLLATE
+environment variables affect the execution of
+.Nm
+as described in
+.Xr environ 7 .
.Sh DIAGNOSTICS
.Ex -std
.Sh SEE ALSO
@@ -238,7 +249,3 @@ The
.Nm
utility first appeared in
.At V.2 .
-.Sh BUGS
-The
-.Nm
-utility does not recognize multibyte characters.
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