From 2ce4f2ee4de62d1c75215751f3e1d86bf799c3c3 Mon Sep 17 00:00:00 2001 From: navichok26 Date: Tue, 16 Nov 2021 09:37:50 +0000 Subject: [PATCH] add man2html program git-svn-id: svn://kolibrios.org@9278 a494cfbc-eb01-0410-851d-a64ba20cac60 --- data/common/utils/MAN2HTML | Bin 0 -> 57141 bytes programs/other/man2html/Makefile | 13 + programs/other/man2html/Makefile.kos | 15 + programs/other/man2html/README | 91 + programs/other/man2html/abbrev.c | 62 + programs/other/man2html/cgibase.c | 123 + programs/other/man2html/defs.h | 43 + programs/other/man2html/man2html.c | 3230 ++++++++++++++++++++++++++ programs/other/man2html/strdefs.c | 176 ++ 9 files changed, 3753 insertions(+) create mode 100644 data/common/utils/MAN2HTML create mode 100644 programs/other/man2html/Makefile create mode 100644 programs/other/man2html/Makefile.kos create mode 100644 programs/other/man2html/README create mode 100644 programs/other/man2html/abbrev.c create mode 100644 programs/other/man2html/cgibase.c create mode 100644 programs/other/man2html/defs.h create mode 100644 programs/other/man2html/man2html.c create mode 100644 programs/other/man2html/strdefs.c diff --git a/data/common/utils/MAN2HTML b/data/common/utils/MAN2HTML new file mode 100644 index 0000000000000000000000000000000000000000..526314df0aaffc5f1a09f029b7e19d6404bada7f GIT binary patch literal 57141 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 QmB9Z>;D06X|FH!A4;667Q~&?~ literal 0 HcmV?d00001 diff --git a/programs/other/man2html/Makefile b/programs/other/man2html/Makefile new file mode 100644 index 0000000000..6514eff48d --- /dev/null +++ b/programs/other/man2html/Makefile @@ -0,0 +1,13 @@ +CC = gcc +NAME = man2html + +CFLAGS = -DNOCGI + +SRC = man2html.c cgibase.c abbrev.c strdefs.c + +$(NAME): $(SRC) + $(CC) $(SRC) -o $(NAME) + +clean: + rm -f $(NAME) + diff --git a/programs/other/man2html/Makefile.kos b/programs/other/man2html/Makefile.kos new file mode 100644 index 0000000000..9131933cf4 --- /dev/null +++ b/programs/other/man2html/Makefile.kos @@ -0,0 +1,15 @@ +TCC = /kolibrios/develop/tcc/tcc + +NAME = man2html + +SRC = man2html.c cgibase.c abbrev.c strdefs.c + +CFLAGS = -D_KOLIBRI -DNOCGI +LIBS = -ltcc -lc.obj + +all: + $(KTCC) $(CFLAGS) $(SRC) $(LIBS) -o $(NAME) + + +clean: + rm $(NAME) diff --git a/programs/other/man2html/README b/programs/other/man2html/README new file mode 100644 index 0000000000..21c3125d41 --- /dev/null +++ b/programs/other/man2html/README @@ -0,0 +1,91 @@ +This directory contains the following. + +1. man2html + +This is a pure manroff -> html converter. +No manpath search etc. + +Call: man2html [-l | -H host.domain:port] [filename] + +The contents of FILENAME (or STDIN, in case FILENAME is "-" or absent) +are converted from man-style nroff to html, and printed on STDOUT. + +With "-l" URLs of the form "lynxcgi:/home/httpd/cgi-bin/..." are generated. +With "-H host" we make URLs of the form "http://host/cgi-bin/...". +The default is "http://localhost/cgi-bin/...". + +2. A collection of scripts + +This part is not installed by "make install" of the global Makefile. +There are security considerations: it is very unlikely that these +scripts (still in alpha) are secure, so for the time being they +should only be used where security is not a major concern. + +If you are not afraid, or are not running a httpd, do +"make install-scripts" in this directory. +This does three things: install man stuff, install glimpse stuff, +and install user interface stuff. + +2A. man stuff + +This first part (that can be done separately with "make install-man-scripts") +puts various scripts under /home/httpd/cgi-bin and /home/httpd/cgi-aux +in a subdirectory man. +It will create a directory /var/man2html to hold the indices. +(This directory should be writable by the cgi scripts; +probably that means that the owner should be nobody. +Choose a group and add all non-httpd users that should be +able to write this directory to that group.) + +Structure of the collection of scripts: + man2html is the main script. + It uses man.aux when called without arguments. + It uses manwhatis when asked for an index of manpages+descriptions. + It uses mansec when asked for a compact index of manpages. + It uses mansearch when asked for a glimpse search. + In its turn mansearch uses mansearch.aux when called + without arguments. It uses mansearchhelp (which uses + mansearchhelp.aux) when asked for help. + +2B. glimpse stuff +The second part (that can be done separately with +"make install-glimpse-stuff") installs .glimpse_filters +in /var/man2html, in order to tell glimpse what decompressors to use. + +2C. user interface stuff +The third part (that can be done separately with "make install-hman") +installs a user interface to these scripts in /usr/bin/hman. +Now people can say + alias man=/usr/bin/hman +and have a man that uses a html browser. +The browser is chosen via environment variables - look at the script. + +3. Glimpse. + +For the glimpse part, I quote Michael Hamilton: +---------------------------------------------------------------------- +To use the Glimpse full text searching, you will need to install +glimpse in /usr/bin. Redhat rpm users can get glimpse from + + ftp://ftp.redhat.com/pub/contrib/i386/glimpse-4.0-6.i386.rpm + +The glimpse home ftp site is cs.arizona.edu. N.B. glimpse is not +freely redistributable for commercial use, I'd be very interested in a +more liberal alternative. Having installed glimpse, you will need to +build a glimpse index in /var/man2html. This doesn't take too long - +about 3 minutes on my 486DX2/66 16MB machine. As root do: + + /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man* /usr/X11R6/man/man* \ + /usr/local/man/man* /opt/man/man* + chmod ugo+r /var/man2html/.glimpse* + +The -z option causes glimpse to apply any filters (for decompression etc) +specified in /var/man2html/.glimpse_filters. + +This could be set up as a cron job in /etc/crontab, e.g. (the following +must be all on one line): + + 21 04 * * 1 root /usr/bin/glimpseindex -z -H /var/man2html /usr/man/man* + /usr/X11R6/man/man* /usr/local/man/man* /opt/man/man* ; + chmod +r /var/man2html/.glimpse* +-------------------------------------------------------------------------- diff --git a/programs/other/man2html/abbrev.c b/programs/other/man2html/abbrev.c new file mode 100644 index 0000000000..5480d6ac5e --- /dev/null +++ b/programs/other/man2html/abbrev.c @@ -0,0 +1,62 @@ +#include +#include "defs.h" +/* + * lookup_abbrev() is used for TX macros - is that + * something SUN-specific? + */ + +char *abbrev_list[] = { + "GSBG", "Getting Started ", + "SUBG", "Customizing SunOS", + "SHBG", "Basic Troubleshooting", + "SVBG", "SunView User's Guide", + "MMBG", "Mail and Messages", + "DMBG", "Doing More with SunOS", + "UNBG", "Using the Network", + "GDBG", "Games, Demos & Other Pursuits", + "CHANGE", "SunOS 4.1 Release Manual", + "INSTALL", "Installing SunOS 4.1", + "ADMIN", "System and Network Administration", + "SECUR", "Security Features Guide", + "PROM", "PROM User's Manual", + "DIAG", "Sun System Diagnostics", + "SUNDIAG", "Sundiag User's Guide", + "MANPAGES", "SunOS Reference Manual", + "REFMAN", "SunOS Reference Manual", + "SSI", "Sun System Introduction", + "SSO", "System Services Overview", + "TEXT", "Editing Text Files", + "DOCS", "Formatting Documents", + "TROFF", "Using nroff and troff", + "INDEX", "Global Index", + "CPG", "C Programmer's Guide", + "CREF", "C Reference Manual", + "ASSY", "Assembly Language Reference", + "PUL", "Programming Utilities and Libraries", + "DEBUG", "Debugging Tools", + "NETP", "Network Programming", + "DRIVER", "Writing Device Drivers", + "STREAMS", "STREAMS Programming", + "SBDK", "SBus Developer's Kit", + "WDDS", "Writing Device Drivers for the SBus", + "FPOINT", "Floating-Point Programmer's Guide", + "SVPG", "SunView 1 Programmer's Guide", + "SVSPG", "SunView 1 System Programmer's Guide", + "PIXRCT", "Pixrect Reference Manual", + "CGI", "SunCGI Reference Manual", + "CORE", "SunCore Reference Manual", + "4ASSY", "Sun-4 Assembly Language Reference", + "SARCH", "SPARC Architecture Manual", + "KR", "The C Programming Language", + 0, 0 }; + +char *lookup_abbrev (char *s) +{ + int i=0; + + if (!s) + return ""; + while (abbrev_list[i] && strcmp(s, abbrev_list[i])) + i = i+2; + return abbrev_list[i] ? abbrev_list[i+1] : s; +} diff --git a/programs/other/man2html/cgibase.c b/programs/other/man2html/cgibase.c new file mode 100644 index 0000000000..1b44d86660 --- /dev/null +++ b/programs/other/man2html/cgibase.c @@ -0,0 +1,123 @@ +/* + * Here are the routines of man2html that output a HREF string. + */ + +#include +#include +#include +#include /* tolower() */ +#include /* strlen() */ +#include "defs.h" + +/* + * The default is to use cgibase. With relative html style + * we generate URLs of the form "../manX/page.html". + */ +static int relat_html_style = 0; + +/* + * The default is to use cgibase. With current html style + * we generate URLs of the form "./page.html". + */ +static int current_html_style = 0; + +/* + * Either the user is non-local (or local, but using httpd), + * in which case we use http:/cgi-bin, or the user is local + * and uses lynx, and we use lynxcgi:/home/httpd/cgi-bin. + */ + +static char *man2htmlpath = "/cgi-bin/man/man2html"; /* default */ +static char *cgibase_format = "http://%s"; /* host.domain:port */ +static char *cgibase_ll_format = "lynxcgi:%s"; /* directory */ +static char *cgibase = "http://localhost"; /* default */ + +/* + * Separator between URL and argument string. + * + * With http:/a/b?c+d+e the script is called + * with PATH_INFO=/a/b and QUERY_STRING=c+d+e and args $1=c, $2=d, $3=e. + * With lynxcgi:?c+d+e no PATH_INFO is possible. + */ +static char sep = '?'; /* or '/' */ + +/* What shall we say in case of relat_html_style? */ +static char *signature = "
\n" +"This document was created by\n" +"man2html,\n" +"using the manual pages.
\n" +"%s\n"; + +#define TIMEFORMAT "%T GMT, %B %d, %Y" +#define TIMEBUFSZ 500 + +void print_sig() +{ + char timebuf[TIMEBUFSZ]; + struct tm *timetm; + time_t clock; + + timebuf[0] = 0; +#ifdef TIMEFORMAT + sprintf(timebuf, "Time: "); + clock=time(NULL); + timetm=localtime(&clock); + snprintf(timebuf, TIMEBUFSZ, "%s%s", timebuf, asctime(timetm)); + timebuf[TIMEBUFSZ-1] = 0; +#endif + fprintf(out, signature, timebuf); +} + +void +include_file_html(char *g) { + fprintf(out, "%s>", g,g); +} + +void +man_page_html(char *sec, char *h) { + if (current_html_style) { + if (!h) + fprintf(out, "" + "Return to Main Contents"); + else + fprintf(out, "%s", + h, h); + } else if (relat_html_style) { + if (!h) + fprintf(out, "" + "Return to Main Contents"); + else + fprintf(out, "%s", + sec, h, sec, h); + } else { + if (!h) + fprintf(out, "Return to Main Contents", + cgibase, man2htmlpath); + else if (!sec) + fprintf(out, "%s", + cgibase, man2htmlpath, sep, h, h); + else + fprintf(out, "%s", + cgibase, man2htmlpath, sep, sec, h, h); + } +} + +void +ftp_html(char *f) { + fprintf(out, "%s", f, f); +} + +void +www_html(char *f) { + fprintf(out, "%s", f, f); +} + +void +mailto_html(char *g) { + fprintf(out, "%s", g, g); +} + +void +url_html(char *g) { + fprintf(out, "%s", g, g); +} diff --git a/programs/other/man2html/defs.h b/programs/other/man2html/defs.h new file mode 100644 index 0000000000..f2dd61e379 --- /dev/null +++ b/programs/other/man2html/defs.h @@ -0,0 +1,43 @@ +#ifndef DEFS_H +#define DEFS_H +#include +#include + +extern FILE *out; + +extern int nroff; +extern int local_lynx; + +typedef struct STRDEF STRDEF; +struct STRDEF { + int nr,slen; + char *st; + STRDEF *next; +}; + +typedef struct INTDEF INTDEF; +struct INTDEF { + int nr; + int val; + int incr; + INTDEF *next; +}; + +extern STRDEF *chardef, *strdef, *defdef; +extern INTDEF *intdef; + +#define V(A,B) ((A)*256+(B)) + +extern void stdinit(void); +extern void print_sig(void); +extern char *lookup_abbrev(char *); +extern void include_file_html(char *); +extern void man_page_html(char*, char *); +extern void ftp_html(char *); +extern void www_html(char *); +extern void mailto_html(char *); +extern void url_html(char *); +extern void *xmalloc(size_t size); +extern void *xrealloc(void *ptr, size_t size); +extern char *xstrdup(const char *s); +#endif \ No newline at end of file diff --git a/programs/other/man2html/man2html.c b/programs/other/man2html/man2html.c new file mode 100644 index 0000000000..f609ca5bfb --- /dev/null +++ b/programs/other/man2html/man2html.c @@ -0,0 +1,3230 @@ +/* +** This program was written by Richard Verhoeven (NL:5482ZX35) +** at the Eindhoven University of Technology. Email: rcb5@win.tue.nl +** +** Permission is granted to distribute, modify and use this program +** as long as this comment is not removed or changed. +*/ + +/* BSD mandoc stuff added by Michael Hamilton. */ + +/* This program is rather buggy, but in spite of that it often works. + Improved things a little - April 1997 & January 1998 & Dec 2001 - + aeb@cwi.nl. */ + +/* some code added by Tsukasa Hamnao. */ + +#include +#include +#include +#include + +#ifdef _KOLIBRI +#include +#include +#else +#include +#include +#endif + +#include "defs.h" +static char version[] = "1.6f-1"; + +/* BSD mandoc Bd/Ed example(?) blocks */ +#define BD_LITERAL 1 +#define BD_INDENT 2 + +#define SIZE(a) (sizeof(a)/sizeof(*a)) + +static char NEWLINE[2]="\n"; +static char idxlabel[6] = "ixAAA"; + +#ifdef _KOLIBRI + #define INDEXFILE "/tmp0/1/manindex.list" +#else + #define INDEXFILE "./manindex.list" +#endif + +char *fname; +char *directory; +FILE *idxfile; + +char eqndelimopen=0, eqndelimclose=0; +char escapesym='\\', nobreaksym='\'', controlsym='.', fieldsym=0, padsym=0; + +char *buffer=NULL; +int buffpos=0, buffmax=0; +int scaninbuff=0; +int still_dd=0; +int tabstops[20] = { 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96 }; +int maxtstop=12; +int curpos=0; + +static char *scan_troff(char *c, int san, char **result); +static char *scan_troff_mandoc(char *c, int san, char **result); + +static char **argument=NULL; + +static char charb[3]; + +FILE *out; + +static char * +expand_char(int nr) +{ + STRDEF *h; + + if (!nr) + return NULL; + + h = chardef; + if (h->nr != V('*','*')) { + fprintf(out, "chardef corrupted\n"); + exit(1); + } + + for (h = chardef; h; h = h->next) + if (h->nr == nr) { + curpos += h->slen; + return h->st; + } + charb[0] = nr/256; + charb[1] = nr%256; + charb[2] = 0; + curpos += 2; + return charb; +} + +static char * +expand_string(int nr) +{ + STRDEF *h; + + if (!nr) + return NULL; + for (h = strdef; h; h = h->next) + if (h->nr == nr) { + curpos += h->slen; + return h->st; + } + return NULL; +} + + +static char outbuffer[1024]; +static int obp=0; +static int no_newline_output=0; /* boolean, set by \c */ +static int newline_for_fun=0; +static int output_possible=0; +static int out_length=0; + +static void +add_links(char *c) +{ + /* + ** Add the links to the output. + ** At the moment the following are recognized: + ** + ** name(*) -> ../man?/name.* + ** method://string -> method://string + ** www.host.name -> http://www.host.name + ** ftp.host.name -> ftp://ftp.host.name + ** name@host -> mailto:name@host + ** -> file:/usr/include/name.h (guess) + ** + ** Other possible links to add in the future: + ** + ** /dir/dir/file -> file:/dir/dir/file + */ + int i,j,nr; + char *f, *g, *h; + char *idtest[6]; /* url, mailto, www, ftp, manpage, include file */ + + out_length+=strlen(c); + + nr=0; + idtest[0]=strstr(c+1,"://"); + /* idtest[1]=strchr(c+1,'@'); */ + idtest[1]=NULL; /* don't create mailto links. */ + idtest[2]=strstr(c,"www."); + idtest[3]=strstr(c,"ftp."); + idtest[4]=strchr(c+1,'('); + idtest[5]=strstr(c+1,".h>"); + for (i=0; i<6; i++) nr += (idtest[i]!=NULL); + while (nr) { + j=-1; + for (i=0; i<6; i++) + if (idtest[i] && (j<0 || idtest[i] */ + f=idtest[5]; + h=f+2; + g=f; + while (g>c && g[-1]!=';') g--; + if (g!=c) { + char t; + t=*g; + *g=0; + fprintf(out, "%s",c); + *g=t;*h=0; + include_file_html(g); + c=f+6; + } else { + f[5]=0; + fprintf(out, "%s",c); + f[5]=';'; + c=f+5; + } + break; + case 4: /* manpage? */ + f=idtest[j]; + /* find section - accept (1), (3F), (3Xt), (n), (l) */ + g=strchr(f,')'); + if (g && g-f<7 /* section has length at most 5, like 3Xlib */ + /* preceded by name or html markup */ + && (isalnum(f[-1]) || f[-1]=='>') + /* section is n or l or starts with a digit */ + && strchr("123456789nl", f[1]) + && (g-f == 2 || (g-f == 3 && isdigit(f[1]) && isalpha(f[2])) + || (f[2] == 'X' && isdigit(f[1]))) + ) { + /* this might be a link */ + h=f-1; + /* skip html markup */ + while (h>c && *h=='>') { + while (h!=c && *h!='<') h--; + if (h!=c) h--; + } + if (isalnum(*h)) { + char t,te,tg,*e; + e=h+1; + while (h>c && (isalnum(h[-1]) || h[-1]=='_' || + h[-1]=='-' || h[-1]=='.' || h[-1]==':')) + h--; + t=*h; *h=0; + fprintf(out, "%s", c); + *h=t; + tg=*g; *g=0; + te=*e; *e=0; + man_page_html(f+1, h); /* section, page */ + *e=te; + *g=tg; + c=e; + } + } + *f=0; + fprintf(out, "%s", c); + *f='('; + idtest[4]=f-1; + c=f; + break; /* manpage */ + case 3: /* ftp */ + case 2: /* www */ + g=f=idtest[j]; + while (*g && (isalnum(*g) || *g=='_' || *g=='-' || *g=='+' || + *g=='.')) g++; + if (g[-1]=='.') g--; + if (g-f>4) { + char t; + t=*f; *f=0; + fprintf(out, "%s",c); + *f=t; t=*g;*g=0; + if (j==3) + ftp_html(f); + else + www_html(f); + *g=t; + c=g; + } else { + f[3]=0; + fprintf(out, "%s",c); + c=f+3; + f[3]='.'; + } + break; + case 1: /* mailto */ + g=f=idtest[1]; + while (g>c && (isalnum(g[-1]) || g[-1]=='_' || g[-1]=='-' || + g[-1]=='+' || g[-1]=='.' || g[-1]=='%')) g--; + h=f+1; + while (*h && (isalnum(*h) || *h=='_' || *h=='-' || *h=='+' || + *h=='.')) h++; + if (h[-1]=='.') h--; + if (h-f>4 && f-g>1) { + char t; + t=*g; + *g=0; + fprintf(out, "%s",c); + *g=t;t=*h;*h=0; + mailto_html(g); + *h=t; + c=h; + } else { + *f=0; + fprintf(out, "%s",c); + *f='@'; + idtest[1]=c; + c=f; + } + break; + case 0: /* url */ + g=f=idtest[0]; + while (g>c && isalpha(g[-1]) && islower(g[-1])) g--; + h=f+3; + while (*h && !isspace(*h) && *h!='<' && *h!='>' && *h!='"' && + *h!='&') h++; + if (f-g>2 && f-g<7 && h-f>3) { + char t; + t=*g; + *g=0; + fprintf(out, "%s", c); + *g=t; t=*h; *h=0; + url_html(g); + *h=t; + c=h; + } else { + f[1]=0; + fprintf(out, "%s", c); + f[1]='/'; + c=f+1; + } + break; + default: + break; + } + nr=0; + if (idtest[0] && idtest[0]= buffmax) { + buffer = xrealloc(buffer, buffmax*2); + buffmax = buffmax*2; + } + if (*c != '\a') + buffer[buffpos++] = *c; + c++; + } + } else if (output_possible) { + while (*c) { + if (*c != '\a') + outbuffer[obp++] = *c; + if (*c == '\n' || obp > 1000) { + outbuffer[obp] = 0; + add_links(outbuffer); + obp = 0; + } + c++; + } + } +} + +/* --------------------------------------------------------------- */ +/* All references to dl_set and itemdepth are here. */ +/* --------------------------------------------------------------- */ +static int itemdepth=0; +static int dl_set[30]= { 0 }; +#define noDL 0 +#define DL 1 +#define UL 2 +#define OL 3 +static char *dl_open[4] = { "", "
\n", "
    ", "
      " }; +static char *dl_close[4] = { "", "
