Importing usr.bin/msgc

Minix-specific changes were needed in msg_sys.def:

 * use minix_mmap()/minix_munmap() since mmap()/munmap() aren't
   defined on Minix.

 * use MAP_PRIVATE flag since MAP_SHARED isn't defined on Minix.

Tested with usr.bin/menuc/testm.

Change-Id: I1c463e7b0623036050adb6a9079c6747e1c1e084
This commit is contained in:
Thomas Cort 2013-11-06 10:52:33 -05:00
parent 525a267e81
commit d44a5ed1c1
13 changed files with 1518 additions and 1 deletions

View file

@ -413,6 +413,7 @@
./usr/bin/mkstr minix-sys
./usr/bin/mktemp minix-sys
./usr/bin/more minix-sys
./usr/bin/msgc minix-sys
./usr/bin/mt minix-sys
./usr/bin/nbperf minix-sys
./usr/bin/newgrp minix-sys
@ -2008,6 +2009,7 @@
./usr/man/man1/mktemp.1 minix-sys
./usr/man/man1/more.1 minix-sys
./usr/man/man1/mount.1 minix-sys
./usr/man/man1/msgc.1 minix-sys
./usr/man/man1/mt.1 minix-sys
./usr/man/man1/mv.1 minix-sys
./usr/man/man1/nbperf.1 minix-sys
@ -4672,6 +4674,7 @@
./usr/share/misc/man.template minix-sys
./usr/share/misc/mdoc.template minix-sys
./usr/share/misc/menu_sys.def minix-sys
./usr/share/misc/msg_sys.def minix-sys
./usr/share/misc/na.phone minix-sys
./usr/share/misc/na.postal minix-sys
./usr/share/misc/NetBSD.el minix-sys

View file

@ -194,6 +194,7 @@
2010/10/15 05:46:48,usr.bin/mkdep
2012/10/17 12:00:00,usr.bin/mkstr
2009/08/15 20:44:56,usr.bin/mktemp
2012/10/17 12:00:00,usr.bin/msgc
2012/10/17 12:00:00,usr.bin/nbperf
2013/10/10 12:00:00,usr.bin/nice
2013/10/13 12:00:00,usr.bin/nl

View file

@ -17,7 +17,7 @@ SUBDIR= asa \
lock login logname lorder m4 \
machine make man menuc mesg \
mkdep mkstr mktemp \
\
msgc \
nbperf newgrp nice nl nohup nvi \
passwd paste pathchk pr \
printenv printf pwhash \

23
usr.bin/msgc/Makefile Normal file
View file

@ -0,0 +1,23 @@
# $NetBSD: Makefile,v 1.18 2009/10/29 14:37:56 christos Exp $
WARNS?= 1 # XXX -Wshadow -Wcast-qual issues
.include <bsd.own.mk>
PROG= msgc
SRCS= msgmain.c msgparse.y msgscan.l msgdb.c util.c avl.c
.PATH: ${NETBSDSRCDIR}/usr.bin/menuc
CPPFLAGS+= -I. -I${.CURDIR}
YHEADER=
.if ${MKSHARE} != "no"
FILES= msg_sys.def
FILESDIR= /usr/share/misc
.endif
.ifndef HOSTPROG
LDADD+= -ll
DPADD+= ${LIBL}
.endif
.include <bsd.prog.mk>

91
usr.bin/msgc/defs.h Normal file
View file

@ -0,0 +1,91 @@
/* $NetBSD: defs.h,v 1.5 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* defs.h: definitions needed for the message system. */
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <stdio.h>
#include "msgdb.h"
#ifdef MAIN
#define EXTERN
#define INIT(x) = x
#else
#define EXTERN extern
#define INIT(x)
#endif
/* some constants */
#define TRUE 1
#define FALSE 0
/* Global variables .. to be defined in main.c, extern elsewhere. */
EXTERN char *prog_name;
EXTERN char *src_name;
EXTERN char *out_name INIT("msg_defs");
EXTERN char *sys_name INIT("msg_sys.def");
EXTERN int line_no INIT(1);
EXTERN int had_errors INIT(FALSE);
EXTERN int max_strlen INIT(1);
EXTERN id_rec *root INIT(NULL);
/* Prototypes. */
/* From util.c */
void yyerror(const char *, ...);
void buff_add_ch(char);
char *buff_copy(void);
/* From avl.c */
id_rec *find_id(id_rec *, char *);
int insert_id(id_rec **, id_rec *);
/* from scan.l */
int yylex(void);
/* from parse.y */
int yyparse(void);
/* Vars not defined in main.c */
extern FILE *yyin;
/* from mdb.c */
void define_msg(char *, char *);
void write_msg_file(void);

