changed to mandoc as dependancy
sophuwu sophie@skisiel.com
Tue, 02 Apr 2024 19:44:06 +0200
6 files changed,
5 insertions(+),
4068 deletions(-)
M
main.go
→
main.go
@@ -25,22 +25,16 @@ var CFG struct {
Hostname string ListenAddr string ListenPort string - MANPATH []string Mandoc string } -func cmdout(s string) string { - b, e := exec.Command("mandoc").Output() - if e != nil { - log.Fatal("Fatal: unable to get " + ss[0]) - } - return strings.TrimSpace(string(b)) -} - func init() { - CFG.MANPATH = cmdout("manpath") CFG.Hostname, _ = os.Hostname() - CFG.Mandoc = cmdout() + b, e := exec.Command("which", "mandoc").Output() + if e != nil || len(b) == 0 { + log.Fatal("Fatal: no mandoc") + } + CFG.Mandoc = strings.TrimSpace(string(b)) CFG.ListenAddr = os.Getenv("ListenAddr") CFG.ListenPort = os.Getenv("ListenPort") if CFG.ListenPort == "" {@@ -127,7 +121,6 @@ search := strings.ReplaceAll(r.Form["search"][0], "\r", "")
args += "\n" + search cmd := exec.Command("apropos", strings.Split(args, "\n")...) cmd.Env = append(cmd.Env, os.Environ()...) - // cmd.Env = append(cmd.Env, "MANPATH="+CFG.MANPATH) b, e := cmd.Output() if e != nil { http.Error(w, "no results", http.StatusNotFound)
D
man2htmlsrc/abbrev.c
@@ -1,62 +0,0 @@
-#include <string.h> -#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 <B>nroff</B> and <B>troff</B>", - "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", "<FONT SIZE=\"-1\">SPARC</FONT> 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; -}
D
man2htmlsrc/cgibase.c
@@ -1,173 +0,0 @@
-/* - * Here are the routines of man2html that output a HREF string. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <ctype.h> /* tolower() */ -#include <string.h> /* strlen() */ -#include "defs.h" -#include <errno.h> -#include <limits.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; - -/* - * 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:/usr/lib/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 = ""; /* default */ - -/* - * Separator between URL and argument string. - * - * With http:<path to script>/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:<full path to script>?c+d+e no PATH_INFO is possible. - */ -static char sep = '?'; /* or '/' */ - -void -set_separator(char s) { - sep = s; -} - -void -set_lynxcgibase(char *s) { - int n = strlen(cgibase_ll_format) + strlen(s); - char *t = (char *) xmalloc(n); - - sprintf(t, cgibase_ll_format, s); - cgibase = t; -} - -void -set_cgibase(char *s) { - int n = strlen(cgibase_format) + strlen(s); - char *t = (char *) xmalloc(n); - - sprintf(t, cgibase_format, s); - cgibase = t; -} - -void -set_man2htmlpath(char *s) { - man2htmlpath = xstrdup(s); -} - -void -set_relative_html_links(void) { - relat_html_style = 1; -} - -/* What shall we say in case of relat_html_style? */ -static char *signature = "<HR>\n" -"This document was created by\n" -"<A HREF=\"%s%s\">man2html</A>,\n" -"using the manual pages.<BR>\n" -"%s\n"; - -#define TIMEFORMAT "%T GMT, %B %d, %Y" -#define TIMEBUFSZ 500 - -void print_sig() -{ - char timebuf[TIMEBUFSZ]; - struct tm *timetm; - time_t now; - char *source_date_epoch; - unsigned long long epoch; - char *endptr; - - timebuf[0] = 0; -#ifdef TIMEFORMAT - sprintf(timebuf, "Time: "); - source_date_epoch = getenv("SOURCE_DATE_EPOCH"); - if (source_date_epoch) { - errno = 0; - epoch = strtoull(source_date_epoch, &endptr, 10); - if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) - || (errno != 0 && epoch == 0)) { - fprintf(stderr, "Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - if (endptr == source_date_epoch) { - fprintf(stderr, "Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n", endptr); - exit(EXIT_FAILURE); - } - if (*endptr != '\0') { - fprintf(stderr, "Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n", endptr); - exit(EXIT_FAILURE); - } - if (epoch > ULONG_MAX) { - fprintf(stderr, "Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to: %lu but was found to be: %llu \n", ULONG_MAX ,epoch); - exit(EXIT_FAILURE); - } - now=epoch; - } - else { - now=time(NULL); - } - timetm=gmtime(&now); - strftime(timebuf+6, TIMEBUFSZ-6, TIMEFORMAT, timetm); - timebuf[TIMEBUFSZ-1] = 0; -#endif - printf(signature, cgibase, man2htmlpath, timebuf); -} - -void -include_file_html(char *g) { - printf("<A HREF=\"file:///usr/include/%s\">%s</A>>", g,g); -} - -void -man_page_html(char *sec, char *h) { - if (relat_html_style) { - if (!h) - printf("<A HREF=\"../index.html\">" - "Return to Main Contents</A>"); - else - printf("<A HREF=\"../man%s/%s.%s.html\">%s</A>", - sec, h, sec, h); - } else { - if (!h) - printf("<A HREF=\"%s%s\">Return to Main Contents</A>", - cgibase, man2htmlpath); - else if (!sec) - printf("<A HREF=\"%s%s%c%s\">%s</A>", - cgibase, man2htmlpath, sep, h, h); - else - printf("<A HREF=\"%s%s%c%s+%s\">%s</A>", - cgibase, man2htmlpath, sep, sec, h, h); - } -} - -void -ftp_html(char *f) { - printf("<A HREF=\"ftp://%s\">%s</A>", f, f); -} - -void -www_html(char *f) { - printf("<A HREF=\"http://%s\">%s</A>", f, f); -} - -void -mailto_html(char *g) { - printf("<A HREF=\"mailto:%s\">%s</A>", g, g); -} - -void -url_html(char *g) { - printf("<A HREF=\"%s\">%s</A>", g, g); -}
D
man2htmlsrc/defs.h
@@ -1,52 +0,0 @@
-extern int nroff; -extern int local_lynx; - -typedef struct STRDEF STRDEF; -struct STRDEF { - int nr,slen; - char *st; - STRDEF *next; -}; - -typedef struct LONGSTRDEF LONGSTRDEF; -struct LONGSTRDEF { - int nr,slen; - char *longname; - char *st; - LONGSTRDEF *next; -}; - - -typedef struct INTDEF INTDEF; -struct INTDEF { - int nr; - int val; - int incr; - INTDEF *next; -}; - -extern STRDEF *chardef, *strdef; -extern LONGSTRDEF *defdef; -extern INTDEF *intdef; - -#define V(A,B) ((A)*256+(B)) - -#include <sys/types.h> -extern LONGSTRDEF *find_longstrdef(LONGSTRDEF* head, int nr, char * longname, char ** out_longname); -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 set_separator(char); -extern void set_lynxcgibase(char *); -extern void set_cgibase(char *); -extern void set_man2htmlpath(char *); -extern void set_relative_html_links(void); -extern void *xmalloc(size_t size); -extern void *xrealloc(void *ptr, size_t size); -extern char *xstrdup(const char *s);
D
man2htmlsrc/man2html.c
@@ -1,3419 +0,0 @@
-/* -** 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. */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <sys/stat.h> -#include "defs.h" -//#include "../src/version.h" - -#define version "1" - -/* BSD mandoc Bd/Ed example(?) blocks */ -#define BD_LITERAL 1 -#define BD_INDENT 2 - -#define SIZE(a) (sizeof(a)/sizeof(*a)) -#define DOCTYPE "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n" -#define CONTENTTYPE "" - -static char NEWLINE[2]="\n"; -static char idxlabel[6] = "ixAAA"; - -#define INDEXFILE "/tmp/manindex.list" - -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]; - -#ifdef GUNZIP -/* from src/utils.c */ -static int -is_shell_safe(const char *ss, int quoted) { - char *bad = " ;'\\\"<>|"; - char *p; - - if (quoted) - bad++; /* allow a space inside quotes */ - for (p = bad; *p; p++) - if (strchr(ss, *p)) - return 0; - return 1; -} -#endif - -/* reads the entire manpage into buffer *buf and returns number of chars read */ -static int -read_manpage_into_buffer(char *path, char **buf) { - int compressed = 0; - FILE * f = NULL; - char * ext; - int l = 0; - struct stat stbuf; - - *buf = NULL; - if (!path) - return -1; - - if (!strcmp(path, "-")) - f = stdin; - else /* strcmp(path, "-") */ - { - char * tmp = NULL; - char * command = NULL; - char * openpath = path; -#ifdef GUNZIP - - if (is_shell_safe(openpath, 1)) { - ext = strrchr(openpath, '.'); - compressed = (ext && !strcmp(ext, ".gz")); - - if (!compressed && stat(openpath, &stbuf)) { - tmp = (char*) xmalloc(strlen(path) + 4); - sprintf(tmp, "%s.gz", path); - if ((compressed = !stat(tmp, &stbuf))) - openpath = tmp; - } - } - - if (compressed) { - command = (char*) xmalloc(strlen(openpath) + sizeof(GUNZIP) + 4); - sprintf(command, GUNZIP " '%s'", openpath); - f = popen(command, "r"); - } else -#endif - f = fopen(openpath, "r"); - - if (tmp) free(tmp); - if (command) free(command); - - if (!f) - return -1; - - } /* strcmp(path, "-") */ - - - /* 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 */ - if (compressed || f == stdin) { - int sz = 1024; - int ct = 1, tot = 0; - char *p = NULL; - - clearerr(f); - while (ct > 0) { - tot += ct; - if (feof(f)) - break; - sz = 2*sz+tot; - p = xrealloc(p, sz); - ct = fread(p+tot,1,sz-tot-XTRA,f); - } - - *buf = p; - l = tot-1; - } else { - int ct; - - l = 0; - if (fstat(fileno(f), &stbuf) != -1) - l = stbuf.st_size; - *buf = (char *) xmalloc((l+1+XTRA)*sizeof(char)); - ct = fread(*buf+1,1,l,f); - if (ct < l) - l = ct; - } - fclose(f); - return l; -} - -static char * -expand_char(int nr) -{ - STRDEF *h; - - if (!nr) - return NULL; - - h = chardef; - if (h->nr != V('*','*')) { - printf("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 - ** <name.h> -> 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, man page, include file */ - - out_length+=strlen(c); - - nr=0; - idtest[0]=strstr(c+1,"://"); - idtest[1]=strchr(c+1,'@'); - 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]<idtest[j])) j=i; - switch (j) { - case 5: /* <name.h> */ - f=idtest[5]; - h=f+2; - g=f; - while (g>c && g[-1]!=';') g--; - if (g!=c) { - char t; - t=*g; - *g=0; - printf("%s",c); - *g=t;*h=0; - include_file_html(g); - c=f+6; - } else { - f[5]=0; - printf("%s",c); - f[5]=';'; - c=f+5; - } - break; - case 4: /* man page? */ - 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])) - || (strncmp(f+1,"3pm",g-f-1) == 0)) - ) { - /* 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; - printf("%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; - printf("%s", c); - *f='('; - idtest[4]=f-1; - c=f; - break; /* man page */ - 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; - printf("%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; - printf("%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; - printf("%s",c); - *g=t;t=*h;*h=0; - mailto_html(g); - *h=t; - c=h; - } else { - *f=0; - printf("%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; - printf("%s", c); - *g=t; t=*h; *h=0; - url_html(g); - *h=t; - c=h; - } else { - f[1]=0; - printf("%s", c); - f[1]='/'; - c=f+1; - } - break; - default: - break; - } - nr=0; - if (idtest[0] && idtest[0]<c) idtest[0]=strstr(c+1,"://"); - if (idtest[1] && idtest[1]<c) idtest[1]=strchr(c+1,'@'); - if (idtest[2] && idtest[2]<c) idtest[2]=strstr(c,"www."); - if (idtest[3] && idtest[3]<c) idtest[3]=strstr(c,"ftp."); - if (idtest[4] && idtest[4]<c) idtest[4]=strchr(c+1,'('); - if (idtest[5] && idtest[5]<c) idtest[5]=strstr(c+1,".h>"); - for (i=0; i<6; i++) nr += (idtest[i]!=NULL); - } - printf("%s", c); -} - -int current_font=0; -int current_size=0; -int fillout = 1; - -/* - * Kludge: remove \a - in the context - * .TH NAME 2 date "Version" "Title" - * we got output \aTitle\a. - */ -static void -out_html(char *c) { - if (!c) - return; - if (no_newline_output) { /* remove \n if present */ - int i=0; - while (c[i]) { - if (!no_newline_output) - c[i-1]=c[i]; - if (c[i]=='\n') - no_newline_output=0; - i++; - } - if (!no_newline_output) - c[i-1]=0; - } - if (scaninbuff) { - while (*c) { - if (buffpos >= 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] = { "", "<DL COMPACT>\n", "<UL>", "<OL>" }; -static char *dl_close[4] = { "", "</DL>\n", "</UL>", "</OL>" }; - -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("<DT>"); -} - -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("<DL COMPACT><DT><DD>"); -} - -static inline void -dl_endlevel(void) { - if (itemdepth) { - dl_end(); - out_html("</DL>\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 - <DT><B>TIOCLINUX, subcode=0<DD> - Dump the screen. - </B><I>argp</I> points to a -from - .IP "\fBTIOCLINUX, subcode=0" - Dump the screen. - \fIargp\fP points to a -Bug 1: incorrect nesting: </B> is needed before <DD>. -Bug 2: incorrect font: after the .IP things are roman again. -*/ - -#define FO0 "" -#define FC0 "" -#define FO1 "<I>" -#define FC1 "</I>" -#define FO2 "<B>" -#define FC2 "</B>" -#define FO3 "<TT>" -#define FC3 "</TT>" - -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, "</FONT>"); - current_size=nr; - if (nr) { - int l; - strcat(sizebuf, "<FONT SIZE=\""); - l=strlen(sizebuf); - if (nr>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; - - -#define EXPAND_BRACKET for (c++, i=0; *c != ']'; c++) i = i * 256 + *c; if (i < 256) i = i * 256 + ' ' - -static char * -scan_escape(char *c) { - char *h=NULL; - char *tmp = NULL; - char b[10]; - 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++; - if (*c == '*' || *c == '@') { - int len = 0; - int quote = (*c == '@') ? 2 : 0; - - for (i = 0; ((h = argument[i])); i++) - len += strlen(h) + 1 + quote; - tmp = (char*) xmalloc(len + 1); - *tmp = 0; - - for (i = 0; ((h = argument[i])); i++) { - sprintf(tmp + strlen(tmp), " %s%s%s", - quote ? "\"" : "", - h, - quote ? "\"" : ""); - }; - h = tmp + 1; - } else { - 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 ':': - 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 '[': - EXPAND_BRACKET; - h = expand_char(i); - break; - case '*': - c++; - if (*c=='(') { - c++; - i= c[0]*256+c[1]; - c++; - } else if (*c == '[') { - EXPAND_BRACKET; - } 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 == '[') { - EXPAND_BRACKET; - } 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="<HR>"; 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 'N': - /* convert \N'ddd' into &#ddd; */ - c++; - i=*c; - j=0; - b[j++] = '&'; - b[j++] = '#'; - while (*(++c) != i) - if (isdigit(*c) && j < sizeof(b) - 2) - b[j++] = *c; - b[j++] = ';'; - b[j] = '\0'; - h = b; - 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="<BR>\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); - if (tmp) free(tmp); - 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); - if (*c != '.') c++; - if (*c != '.' && !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("</PRE>"); - } - while (*h && *h!='\n') h++; - if (h[-1]==';') { - /* scan table options */ - while (c<h) { - while (isspace(*c)) c++; - for (i=0; tableopt[i] && strncmp(tableopt[i],c,tableoptl[i]);i++); - c=c+tableoptl[i]; - switch (i) { - case 0: center=1; break; - case 1: expand=1; break; - case 2: box=1; break; - case 3: border=1; break; - case 4: box=2; break; - case 5: while (*c++!='('); itemsep=*c++; break; - case 6: while (*c++!='('); linesize=0; - while (isdigit(*c)) linesize=linesize*10+(*c++)-'0'; - break; - case 7: while (*c!=')') c++; - default: break; - } - c++; - } - c=h+1; - } - /* scan layout */ - c=scan_format(c,&layout, &maxcol); - currow=layout; - next_row(currow); - curfield=layout->first; - 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 */ - 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->rowspan<ti->rowspan) 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; - } - /* produce html output */ - if (center) out_html("<CENTER>"); - if (box==2) out_html("<TABLE BORDER><TR><TD>"); - out_html("<TABLE"); - if (box || border) { - out_html(" BORDER"); - if (!border) out_html("><TR><TD><TABLE"); - if (expand) out_html(" WIDTH=100%"); - } - out_html(">\n"); - currow=layout; - while (currow) { - j=0; - out_html("<TR VALIGN=top>"); - curfield=currow->first; - while (curfield) { - if (curfield->align!='S' && curfield->align!='^') { - out_html("<TD"); - switch (curfield->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("<HR><HR>"); break; - case '_': out_html("<HR>"); break; - default: - if (curfield->contents) out_html(curfield->contents); - break; - } - if (curfield->space) - for (i=0; i<curfield->space;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("<BR>"); - out_html("</TD>"); - } - curfield=curfield->next; - } - out_html("</TR>\n"); - currow=currow->next; - } - if (box && !border) out_html("</TABLE>"); - out_html("</TABLE>"); - if (box==2) out_html("</TABLE>"); - if (center) out_html("</CENTER>\n"); - else out_html("\n"); - if (!oldfillout) out_html("<PRE>"); - 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<value2); break; - case '>': 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, *t; - 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 == '"') { - if (skipspace && *(s+1) == '"') { - /* "" inside the quoted text means " */ - for (t = s++; t > words[*n]; t--) - *t = *(t-1); - words[*n]++; - } else { - *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, "</DL>\n"); - mip += 6; - } else { - strcpy(manidx+mip, "<DL>\n"); - mip += 5; - } - } - subs = level; - - scan_troff(item, 1, &c); - manidx_need(100 + strlen(c)); - sprintf(manidx+mip, "<DT><A HREF=\"#%s\">%s</A><DD>\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[30]; - int words; - char *sl; - LONGSTRDEF *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]); - /* search macro database of self-defined macros */ - owndef = find_longstrdef(defdef, i, c, NULL); - if (owndef) { - char **oldargument; - int deflen; - int onff; - sl=fill_words(c+strlen(owndef->longname), wordlist, SIZE(wordlist), &words, '\n'); - c=sl+1; - *sl=0; - for (i=1; i<words; i++) - wordlist[i][-1]=0; - for (i=0; i<words; i++) { - char *hl=NULL; - if (mandoc_command) - scan_troff_mandoc(wordlist[i],1,&hl); - else - scan_troff(wordlist[i],2,&hl); - wordlist[i]=hl; - } - for (i=words; i<SIZE(wordlist); i++) - wordlist[i]=NULL; - deflen = strlen(owndef->st); - 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<words; i++) if (wordlist[i]) free(wordlist[i]); - owndef->st[deflen+1]=0; - *sl='\n'; - } else 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 *hl; - de=(STRDEF*) xmalloc(sizeof(STRDEF)); - de->nr=i; - de->slen=0; - de->next=strdef; - de->st=NULL; - strdef=de; - hl=NULL; - c=scan_troff(c, 1, &hl); - de->st=hl; - de->slen=curpos; - } else { - if (mode) { /* .ds */ - char *hl=NULL; - c=scan_troff(c, 1, &hl); - free(de->st); /* segfault XXX */ - de->slen=curpos; - de->st=hl; - } 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("<DD>"); - else out_html("<BR>\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("<CENTER>\n"); - while (i && *c) { - char *line=NULL; - c=scan_troff(c,1, &line); - if (line && strncmp(line, "<BR>", 4)) { - out_html(line); - out_html("<BR>\n"); - i--; - } - } - out_html("</CENTER>\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("</PRE>\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("<PRE>\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("<P>"); else { - out_html(NEWLINE); - NEWLINE[0]='\n'; - } - curpos=0; - c=skip_till_newline(c); - break; - case V('s','o'): - { - 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] = '/'; -*/ - h = c; - } - - 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; -#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(CONTENTTYPE DOCTYPE); - printf("<HTML><HEAD><link rel=\"stylesheet\" href=\"/style.css\"><TITLE> Man page of %s</TITLE>\n" - "</HEAD><BODY>\n" - "See the man page for <A HREF=\"%s.html\">%s</A>.\n" - "</BODY></HTML>\n", - s, h, h); - } else -#endif - { - /* this works alright, except for section 3 */ - if ((l = read_manpage_into_buffer(h, &buf)) < 0) { - fprintf(stderr, - "man2html: unable to open or read file %s\n", h); - out_html("<BLOCKQUOTE>" - "man2html: unable to open or read file\n"); - out_html(h); - out_html("</BLOCKQUOTE>\n"); - } else { - 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("<BR>\n"); - c=c+j; - c=scan_expression(c, &j); - for (i=0; i<j; i++) out_html(" "); - curpos=j; - c=skip_till_newline(c); - break; - case V('t','m'): - c=c+j; - h=c; - while (*c!='\n') c++; - *c=0; - fprintf(stderr,"%s\n", h); /* XXX */ - *c='\n'; - break; - case V('B',' '): - case V('B','\n'): - case V('I',' '): - case V('I','\n'): - /* parse one line in a certain font */ - out_html(change_to_font(*c)); - trans_char(c, '"', '\a'); - c=c+j; - if (*c == '\n') c++; - c=scan_troff(c, 1, NULL); - out_html(change_to_font('R')); - out_html(NEWLINE); - if (fillout) curpos++; else curpos=0; - break; - case V('O','P'): /* groff man pages use this construction */ - /* .OP a b : [ <B>a</B> <I>b</I> ] */ - 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++; - break; - } - 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<words; i++) { - if (mode) { out_html(" "); curpos++; } - wordlist[i][-1]=' '; - out_html(change_to_font(font[i&1])); - scan_troff(wordlist[i],1,NULL); - } - out_html(change_to_font('R')); - if (mode) { out_html(" ]"); curpos++;} - out_html(NEWLINE); if (!fillout) curpos=0; else curpos++; - } - break; - case V('D','T'): - maxtstop = SIZE(tabstops); - for (j=0; j<maxtstop; j++) - tabstops[j]=(j+1)*8; - c=skip_till_newline(c); break; - case V('I','P'): - sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); - c = sl+1; - dl_begin(); - if (words) { - scan_troff(wordlist[0], 1,NULL); - } - out_html("<DD>"); - 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("<DD>"); - } - 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<words; j++) { - h=NULL; - scan_troff(wordlist[j], 1, &h); - fprintf(idxfile, "_\b@%s", h); - free(h); - } - fprintf(idxfile,"\n"); - } -#endif - out_html("<A NAME=\""); - out_html(idxlabel); - /* this will not work in mosaic (due to a bug). - ** Adding ' ' between '>' and '<' solves it, but creates - ** some space. A normal space does not work. - */ - out_html("\"></A>"); - break; - case V('P',' '): - case V('P','\n'): - case V('L','P'): - case V('P','P'): - dl_end(); - if (fillout) out_html("<P>\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("</PRE>"); - } - trans_char(c,'"', '\a'); - add_to_index(mode, c); - out_html("<A NAME=\""); - out_html(label); - /* for mosaic users */ - if (mode) out_html("\"> </A>\n<H3>"); - else out_html("\"> </A>\n<H2>"); - mandoc_synopsis = (strncmp(c, "SYNOPSIS", 8) == 0); - c = (mandoc_command ? scan_troff_mandoc : scan_troff)(c,1,NULL); - if (mode) out_html("</H3>\n"); - else out_html("</H2>\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); - /* - * fill_words changes `"' into `\a', - * remove all `\a' now - * robert@debian.org, Jan 2003 - */ - for (i=0; i<words; i++) { - if (wordlist[i][0] == '\a') { - char *tmp; - (wordlist[i])++; - if ((tmp = strchr(wordlist[i], '\a'))) - *tmp = '\0'; - } - } - *sl = 0; - if (words > 1) { - char *t = NULL; - char *s, *q; - int skip=0; - output_possible=1; - printf(CONTENTTYPE DOCTYPE); - out_html("<HTML><HEAD><link rel=\"stylesheet\" href=\"/style.css\"><TITLE>Man page of "); - scan_troff(wordlist[0], 0, &t); - /* we need to remove all html tags */ - for (s=q=t; *s; s++) { - if (skip && *s == '>') skip=0; - else if (!skip && *s == '<') skip=1; - else if (!skip) *q++ = *s; - } - *q = '\0'; - out_html(t); - free(t); - out_html("</TITLE>\n</HEAD><BODY>\n<H1>"); - scan_troff(wordlist[0], 0, NULL); - out_html("</H1>\nSection: "); - if (words>4) - scan_troff(wordlist[4], 0, NULL); - else - out_html(section_name(wordlist[1])); - out_html(" ("); - scan_troff(wordlist[1], 0, NULL); - if (words>2) { - out_html(")<BR>Updated: "); - scan_troff(wordlist[2], 1, NULL); - } else out_html(")"); - out_html("<BR><A HREF=\"#index\">Index</A>\n"); - man_page_html(0,0); /* Return to Main Contents */ - *sl='\n'; - out_html("<HR>\n"); - if (mandoc_command) out_html("<BR>BSD mandoc<BR>"); - } - 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 */ - { - LONGSTRDEF *de; - char *longname; - int olen=0; - c=c+j; - sl=fill_words(c, wordlist, SIZE(wordlist), &words, '\n'); - i=V(c[0],c[1]);j=2; - longname = c; - if (words == 1) wordlist[1]=".."; else { - wordlist[1]--; - wordlist[1][0]='.'; - j=3; - } - c=sl+1; - *sl=0; - sl=c; - while (*c && strncmp(c,wordlist[1],j)) c=skip_till_newline(c); - de = find_longstrdef(defdef, i, longname, &longname); - if (mode && de) olen=strlen(de->st); - j=olen+c-sl; - h= (char*) xmalloc((j*2+5)*sizeof(char)); - if (h) { - for (j=0; j<olen; j++) - h[j]=de->st[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 = (LONGSTRDEF*) xmalloc(sizeof(LONGSTRDEF)); - de->nr=i; - de->longname=longname; - de->slen=0; - 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("<P>\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("<P>\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("<DT>"); - 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("<DD>"); - } else if (dl_type(UL) || dl_type(OL)) { - out_html("<LI>"); - 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("<DD>"); - inXo = 0; - } - break; - case V('S','m'): /* BSD mandoc - called with arg on/off */ - case V('B','k'): /* BSD mandoc - may be called with -words arg*/ - case V('E','k'): /* BSD mandoc */ - c=skip_till_newline(c); - break; - 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("<BLOCKQUOTE>"); - 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("</BLOCKQUOTE>"); - 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("<BLOCKQUOTE>\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("<PRE>\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("</PRE>\n"); - } - } - if (mandoc_bd_options & BD_INDENT) - out_html("</BLOCKQUOTE>\n"); - curpos=0; - fillout=1; - c=skip_till_newline(c); - break; - case V('B','e'): /* BSD mandoc */ - c=c+j; - if (fillout) out_html("<P>"); 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("<P>\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; - while (*c == ' ' || *c == '\t') c++; - if (!mandoc_name) { - /* Save the name of the first .Nm call */ - char *end, t=0 /* just for gcc */; - end = strpbrk(c, "\t \n"); - if (end && end != c) { - t = *end; - *end = 0; - mandoc_name = xstrdup(c); - *end = t; - } - } - 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("<BR>"); - } - count++; - } - out_html(change_to_font('B')); - if (*c == '\n' || (ispunct(*c) && *(c+1) == '\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); - } - if (*c != '\n') { - 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: - if (mandoc_command && - ((isupper(*c) && islower(c[1])) - || (islower(*c) && isupper(c[1])))) { - /* - * Let through any BSD mandoc commands that haven't - * been dealt with. - * I don't want to miss anything out of the text. - */ - char buf[4]; - strncpy(buf,c,2); - buf[2] = ' '; - buf[3] = 0; - out_html(buf); /* Print the command (it might just be text). */ - c=c+j; - trans_char(c,'"','\a'); - if (*c == '\n') c++; /* really? */ - out_html(change_to_font('R')); - c=scan_troff(c, 1, NULL); - out_html(NEWLINE); - if (fillout) curpos++; else curpos=0; - } else - c=skip_till_newline(c); - break; - } - } - if (fillout) { out_html(NEWLINE); curpos++; } - NEWLINE[0]='\n'; - return c; -} - -static int contained_tab=0; -static int mandoc_line=0;/* Signals whether to look for embedded mandoc cmds */ - -static char * -scan_troff(char *c, int san, char **result) { /* san : stop at newline */ - char *h; - char intbuff[500]; - int ibp=0; -#define FLUSHIBP if (ibp) { intbuff[ibp]=0; out_html(intbuff); ibp=0; } - char *exbuffer; - int exbuffpos, exbuffmax, exscaninbuff, exnewline_for_fun; - int usenbsp = 0; - - exbuffer = buffer; - exbuffpos = buffpos; - exbuffmax = buffmax; - exnewline_for_fun = newline_for_fun; - exscaninbuff = scaninbuff; - newline_for_fun = 0; - if (result) { - if (*result) { - buffer = *result; - buffpos = strlen(buffer); - buffmax = buffpos; - } else { - buffer = (char *) xmalloc(1000*sizeof(char)); - buffpos = 0; - buffmax = 1000; - } - scaninbuff = 1; - } - h = c; - /* start scanning */ - while (*h && (!san || newline_for_fun || *h != '\n')) { - if (*h == escapesym) { - h++; - FLUSHIBP; - h = scan_escape(h); - } else if (san != 2 && *h == controlsym && h[-1] == '\n') { - h++; - FLUSHIBP; - h = scan_request(h); - if (san && h[-1] == '\n') h--; - } else if (san != 2 && mandoc_line - && *(h) && isupper(*(h)) - && *(h+1) && islower(*(h+1)) - && *(h+2) && isspace(*(h+2))) { - /* BSD imbedded command eg ".It Fl Ar arg1 Fl Ar arg2" */ - FLUSHIBP; - h = scan_request(h); - if (san && h[-1] == '\n') h--; - } else if (san != 2 && *h == nobreaksym && h[-1] == '\n') { - h++; - FLUSHIBP; - h = scan_request(h); - if (san && h[-1] == '\n') h--; - } else { - if (h[-1] == '\n' && still_dd && isalnum(*h)) { - /* sometimes a .HP request is not followed by a .br request */ - FLUSHIBP; - out_html("<DD>"); - 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 (curpos<tabstops[curtab]) { - intbuff[ibp++]=' '; - if (ibp>480) { FLUSHIBP; } - curpos++; - } - } else { - out_html("<TT>"); - while (curpos < tabstops[curtab]) { - out_html(" "); - curpos++; - } - out_html("</TT>"); - } - } - } - break; - default: - if (*h == ' ' && (h[-1] == '\n' || usenbsp)) { - FLUSHIBP; - if (!usenbsp && fillout) { - out_html("<BR>"); - 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; - -static void -error_page(int status, char *s, char *t, ...) { - va_list p; - - switch(status) { - case 403: - //printf("Status: 403 Forbidden\n"); - break; - case 404: - //printf("Status: 404 Not Found\n"); - break; - case 500: - //printf("Status: 500 Internal Server Error\n"); - break; - case 0: - default: - break; - } - - printf(CONTENTTYPE DOCTYPE); - printf("<HTML><HEAD><link rel=\"stylesheet\" href=\"/style.css\"><TITLE>%s</TITLE></HEAD>\n" - "<BODY>\n<H1>%s</H1>\n", s, s); - va_start(p, t); - vfprintf(stdout, t, p); - va_end(p); - printf("</BODY></HTML>\n"); - exit(0); -} - -char * -xstrdup(const char *s) { - char *p = strdup(s); - if (p == NULL) - error_page(500, "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(500, "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(500, "Out of memory", - "Sorry, out of memory, aborting...\n"); - return p; -} - -static void -usage(void) { - error_page(500, "man2html: bad invocation", - "Call: man2html [-l|-h host.domain:port] [-p|-q] [filename]\n" - "or: man2html -r [filename]\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; - if (chdir(s) == 0) { - 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) { - int l, c; - char *buf, *filename, *fnam = NULL; - -#ifdef __CYGWIN__ - int opterr; - - extern int optind; - extern char *optarg; -#endif - -/* printf("Content-type: text/html\n\n"); */ - - opterr = 0; /* no stderr error messages */ - while ((c = getopt (argc, argv, "D:E:hH:lL:M:pqr?vVf")) != -1) { - switch(c) { - case 'D': - goto_dir(optarg, 0, 0); break; - case 'E': - error_page(0, "Error", "%s", optarg); break; - case 'h': - set_cgibase("localhost"); break; - case 'H': - set_cgibase(optarg); break; - case 'l': - set_lynxcgibase("/usr/lib"); break; - case 'L': - set_lynxcgibase(optarg); break; - case 'M': - set_man2htmlpath(optarg); break; - case 'p': - set_separator('/'); break; - case 'q': - set_separator('?'); break; - case 'r': - set_relative_html_links(); break; - case 'v': - case 'V': - error_page(0, "Version", "%s from man-%s", argv[0], version); - exit(0); - case '?': - default: - usage(); - case 'f': /* It is rumoured that some other - incarnation of man2html uses this flag; - ignore when given for compatibility. */ - /* case 'F': this will assign a format for man_page_html() */ - break; - } - } - - /* Find filename */ - if (argc == optind+1) - fnam = argv[optind]; - else if (argc != optind) - usage(); - - filename = fnam; - directory = 0; - - /* Open input file */ - if (!fnam || !strcmp(fnam, "-")) { - fnam = "-"; - fname = "(stdin)"; - } else { - /* do a chdir() first, to get .so expansion right */ - goto_dir(fnam, &directory, &fnam); - fname = fnam; - } - - l = read_manpage_into_buffer(fnam, &buf); - if (l < 0) - error_page(404, "File not found", "Could not open %s\n", fname); - - 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("</PRE>"); - } - out_html(NEWLINE); - if (output_possible) { - /* for mosaic users */ - if (manidx) { - printf("<HR>\n<A NAME=\"index\"> </A><H2>Index</H2>\n<DL>\n"); - manidx[mip]=0; - printf("%s", manidx); - if (subs) printf("</DL>\n"); - printf("</DL>\n"); - } - print_sig(); - printf("</BODY>\n</HTML>\n"); - } else { - if (!filename) - filename = fname; - if (*filename == '/') - error_page(403, "Invalid Man Page", - "The requested file %s is not a valid (unformatted) " - "man page.\nIf the file is a formatted man page, " - "you could try to load the\n" - "<A HREF=\"file://%s\">plain file</A>.\n", - filename, filename); - else - error_page(403, "Invalid Man Page", - "The requested file %s is not a valid (unformatted) " - "man page.", filename); - } - if (idxfile) - fclose(idxfile); - if (buf) - free(buf); - return 0; -}
D
man2htmlsrc/strdefs.c
@@ -1,350 +0,0 @@
-#include "defs.h" -#include <ctype.h> -#include <string.h> - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -int nroff = 1; - -#define NROFF (-666) -#define TROFF (-667) - -STRDEF *chardef, *strdef; -LONGSTRDEF *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('<','='), 2, "<=", NULL }, /* less equal */ - { V('>','='), 2, ">=;", NULL }, /* greather equal */ - { V('A','m'), 1, "&", NULL }, /* infinity */ - { V('B','a'), 1, "|", NULL }, /* vartical bar */ - { V('G','e'), 2, ">=;", NULL }, /* greather equal */ - { V('G','t'), 1, ">", NULL }, /* greather than */ - { V('I','f'), 1, "∞", NULL }, /* infinity */ - { V('L','e'), 2, "<=", NULL }, /* less equal */ - { V('L','q'), 1, "“", NULL }, /* left double quote */ - { V('L','t'), 1, "<", NULL }, /* less than */ - { V('N','a'), 3, "NaN", NULL }, /* not a number */ - { V('N','e'), 2, "!=", NULL }, /* not equal */ - { V('P','i'), 2, "Pi", NULL }, /* pi */ - { V('P','m'), 1, "±", NULL }, /* plus minus */ - { V('R',' '), 1, "®", NULL }, - { V('R','q'), 1, "”", NULL }, /* right double quote */ - { V('a','a'), 1, "'", NULL }, /* accute accent */ - { V('g','a'), 1, "`", NULL }, /* grave accent */ - { V('l','q'), 2, "``", NULL }, - { V('q',' '), 1, """, NULL }, /* straight double quote */ - { V('r','q'), 2, "''", NULL }, - { V('u','a'), 1, "^", NULL }, /* upwards arrow */ - { 0, 0, NULL, NULL} -}; - -static STRDEF standardchar[] = { - { V('*','*'), 1, "*", NULL }, /* math star */ - { V('*','A'), 1, "Α", NULL }, - { V('*','B'), 1, "Β", NULL }, - { V('*','C'), 1, "Ξ", NULL }, - { V('*','D'), 1, "Δ", NULL }, - { V('*','E'), 1, "Ε", NULL }, - { V('*','F'), 1, "Φ", NULL }, - { V('*','G'), 1, "Γ", NULL }, - { V('*','H'), 1, "Θ", NULL }, - { V('*','I'), 1, "Ι", NULL }, - { V('*','K'), 1, "Κ", NULL }, - { V('*','L'), 1, "Λ", NULL }, - { V('*','M'), 1, "Μ", NULL }, - { V('*','N'), 1, "Ν", NULL }, - { V('*','O'), 1, "Ο", NULL }, - { V('*','P'), 1, "Π", NULL }, - { V('*','Q'), 1, "Ψ", NULL }, - { V('*','R'), 1, "Ρ", NULL }, - { V('*','S'), 1, "Σ", NULL }, - { V('*','T'), 1, "Τ", NULL }, - { V('*','U'), 1, "Υ", NULL }, - { V('*','W'), 1, "Ω", NULL }, - { V('*','X'), 1, "Χ", NULL }, - { V('*','Y'), 1, "Η", NULL }, - { V('*','Z'), 1, "Ζ", NULL }, - { V('*','a'), 1, "α", NULL }, - { V('*','b'), 1, "β", NULL }, - { V('*','c'), 1, "ξ", NULL }, - { V('*','d'), 1, "δ", NULL }, - { V('*','e'), 1, "ε", NULL }, - { V('*','f'), 1, "φ", NULL }, - { V('*','g'), 1, "γ", NULL }, - { V('*','h'), 1, "θ", NULL }, - { V('*','i'), 1, "ι", NULL }, - { V('*','k'), 1, "κ", NULL }, - { V('*','l'), 1, "λ", NULL }, - { V('*','m'), 1, "μ", NULL }, - { V('*','n'), 1, "ν", NULL }, - { V('*','o'), 1, "ο", NULL }, - { V('*','p'), 1, "π", NULL }, - { V('*','q'), 1, "ψ", NULL }, - { V('*','r'), 1, "ρ", NULL }, - { V('*','s'), 1, "σ", NULL }, - { V('*','t'), 1, "τ", NULL }, - { V('*','u'), 1, "υ", NULL }, - { V('*','w'), 1, "ω", NULL }, - { V('*','x'), 1, "χ", NULL }, - { V('*','y'), 1, "η", NULL }, - { V('*','z'), 1, "ζ", NULL }, - { V('\'','A'), 1, "Á", NULL }, - { V('\'','E'), 1, "É", NULL }, - { V('\'','I'), 1, "Í", NULL }, - { V('\'','O'), 1, "Ó", NULL }, - { V('\'','U'), 1, "Ú", NULL }, - { V('\'','Y'), 1, "Ý", NULL }, - { V('\'','a'), 1, "á", NULL }, - { V('\'','e'), 1, "é", NULL }, - { V('\'','i'), 1, "í", NULL }, - { V('\'','o'), 1, "ó", NULL }, - { V('\'','u'), 1, "ú", NULL }, - { V('\'','y'), 1, "ý", NULL }, - { V('!','='), 1, "≠", NULL }, - { V('%','0'), 1, "‰", NULL }, - { V('+','-'), 1, "±", NULL }, - { V(',','C'), 1, "Ç", NULL }, - { V(',','c'), 1, "ç", NULL }, - { V('-','>'), 1, "→", NULL }, - { V('-','D'), 1, "Ð", NULL }, - { V('.','i'), 1, "ı", NULL }, - { V('/','L'), 1, "Ł", NULL }, - { V('/','O'), 1, "Ø", NULL }, - { V('/','l'), 1, "ł", NULL }, - { V('/','o'), 1, "ø", NULL }, - { V('1','2'), 1, "½", NULL }, - { V('1','4'), 1, "¼", NULL }, - { V('3','4'), 1, "¾", NULL }, - { V(':','A'), 1, "Ä", NULL }, - { V(':','E'), 1, "Ë", NULL }, - { V(':','I'), 1, "Ï", NULL }, - { V(':','O'), 1, "Ö", NULL }, - { V(':','U'), 1, "Ü", NULL }, - { V(':','a'), 1, "ä", NULL }, - { V(':','e'), 1, "ë", NULL }, - { V(':','i'), 1, "ï", NULL }, - { V(':','o'), 1, "ö", NULL }, - { V(':','u'), 1, "ü", NULL }, - { V(':','y'), 1, "ÿ", NULL }, - { V('<','-'), 1, "←", NULL }, - { V('<','='), 1, "≤", NULL }, - { V('<','>'), 1, "↔", NULL }, - { V('=','='), 1, "≡", NULL }, - { V('=','~'), 1, "≅", NULL }, - { V('>','='), 1, "≥", NULL }, - { V('A','E'), 1, "Æ", NULL }, - { V('A','h'), 1, "&alepfsym;", NULL }, - { V('C','R'), 1, "␍", NULL }, - { V('C','s'), 1, "¤", NULL }, - { V('D','o'), 1, "$", NULL }, - { V('E','u'), 1, "€", NULL }, - { V('F','c'), 1, "»", NULL }, - { V('F','i'), 3, "ffi", NULL }, - { V('F','l'), 3, "ffl", NULL }, - { V('F','o'), 1, "«", NULL }, - { V('O','E'), 1, "Œ", NULL }, - { V('P','o'), 1, "£", NULL }, - { V('S','1'), 1, "¹", NULL }, - { V('S','2'), 1, "²", NULL }, - { V('S','3'), 1, "³", NULL }, - { V('S','d'), 1, "ð", NULL }, - { V('T','P'), 1, "Þ", NULL }, - { V('T','p'), 1, "þ", NULL }, - { V('Y','e'), 1, "¥", NULL }, - { V('^','A'), 1, "Â", NULL }, - { V('^','E'), 1, "Ê", NULL }, - { V('^','I'), 1, "Î", NULL }, - { V('^','O'), 1, "Ô", NULL }, - { V('^','U'), 1, "Û", NULL }, - { V('^','a'), 1, "â", NULL }, - { V('^','e'), 1, "ê", NULL }, - { V('^','i'), 1, "î", NULL }, - { V('^','o'), 1, "ô", NULL }, - { V('^','u'), 1, "û", NULL }, - { V('`','A'), 1, "À", NULL }, - { V('`','E'), 1, "È", NULL }, - { V('`','I'), 1, "Ì", NULL }, - { V('`','O'), 1, "Ò", NULL }, - { V('`','U'), 1, "Ù", NULL }, - { V('`','a'), 1, "à", NULL }, - { V('`','e'), 1, "è", NULL }, - { V('`','i'), 1, "ì", NULL }, - { V('`','o'), 1, "ò", NULL }, - { V('`','u'), 1, "ù", NULL }, - { V('a','a'), 1, "´", NULL }, - { V('a','e'), 1, "æ", NULL }, - { V('a','p'), 1, "≈", NULL }, - { V('a','q'), 1, "'", NULL }, - { V('a','t'), 1, "@", NULL }, - { V('a','~'), 1, "~", NULL }, - { V('b','a'), 1, "|", NULL }, - { V('b','b'), 1, "|", NULL }, - { V('b','r'), 1, "|", NULL }, - { V('b','r'), 1, "|", NULL }, - { V('b','u'), 1, "•", NULL }, - { V('b','v'), 1, "|", NULL }, - { V('c','*'), 1, "⊗", NULL }, - { V('c','+'), 1, "⊕", NULL }, - { V('c','i'), 1, "○", NULL }, - { V('c','o'), 1, "©", NULL }, - { V('c','q'), 1, "'", NULL }, - { V('c','t'), 1, "¢", NULL }, - { V('d','A'), 1, "⇓", NULL }, - { V('d','a'), 1, "↓", NULL }, - { V('d','d'), 1, "=", NULL }, - { V('d','e'), 1, "°", NULL }, - { V('d','g'), 1, "-", NULL }, - { V('d','i'), 1, "÷", NULL }, - { V('d','q'), 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('e','u'), 1, "€", NULL }, - { V('f','/'), 1, "⁄", NULL }, - { V('f','c'), 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('f','o'), 1, "‹", NULL }, - { V('g','a'), 1, "`", NULL }, - { V('h','A'), 1, "⇔", NULL }, - { V('h','y'), 1, "-", NULL }, - { V('i','f'), 1, "∞", NULL }, - { V('i','s'), 8, "Integral", NULL }, /* integral sign */ - { V('l','A'), 1, "⇐", NULL }, - { V('l','B'), 1, "[", NULL }, - { V('l','C'), 1, "{", NULL }, - { V('l','a'), 1, "<", NULL }, - { V('l','b'), 1, "[", NULL }, - { V('l','c'), 2, "|¯", NULL }, - { V('l','f'), 2, "|_", NULL }, - { V('l','h'), 1, "☚", NULL }, - { V('l','k'), 1, "<FONT SIZE=\"+2\">{</FONT>", NULL }, - { V('l','q'), 1, "\"", NULL }, - { V('l','z'), 1, "◊", NULL }, - { V('m','c'), 1, "µ", NULL }, - { V('m','i'), 1, "-", NULL }, - { V('m','u'), 1, "×", NULL }, - { V('n','o'), 1, "¬", NULL }, - { V('o','A'), 1, "Å", NULL }, - { V('o','a'), 1, "å", NULL }, - { V('o','e'), 1, "œ", NULL }, - { V('o','q'), 1, "'", NULL }, - { V('o','r'), 1, "|", NULL }, - { V('p','d'), 1, "d", NULL }, /* partial derivative */ - { V('p','l'), 1, "+", NULL }, - { V('p','s'), 1, "¶", NULL }, - { V('r','!'), 1, "¡", NULL }, - { V('r','?'), 1, "¿", NULL }, - { V('r','A'), 1, "⇒", NULL }, - { V('r','B'), 1, "]", NULL }, - { V('r','C'), 1, "}", NULL }, - { V('r','a'), 1, ">", NULL }, - { V('r','c'), 2, "¯|", NULL }, - { V('r','f'), 2, "_|", NULL }, - { V('r','g'), 1, "®", NULL }, - { V('r','h'), 1, "☛", NULL }, - { V('r','k'), 1, "<FONT SIZE=\"+2\">}</FONT>", NULL }, - { V('r','n'), 1, "¯", NULL }, - { V('r','q'), 1, "\"", NULL }, - { V('r','s'), 1, "\\", NULL }, - { V('r','u'), 1, "_", NULL }, - { V('s','c'), 1, "§", NULL }, - { V('s','h'), 1, "#", NULL }, - { V('s','l'), 1, "/", NULL }, - { V('s','q'), 1, "□", NULL }, - { V('s','s'), 1, "ß", NULL }, - { V('t','f'), 1, "∴", NULL }, - { V('t','i'), 1, "~", NULL }, - { V('t','m'), 1, "™", NULL }, - { V('t','s'), 1, "s", NULL }, /* should be terminal sigma */ - { V('u','A'), 1, "⇑", NULL }, - { V('u','a'), 1, "↑", NULL }, - { V('u','l'), 1, "_", NULL }, - { V('~','A'), 1, "Ã", NULL }, - { V('~','N'), 1, "Ñ", NULL }, - { V('~','O'), 1, "Õ", NULL }, - { V('~','a'), 1, "ã", NULL }, - { V('~','n'), 1, "ñ", NULL }, - { V('~','o'), 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; -} - - -LONGSTRDEF* find_longstrdef(LONGSTRDEF * head, int nr, char * longname, char ** out_longname) -{ - char *p, c; - LONGSTRDEF *de; - - p = longname; - while (p && !isspace(*p)) p++; - c = *p; - *p = 0; - - de = head; - while (de && (de->nr != nr || (de->longname && strcmp(longname, de->longname)))) - de = de->next; - - if (out_longname) - *out_longname = de ? de->longname : xstrdup(longname); - *p = c; - return de; -}