Add support for multibyte characters.

This commit is contained in:
Tim J. Robbins 2004-07-13 02:18:21 +00:00
parent 7eb52d171e
commit 33ec7f265b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=132078
2 changed files with 47 additions and 22 deletions

View File

@ -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.

View File

@ -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)