612
usr.bin/msgc/msg_sys.def Normal file
View file

@ -0,0 +1,612 @@
/* $NetBSD: msg_sys.def,v 1.41 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
static WINDOW *msg_win = NULL;
static char *cbuffer;
static size_t cbuffersize;
static int last_i_was_nl, last_i_was_space;
static int last_o_was_punct, last_o_was_space;
static void _msg_beep(void);
static int _msg_vprintf(int, const char *, va_list);
#define MSG_PROMPT_ECHO 1
#define MSG_PROMPT_HIDE_DFLT 2
static void _msg_vprompt(const char *, int, const char *, char *,
size_t, va_list);
static char *msgmap = MAP_FAILED;
static size_t msgmapsz;
static unsigned int msgmapcount;
/* Routines */
static void
_msg_beep(void)
{
fprintf(stderr, "\a");
}
WINDOW *
msg_window(WINDOW *window)
{
size_t ncbuffersize;
char *ncbuffer;
WINDOW *old;
old = msg_win;
if (!window)
return old;
msg_win = window;
ncbuffersize = getmaxx(window) * getmaxy(window) + 1;
while (ncbuffersize > cbuffersize) {
ncbuffer = malloc(ncbuffersize);
if (ncbuffer == NULL) {
/* we might get truncated messages... */
ncbuffersize <<= 1;
continue;
}
if (cbuffer != NULL)
free(cbuffer);
cbuffer = ncbuffer;
cbuffersize = ncbuffersize;
break;
}
last_o_was_punct = 0;
last_o_was_space = 1;
return old;
}
int
msg_file(const char *file)
{
int fd;
if (msgmap != MAP_FAILED)
#ifdef __minix
minix_munmap(msgmap, msgmapsz);
#else /* ! __minix */
munmap(msgmap, msgmapsz);
#endif /* ! __minix */
msgmap = MAP_FAILED;
if (!file)
return 0;
fd = open(file, O_RDONLY, 0);
if (fd == -1)
return -1;
msgmapsz = lseek(fd, 0, SEEK_END);
#ifdef __minix
msgmap = minix_mmap(0, msgmapsz, PROT_READ, MAP_PRIVATE, fd, 0);
#else /* ! __minix */
msgmap = mmap(0, msgmapsz, PROT_READ, MAP_SHARED, fd, 0);
#endif /* ! __minix */
close(fd);
if (msgmap == MAP_FAILED)
return -1;
/* check_magic */
if (strcmp(msgmap, "MSGTXTS") != 0) {
msg_file(NULL);
return -1;
}
msgmapcount = atoi(msgmap + 8);
return 0;
}
const char *
msg_string(msg msg_no)
{
uintptr_t m = (uintptr_t)msg_no;
if (m > sizeof msg_list / sizeof msg_list[0])
/* guess that we were passed a text string */
return msg_no;
if (msgmap != MAP_FAILED && m != 0 && m <= msgmapcount) {
unsigned int offset = atoi(msgmap + 8 + 8 * m);
if (offset != 0 && offset < msgmapsz)
return msgmap + offset;
}
return msg_list[m];
}
void
msg_clear(void)
{
wclear(msg_win);
last_o_was_punct = 0;
last_o_was_space = 1;
}
void
msg_standout(void)
{
wstandout(msg_win);
}
void
msg_standend(void)
{
wstandend(msg_win);
}
static int
_msg_vprintf(int auto_fill, const char *fmt, va_list ap)
{
const char *wstart, *afterw;
int wordlen, nspaces;
int ret;
ret = vsnprintf(cbuffer, cbuffersize, fmt, ap);
if (!auto_fill) {
waddstr(msg_win, cbuffer);
/*
* nothing is perfect if they flow text after a table,
* but this may be decent.
*/
last_i_was_nl = last_i_was_space = 1;
last_o_was_punct = 0;
last_o_was_space = 1;
goto out;
}
for (wstart = afterw = cbuffer; *wstart; wstart = afterw) {
/* eat one space, or a whole word of non-spaces */
if (isspace((unsigned char)*afterw))
afterw++;
else
while (*afterw && !isspace((unsigned char)*afterw))
afterw++;
/* this is an nl: special formatting necessary */
if (*wstart == '\n') {
if (last_i_was_nl || last_i_was_space) {
if (getcurx(msg_win) != 0)
waddch(msg_win, '\n');
if (last_i_was_nl) {
/* last was an nl: paragraph break */
waddch(msg_win, '\n');
} else {
/* last was space: line break */
}
last_o_was_punct = 0;
last_o_was_space = 1;
} else {
/* last_o_was_punct unchanged */
/* last_o_was_space unchanged */
}
last_i_was_space = 1;
last_i_was_nl = 1;
continue;
}
/* this is a tab: special formatting necessary. */
if (*wstart == '\t') {
if (last_i_was_nl) {
/* last was an nl: list indent */
if (getcurx(msg_win) != 0)
waddch(msg_win, '\n');
} else {
/* last was not an nl: columns */
}
waddch(msg_win, '\t');
last_i_was_nl = 0;
last_i_was_space = 1;
last_o_was_punct = 0;
last_o_was_space = 1;
continue;
}
/* this is a space: ignore it but set flags */
last_i_was_nl = 0; /* all newlines handled above */
last_i_was_space = isspace((unsigned char)*wstart);
if (last_i_was_space)
continue;
/*
* we have a real "word," i.e. a sequence of non-space
* characters. wstart is now the start of the word,
* afterw is the next character after the end.
*/
wordlen = afterw - wstart;
nspaces = last_o_was_space ? 0 : (last_o_was_punct ? 2 : 1);
if ((getcurx(msg_win) + nspaces + wordlen) >=
getmaxx(msg_win) &&
wordlen < (getmaxx(msg_win) / 3)) {
/* wrap the line */
waddch(msg_win, '\n');
nspaces = 0;
}
/* output the word, preceded by spaces if necessary */
while (nspaces-- > 0)
waddch(msg_win, ' ');
waddbytes(msg_win, wstart, wordlen);
/* set up the 'last' state for the next time around */
switch (afterw[-1]) {
case '.':
case '?':
case '!':
last_o_was_punct = 1;
break;
default:
last_o_was_punct = 0;
break;
}
last_o_was_space = 0;
/* ... and do it all again! */
}
/* String ended with a newline. They really want a line break. */
if (last_i_was_nl) {
if (getcurx(msg_win) != 0)
waddch(msg_win, '\n');
last_o_was_punct = 0;
last_o_was_space = 1;
}
out:
wrefresh(msg_win);
return ret;
}
void
msg_display(msg msg_no, ...)
{
va_list ap;
msg_clear();
va_start(ap, msg_no);
(void)_msg_vprintf(1, msg_string(msg_no), ap);
va_end(ap);
}
void
msg_display_add(msg msg_no, ...)
{
va_list ap;
va_start(ap, msg_no);
(void)_msg_vprintf(1, msg_string(msg_no), ap);
va_end(ap);
}
void
msg_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
(void)_msg_vprintf(1, fmt, ap);
va_end(ap);
}
static void
_msg_vprompt(const char *fmt, int flags, const char *def, char *val,
size_t val_buf_len, va_list ap)
{
int ch;
int len, pos, npos, off;
int first;
int txt_y, txt_x;
char *ibuf;
int maxx;
if (val == NULL || val_buf_len == 0) {
/* No answer wanted */
val = NULL;
val_buf_len = 1;
}
ibuf = malloc(val_buf_len);
keypad(msg_win, TRUE);
_msg_vprintf(0, fmt, ap);
ibuf[0] = 0;
if (def != NULL && *def) {
if (flags & MSG_PROMPT_HIDE_DFLT)
strlcpy(ibuf, def, val_buf_len);
else {
waddstr(msg_win, " [");
waddstr(msg_win, def);
waddstr(msg_win, "]");
}
}
waddstr(msg_win, ": ");
len = strlen(ibuf);
pos = len;
getyx(msg_win, txt_y, txt_x);
maxx = getmaxx(msg_win) - txt_x - 1;
off = 0;
for (first = 1; ; first = 0) {
if (flags & MSG_PROMPT_ECHO) {
/* shift text right as we near the buffer start */
if (pos - off < 4)
off = pos - 4;
/* keep offset to a minimum if we are at the end */
if (pos == len)
off = pos - maxx;
if (off < 0 || len <= maxx)
off = 0;
/* shift text left as we near the buffer end */
npos = pos + 4;
if (npos > len)
npos = len;
if (npos - off > maxx)
off = npos - maxx;
/* calc. length to display */
npos = len - off;
if (npos > maxx)
npos = maxx;
mvwaddnstr(msg_win, txt_y, txt_x, ibuf + off, npos);
wclrtoeol(msg_win);
if (off != 0)
mvwaddstr(msg_win, txt_y, txt_x, "+");
wmove(msg_win, txt_y, txt_x + pos - off);
wrefresh(msg_win);
}
ch = wgetch(msg_win);
if (ch == '\n')
break;
switch (ch) {
case KEY_BACKSPACE:
case 'h' & 0x1f: case 0x7f: /* bs or del - delete left */
if (first) {
/* delete all of default string */
len = pos = 0;
break;
}
if (pos > 0) {
memmove(ibuf + pos - 1, ibuf + pos, len - pos);
len--;
pos--;
} else
_msg_beep();
break;
case 'u' & 0x1f: /* ^U; line kill */
/* kill line */
len = pos = 0;
break;
case 'w' & 0x1f: /* ^W; word kill */
/*
* word kill kills the spaces and the 'word'
* (non-spaces) last typed. the spaces before
* the 'word' aren't killed.
*/
npos = pos;
while (npos > 0 && isspace((unsigned char)ibuf[npos - 1]))
npos--;
while (npos > 0 && !isspace((unsigned char)ibuf[npos - 1]))
npos--;
memmove(ibuf + npos, ibuf + pos, len - pos);
len -= pos - npos;
pos = npos;
break;
case KEY_LEFT:
if (pos > 0)
pos--;
break;
case KEY_RIGHT:
if (len == 0 && pos == 0 && def != NULL) {
/* restore default! */
strlcpy(ibuf, def, val_buf_len);
len = pos = strlen(ibuf);
break;
}
if (pos < len)
pos++;
break;
default:
if (len < (int)(val_buf_len - 1) && isprint(ch)) {
memmove(ibuf + pos + 1, ibuf + pos, len - pos);
ibuf[pos++] = ch;
len++;
} else
_msg_beep();
break;
}
}
if (flags & MSG_PROMPT_ECHO) {
mvwaddch(msg_win, txt_y, txt_x + len - off, '\n');
last_o_was_punct = 0;
last_o_was_space = 1;
}
if (val != NULL) {
/* copy the appropriate string to the output */
if (len != 0 || flags & MSG_PROMPT_HIDE_DFLT) {
ibuf[len] = '\0';
strlcpy(val, ibuf, val_buf_len);
} else if (def != NULL && val != def) {
strlcpy(val, def, val_buf_len);
}
}
free(ibuf);
}
void
msg_prompt(msg msg_no, const char *def, char *val, size_t val_buf_len, ...)
{
va_list ap;
msg_clear();
va_start(ap, val_buf_len);
_msg_vprompt(msg_string(msg_no), MSG_PROMPT_ECHO,
def, val, val_buf_len, ap);
va_end(ap);
}
void
msg_prompt_win(msg msg_no, int x, int y, int w, int h,
const char *def, char *val, size_t val_buf_len, ...)
{
va_list ap;
WINDOW *win;
WINDOW *svmsg = NULL, *sv_win = NULL; /* XXX -Wuninitialized [many] */
int maxx, maxy;
int msg_flags = MSG_PROMPT_ECHO | MSG_PROMPT_HIDE_DFLT;
maxx = getmaxx(msg_win);
maxy = getmaxy(msg_win);
if (w == 0) {
va_start(ap, val_buf_len);
w = vsnprintf(NULL, 0, msg_string(msg_no), ap);
va_end(ap);
if (def != NULL && *def != 0 && w + (int)val_buf_len * 2 < maxx) {
w += 2 + strlen(def) + 1;
msg_flags &= ~MSG_PROMPT_HIDE_DFLT;
}
w += 1 + 2 + val_buf_len + 1;
if (w > maxx) {
if (!(msg_flags & MSG_PROMPT_HIDE_DFLT)) {
w -= 2 + strlen(def) + 1;
msg_flags |= MSG_PROMPT_HIDE_DFLT;
}
w = maxx;
}
}
if (x == -1)
x = (maxx - w) / 2 + 1;
if (h < 3)
h = 3;
if (y < 3)
y = (maxy - h) / 2;
if (y + h > maxy)
y = maxy - h;
win = subwin(msg_win, h, w, y, x);
if (win == NULL)
wprintw(msg_win, "msg_prompt_win: "
"newwin(%d, %d, %d, %d) failed\n",
h, w, y, x);
else {
/*
* Save screen contents from under our window
* Due to a mis-feature of NetBSD curses, curscr contains
* the data processed by doupdate() not that by wnoutrefresh().
* We must call doupdate() here to ensure we save the correct
* data. See PR 26660
*/
doupdate();
sv_win = dupwin(win);
if (sv_win)
overwrite(curscr, sv_win);
wbkgd(win, getbkgd(msg_win));
wattrset(win, getattrs(msg_win));
box(win, 0, 0);
wrefresh(win);
/* Change message window to be our little box */
svmsg = msg_window(subwin(msg_win, h - 2, w - 2, y + 1, x + 1));
wbkgd(msg_win, getbkgd(win));
wattrset(msg_win, getattrs(win));
msg_clear();
}
va_start(ap, val_buf_len);
_msg_vprompt(msg_string(msg_no), msg_flags, def, val, val_buf_len, ap);
va_end(ap);
if (win != NULL) {
wclear(win);
if (sv_win) {
/* Restore original screen contents */
overwrite(sv_win, win);
delwin(sv_win);
}
wnoutrefresh(win);
/* Restore normal message window */
delwin(msg_window(svmsg));
delwin(win);
}
}
void
msg_prompt_add(msg msg_no, const char *def, char *val, size_t val_buf_len, ...)
{
va_list ap;
va_start(ap, val_buf_len);
_msg_vprompt(msg_string(msg_no), MSG_PROMPT_ECHO, def, val, val_buf_len, ap);
va_end(ap);
}
void
msg_prompt_noecho(msg msg_no, const char *def, char *val, size_t val_buf_len, ...)
{
va_list ap;
msg_clear();
va_start(ap, val_buf_len);
_msg_vprompt(msg_string(msg_no), 0, def, val, val_buf_len, ap);
va_end(ap);
}
void
msg_table_add(msg msg_no, ...)
{
va_list ap;
va_start(ap, msg_no);
(void)_msg_vprintf(0, msg_string(msg_no), ap);
va_end(ap);
}
int
msg_row(void)
{
return getcury(msg_win) + getbegy(msg_win);
}