\n", "", "" }; + +static inline void +dl_begin(void) { + if (itemdepth < SIZE(dl_set) && dl_set[itemdepth] == noDL) { + out_html(dl_open[DL]); + dl_set[itemdepth]=DL; + } + out_html("
"); +} + +static inline void +dl_end(void) { + if (itemdepth < SIZE(dl_set)) { + int type = dl_set[itemdepth]; + if (type == DL) { + out_html(dl_close[type]); + dl_set[itemdepth]=noDL; + } + } +} + +static inline void +dl_newlevel(void) { + itemdepth++; + if (itemdepth < SIZE(dl_set)) + dl_set[itemdepth]=noDL; + out_html("
"); +} + +static inline void +dl_endlevel(void) { + if (itemdepth) { + dl_end(); + out_html("
\n"); + itemdepth--; + } +} + +static inline void +dl_down(void) { + while (itemdepth) + dl_endlevel(); + dl_end(); +} + +static inline int +dl_type(int type) { + return (itemdepth < SIZE(dl_set) && dl_set[itemdepth] == type); +} + +static inline void +dl_newlevel_type(int type) { + itemdepth++; + if (itemdepth < SIZE(dl_set)) { + dl_set[itemdepth]=type; + out_html(dl_open[type]); + } +} + +static inline void +dl_endlevel_type(void) { + if (itemdepth) { + if (itemdepth < SIZE(dl_set)) + out_html(dl_close[dl_set[itemdepth]]); + itemdepth--; + } +} +/* --------------------------------------------------------------- */ +/* This stuff is broken. +It generates +
TIOCLINUX, subcode=0
+ Dump the screen. + argp points to a +from + .IP "\fBTIOCLINUX, subcode=0" + Dump the screen. + \fIargp\fP points to a +Bug 1: incorrect nesting: is needed before
. +Bug 2: incorrect font: after the .IP things are roman again. +*/ + +#define FO0 "" +#define FC0 "" +#define FO1 "" +#define FC1 "" +#define FO2 "" +#define FC2 "" +#define FO3 "" +#define FC3 "" + +char *switchfont[16] = { "" , FC0 FO1, FC0 FO2, FC0 FO3, + FC1 FO0, "" , FC1 FO2, FC1 FO3, + FC2 FO0, FC2 FO1, "" , FC2 FO3, + FC3 FO0, FC3 FO1, FC3 FO2, "" }; + +static char * +change_to_font(int nr) +{ + int i; + switch (nr) { + case '0': nr++; + case '1': case '2': case '3': case '4': + nr = nr-'1'; break; + case V('C','W'): nr=3; break; + case 'L': nr=3; break; + case 'B': nr=2; break; + case 'I': nr=1; break; + case 0: case 1: case 2: case 3: + break; + case 'P': case 'R': + default: nr=0; break; + } + i= current_font*4+nr%4; + current_font=nr%4; + return switchfont[i]; +} + +static char sizebuf[200]; + +static char * +change_to_size(int nr) +{ + int i; + switch (nr) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': + case '7': case '8': case '9': nr=nr-'0'; break; + case '\0': break; + default: nr=current_size+nr; if (nr>9) nr=9; if (nr< -9) nr=-9; break; + } + if (nr==current_size) return ""; + i=current_font; + sizebuf[0]=0; + strcat(sizebuf, change_to_font(0)); + if (current_size) strcat(sizebuf, ""); + current_size=nr; + if (nr) { + int l; + strcat(sizebuf, "0) sizebuf[l++]='+'; else sizebuf[l++]='-',nr=-nr; + sizebuf[l++]=nr+'0'; + sizebuf[l++]='"'; + sizebuf[l++]='>'; + sizebuf[l]=0; + } + strcat(sizebuf, change_to_font(i)); + return sizebuf; +} + +int asint=0; +int intresult=0; + +#define SKIPEOL while (*c && *c++!='\n') + +static int skip_escape=0; +static int single_escape=0; + +static char * +scan_escape(char *c) { + char *h=NULL; + char b[5]; + INTDEF *intd; + int exoutputp,exskipescape; + int i,j; + + intresult=0; + switch (*c) { + case 'e': h="\\"; curpos++;break; + case '0': + case ' ': h=" ";curpos++; break; + case '|': h=""; break; + case '"': SKIPEOL; c--; h=""; break; + case '$': + if (argument) { + c++; + i=(*c -'1'); + if (!(h=argument[i])) h=""; + } + break; + case 'z': + c++; + if (*c=='\\') { c=scan_escape(c+1); c--;h=""; } + else { + b[0]=*c; + b[1]=0; + h=""; + } + break; + case 'k': c++; if (*c=='(') c+=2; + case '^': + case '!': + case '%': + case 'a': + case 'd': + case 'r': + case 'u': + case '\n': + case '&': h=""; break; + case '(': + c++; + i= c[0]*256+c[1]; + c++; + h = expand_char(i); + break; + case '*': + c++; + if (*c=='(') { + c++; + i= c[0]*256+c[1]; + c++; + } else + i= *c *256+' '; + h = expand_string(i); + break; + case 'f': + c++; + if (*c=='\\') { + c++; + c=scan_escape(c); + c--; + i=intresult; + } else if (*c != '(') + i=*c; + else { + c++; + i=c[0]*256+c[1]; + c++; + } + if (!skip_escape) h=change_to_font(i); else h=""; + break; + case 's': + c++; + j=0;i=0; + if (*c=='-') {j= -1; c++;} else if (*c=='+') {j=1; c++;} + if (*c=='0') c++; else if (*c=='\\') { + c++; + c=scan_escape(c); + i=intresult; if (!j) j=1; + } else + while (isdigit(*c) && (!i || (!j && i<4))) i=i*10+(*c++)-'0'; + if (!j) { j=1; if (i) i=i-10; } + if (!skip_escape) h=change_to_size(i*j); else h=""; + c--; + break; + case 'n': + c++; + j=0; + switch (*c) { + case '+': j=1; c++; break; + case '-': j=-1; c++; break; + default: break; + } + if (*c=='(') { + c++; + i=V(c[0],c[1]); + c=c+1; + } else { + i=V(c[0],' '); + } + intd=intdef; + while (intd && intd->nr!=i) intd=intd->next; + if (intd) { + intd->val=intd->val+j*intd->incr; + intresult=intd->val; + } else { + switch (i) { + case V('.','s'): intresult=current_size; break; + case V('.','f'): intresult=current_font; break; + default: intresult=0; break; + } + } + h=""; + break; + case 'w': + c++; + i=*c; + c++; + exoutputp=output_possible; + exskipescape=skip_escape; + output_possible=0; + skip_escape=1; + j=0; + while (*c!=i) { + j++; + if (*c==escapesym) c=scan_escape(c+1); else c++; + } + output_possible=exoutputp; + skip_escape=exskipescape; + intresult=j; + break; + case 'l': h="
"; curpos=0; + case 'b': + case 'v': + case 'x': + case 'o': + case 'L': + case 'h': + c++; + i=*c; + c++; + exoutputp=output_possible; + exskipescape=skip_escape; + output_possible=0; + skip_escape=1; + while (*c != i) + if (*c==escapesym) c=scan_escape(c+1); + else c++; + output_possible=exoutputp; + skip_escape=exskipescape; + break; + case 'c': no_newline_output=1; break; + case '{': newline_for_fun++; h="";break; + case '}': if (newline_for_fun) newline_for_fun--; h="";break; + case 'p': h="
\n";curpos=0; break; + case 't': h="\t";curpos=(curpos+8)&0xfff8; break; + case '<': h="<";curpos++; break; + case '>': h=">";curpos++; break; + case '\\': if (single_escape) { c--; break;} + default: b[0]=*c; b[1]=0; h=b; curpos++; break; + } + c++; + if (!skip_escape) out_html(h); + return c; +} + +typedef struct TABLEITEM TABLEITEM; + +struct TABLEITEM { + char *contents; + int size,align,valign,colspan,rowspan,font,vleft,vright,space,width; + TABLEITEM *next; +}; + +static TABLEITEM emptyfield = {NULL,0,0,0,1,1,0,0,0,0,0,NULL}; +typedef struct TABLEROW TABLEROW; + +struct TABLEROW { + TABLEITEM *first; + TABLEROW *prev, *next; +}; + +static char *tableopt[]= { "center", "expand", "box", "allbox", "doublebox", + "tab", "linesize", "delim", NULL }; +static int tableoptl[] = { 6,6,3,6,9,3,8,5,0}; + + +static void clear_table(TABLEROW *table) +{ + TABLEROW *tr1,*tr2; + TABLEITEM *ti1,*ti2; + + tr1=table; + while (tr1->prev) tr1=tr1->prev; + while (tr1) { + ti1=tr1->first; + while (ti1) { + ti2=ti1->next; + if (ti1->contents) free(ti1->contents); + free(ti1); + ti1=ti2; + } + tr2=tr1; + tr1=tr1->next; + free(tr2); + } +} + +char *scan_expression(char *c, int *result); + +static char *scan_format(char *c, TABLEROW **result, int *maxcol) +{ + TABLEROW *layout, *currow; + TABLEITEM *curfield; + int i,j; + if (*result) { + clear_table(*result); + } + layout= currow=(TABLEROW*) xmalloc(sizeof(TABLEROW)); + currow->next=currow->prev=NULL; + currow->first=curfield=(TABLEITEM*) xmalloc(sizeof(TABLEITEM)); + *curfield=emptyfield; + while (*c && *c!='.') { + switch (*c) { + case 'C': case 'c': case 'N': case 'n': + case 'R': case 'r': case 'A': case 'a': + case 'L': case 'l': case 'S': case 's': + case '^': case '_': + if (curfield->align) { + curfield->next=(TABLEITEM*)xmalloc(sizeof(TABLEITEM)); + curfield=curfield->next; + *curfield=emptyfield; + } + curfield->align=toupper(*c); + c++; + break; + case 'i': case 'I': case 'B': case 'b': + curfield->font = toupper(*c); + c++; + break; + case 'f': case 'F': + c++; + curfield->font = toupper(*c); + c++; + if (!isspace(*c)) c++; + break; + case 't': case 'T': curfield->valign='t'; c++; break; + case 'p': case 'P': + c++; + i=j=0; + if (*c=='+') { j=1; c++; } + if (*c=='-') { j=-1; c++; } + while (isdigit(*c)) i=i*10+(*c++)-'0'; + if (j) curfield->size= i*j; else curfield->size=j-10; + break; + case 'v': case 'V': + case 'w': case 'W': +// c=scan_expression(c+2,&curfield->width); + c++; + if (*c == '(') { + c=scan_expression(c+1,&curfield->width); + } else { + i=0; + while (isdigit(*c)) i=i*10+(*c++)-'0'; + curfield->width=i; + } + break; + case '|': + if (curfield->align) curfield->vleft++; + else curfield->vright++; + c++; + break; + case 'e': case 'E': + c++; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + i=0; + while (isdigit(*c)) i=i*10+(*c++)-'0'; + curfield->space=i; + break; + case ',': case '\n': + currow->next=(TABLEROW*)xmalloc(sizeof(TABLEROW)); + currow->next->prev=currow; + currow=currow->next; + currow->next=NULL; + curfield=currow->first=(TABLEITEM*)xmalloc(sizeof(TABLEITEM)); + *curfield=emptyfield; + c++; + break; + default: + c++; + break; + } + } + if (*c=='.') while (*c++!='\n'); + *maxcol=0; + currow=layout; + while (currow) { + curfield=layout->first; + i=0; + while (curfield) { + i++; + curfield=curfield->next; + } + if (i>*maxcol) *maxcol=i; + currow=currow->next; + } + *result=layout; + return c; +} + +static TABLEROW * +next_row(TABLEROW *tr) +{ + if (tr->next) { + tr=tr->next; + if (!tr->next) next_row(tr); + return tr; + } else { + TABLEITEM *ti, *ti2; + tr->next=(TABLEROW*)xmalloc(sizeof(TABLEROW)); + tr->next->prev=tr; + ti=tr->first; + tr=tr->next; + tr->next=NULL; + if (ti) tr->first=ti2=(TABLEITEM*) xmalloc(sizeof(TABLEITEM)); + else tr->first=ti2=NULL; + while (ti!=ti2) { + *ti2=*ti; + ti2->contents=NULL; + if ((ti=ti->next)) { + ti2->next=(TABLEITEM*) xmalloc(sizeof(TABLEITEM)); + } + ti2=ti2->next; + } + return tr; + } +} + +char itemreset[20]="\\fR\\s0"; + +static char * +scan_table(char *c) { + char *h; + char *g; + int center=0, expand=0, box=0, border=0, linesize=1; + int i,j,maxcol=0, finished=0; + int oldfont, oldsize,oldfillout; + char itemsep='\t'; + TABLEROW *layout=NULL, *currow; + TABLEITEM *curfield; + while (*c++!='\n'); /* skip TS */ + h=c; + if (*h=='.') return c-1; + oldfont=current_font; + oldsize=current_size; + oldfillout=fillout; + out_html(change_to_font(0)); + out_html(change_to_size(0)); + if (!fillout) { + fillout=1; + out_html(""); + } + while (*h && *h!='\n') h++; + if (h[-1]==';') { + /* scan table options */ + while (cfirst; + i=0; + while (!finished && *c) { + /* search item */ + h=c; + if ((*c=='_' || *c=='=') && (c[1]==itemsep || c[1]=='\n')) { + if (c[-1]=='\n' && c[1]=='\n') { + if (currow->prev) { + currow->prev->next=(TABLEROW*) xmalloc(sizeof(TABLEROW)); + currow->prev->next->next=currow; + currow->prev->next->prev=currow->prev; + currow->prev=currow->prev->next; + } else { + currow->prev=layout=(TABLEROW*) xmalloc(sizeof(TABLEROW)); + currow->prev->prev=NULL; + currow->prev->next=currow; + } + curfield=currow->prev->first= + (TABLEITEM*) xmalloc(sizeof(TABLEITEM)); + *curfield=emptyfield; + curfield->align=*c; + curfield->colspan=maxcol; + curfield=currow->first; + c=c+2; + } else { + if (curfield) { + curfield->align=*c; + do { + curfield=curfield->next; + } while (curfield && curfield->align=='S'); + } + if (c[1]=='\n') { + currow=next_row(currow); + curfield=currow->first; + } + c=c+2; + } + } else if (*c=='T' && c[1]=='{') { + h=c+2; + c=strstr(h,"\nT}"); + c++; + *c=0; + g=NULL; + scan_troff(h, 0, &g); + scan_troff(itemreset, 0, &g); + *c='T'; + c+=3; + if (curfield) { + curfield->contents=g; + do { + curfield=curfield->next; + } while (curfield && curfield->align=='S'); + } else + if (g) free(g); + if (c[-1]=='\n') { + currow=next_row(currow); + curfield=currow->first; + } + } else if (*c=='.' && c[1]=='T' && c[2]=='&' && c[-1]=='\n') { + TABLEROW *hr; + while (*c++!='\n'); + hr=currow; + currow=currow->prev; + hr->prev=NULL; + c=scan_format(c,&hr, &i); + hr->prev=currow; + currow->next=hr; + currow=hr; + next_row(currow); + curfield=currow->first; + } else if (*c=='.' && c[1]=='T' && c[2]=='E' && c[-1]=='\n') { + finished=1; + while (*c++!='\n'); + if (currow->prev) + currow->prev->next=NULL; + currow->prev=NULL; + clear_table(currow); + } else if (*c=='.' && c[-1]=='\n' && !isdigit(c[1])) { + /* skip troff request inside table (usually only .sp ) */ + while (*c++!='\n'); + } else { + h=c; + while (*c && (*c!=itemsep || c[-1]=='\\') && + (*c!='\n' || c[-1]=='\\')) c++; + i=0; + if (*c==itemsep) {i=1; *c='\n'; } + if (h[0]=='\\' && h[2]=='\n' && + (h[1]=='_' || h[1]=='^')) { + if (curfield) { + curfield->align=h[1]; + do { + curfield=curfield->next; + } while (curfield && curfield->align=='S'); + } + h=h+3; + } else { + g=NULL; + h=scan_troff(h,1,&g); + scan_troff(itemreset,0,&g); + if (curfield) { + curfield->contents=g; + do { + curfield=curfield->next; + } while (curfield && curfield->align=='S'); + } else if (g) free(g); + } + if (i) *c=itemsep; + c=h; + if (c[-1]=='\n') { + currow=next_row(currow); + curfield=currow->first; + } + } + } + /* calculate colspan and rowspan */ +#if 0 + currow=layout; + while (currow->next) currow=currow->next; + while (currow) { + TABLEITEM *ti, *ti1=NULL, *ti2=NULL; + ti=currow->first; + if (currow->prev) ti1=currow->prev->first; + while (ti) { + switch (ti->align) { + case 'S': + if (ti2) { + ti2->colspan++; + if (ti2->rowspanrowspan) ti2->rowspan=ti->rowspan; + } + break; + case '^': + if (ti1) ti1->rowspan++; + default: + if (!ti2) ti2=ti; + else { + do { + ti2=ti2->next; + } while (ti2 && curfield->align=='S'); + } + break; + } + ti=ti->next; + if (ti1) ti1=ti1->next; + } + currow=currow->prev; + } +#endif + /* produce html output */ + if (center) out_html("
"); + if (box==2) out_html(""); + curfield=currow->first; + while (curfield) { + if (curfield->align!='S' && curfield->align!='^') { + out_html("align) { + case 'N': + curfield->space+=4; + case 'R': + out_html(" ALIGN=right"); + break; + case 'C': + out_html(" ALIGN=center"); + default: + break; + } + if (!curfield->valign && curfield->rowspan>1) + out_html(" VALIGN=center"); + if (curfield->colspan>1) { + char buf[5]; + out_html(" COLSPAN="); + sprintf(buf, "%i", curfield->colspan); + out_html(buf); + } + if (curfield->rowspan>1) { + char buf[5]; + out_html(" ROWSPAN="); + sprintf(buf, "%i", curfield->rowspan); + out_html(buf); + } + j=j+curfield->colspan; + out_html(">"); + if (curfield->size) out_html(change_to_size(curfield->size)); + if (curfield->font) out_html(change_to_font(curfield->font)); + switch (curfield->align) { + case '=': out_html("

"); break; + case '_': out_html("
"); break; + default: + if (curfield->contents) out_html(curfield->contents); + break; + } + if (curfield->space) + for (i=0; ispace;i++) out_html(" "); + if (curfield->font) out_html(change_to_font(0)); + if (curfield->size) out_html(change_to_size(0)); + if (j>=maxcol && curfield->align>'@' && curfield->align!='_') + out_html("
"); + out_html(""); + } + curfield=curfield->next; + } + out_html("
\n"); + currow=currow->next; + } + if (box && !border) out_html("
"); + out_html("
\n"); + currow=layout; + while (currow) { + j=0; + out_html("
"); + out_html(""); + if (box==2) out_html(""); + if (center) out_html("
\n"); + else out_html("\n"); + if (!oldfillout) out_html("
");
+    fillout=oldfillout;
+    out_html(change_to_size(oldsize));
+    out_html(change_to_font(oldfont));
+    return c;
+}
+
+char *scan_expression(char *c, int *result) {
+    int value=0,value2,sign=1,opex=0;
+    char oper='c';
+
+    if (*c=='!') {
+	c=scan_expression(c+1, &value);
+	value= (!value);
+    } else if (*c=='n') {
+	c++;
+	value=nroff;
+    } else if (*c=='t') {
+	c++;
+	value=1-nroff;
+    } else if (*c=='\'' || *c=='"' || *c<' ' || (*c=='\\' && c[1]=='(')) {
+	/* ?string1?string2?
+	** test if string1 equals string2.
+	*/
+	char *st1=NULL, *st2=NULL, *h;
+	char *tcmp=NULL;
+	char sep;
+	sep=*c;
+	if (sep=='\\') {
+	    tcmp=c;
+	    c=c+3;
+	}
+	c++;
+	h=c;
+	while (*c!= sep && (!tcmp || strncmp(c,tcmp,4))) c++;
+	*c='\n';
+	scan_troff(h, 1, &st1);
+	*c=sep;
+	if (tcmp) c=c+3;
+	c++;
+	h=c;
+	while (*c!=sep && (!tcmp || strncmp(c,tcmp,4))) c++;
+	*c='\n';
+	scan_troff(h,1,&st2);
+	*c=sep;
+	if (!st1 && !st2) value=1;
+	else if (!st1 || !st2) value=0;
+	else value=(!strcmp(st1, st2));
+	if (st1) free(st1);
+	if (st2) free(st2);
+	if (tcmp) c=c+3;
+	c++;
+    } else {
+	while (*c && !isspace(*c) && *c!=')') {
+	    opex=0;
+	    switch (*c) {
+	    case '(':
+		c=scan_expression(c+1, &value2);
+		value2=sign*value2;
+		opex=1;
+		break;
+	    case '.':
+	    case '0': case '1':
+	    case '2': case '3':
+	    case '4': case '5':
+	    case '6': case '7':
+	    case '8': case '9': {
+		int num=0,denum=1;
+		value2=0;
+		while (isdigit(*c)) value2=value2*10+((*c++)-'0');
+		if (*c=='.') {
+		    c++;
+		    while (isdigit(*c)) {
+			num=num*10+((*c++)-'0');
+			denum=denum*10;
+		    }
+		}
+		if (isalpha(*c)) {
+		    /* scale indicator */
+		    switch (*c) {
+		    case 'i': /* inch -> 10pt */
+			value2=value2*10+(num*10+denum/2)/denum;
+			num=0;
+			break;
+		    default:
+			break;
+		    }
+		    c++;
+		}
+		value2=value2+(num+denum/2)/denum;
+		value2=sign*value2;
+		opex=1;
+		break;
+	    }
+	    case '\\':
+		c=scan_escape(c+1);
+		value2=intresult*sign;
+		if (isalpha(*c)) c++; /* scale indicator */
+		opex=1;
+		break;
+	    case '-':
+		if (oper) { sign=-1; c++; break; }
+	    case '>':
+	    case '<':
+	    case '+':
+	    case '/':
+	    case '*':
+	    case '%':
+	    case '&':
+	    case '=':
+	    case ':':
+		if (c[1]=='=') oper=(*c++) +16; else oper=*c;
+		c++;
+		break;
+	    default: c++; break;
+	    }
+	    if (opex) {
+		sign=1;
+		switch (oper) {
+		case 'c': value=value2; break;
+		case '-': value=value-value2; break;
+		case '+': value=value+value2; break;
+		case '*': value=value*value2; break;
+		case '/': if (value2) value=value/value2; break;
+		case '%': if (value2) value=value%value2; break;
+		case '<': value=(value': value=(value>value2); break;
+		case '>'+16: value=(value>=value2); break;
+		case '<'+16: value=(value<=value2); break;
+		case '=': case '='+16: value=(value==value2); break;
+		case '&': value = (value && value2); break;
+		case ':': value = (value || value2); break;
+		default: fprintf(stderr,
+				 "man2html: Unknown operator %c.\n", oper);
+		}
+		oper=0;
+	    }
+	}
+	if (*c==')') c++;
+    }
+    *result=value;
+    return c;
+}
+
+static void
+trans_char(char *c, char s, char t) {
+	char *sl = c;
+	int slash = 0;
+
+	while (*sl && (*sl != '\n' || slash)) {
+		if (!slash) {
+			if (*sl == escapesym)
+				slash = 1;
+			else if (*sl == s)
+				*sl = t;
+		} else
+			slash = 0;
+		sl++;
+	}
+}
+
+/*
+ * Read STR until end-of-line (not preceded by \).
+ * Find whitespace separated words, and store starts in WORDS of lth MAXN.
+ * Return number of words in N.
+ * Replace each end-of-word by the character EOW (usually \n or 0).
+ * Return pointer to last char seen (either \n or 0).
+ *
+ * A part \"... is skipped.
+ * Quotes not preceded by \ are replaced by \a.
+ */
+static char *
+fill_words(char *str, char *words[], int maxn, int *n, char eow) {
+	char *s = str;
+	int backslash = 0;
+	int skipspace = 0;	/* 1 if space is not end-of-word */
+
+	*n = 0;
+	words[*n] = s;
+	while (*s && (*s != '\n' || backslash)) {
+		if (!backslash) {
+			if (*s == '"') {
+				*s = '\a';
+				skipspace = !skipspace;
+			} else if (*s == escapesym) {
+				backslash = 1;
+			} else if ((*s == ' ' || *s == '\t') && !skipspace) {
+				*s = eow;
+				if (words[*n] != s && *n < maxn-1)
+					(*n)++;
+				words[*n] = s+1;
+			}
+		} else {
+			if (*s == '"') {
+				s--;
+				*s = eow;
+				if (words[*n] != s && *n < maxn-1)
+					(*n)++;
+				s++;
+				while (*s && *s != '\n') s++;
+				words[*n] = s;
+				s--;
+			}
+			backslash = 0;
+		}
+		s++;
+	}
+	if (s != words[*n])
+		(*n)++;
+	return s;
+}
+
+
+char *section_list[] = {
+    "1", "User Commands ",
+    "1C", "User Commands",
+    "1G", "User Commands",
+    "1S", "User Commands",
+    "1V", "User Commands ",
+    "2", "System Calls",
+    "2V", "System Calls",
+    "3", "C Library Functions",
+    "3C", "Compatibility Functions",
+    "3F", "Fortran Library Routines",
+    "3K", "Kernel VM Library Functions",
+    "3L", "Lightweight Processes Library",
+    "3M", "Mathematical Library",
+    "3N", "Network Functions",
+    "3R", "RPC Services Library",
+    "3S", "Standard I/O Functions",
+    "3V", "C Library Functions",
+    "3X", "Miscellaneous Library Functions",
+    "4", "Devices and Network Interfaces",
+    "4F", "Protocol Families",
+    "4I", "Devices and Network Interfaces",
+    "4M", "Devices and Network Interfaces",
+    "4N", "Devices and Network Interfaces",
+    "4P", "Protocols",
+    "4S", "Devices and Network Interfaces",
+    "4V", "Devices and Network Interfaces",
+    "5", "File Formats",
+    "5V", "File Formats",
+    "6", "Games and Demos",
+    "7", "Environments, Tables, and Troff Macros",
+    "7V", "Environments, Tables, and Troff Macros",
+    "8", "Maintenance Commands",
+    "8C", "Maintenance Commands",
+    "8S", "Maintenance Commands",
+    "8V", "Maintenance Commands",
+    "L", "Local Commands",
+/* for Solaris:
+    "1", "User Commands",
+    "1B", "SunOS/BSD Compatibility Package Commands",
+    "1b", "SunOS/BSD Compatibility Package Commands",
+    "1C", "Communication Commands ",
+    "1c", "Communication Commands",
+    "1F", "FMLI Commands ",
+    "1f", "FMLI Commands",
+    "1G", "Graphics and CAD Commands ",
+    "1g", "Graphics and CAD Commands ",
+    "1M", "Maintenance Commands",
+    "1m", "Maintenance Commands",
+    "1S", "SunOS Specific Commands",
+    "1s", "SunOS Specific Commands",
+    "2", "System Calls",
+    "3", "C Library Functions",
+    "3B", "SunOS/BSD Compatibility Library Functions",
+    "3b", "SunOS/BSD Compatibility Library Functions",
+    "3C", "C Library Functions",
+    "3c", "C Library Functions",
+    "3E", "C Library Functions",
+    "3e", "C Library Functions",
+    "3F", "Fortran Library Routines",
+    "3f", "Fortran Library Routines",
+    "3G", "C Library Functions",
+    "3g", "C Library Functions",
+    "3I", "Wide Character Functions",
+    "3i", "Wide Character Functions",
+    "3K", "Kernel VM Library Functions",
+    "3k", "Kernel VM Library Functions",
+    "3L", "Lightweight Processes Library",
+    "3l", "Lightweight Processes Library",
+    "3M", "Mathematical Library",
+    "3m", "Mathematical Library",
+    "3N", "Network Functions",
+    "3n", "Network Functions",
+    "3R", "Realtime Library",
+    "3r", "Realtime Library",
+    "3S", "Standard I/O Functions",
+    "3s", "Standard I/O Functions",
+    "3T", "Threads Library",
+    "3t", "Threads Library",
+    "3W", "C Library Functions",
+    "3w", "C Library Functions",
+    "3X", "Miscellaneous Library Functions",
+    "3x", "Miscellaneous Library Functions",
+    "4", "File Formats",
+    "4B", "SunOS/BSD Compatibility Package File Formats",
+    "4b", "SunOS/BSD Compatibility Package File Formats",
+    "5", "Headers, Tables, and Macros",
+    "6", "Games and Demos",
+    "7", "Special Files",
+    "7B", "SunOS/BSD Compatibility Special Files",
+    "7b", "SunOS/BSD Compatibility Special Files",
+    "8", "Maintenance Procedures",
+    "8C", "Maintenance Procedures",
+    "8c", "Maintenance Procedures",
+    "8S", "Maintenance Procedures",
+    "8s", "Maintenance Procedures",
+    "9", "DDI and DKI",
+    "9E", "DDI and DKI Driver Entry Points",
+    "9e", "DDI and DKI Driver Entry Points",
+    "9F", "DDI and DKI Kernel Functions",
+    "9f", "DDI and DKI Kernel Functions",
+    "9S", "DDI and DKI Data Structures",
+    "9s", "DDI and DKI Data Structures",
+    "L", "Local Commands",
+*/
+    NULL, "Misc. Reference Manual Pages",
+    NULL, NULL
+};
+
+static char *
+section_name(char *c)
+{
+    int i=0;
+
+    if (!c) return "";
+    while (section_list[i] && strcmp(c,section_list[i])) i=i+2;
+    if (section_list[i+1]) return section_list[i+1];
+    else return c;
+}
+
+int manidxlen = 0;
+char *manidx = NULL;
+int subs = 0;
+int mip = 0;	/* current offset in manidx[] */
+char label[5]="lbAA";
+
+static void
+manidx_need(int m) {
+	if (mip + m >= manidxlen) {
+		manidxlen += 10000;
+		manidx = xrealloc(manidx, manidxlen);
+	}
+}
+
+static void
+add_to_index(int level, char *item)
+{
+    char *c = NULL;
+
+    label[3]++;
+    if (label[3]>'Z') {
+	label[3]='A';
+	label[2]++;
+    }
+
+    if (level != subs) {
+	manidx_need(6);
+	if (subs) {
+	    strcpy(manidx+mip, "\n");
+	    mip += 6;
+	} else {
+	    strcpy(manidx+mip, "
\n"); + mip += 5; + } + } + subs = level; + + scan_troff(item, 1, &c); + manidx_need(100 + strlen(c)); + sprintf(manidx+mip, "
%s
\n", label, c); + if (c) free(c); + while (manidx[mip]) mip++; +} + +static char * +skip_till_newline(char *c) +{ + int lvl=0; + + while (*c && (*c!='\n' || lvl>0)) { + if (*c=='\\') { + c++; + if (*c=='}') lvl--; else if (*c=='{') lvl++; + } + c++; + } + c++; + if (lvl<0 && newline_for_fun) { + newline_for_fun = newline_for_fun+lvl; + if (newline_for_fun<0) newline_for_fun=0; + } + return c; +} + +int ifelseval=0; + +static char * +scan_request(char *c) { + /* BSD Mandoc stuff - by Michael Hamilton */ + static int mandoc_synopsis=0; /* True if we are in the synopsis section */ + static int mandoc_command=0; /* True if this is mandoc page */ + static int mandoc_bd_options; /* Only copes with non-nested Bd's */ + static int inXo=0; + + int i,j,mode = 0; + char *h; + char *wordlist[20]; + int words; + char *sl; + STRDEF *owndef; + + while (*c == ' ' || *c == '\t') + c++; + if (c[0] == '\n') + return c+1; + if (c[1] == '\n') + j = 1; + else + j = 2; + while (c[j] == ' ' || c[j] == '\t') + j++; + if (c[0] == escapesym) { + /* some pages use .\" .\$1 .\} */ + /* .\$1 is too difficult/stupid */ + if (c[1] == '$') + c = skip_till_newline(c); + else + c = scan_escape(c+1); + } else { + i=V(c[0],c[1]); + switch (i) { + case V('a','b'): + h=c+j; + while (*h && *h !='\n') h++; + *h=0; + if (scaninbuff && buffpos) { + buffer[buffpos]=0; + printf("%s\n", buffer); + } + fprintf(stderr, "%s\n", c+2); /* XXX */ + exit(0); + break; + case V('d','i'): + { + STRDEF *de; + c=c+j; + i=V(c[0],c[1]); + if (*c == '\n') { c++;break; } + while (*c && *c!='\n') c++; + c++; + h=c; + while (*c && strncmp(c,".di",3)) while (*c && *c++!='\n'); + *c=0; + de=strdef; + while (de && de->nr !=i) de=de->next; + if (!de) { + de=(STRDEF*) xmalloc(sizeof(STRDEF)); + de->nr=i; + de->slen=0; + de->next=strdef; + de->st=NULL; + strdef=de; + } else { + if (de->st) free(de->st); + de->slen=0; + de->st=NULL; + } + scan_troff(h,0,&de->st); + *c='.'; + while (*c && *c++!='\n'); + break; + } + case V('d','s'): + mode=1; + case V('a','s'): + { + STRDEF *de; + int oldcurpos=curpos; + c=c+j; + while (*c == ' ') c++; + i=V(c[0],c[1]); + j=0; + while (c[j] && c[j]!='\n') j++; + if (j<3) { c=c+j; break; } + if (c[1] == ' ') c=c+1; else c=c+2; + while (isspace(*c)) c++; + if (*c == '"') c++; + de=strdef; + while (de && de->nr != i) de=de->next; + single_escape=1; + curpos=0; + if (!de) { + char *h; + de=(STRDEF*) xmalloc(sizeof(STRDEF)); + de->nr=i; + de->slen=0; + de->next=strdef; + de->st=NULL; + strdef=de; + h=NULL; + c=scan_troff(c, 1, &h); + de->st=h; + de->slen=curpos; + } else { + if (mode) { /* .ds */ + char *h=NULL; + c=scan_troff(c, 1, &h); + free(de->st); /* segfault XXX */ + de->slen=curpos; + de->st=h; + } else { /* .as */ + c=scan_troff(c,1,&de->st); /* XXX */ + de->slen+=curpos; + } + } + single_escape=0; + curpos=oldcurpos; + } + break; + case V('b','r'): + if (still_dd) out_html("
"); + else out_html("
\n"); + curpos=0; + c=c+j; + if (c[0] == escapesym) { c=scan_escape(c+1); } + c=skip_till_newline(c);break; + case V('c','2'): + c=c+j; + if (*c!='\n') { nobreaksym=*c; } + else nobreaksym='\''; + c=skip_till_newline(c); + break; + case V('c','c'): + c=c+j; + if (*c!='\n') { controlsym=*c; } + else controlsym='.'; + c=skip_till_newline(c); + break; + case V('c','e'): + c=c+j; + if (*c == '\n') { i=1; } + else { + i=0; + while ('0'<=*c && *c<='9') { + i=i*10+*c-'0'; + c++; + } + } + c=skip_till_newline(c); + /* center next i lines */ + if (i>0) { + out_html("
\n"); + while (i && *c) { + char *line=NULL; + c=scan_troff(c,1, &line); + if (line && strncmp(line, "
", 4)) { + out_html(line); + out_html("
\n"); + i--; + } + } + out_html("
\n"); + curpos=0; + } + break; + case V('e','c'): + c=c+j; + if (*c!='\n') { escapesym=*c; } + else escapesym='\\'; + break; + c=skip_till_newline(c); + case V('e','o'): + escapesym=0; + c=skip_till_newline(c); + break; + case V('e','x'): + exit(0); + break; + case V('f','c'): + c=c+j; + if (*c == '\n') { + fieldsym=padsym=0; + } else { + fieldsym=c[0]; + padsym=c[1]; + } + c=skip_till_newline(c); + break; + case V('f','i'): + if (!fillout) { + out_html(change_to_font(0)); + out_html(change_to_size('0')); + out_html("
\n"); + } + curpos=0; + fillout=1; + c=skip_till_newline(c); + break; + case V('f','t'): + c=c+j; + if (*c == '\n') { + out_html(change_to_font(0)); + } else { + if (*c == escapesym) { + int fn; + c=scan_expression(c, &fn); + c--; + out_html(change_to_font(fn)); + } else { + out_html(change_to_font(*c)); + c++; + } + } + c=skip_till_newline(c); + break; + case V('e','l'): + /* .el anything : else part of if else */ + if (ifelseval) { + c=c+j; + c[-1]='\n'; + c=scan_troff(c,1,NULL); + } else + c=skip_till_newline(c+j); + break; + case V('i','e'): + /* .ie c anything : then part of if else */ + case V('i','f'): + /* .if c anything + * .if !c anything + * .if N anything + * .if !N anything + * .if 'string1'string2' anything + * .if !'string1'string2' anything + */ + c=c+j; + c=scan_expression(c, &i); + ifelseval=!i; + if (i) { + *c='\n'; + c++; + c=scan_troff(c,1,NULL); + } else + c=skip_till_newline(c); + break; + case V('i','g'): /* .ig: ignore until .. */ + { + char *endwith="..\n"; + i=3; + c=c+j; + while (*c == ' ') c++; + if (*c == escapesym && c[1] == '"') + while (*c != '\n') c++; + if (*c!='\n') { /* .ig yy: ignore until .yy, then call .yy */ + endwith=c-1;i=1; + c[-1]='.'; + while (*c && *c!='\n') c++,i++; + } + c++; + while (*c && strncmp(c,endwith,i)) + while (*c && *c++!='\n'); + while (*c && *c++!='\n'); + break; + } + case V('n','f'): + if (fillout) { + out_html(change_to_font(0)); + out_html(change_to_size('0')); + out_html("
\n");
+	    }
+	    curpos=0;
+	    fillout=0;
+	    c=skip_till_newline(c);
+	    break;
+	case V('p','s'):
+	    c=c+j;
+	    if (*c == '\n') {
+		out_html(change_to_size('0'));
+	    } else {
+		j=0;i=0;
+		if (*c == '-') { j= -1;c++; } else if (*c == '+') { j=1;c++;}
+		c=scan_expression(c, &i);
+		if (!j) { j=1; if (i>5) i=i-10; }
+		out_html(change_to_size(i*j));
+	    }
+	    c=skip_till_newline(c);
+	    break;
+	case V('s','p'):
+	    c=c+j;
+	    if (fillout) out_html("

"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('s','o'): + { + FILE *f; + int l; char *buf; + char *name = NULL; + + curpos=0; + c += j; /* skip .so part and whitespace */ + if (*c == '/') { + h = c; + } else { /* .so man3/cpow.3 -> ../man3/cpow.3 */ + h = c-3; + h[0] = '.'; + h[1] = '.'; + h[2] = '/'; + } + while (*c != '\n') c++; + while (c[-1] == ' ') c--; + while (*c != '\n') *c++ = 0; + *c = 0; + scan_troff(h,1, &name); + if (name[3] == '/') h=name+3; else h=name; + l = 0; +#ifdef _KOLIBRI + ksys_bdfe_t bdfe; + _ksys_file_get_info(h, &bdfe); + l = bdfe.size; +#else + struct stat stbuf; + if (stat(h, &stbuf)!=-1) l=stbuf.st_size; +#endif + + buf = (char*) xmalloc((l+4)*sizeof(char)); +#if NOCGI + if (!out_length) { + char *t,*s; + t=strrchr(fname, '/'); + if (!t) t=fname; + fprintf(stderr, "ln -s %s.html %s.html\n", h, t); + s=strrchr(t, '.');if (!s) s=t; + printf(" Manpage of %s\n" + "\n" + "See the manpage for %s.\n" + "\n", + s, h, h); + } else +#endif + { + /* this works alright, except for section 3 */ + if (!l || !(f = fopen(h,"r"))) { + fprintf(stderr, + "man2html: unable to open or read file %s\n", h); + out_html("

" + "man2html: unable to open or read file\n"); + out_html(h); + out_html("
\n"); + } else { + i=fread(buf+1,1,l,f); + fclose(f); + buf[0]=buf[l]='\n'; + buf[l+1]=buf[l+2]=0; + scan_troff(buf+1,0,NULL); + } + if (buf) free(buf); + } + *c++='\n'; + break; + } + case V('t','a'): + c=c+j; + j=0; + while (*c!='\n') { + sl=scan_expression(c, &tabstops[j]); + if (*c == '-' || *c == '+') tabstops[j]+=tabstops[j-1]; + c=sl; + while (*c == ' ' || *c == '\t') c++; + if (j+1 < SIZE(tabstops)) + j++; + } + maxtstop=j; + curpos=0; + break; + case V('t','i'): +#if 0 + dl_down(); +#endif + out_html("
\n"); + c=c+j; + c=scan_expression(c, &j); + for (i=0; ia b ] */ + mode=1; + c[0]='B'; c[1]='I'; + out_html(change_to_font('R')); + out_html("["); + curpos++; + case V('B','R'): + case V('B','I'): + case V('I','B'): + case V('I','R'): + case V('R','B'): + case V('R','I'): + { + char font[2]; + font[0] = c[0]; font[1] = c[1]; + c = c+j; + if (*c == '\n') c++; + sl = fill_words(c, wordlist, SIZE(wordlist), &words, '\n'); + c = sl+1; + /* .BR name (section) + ** indicates a link. It will be added in the output routine. + */ + for (i=0; i"); + curpos = 0; + break; + case V('T','P'): + dl_begin(); + c=skip_till_newline(c); + /* somewhere a definition ends with '.TP' */ + if (!*c) still_dd=1; else { + c=scan_troff(c,1,NULL); + out_html("
"); + } + curpos=0; + break; + case V('I','X'): + /* general index */ + sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + c = sl+1; + j = 4; + while (idxlabel[j] == 'Z') idxlabel[j--]='A'; + idxlabel[j]++; +#ifdef MAKEINDEX + if (idxfile) { + fprintf(idxfile, "%s@%s@", fname, idxlabel); + for (j=0; j' and '<' solves it, but creates + ** some space. A normal space does not work. + */ + out_html("\">"); + break; + case V('L','P'): + case V('P','P'): + dl_end(); + if (fillout) out_html("

\n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('H','P'): + dl_begin(); + still_dd=1; + c=skip_till_newline(c); + curpos=0; + break; + case V('P','D'): + c=skip_till_newline(c); + break; + case V('R','s'): /* BSD mandoc */ + case V('R','S'): + sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + j = 1; + if (words>0) scan_expression(wordlist[0], &j); + if (j>=0) { + dl_newlevel(); + c=skip_till_newline(c); + curpos=0; + break; + } + case V('R','e'): /* BSD mandoc */ + case V('R','E'): + dl_endlevel(); + c=skip_till_newline(c); + curpos=0; + break; + case V('S','B'): + out_html(change_to_size(-1)); + out_html(change_to_font('B')); + c=scan_troff(c+j, 1, NULL); + out_html(change_to_font('R')); + out_html(change_to_size('0')); + break; + case V('S','M'): + c=c+j; + if (*c == '\n') c++; + out_html(change_to_size(-1)); + trans_char(c,'"','\a'); + c=scan_troff(c,1,NULL); + out_html(change_to_size('0')); + break; + case V('S','s'): /* BSD mandoc */ + mandoc_command = 1; + case V('S','S'): + mode=1; + goto sh_below; + case V('S','h'): /* BSD mandoc */ + mandoc_command = 1; + case V('S','H'): + sh_below: + c=c+j; + if (*c == '\n') c++; + dl_down(); + out_html(change_to_font(0)); + out_html(change_to_size(0)); + if (!fillout) { + fillout=1; + out_html("

"); + } + trans_char(c,'"', '\a'); + add_to_index(mode, c); + out_html(" \n

"); + else out_html("\"> \n

"); + mandoc_synopsis = (strncmp(c, "SYNOPSIS", 8) == 0); + c = (mandoc_command ? scan_troff_mandoc : scan_troff)(c,1,NULL); + if (mode) out_html("

\n"); + else out_html("\n"); + curpos=0; + break; + case V('T','S'): + c=scan_table(c); + break; + case V('D','t'): /* BSD mandoc */ + mandoc_command = 1; + case V('T','H'): + if (!output_possible) { + sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, 0); + *sl = 0; + if (words > 1) { + output_possible=1; + out_html("Manpage of "); + out_html(wordlist[0]); + out_html("\n"); + out_html("\n"); + out_html("\n

"); + out_html(wordlist[0]); + out_html("

\nSection: "); + if (words>4) + out_html(wordlist[4]); + else + out_html(section_name(wordlist[1])); + out_html(" ("); + out_html(wordlist[1]); + if (words>2) { + out_html(")
Updated: "); + scan_troff(wordlist[2], 1, NULL); + } else out_html(")"); + out_html("
Index\n"); + man_page_html(0,0); /* Return to Main Contents */ + *sl='\n'; + out_html("
\n"); + if (mandoc_command) out_html("
BSD mandoc
"); + } + c = sl+1; + } else + c = skip_till_newline(c); + curpos=0; + break; + case V('T','X'): + sl=fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + *sl=0; + out_html(change_to_font('I')); + if (words>1) wordlist[1][-1]=0; + c=lookup_abbrev(wordlist[0]); + curpos+=strlen(c); + out_html(c); + out_html(change_to_font('R')); + if (words>1) + out_html(wordlist[1]); + *sl='\n'; + c=sl+1; + break; + case V('r','m'): + /* .rm xx : Remove request, macro or string */ + case V('r','n'): + /* .rn xx yy : Rename request, macro or string xx to yy */ + { + STRDEF *de; + c=c+j; + i=V(c[0],c[1]); + c=c+2; + while (isspace(*c) && *c!='\n') c++; + j=V(c[0],c[1]); + while (*c && *c!='\n') c++; + c++; + de=strdef; + while (de && de->nr!=j) de=de->next; + if (de) { + if (de->st) free(de->st); + de->nr=0; + } + de=strdef; + while (de && de->nr!=i) de=de->next; + if (de) de->nr=j; + break; + } + case V('n','x'): + /* .nx filename : next file. */ + case V('i','n'): + /* .in +-N : Indent */ + c=skip_till_newline(c); + break; + case V('n','r'): + /* .nr R +-N M: define and set number register R by +-N; + ** auto-increment by M + */ + { + INTDEF *intd; + c=c+j; + i=V(c[0],c[1]); + c=c+2; + intd=intdef; + while (intd && intd->nr!=i) intd=intd->next; + if (!intd) { + intd = (INTDEF*) xmalloc(sizeof(INTDEF)); + intd->nr=i; + intd->val=0; + intd->incr=0; + intd->next=intdef; + intdef=intd; + } + while (*c == ' ' || *c == '\t') c++; + c=scan_expression(c,&intd->val); + if (*c!='\n') { + while (*c == ' ' || *c == '\t') c++; + c=scan_expression(c,&intd->incr); + } + c=skip_till_newline(c); + break; + } + case V('a','m'): + /* .am xx yy : append to a macro. */ + /* define or handle as .ig yy */ + mode=1; + case V('d','e'): + /* .de xx yy : define or redefine macro xx; end at .yy (..) */ + /* define or handle as .ig yy */ + { + STRDEF *de; + int olen=0; + c=c+j; + sl=fill_words(c, wordlist, SIZE(wordlist), &words, '\n'); + i=V(c[0],c[1]);j=2; + if (words == 1) wordlist[1]=".."; else { + wordlist[1]--; + wordlist[1][0]='.'; + j=3; + } + c=sl+1; + sl=c; + while (*c && strncmp(c,wordlist[1],j)) c=skip_till_newline(c); + de=defdef; + while (de && de->nr!= i) de=de->next; + if (mode && de) olen=strlen(de->st); + j=olen+c-sl; + h= (char*) xmalloc((j*2+4)*sizeof(char)); + if (h) { + for (j=0; jst[j]; + if (!j || h[j-1]!='\n') + h[j++]='\n'; + while (sl!=c) { + if (sl[0] == '\\' && sl[1] == '\\') { + h[j++]='\\'; sl++; + } else + h[j++]=*sl; + sl++; + } + h[j]=0; + if (de) { + if (de->st) free(de->st); + de->st=h; + } else { + de = (STRDEF*) xmalloc(sizeof(STRDEF)); + de->nr=i; + de->next=defdef; + de->st=h; + defdef=de; + } + } + } + c=skip_till_newline(c); + break; + + /* ----- BSD mandoc stuff below ----- */ + case V('U','x'): /* BSD mandoc */ + c=c+j; + out_html("UNIX"); + c=skip_till_newline(c); + break; + case V('A','t'): /* BSD mandoc - called with arg V */ + c=c+j; + out_html("AT&T System"); + break; + case V('B','l'): /* BSD mandoc */ + { + char *nl, t=0 /* just for gcc */; + c=c+j; + nl = strchr(c,'\n'); + if (nl) { + t = *nl; + *nl = 0; + } + if (strstr(c, "-bullet")) /* HTML Unnumbered List */ + dl_newlevel_type(UL); + else if (strstr(c, "-enum")) /* HTML Ordered List */ + dl_newlevel_type(OL); + else /* HTML Descriptive List */ + dl_newlevel_type(DL); + if (nl) + *nl = t; + if (fillout) out_html("

\n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + } + case V('E','l'): /* BSD mandoc */ + c=c+j; + dl_endlevel_type(); + if (fillout) out_html("

\n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('I','t'): /* BSD mandoc */ + c=c+j; + if (dl_type(DL)) { + out_html("

"); + out_html(change_to_font('B')); + if (*c == '\n') { + /* Don't allow embedded comms after a newline */ + c++; + c=scan_troff(c,1,NULL); + } else { + /* Do allow embedded comms on the same line. */ + c=scan_troff_mandoc(c,1,NULL); + } + out_html(change_to_font('R')); + out_html(NEWLINE); + if (inXo) + still_dd = 1; + else + out_html("
"); + } else if (dl_type(UL) || dl_type(OL)) { + out_html("
  • "); + c=scan_troff_mandoc(c,1,NULL); + out_html(NEWLINE); + } + if (fillout) curpos++; else curpos=0; + break; + case V('X','o'): /* BSD mandoc */ + c=c+j; + inXo = 1; + break; + case V('X','c'): /* BSD mandoc - Xc closes an Xo */ + c=c+j; + if (inXo) { + if (still_dd) + out_html("
    "); + inXo = 0; + } + break; + case V('S','m'): /* BSD mandoc - called with arg on/off */ + c=skip_till_newline(c); + break; + case V('B','k'): /* BSD mandoc */ + case V('E','k'): /* BSD mandoc */ + case V('D','d'): /* BSD mandoc */ + case V('O','s'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('B','t'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + out_html(" is currently in beta test."); + if (fillout) curpos++; else curpos=0; + break; + case V('B','x'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html("BSD "); + c=scan_troff_mandoc(c, 1, NULL); + if (fillout) curpos++; else curpos=0; + break; + case V('D','l'): /* BSD mandoc */ + c=c+j; + out_html(NEWLINE); + out_html("
    "); + out_html(change_to_font('L')); + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html("
    "); + if (fillout) curpos++; else curpos=0; + break; + case V('B','d'): /* BSD mandoc */ + { /* Seems like a kind of example/literal mode */ + char *nl, t=0 /* just for gcc */; + c=c+j; + nl = strchr(c,'\n'); + if (nl) { + t = *nl; + *nl = 0; + } + out_html(NEWLINE); + mandoc_bd_options = 0; /* Remember options for terminating Bl */ + if (strstr(c, "-offset indent")) { + mandoc_bd_options |= BD_INDENT; + out_html("
    \n"); + } + if (strstr(c, "-literal") || strstr(c, "-unfilled")) { + if (fillout) { + mandoc_bd_options |= BD_LITERAL; + out_html(change_to_font(0)); + out_html(change_to_size('0')); + out_html("
    \n");
    +		  }
    +		  curpos=0;
    +		  fillout=0;
    +	     }
    +	     if (nl)
    +		  *nl = t;
    +	     c=skip_till_newline(c);
    +	     break;
    +	}
    +	case V('E','d'):	/* BSD mandoc */
    +	     if (mandoc_bd_options & BD_LITERAL) {
    +		  if (!fillout) {
    +		       out_html(change_to_font(0));
    +		       out_html(change_to_size('0'));
    +		       out_html("
    \n"); + } + } + if (mandoc_bd_options & BD_INDENT) + out_html("
    \n"); + curpos=0; + fillout=1; + c=skip_till_newline(c); + break; + case V('B','e'): /* BSD mandoc */ + c=c+j; + if (fillout) out_html("

    "); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('X','r'): /* BSD mandoc */ + { + /* Translate xyz 1 to xyz(1) + * Allow for multiple spaces. Allow the section to be missing. + */ + char buff[100]; + char *bufptr; + trans_char(c,'"','\a'); + bufptr = buff; + c = c+j; + if (*c == '\n') c++; /* Skip spaces */ + while (isspace(*c) && *c != '\n') c++; + while (isalnum(*c) && bufptr < buff + SIZE(buff)-4) { + /* Copy the xyz part */ + *bufptr++ = *c++; + } + while (isspace(*c) && *c != '\n') c++; /* Skip spaces */ + if (isdigit(*c)) { /* Convert the number if there is one */ + *bufptr++ = '('; + while (isalnum(*c) && bufptr < buff + SIZE(buff)-3) { + *bufptr++ = *c++; + } + *bufptr++ = ')'; + } + while (*c != '\n' && bufptr < buff + SIZE(buff)-2) { + /* Copy the remainder */ + if (!isspace(*c)) { + *bufptr++ = *c; + } + c++; + } + *bufptr++ = '\n'; + *bufptr = 0; + scan_troff_mandoc(buff, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + } + break; + case V('F','l'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + out_html("-"); + if (*c!='\n') { + out_html(change_to_font('B')); + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + } + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('P','a'): /* BSD mandoc */ + case V('P','f'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('P','p'): /* BSD mandoc */ + if (fillout) out_html("

    \n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('D','q'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html("``"); + c=scan_troff_mandoc(c, 1, NULL); + out_html("''"); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('O','p'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html(change_to_font('R')); + out_html("["); + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html("]"); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('O','o'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html(change_to_font('R')); + out_html("["); + c=scan_troff_mandoc(c, 1, NULL); + if (fillout) curpos++; else curpos=0; + break; + case V('O','c'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html("]"); + if (fillout) curpos++; else curpos=0; + break; + case V('P','q'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html("("); + c=scan_troff_mandoc(c, 1, NULL); + out_html(")"); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('Q','l'): /* BSD mandoc */ + { /* Single quote first word in the line */ + char *sp; + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + sp = c; + do { /* Find first whitespace after the + * first word that isn't a mandoc macro + */ + while (*sp && isspace(*sp)) sp++; + while (*sp && !isspace(*sp)) sp++; + } while (*sp && isupper(*(sp-2)) && islower(*(sp-1))); + + /* Use a newline to mark the end of text to + * be quoted + */ + if (*sp) *sp = '\n'; + out_html("`"); /* Quote the text */ + c=scan_troff_mandoc(c, 1, NULL); + out_html("'"); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + } + case V('S','q'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html("`"); + c=scan_troff_mandoc(c, 1, NULL); + out_html("'"); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('A','r'): /* BSD mandoc */ + /* parse one line in italics */ + out_html(change_to_font('I')); + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') { /* An empty Ar means "file ..." */ + out_html("file ..."); + } else { + c=scan_troff_mandoc(c, 1, NULL); + } + out_html(change_to_font('R')); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('A','d'): /* BSD mandoc */ + case V('E','m'): /* BSD mandoc */ + case V('V','a'): /* BSD mandoc */ + /* parse one line in italics */ + out_html(change_to_font('I')); + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('N','d'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html(" - "); + c=scan_troff_mandoc(c, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('N','m'): /* BSD mandoc */ + { + static char *mandoc_name = 0; + trans_char(c,'"','\a'); + c=c+j; + if (mandoc_synopsis) { + /* + * Break lines only in the Synopsis. + * The Synopsis section seems to be treated + * as a special case - Bummer! + */ + static int count = 0; /* Don't break on the first Nm */ + if (count) { + out_html("
    "); + } else { + char *end, t=0 /* just for gcc */; + end = strchr(c, '\n'); + if (end) { + t = *end; + *end = 0; + } + if (mandoc_name) + free(mandoc_name); + mandoc_name = xstrdup(c); + if (end) + *end = t; + } + count++; + } + out_html(change_to_font('B')); + while (*c == ' ' || *c == '\t') c++; + if (*c == '\n') { + /* + * If Nm has no argument, use one from an earlier + * Nm command that did have one. Hope there aren't + * too many commands that do this. + */ + if (mandoc_name) + out_html(mandoc_name); + } else { + c=scan_troff_mandoc(c, 1, NULL); + } + out_html(change_to_font('R')); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + } + case V('C','d'): /* BSD mandoc */ + case V('C','m'): /* BSD mandoc */ + case V('I','c'): /* BSD mandoc */ + case V('M','s'): /* BSD mandoc */ + case V('O','r'): /* BSD mandoc */ + case V('S','y'): /* BSD mandoc */ + /* parse one line in bold */ + out_html(change_to_font('B')); + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('D','v'): /* BSD mandoc */ + case V('E','v'): /* BSD mandoc */ + case V('F','r'): /* BSD mandoc */ + case V('L','i'): /* BSD mandoc */ + case V('N','o'): /* BSD mandoc */ + case V('N','s'): /* BSD mandoc */ + case V('T','n'): /* BSD mandoc */ + case V('n','N'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + out_html(change_to_font('B')); + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('%','A'): /* BSD mandoc biblio stuff */ + case V('%','D'): + case V('%','N'): + case V('%','O'): + case V('%','P'): + case V('%','Q'): + case V('%','V'): + c=c+j; + if (*c == '\n') c++; + c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */ + if (fillout) curpos++; else curpos=0; + break; + case V('%','B'): + case V('%','J'): + case V('%','R'): + case V('%','T'): + c=c+j; + out_html(change_to_font('I')); + if (*c == '\n') c++; + c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */ + out_html(change_to_font('R')); + if (fillout) curpos++; else curpos=0; + break; + /* ----- end of BSD mandoc stuff ----- */ + + default: + /* search macro database of self-defined macros */ + owndef = defdef; + while (owndef && owndef->nr!=i) owndef=owndef->next; + if (owndef) { + char **oldargument; + int deflen; + int onff; + sl=fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + c=sl+1; + *sl=0; + for (i=1; ist); + owndef->st[deflen+1]='a'; + for (i=0; (owndef->st[deflen+2+i] = owndef->st[i]); i++); + oldargument=argument; + argument=wordlist; + onff=newline_for_fun; + if (mandoc_command) + scan_troff_mandoc(owndef->st+deflen+2, 0, NULL); + else + scan_troff(owndef->st+deflen+2, 0, NULL); + newline_for_fun=onff; + argument=oldargument; + for (i=0; i"); + curpos=0; + still_dd=0; + } + switch (*h) { + case '&': + intbuff[ibp++]='&'; + intbuff[ibp++]='a'; + intbuff[ibp++]='m'; + intbuff[ibp++]='p'; + intbuff[ibp++]=';'; + curpos++; + break; + case '<': + intbuff[ibp++]='&'; + intbuff[ibp++]='l'; + intbuff[ibp++]='t'; + intbuff[ibp++]=';'; + curpos++; + break; + case '>': + intbuff[ibp++]='&'; + intbuff[ibp++]='g'; + intbuff[ibp++]='t'; + intbuff[ibp++]=';'; + curpos++; + break; + case '"': + intbuff[ibp++]='&'; + intbuff[ibp++]='q'; + intbuff[ibp++]='u'; + intbuff[ibp++]='o'; + intbuff[ibp++]='t'; + intbuff[ibp++]=';'; + curpos++; + break; + case '\n': + if (h[-1] == '\n' && fillout) { + intbuff[ibp++]='<'; + intbuff[ibp++]='P'; + intbuff[ibp++]='>'; + } + if (contained_tab && fillout) { + intbuff[ibp++]='<'; + intbuff[ibp++]='B'; + intbuff[ibp++]='R'; + intbuff[ibp++]='>'; + } + contained_tab=0; + curpos=0; + usenbsp=0; + intbuff[ibp++]='\n'; + break; + case '\t': + { + int curtab=0; + contained_tab=1; + FLUSHIBP; + /* like a typewriter, not like TeX */ + tabstops[SIZE(tabstops)-1] = curpos+1; + while (curtab < maxtstop && tabstops[curtab] <= curpos) + curtab++; + if (curtab < maxtstop) { + if (!fillout) { + while (curpos480) { FLUSHIBP; } + curpos++; + } + } else { + out_html(""); + while (curpos < tabstops[curtab]) { + out_html(" "); + curpos++; + } + out_html(""); + } + } + } + break; + default: + if (*h == ' ' && (h[-1] == '\n' || usenbsp)) { + FLUSHIBP; + if (!usenbsp && fillout) { + out_html("
    "); + curpos=0; + } + usenbsp=fillout; + if (usenbsp) out_html(" "); else intbuff[ibp++]=' '; + } else if (*h > 31 && *h < 127) { + intbuff[ibp++]=*h; + } else if (((unsigned char)(*h)) > 127) { +#ifdef NO_8BIT + intbuff[ibp++]='&'; + intbuff[ibp++]='#'; + intbuff[ibp++]='0'+((unsigned char)(*h))/100; + intbuff[ibp++]='0'+(((unsigned char)(*h))%100)/10; + intbuff[ibp++]='0'+((unsigned char)(*h))%10; + intbuff[ibp++]=';'; +#else + intbuff[ibp++]=*h; +#endif + } + curpos++; + break; + } + if (ibp>480) FLUSHIBP; + h++; + } + } + FLUSHIBP; + if (buffer) buffer[buffpos]=0; + if (san && *h) h++; + newline_for_fun=exnewline_for_fun; + if (result) { + *result = buffer; + buffer=exbuffer; + buffpos=exbuffpos; + buffmax=exbuffmax; + scaninbuff=exscaninbuff; + } + return h; +} + +static char *scan_troff_mandoc(char *c, int san, char **result) { + char *ret, *end = c; + int oldval = mandoc_line; + mandoc_line = 1; + while (*end && *end != '\n') { + end++; + } + + if (end > c + 2 + && ispunct(*(end - 1)) + && isspace(*(end - 2)) && *(end - 2) != '\n') { + /* + * Don't format lonely punctuation. E.g. in "xyz ," format + * the xyz and then append the comma removing the space. + */ + *(end - 2) = '\n'; + ret = scan_troff(c, san, result); + *(end - 2) = *(end - 1); + *(end - 1) = ' '; + } else { + ret = scan_troff(c, san, result); + } + mandoc_line = oldval; + return ret; +} + +STRDEF *foundpages=NULL; + +#define BUFSMSG 1024 +#define MSGLEN 2048 +static void +error_page(char *s, char *t, ...) { + va_list p; + char msg[MSGLEN]; + char buf[BUFSMSG]; + + sprintf(msg, "'%s\n", s, s); + va_start(p, t); + vsprintf(buf, t, p); + va_end(p); +#ifdef _KOLIBRI + sprintf(msg, "%s%s%s", msg, buf, "' -E"); + _ksys_exec("/sys/@notify", buf); +#else + sprintf(msg, "%s%s%s", msg, buf, "'"); + printf("%s", msg); +#endif + exit(0); +} + +char * +xstrdup(const char *s) { + char *p = strdup(s); + if (p == NULL) + error_page("Out of memory", + "Sorry, out of memory, aborting...\n"); + return p; +} + +void * +xmalloc(size_t size) { + void *p = malloc(size); + if (p == NULL) + error_page("Out of memory", + "Sorry, out of memory, aborting...\n"); + return p; +} + +void * +xrealloc(void *ptr, size_t size) { + void *p = realloc(ptr,size); + if (p == NULL) + error_page("Out of memory", + "Sorry, out of memory, aborting...\n"); + return p; +} + +static void +usage(void) { + error_page("man2html: bad invocation", + "Usage: man2html in_file [out_file.html]\n"); +} + +static void +goto_dir(char *path, char **dir, char **name) { + char *s, *t, *u; + + s = xstrdup(path); + t = strrchr(s, '/'); + if (t) { + *t = 0; + u = strrchr(s, '/'); + *t = '/'; + if (u) { + *u = 0; +#ifdef _KOLIBRI + setcwd(s); +#else + chdir(s); +#endif + if (dir) + *dir = s; + if (name) + *name = u+1; +#if 0 + else /* complain or not - this need not be fatal */ + error_page("Error", "man2html: could not chdir to %s", s); +#endif + } + } +} + +/* + * Call: man2html [-l] [filename] + * + * The contents of FILENAME (or STDIN, in case FILENAME is "-" or absent) + * are converted from man-style nroff to html, and printed on STDOUT. + * + * Possible errors are reflected in the output. The return status is 0. + */ +int +main(int argc, char **argv) { + FILE *f; + int l, c; + char *buf, *filename, *fnam = NULL; + char *outfilename; + +#ifdef _KOLIBRI + outfilename = "/tmp0/1/out.html"; +#else + outfilename = "./out.html"; +#endif + +// printf("Content-type: text/html\n\n"); + + + /* Find filename */ + if (argc > 2) { + outfilename = argv[2]; + } if (argc > 1) { + fnam = argv[1]; + } else { + usage(); + } + + if ((out = fopen(outfilename, "w")) == NULL) { + printf("Cannot open file %s", outfilename); + return 0; + } + + filename = fnam; + directory = 0; + + /* Open input file */ + goto_dir(fnam, &directory, &fnam); + + f = fopen(fnam, "r"); + if (f == NULL) + error_page("File not found", "Could not open %s\n", filename); + fname = fnam; + + /* Read entire file into buf[1..l] */ +#define XTRA 5 + /* buf has 1 extra byte at the start, and XTRA extra bytes at the end */ + int ct; + + l = 0; + +#ifdef _KOLIBRI + ksys_bdfe_t bdfe; + _ksys_file_get_info(filename, &bdfe); + l = bdfe.size; +#else + struct stat stbuf; + if (stat(filename, &stbuf) != -1) l=stbuf.st_size; +#endif + + buf = (char *) xmalloc((l+1+XTRA)*sizeof(char)); + ct = fread(buf+1,1,l,f); + if (ct < l) + l = ct; + fclose(f); + + buf[0] = '\n'; + buf[l+1] = '\n'; + buf[l+2] = buf[l+3] = 0; + +#ifdef MAKEINDEX + idxfile = fopen(INDEXFILE, "a"); +#endif + stdinit(); + scan_troff(buf+1,0,NULL); + dl_down(); + out_html(change_to_font(0)); + out_html(change_to_size(0)); + if (!fillout) { + fillout=1; + out_html(""); + } + out_html(NEWLINE); + if (output_possible) { + /*   for mosaic users */ + fprintf(out, "


    \n 

    Index

    \n
    \n"); + manidx[mip]=0; + fprintf(out, "%s", manidx); + if (subs) printf("
    \n"); + fprintf(out, "\n"); + print_sig(); + fprintf(out, "\n\n"); + } else { + if (!filename) + filename = fname; + if (*filename == '/') + error_page("Invalid Manpage", + "The requested file %s is not a valid (unformatted) " + "man page.\nIf the file is a formatted manpage, " + "you could try to load the\n" + "plain file.\n", + filename, filename); + else + error_page("Invalid Manpage", + "The requested file %s is not a valid (unformatted) " + "man page.", filename); + } + if (idxfile) + fclose(idxfile); + if (buf) + free(buf); + return 0; +} diff --git a/programs/other/man2html/strdefs.c b/programs/other/man2html/strdefs.c new file mode 100644 index 0000000000..bcbc366b1c --- /dev/null +++ b/programs/other/man2html/strdefs.c @@ -0,0 +1,176 @@ +#include "defs.h" + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +int nroff = 1; + +#define NROFF (-666) +#define TROFF (-667) + +STRDEF *chardef, *strdef, *defdef; +INTDEF *intdef; + +static INTDEF standardint[] = { + { V('n',' '), NROFF, 0, NULL }, + { V('t',' '), TROFF, 0, NULL }, + { V('o',' '), 1, 0, NULL }, + { V('e',' '), 0, 0, NULL }, + { V('.','l'), 70, 0, NULL }, + { V('.','$'), 0, 0, NULL }, + { V('.','A'), NROFF, 0, NULL }, + { V('.','T'), TROFF, 0, NULL }, + { V('.','V'), 1, 0, NULL }, /* the me package tests for this */ + { 0, 0, 0, NULL } }; + +static STRDEF standardstring[] = { + { V('R',' '), 1, "®", NULL }, + { V('l','q'), 2, "``", NULL }, + { V('r','q'), 2, "''", NULL }, + { 0, 0, NULL, NULL} +}; + + +static STRDEF standardchar[] = { + { V('*','*'), 1, "*", NULL }, /* math star */ + { V('*','A'), 1, "A", NULL }, + { V('*','B'), 1, "B", NULL }, + { V('*','C'), 2, "Xi", NULL }, + { V('*','D'), 5, "Delta", NULL }, + { V('*','E'), 1, "E", NULL }, + { V('*','F'), 3, "Phi", NULL }, + { V('*','G'), 5, "Gamma", NULL }, + { V('*','H'), 5, "Theta", NULL }, + { V('*','I'), 1, "I", NULL }, + { V('*','K'), 1, "K", NULL }, + { V('*','L'), 6, "Lambda", NULL }, + { V('*','M'), 1, "M", NULL }, + { V('*','N'), 1, "N", NULL }, + { V('*','O'), 1, "O", NULL }, + { V('*','P'), 2, "Pi", NULL }, + { V('*','Q'), 3, "Psi", NULL }, + { V('*','R'), 1, "P", NULL }, + { V('*','S'), 5, "Sigma", NULL }, + { V('*','T'), 1, "T", NULL }, + { V('*','U'), 1, "Y", NULL }, + { V('*','W'), 5, "Omega", NULL }, + { V('*','X'), 1, "X", NULL }, + { V('*','Y'), 1, "H", NULL }, + { V('*','Z'), 1, "Z", NULL }, + { V('*','a'), 5, "alpha", NULL }, + { V('*','b'), 4, "beta", NULL }, + { V('*','c'), 2, "xi", NULL }, + { V('*','d'), 5, "delta", NULL }, + { V('*','e'), 7, "epsilon", NULL }, + { V('*','f'), 3, "phi", NULL }, + { V('*','g'), 5, "gamma", NULL }, + { V('*','h'), 5, "theta", NULL }, + { V('*','i'), 4, "iota", NULL }, + { V('*','k'), 5, "kappa", NULL }, + { V('*','l'), 6, "lambda", NULL }, + { V('*','m'), 1, "µ", NULL }, + { V('*','n'), 2, "nu", NULL }, + { V('*','o'), 1, "o", NULL }, + { V('*','p'), 2, "pi", NULL }, + { V('*','q'), 3, "psi", NULL }, + { V('*','r'), 3, "rho", NULL }, + { V('*','s'), 5, "sigma", NULL }, + { V('*','t'), 3, "tau", NULL }, + { V('*','u'), 7, "upsilon", NULL }, + { V('*','w'), 5, "omega", NULL }, + { V('*','x'), 3, "chi", NULL }, + { V('*','y'), 3, "eta", NULL }, + { V('*','z'), 4, "zeta", NULL }, + { V('+','-'), 1, "±", NULL }, + { V('1','2'), 1, "½", NULL }, + { V('1','4'), 1, "¼", NULL }, + { V('3','4'), 1, "¾", NULL }, + { V('F','i'), 3, "ffi", NULL }, + { V('F','l'), 3, "ffl", NULL }, + { V('a','a'), 1, "´", NULL }, + { V('a','p'), 1, "~", NULL }, + { V('b','r'), 1, "|", NULL }, + { V('b','u'), 1, "*", NULL }, /* bullet */ + { V('b','v'), 1, "|", NULL }, + { V('c','i'), 1, "o", NULL }, /* circle */ + { V('c','o'), 1, "©", NULL }, + { V('c','t'), 1, "¢", NULL }, + { V('d','e'), 1, "°", NULL }, + { V('d','g'), 1, "+", NULL }, /* dagger */ + { V('d','i'), 1, "÷", NULL }, + { V('e','m'), 3, "---", NULL }, /* em dash */ + { V('e','n'), 1, "-", NULL }, /* en dash */ + { V('e','q'), 1, "=", NULL }, + { V('e','s'), 1, "Ø", NULL }, + { V('f','f'), 2, "ff", NULL }, + { V('f','i'), 2, "fi", NULL }, + { V('f','l'), 2, "fl", NULL }, + { V('f','m'), 1, "´", NULL }, + { V('g','a'), 1, "`", NULL }, + { V('h','y'), 1, "-", NULL }, + { V('l','c'), 2, "|¯", NULL }, + { V('i','f'), 8, "Infinity", NULL }, /* infinity sign */ + { V('i','s'), 8, "Integral", NULL }, /* integral sign */ + { V('l','f'), 2, "|_", NULL }, + { V('l','k'), 1, "{", NULL }, + { V('m','i'), 1, "-", NULL }, + { V('m','u'), 1, "×", NULL }, + { V('n','o'), 1, "¬", NULL }, + { V('o','r'), 1, "|", NULL }, + { V('p','d'), 1, "d", NULL }, /* partial derivative */ + { V('p','l'), 1, "+", NULL }, + { V('r','c'), 2, "¯|", NULL }, + { V('r','f'), 2, "_|", NULL }, + { V('r','g'), 1, "®", NULL }, + { V('r','k'), 1, "}", NULL }, + { V('r','n'), 1, "¯", NULL }, + { V('r','u'), 1, "_", NULL }, + { V('s','c'), 1, "§", NULL }, + { V('s','l'), 1, "/", NULL }, + { V('s','q'), 2, "[]", NULL }, + { V('t','s'), 1, "s", NULL }, /* should be terminal sigma */ + { V('u','l'), 1, "_", NULL }, + { V('>','='), 1, ">", NULL }, + { V('<','='), 1, "<", NULL }, + { 0, 0, NULL, NULL } +}; + +void stdinit(void) { + STRDEF *stdf; + int i; + + stdf = &standardchar[0]; + i = 0; + while (stdf->nr) { + if (stdf->st) stdf->st = xstrdup(stdf->st); + stdf->next = &standardchar[i]; + stdf = stdf->next; + i++; + } + chardef=&standardchar[0]; + + stdf=&standardstring[0]; + i=0; + while (stdf->nr) { + /* waste a little memory, and make a copy, to avoid + the segfault when we free non-malloced memory */ + if (stdf->st) stdf->st = xstrdup(stdf->st); + stdf->next = &standardstring[i]; + stdf = stdf->next; + i++; + } + strdef=&standardstring[0]; + + intdef=&standardint[0]; + i=0; + while (intdef->nr) { + if (intdef->nr == NROFF) intdef->nr = nroff; else + if (intdef->nr == TROFF) intdef->nr = !nroff; + intdef->next = &standardint[i]; + intdef = intdef->next; + i++; + } + intdef = &standardint[0]; + defdef = NULL; +}