From d44a5ed1c177718aebe860f2bd736ea12fb19804 Mon Sep 17 00:00:00 2001 From: Thomas Cort Date: Wed, 6 Nov 2013 10:52:33 -0500 Subject: [PATCH] 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 --- distrib/sets/lists/minix/mi | 3 + releasetools/nbsd_ports | 1 + usr.bin/Makefile | 2 +- usr.bin/msgc/Makefile | 23 ++ usr.bin/msgc/defs.h | 91 ++++++ usr.bin/msgc/msg_sys.def | 612 ++++++++++++++++++++++++++++++++++++ usr.bin/msgc/msgc.1 | 211 +++++++++++++ usr.bin/msgc/msgdb.c | 213 +++++++++++++ usr.bin/msgc/msgdb.h | 56 ++++ usr.bin/msgc/msgmain.c | 105 +++++++ usr.bin/msgc/msgparse.y | 66 ++++ usr.bin/msgc/msgscan.l | 131 ++++++++ usr.bin/msgc/pathnames.h | 5 + 13 files changed, 1518 insertions(+), 1 deletion(-) create mode 100644 usr.bin/msgc/Makefile create mode 100644 usr.bin/msgc/defs.h create mode 100644 usr.bin/msgc/msg_sys.def create mode 100644 usr.bin/msgc/msgc.1 create mode 100644 usr.bin/msgc/msgdb.c create mode 100644 usr.bin/msgc/msgdb.h create mode 100644 usr.bin/msgc/msgmain.c create mode 100644 usr.bin/msgc/msgparse.y create mode 100644 usr.bin/msgc/msgscan.l create mode 100644 usr.bin/msgc/pathnames.h diff --git a/distrib/sets/lists/minix/mi b/distrib/sets/lists/minix/mi index 17cbcb62f..5e197e485 100644 --- a/distrib/sets/lists/minix/mi +++ b/distrib/sets/lists/minix/mi @@ -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 diff --git a/releasetools/nbsd_ports b/releasetools/nbsd_ports index fbe0e5349..b2099498b 100644 --- a/releasetools/nbsd_ports +++ b/releasetools/nbsd_ports @@ -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 diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 983e398e8..e468a1797 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -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 \ diff --git a/usr.bin/msgc/Makefile b/usr.bin/msgc/Makefile new file mode 100644 index 000000000..770e94ba6 --- /dev/null +++ b/usr.bin/msgc/Makefile @@ -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 + +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 diff --git a/usr.bin/msgc/defs.h b/usr.bin/msgc/defs.h new file mode 100644 index 000000000..dbbf57feb --- /dev/null +++ b/usr.bin/msgc/defs.h @@ -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 +#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); diff --git a/usr.bin/msgc/msg_sys.def b/usr.bin/msgc/msg_sys.def new file mode 100644 index 000000000..f6bb95261 --- /dev/null +++ b/usr.bin/msgc/msg_sys.def @@ -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); +} diff --git a/usr.bin/msgc/msgc.1 b/usr.bin/msgc/msgc.1 new file mode 100644 index 000000000..9e47cdbcc --- /dev/null +++ b/usr.bin/msgc/msgc.1 @@ -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. diff --git a/usr.bin/msgc/msgdb.c b/usr.bin/msgc/msgdb.c new file mode 100644 index 000000000..024145e2d --- /dev/null +++ b/usr.bin/msgc/msgdb.c @@ -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 + +#if defined(__RCSID) && !defined(lint) +__RCSID("$NetBSD: msgdb.c,v 1.23 2012/03/06 16:26:01 mbalmer Exp $"); +#endif + + +#include +#include +#include + +#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 \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \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); +} diff --git a/usr.bin/msgc/msgdb.h b/usr.bin/msgc/msgdb.h new file mode 100644 index 000000000..f983ad22c --- /dev/null +++ b/usr.bin/msgc/msgdb.h @@ -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 diff --git a/usr.bin/msgc/msgmain.c b/usr.bin/msgc/msgmain.c new file mode 100644 index 000000000..83daf872e --- /dev/null +++ b/usr.bin/msgc/msgmain.c @@ -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 + +#if defined(__RCSID) && !defined(lint) +__RCSID("$NetBSD: msgmain.c,v 1.9 2012/03/06 16:26:01 mbalmer Exp $"); +#endif + + +#include +#include +#include + +#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); +} diff --git a/usr.bin/msgc/msgparse.y b/usr.bin/msgc/msgparse.y new file mode 100644 index 000000000..722fdc543 --- /dev/null +++ b/usr.bin/msgc/msgparse.y @@ -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 + +#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 NAME VALUE + +%start list + +%% + +list : /* empty */ + | list msg + ; + + +msg : MESSAGE NAME VALUE + { define_msg ($2, $3); } diff --git a/usr.bin/msgc/msgscan.l b/usr.bin/msgc/msgscan.l new file mode 100644 index 000000000..a9aa31d4c --- /dev/null +++ b/usr.bin/msgc/msgscan.l @@ -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 + +#if defined(__RCSID) && !defined(lint) +__RCSID("$NetBSD: msgscan.l,v 1.7 2012/03/06 16:26:01 mbalmer Exp $"); +#endif + + +#include +#include +#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; } + +"/*" { level++; } + +"*/" { if (level-- == 1) BEGIN 0; } + +"\n" { line_no++; } + +<> { yyerror ("EOF inside a comment."); exit (1); } + +. {/* eat character */} + +"{" { level = 1; BEGIN BRACE; } + +"\\{" { buff_add_ch('{'); } + +"\\}" { buff_add_ch('}'); } + +"{" { buff_add_ch(yytext[0]); level++; } + +"}" { if (level-- == 1) { + BEGIN 0; + yylval.s_value = buff_copy(); + return VALUE; + } else + buff_add_ch (yytext[0]); + } + +"\n" { buff_add_ch (yytext[0]); line_no++; } + +. { 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 diff --git a/usr.bin/msgc/pathnames.h b/usr.bin/msgc/pathnames.h new file mode 100644 index 000000000..6316d78d1 --- /dev/null +++ b/usr.bin/msgc/pathnames.h @@ -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