211
usr.bin/msgc/msgc.1 Normal file
View file

@ -0,0 +1,211 @@
.\" $NetBSD: msgc.1,v 1.26 2012/03/06 16:26:01 mbalmer Exp $
.\"
.\" Copyright 1997 Piermont Information Systems Inc.
.\" All rights reserved.
.\"
.\" Written by Philip A. Nelson for Piermont Information Systems Inc.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. The name of Piermont Information Systems Inc. may not be used to endorse
.\" or promote products derived from this software without specific prior
.\" written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd March 3, 2012
.Dt MSGC 1
.Os
.Sh NAME
.Nm msgc ,
.Nm msg_window ,
.Nm msg_string ,
.Nm msg_clear ,
.Nm msg_standout ,
.Nm msg_standend ,
.Nm msg_display ,
.Nm msg_display_add ,
.Nm msg_printf ,
.Nm msg_prompt ,
.Nm msg_prompt_add ,
.Nm msg_prompt_win ,
.Nm msg_prompt_noecho ,
.Nm msg_row ,
.Nm msg_table_add
.Nd simple message list compiler
.Sh SYNOPSIS
msgc
.Op Fl o Ar name
.Ar file
.Pp
.Fd #include \&"msg_defs.h"
.Ft void
.Fn msg_window "WINDOW *window"
.Ft const char *
.Fn msg_string "msg msg_no"
.Ft void
.Fn msg_clear "void"
.Ft void
.Fn msg_standout "void"
.Ft void
.Fn msg_standend "void"
.Ft void
.Fn msg_display "msg msg_no" ...
.Ft void
.Fn msg_display_add "msg msg_no" ...
.Ft void
.Fn msg_printf "fmt" ...
.Ft void
.Fn msg_prompt "msg msg_no" "const char *def" "char *val" "int max_chars" ...
.Ft void
.Fn msg_prompt_add "msg msg_no" "const char *def" "char *val" "int max_chars" ...
.Ft void
.Fn msg_prompt_win "msg msg_no" "WINDOW *win" "const char *def" "char *val" "int max_chars" ...
.Ft void
.Fn msg_prompt_noecho "msg msg_no" "const char *def" "char *val" "int max_chars" ...
.Ft int
.Fn msg_row "void"
.Ft void
.Fn msg_table_add "msg msg_no" ...
.Sh DESCRIPTION
This implements a curses based message display system.
A source file that lists messages with associated names is given to
.Nm
and produces both a .c and a .h file that implement the menu system.
The standard root name of the files is
.Pa msg_defs .
The
.Fl o Ar name
can be used to specify a different root name.
.Sh ENVIRONMENT
.Bl -tag -width MSGDEF
.It Ev MSGDEF
Can be set to point to a different set of
definition files for
.Nm msgc .
The current location defaults to
.Pa /usr/share/misc .
.El
.Sh FILES
.Bl -item
.It
.Pa /usr/share/misc/msg_sys.def
.El
.Sh SOURCE DESCRIPTION
The format is very simple.
Each message is started with the word
.Sq message
followed by the name of the message.
The body of the message is next and is started by a { and closed by a }.
The braces are not part of the message.
Everything, including newlines between the braces are part of the message.
.Sh MESSAGE FUNCTIONS
The defined messages are used through calls routines that manipulate
the messages.
You first need to set the
.Xr curses 3
environment up and then tell the message system which window to use
for displaying message by calling the function
.Fn msg_window .
.Pp
All variable argument lists in the functions are used as
are arguments to
.Xr sprintf 3 .
The messages may have
.Xr sprintf 3
conversions in them and the corresponding parameters should match.
Messages are identified by name using the notation
.Sq MSG_name
where
.Dq name
is the name in the message source file.
(The definitions are accessed by including the generated .h file into a
source file wanting to use the message routines.)
.Pp
The function
.Fn msg_string
just returns a pointer to the actual message string.
The functions
.Fn msg_clear ,
.Fn msg_standout
and
.Fn msg_standend
respectively clear the message window, set standout mode and clear standout
mode.
.Pp
The functions
.Fn msg_display
and
.Fn msg_display_add
cause a defined message to be displayed in the message window and does
the requested conversions before printing.
The difference is that
.Fn msg_display
clears the window before displaying the message.
These functions fill paragraphs for readability.
The
.Fn msg_table_add
function behaves like
.Fn msg_display_add
but does not fill text.
.Pp
The function
.Fn msg_printf
allows to display a raw message without going through the message catalog.
.Pp
The remaining functions deal with a prompt facility.
A prompt message is either taken from the message directory or from a
given string.
The message is processed with
.Xr sprintf 3
and then displayed.
If the parameter
.Ar def
is
.No non- Ns Dv NULL
and not a string of zero length, a default value is printed
in brackets.
The user is allowed to type in a response.
If the user types just the newline character, the default is returned
in the value.
The parameter
.Ar max_chars
is the length of the parameter
.Ar val ,
where the results are stored.
The parameters
.Ar def
and
.Ar val
may point to the same character array.
If the default is chosen, the character array is not changed.
The functions
.Fn msg_echo
and
.Fn msg_noecho
control whether the prompt routine echo or don't echo the input that
is typed by the user.
.Pp
.Fn msg_prompt_win
uses the specified curses window instead of the default one.
.Pp
.Fn msg_row
return the current row - i.e.: getcury(msg_win) + getbegy(msg_win).
.Sh AUTHORS
Philip A. Nelson for Piermont Information Systems Inc.

213
usr.bin/msgc/msgdb.c Normal file
View file

@ -0,0 +1,213 @@
/* $NetBSD: msgdb.c,v 1.23 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* mdb.c - message database manipulation */
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: msgdb.c,v 1.23 2012/03/06 16:26:01 mbalmer Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "defs.h"
#include "pathnames.h"
static struct id_rec *head = NULL, *tail = NULL;
static int msg_no = 1;
void define_msg (char *name, char *value)
{
struct id_rec *tmp = (struct id_rec *)malloc(sizeof(struct id_rec));
if (find_id (root, name))
yyerror ("%s is defined twice", name);
tmp->id = name;
tmp->msg = value;
tmp->msg_no = msg_no++;
tmp->next = NULL;
if (tail == NULL)
head = tail = tmp;
else {
tail->next = tmp;
tail = tmp;
}
insert_id (&root, tmp);
}
static void write_str (FILE *f, char *str)
{
(void)fprintf (f, "\"");
while (*str) {
if (*str == '\n')
(void) fprintf (f, "\\n\"\n\""), str++;
else if (*str == '"')
(void) fprintf (f, "\\\""), str++;
else
(void) fprintf (f, "%c", *str++);
}
(void)fprintf (f, "\",");
}
/* Write out the msg files. */
void
write_msg_file ()
{
FILE *out_file;
FILE *sys_file;
char hname[1024];
char cname[1024];
char sname[1024];
char *sys_prefix;
int nlen;
int ch;
struct id_rec *t;
/* Generate file names */
snprintf (hname, 1024, "%s.h", out_name);
nlen = strlen(hname);
if (hname[nlen-2] != '.' || hname[nlen-1] != 'h') {
(void) fprintf (stderr, "%s: name `%s` too long.\n",
prog_name, out_name);
exit(1);
}
snprintf (cname, 1024, "%s.c", out_name);
/* Open the msg_sys file first. */
sys_prefix = getenv ("MSGDEF");
if (sys_prefix == NULL)
sys_prefix = _PATH_DEFSYSPREFIX;
snprintf (sname, 1024, "%s/%s", sys_prefix, sys_name);
sys_file = fopen (sname, "r");
if (sys_file == NULL) {
(void) fprintf (stderr, "%s: could not open %s.\n",
prog_name, sname);
exit (1);
}
/* Output the .h file first. */
out_file = fopen (hname, "w");
if (out_file == NULL) {
(void) fprintf (stderr, "%s: could not open %s.\n",
prog_name, hname);
exit (1);
}
/* Write it */
(void) fprintf (out_file, "%s",
"/* msg system definitions. */\n"
"\n"
"#ifndef MSG_DEFS_H\n"
"#define MSG_DEFS_H\n"
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <unistd.h>\n"
"#include <fcntl.h>\n"
"#include <string.h>\n"
"#include <ctype.h>\n"
"#include <stdarg.h>\n"
"#include <stdint.h>\n"
"#include <curses.h>\n"
"#include <sys/mman.h>\n"
"\n"
"typedef const char *msg;\n"
"\n"
"/* Prototypes */\n"
"WINDOW *msg_window(WINDOW *window);\n"
"const char *msg_string(msg msg_no);\n"
"int msg_file(const char *);\n"
"void msg_clear(void);\n"
"void msg_standout(void);\n"
"void msg_standend(void);\n"
"void msg_display(msg msg_no,...);\n"
"void msg_display_add(msg msg_no,...);\n"
"void msg_printf(const char *fmt, ...) __printflike(1, 2);\n"
"void msg_prompt (msg msg_no, const char *def,"
" char *val, size_t max_chars, ...);\n"
"void msg_prompt_add (msg msg_no, const char *def,"
" char *val, size_t max_chars, ...);\n"
"void msg_prompt_noecho (msg msg_no, const char *def,"
" char *val, size_t max_chars, ...);\n"
"void msg_prompt_win (msg, int, int, int, int,"
" const char *, char *, size_t, ...);\n"
"void msg_table_add(msg msg_no,...);\n"
"int msg_row(void);\n"
"\n"
"/* Message names */\n"
);
(void) fprintf (out_file, "#define MSG_NONE\tNULL\n");
for (t=head; t != NULL; t = t->next) {
(void) fprintf (out_file, "#define MSG_%s\t((msg)(long)%d)\n",
t->id, t->msg_no);
}
(void) fprintf (out_file, "\n#endif\n");
fclose (out_file);
/* Now the C file */
out_file = fopen (cname, "w");
if (out_file == NULL) {
(void) fprintf (stderr, "%s: could not open %s.\n",
prog_name, cname);
exit (1);
}
/* hfile include ... */
(void)fprintf (out_file, "#include \"%s\"\n", hname);
/* msg_list */
(void)fprintf (out_file, "const char *msg_list[] = {\nNULL,\n");
for (t=head ; t != NULL; t = t->next)
write_str (out_file, t->msg);
(void)fprintf (out_file, "NULL};\n");
/* sys file out! */
while ((ch = fgetc(sys_file)) != EOF)
fputc(ch, out_file);
fclose (out_file);
fclose (sys_file);
}

56
usr.bin/msgc/msgdb.h Normal file
View file

@ -0,0 +1,56 @@
/* $NetBSD: msgdb.h,v 1.3 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* mdb.h - definitions for the msg database. */
#ifndef MSGDB_H
#define MSGDB_H
/* Definition for a list of messages. */
typedef struct id_rec {
char *id;
/* For the balanced tree. */
short balance;
struct id_rec *left, *right;
/* For the list of messages. */
struct id_rec *next;
char *msg;
int msg_no;
} id_rec;
#endif

105
usr.bin/msgc/msgmain.c Normal file
View file

@ -0,0 +1,105 @@
/* $NetBSD: msgmain.c,v 1.9 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* main.c - main program */
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: msgmain.c,v 1.9 2012/03/06 16:26:01 mbalmer Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define MAIN
#include "defs.h"
/* Local prototypes */
void usage (char *);
int
main (int argc, char **argv)
{
int ch;
prog_name = argv[0];
/* Process the arguments. */
while ( (ch = getopt (argc, argv, "o:")) != -1 ) {
switch (ch) {
case 'o': /* output file name */
out_name = optarg;
break;
default:
usage (prog_name);
}
}
if (optind != argc-1)
usage (prog_name);
src_name = argv[optind];
yyin = fopen (src_name, "r");
if (yyin == NULL) {
(void) fprintf (stderr, "%s: could not open %s.\n",
prog_name, src_name);
exit (1);
}
/* Do the parse */
(void) yyparse ();
if (had_errors)
return 1;
write_msg_file();
return 0;
}
void
usage (char *prog)
{
(void) fprintf (stderr, "%s [-o name] file\n", prog);
exit (1);
}

66
usr.bin/msgc/msgparse.y Normal file
View file

@ -0,0 +1,66 @@
/* $NetBSD: msgparse.y,v 1.5 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
%{
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: msgparse.y,v 1.5 2012/03/06 16:26:01 mbalmer Exp $");
#endif
#include "defs.h"
%}
%union {
char *s_value;
}
%token MESSAGE
%token <s_value> NAME VALUE
%start list
%%
list : /* empty */
| list msg
;
msg : MESSAGE NAME VALUE
{ define_msg ($2, $3); }

131
usr.bin/msgc/msgscan.l Normal file
View file

@ -0,0 +1,131 @@
/* $NetBSD: msgscan.l,v 1.7 2012/03/06 16:26:01 mbalmer Exp $ */
/*
* Copyright 1997 Piermont Information Systems Inc.
* All rights reserved.
*
* Written by Philip A. Nelson for Piermont Information Systems Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Piermont Information Systems Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
%{
/* scan.l: scanner description for message compiler. */
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: msgscan.l,v 1.7 2012/03/06 16:26:01 mbalmer Exp $");
#endif
#include <stdio.h>
#include <string.h>
#include "defs.h"
#include "msgparse.h"
static int level; /* For nested comments. */
%}
%x COMMENT
%x BRACE
%option noinput
%%
[ \t]+ { /* ignore spaces and tabs */ }
[\n] { line_no++; }
";" { return (int)yytext[0]; }
message { return MESSAGE; }
[a-zA-Z][a-zA-Z0-9_]* {
yylval.s_value = strdup(yytext);
return(NAME);
}
"/*" { level = 1; BEGIN COMMENT; }
<COMMENT>"/*" { level++; }
<COMMENT>"*/" { if (level-- == 1) BEGIN 0; }
<COMMENT>"\n" { line_no++; }
<COMMENT><<EOF>> { yyerror ("EOF inside a comment."); exit (1); }
<COMMENT>. {/* eat character */}
"{" { level = 1; BEGIN BRACE; }
<BRACE>"\\{" { buff_add_ch('{'); }
<BRACE>"\\}" { buff_add_ch('}'); }
<BRACE>"{" { buff_add_ch(yytext[0]); level++; }
<BRACE>"}" { if (level-- == 1) {
BEGIN 0;
yylval.s_value = buff_copy();
return VALUE;
} else
buff_add_ch (yytext[0]);
}
<BRACE>"\n" { buff_add_ch (yytext[0]); line_no++; }
<BRACE>. { buff_add_ch (yytext[0]); }
. {
if (yytext[0] < ' ')
yyerror ("illegal character: ^%c",yytext[0] + '@');
else
if (yytext[0] > '~')
yyerror ("illegal character: \\%3d", (int) yytext[0]);
else
yyerror ("illegal character: %s",yytext);
/* To quiet the compiler */
if (0) unput(0);
}
%%
#ifdef SCAN
YYSTYPE yylval;
main()
{
int val;
line_no = 1;
while ( (val = yylex()) != 0 )
printf ("val = %d\n yytext = %s\n", val, yytext);
}
#endif

5
usr.bin/msgc/pathnames.h Normal file
View file

@ -0,0 +1,5 @@
/* $NetBSD: pathnames.h,v 1.1 2001/10/15 22:11:12 bjh21 Exp $ */
#ifndef _PATH_DEFSYSPREFIX
#define _PATH_DEFSYSPREFIX "/usr/share/misc"
#endif