");
+ out_html("
|
"); + fillout=oldfillout; + out_html(change_to_size(oldsize)); + out_html(change_to_font(oldfont)); + return c; +} + +char *scan_expression(char *c, int *result) { + int value=0,value2,sign=1,opex=0; + char oper='c'; + + if (*c=='!') { + c=scan_expression(c+1, &value); + value= (!value); + } else if (*c=='n') { + c++; + value=nroff; + } else if (*c=='t') { + c++; + value=1-nroff; + } else if (*c=='\'' || *c=='"' || *c<' ' || (*c=='\\' && c[1]=='(')) { + /* ?string1?string2? + ** test if string1 equals string2. + */ + char *st1=NULL, *st2=NULL, *h; + char *tcmp=NULL; + char sep; + sep=*c; + if (sep=='\\') { + tcmp=c; + c=c+3; + } + c++; + h=c; + while (*c!= sep && (!tcmp || strncmp(c,tcmp,4))) c++; + *c='\n'; + scan_troff(h, 1, &st1); + *c=sep; + if (tcmp) c=c+3; + c++; + h=c; + while (*c!=sep && (!tcmp || strncmp(c,tcmp,4))) c++; + *c='\n'; + scan_troff(h,1,&st2); + *c=sep; + if (!st1 && !st2) value=1; + else if (!st1 || !st2) value=0; + else value=(!strcmp(st1, st2)); + if (st1) free(st1); + if (st2) free(st2); + if (tcmp) c=c+3; + c++; + } else { + while (*c && !isspace(*c) && *c!=')') { + opex=0; + switch (*c) { + case '(': + c=scan_expression(c+1, &value2); + value2=sign*value2; + opex=1; + break; + case '.': + case '0': case '1': + case '2': case '3': + case '4': case '5': + case '6': case '7': + case '8': case '9': { + int num=0,denum=1; + value2=0; + while (isdigit(*c)) value2=value2*10+((*c++)-'0'); + if (*c=='.') { + c++; + while (isdigit(*c)) { + num=num*10+((*c++)-'0'); + denum=denum*10; + } + } + if (isalpha(*c)) { + /* scale indicator */ + switch (*c) { + case 'i': /* inch -> 10pt */ + value2=value2*10+(num*10+denum/2)/denum; + num=0; + break; + default: + break; + } + c++; + } + value2=value2+(num+denum/2)/denum; + value2=sign*value2; + opex=1; + break; + } + case '\\': + c=scan_escape(c+1); + value2=intresult*sign; + if (isalpha(*c)) c++; /* scale indicator */ + opex=1; + break; + case '-': + if (oper) { sign=-1; c++; break; } + case '>': + case '<': + case '+': + case '/': + case '*': + case '%': + case '&': + case '=': + case ':': + if (c[1]=='=') oper=(*c++) +16; else oper=*c; + c++; + break; + default: c++; break; + } + if (opex) { + sign=1; + switch (oper) { + case 'c': value=value2; break; + case '-': value=value-value2; break; + case '+': value=value+value2; break; + case '*': value=value*value2; break; + case '/': if (value2) value=value/value2; break; + case '%': if (value2) value=value%value2; break; + case '<': value=(value\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("': value=(value>value2); break; + case '>'+16: value=(value>=value2); break; + case '<'+16: value=(value<=value2); break; + case '=': case '='+16: value=(value==value2); break; + case '&': value = (value && value2); break; + case ':': value = (value || value2); break; + default: fprintf(stderr, + "man2html: Unknown operator %c.\n", oper); + } + oper=0; + } + } + if (*c==')') c++; + } + *result=value; + return c; +} + +static void +trans_char(char *c, char s, char t) { + char *sl = c; + int slash = 0; + + while (*sl && (*sl != '\n' || slash)) { + if (!slash) { + if (*sl == escapesym) + slash = 1; + else if (*sl == s) + *sl = t; + } else + slash = 0; + sl++; + } +} + +/* + * Read STR until end-of-line (not preceded by \). + * Find whitespace separated words, and store starts in WORDS of lth MAXN. + * Return number of words in N. + * Replace each end-of-word by the character EOW (usually \n or 0). + * Return pointer to last char seen (either \n or 0). + * + * A part \"... is skipped. + * Quotes not preceded by \ are replaced by \a. + */ +static char * +fill_words(char *str, char *words[], int maxn, int *n, char eow) { + char *s = str; + int backslash = 0; + int skipspace = 0; /* 1 if space is not end-of-word */ + + *n = 0; + words[*n] = s; + while (*s && (*s != '\n' || backslash)) { + if (!backslash) { + if (*s == '"') { + *s = '\a'; + skipspace = !skipspace; + } else if (*s == escapesym) { + backslash = 1; + } else if ((*s == ' ' || *s == '\t') && !skipspace) { + *s = eow; + if (words[*n] != s && *n < maxn-1) + (*n)++; + words[*n] = s+1; + } + } else { + if (*s == '"') { + s--; + *s = eow; + if (words[*n] != s && *n < maxn-1) + (*n)++; + s++; + while (*s && *s != '\n') s++; + words[*n] = s; + s--; + } + backslash = 0; + } + s++; + } + if (s != words[*n]) + (*n)++; + return s; +} + + +char *section_list[] = { + "1", "User Commands ", + "1C", "User Commands", + "1G", "User Commands", + "1S", "User Commands", + "1V", "User Commands ", + "2", "System Calls", + "2V", "System Calls", + "3", "C Library Functions", + "3C", "Compatibility Functions", + "3F", "Fortran Library Routines", + "3K", "Kernel VM Library Functions", + "3L", "Lightweight Processes Library", + "3M", "Mathematical Library", + "3N", "Network Functions", + "3R", "RPC Services Library", + "3S", "Standard I/O Functions", + "3V", "C Library Functions", + "3X", "Miscellaneous Library Functions", + "4", "Devices and Network Interfaces", + "4F", "Protocol Families", + "4I", "Devices and Network Interfaces", + "4M", "Devices and Network Interfaces", + "4N", "Devices and Network Interfaces", + "4P", "Protocols", + "4S", "Devices and Network Interfaces", + "4V", "Devices and Network Interfaces", + "5", "File Formats", + "5V", "File Formats", + "6", "Games and Demos", + "7", "Environments, Tables, and Troff Macros", + "7V", "Environments, Tables, and Troff Macros", + "8", "Maintenance Commands", + "8C", "Maintenance Commands", + "8S", "Maintenance Commands", + "8V", "Maintenance Commands", + "L", "Local Commands", +/* for Solaris: + "1", "User Commands", + "1B", "SunOS/BSD Compatibility Package Commands", + "1b", "SunOS/BSD Compatibility Package Commands", + "1C", "Communication Commands ", + "1c", "Communication Commands", + "1F", "FMLI Commands ", + "1f", "FMLI Commands", + "1G", "Graphics and CAD Commands ", + "1g", "Graphics and CAD Commands ", + "1M", "Maintenance Commands", + "1m", "Maintenance Commands", + "1S", "SunOS Specific Commands", + "1s", "SunOS Specific Commands", + "2", "System Calls", + "3", "C Library Functions", + "3B", "SunOS/BSD Compatibility Library Functions", + "3b", "SunOS/BSD Compatibility Library Functions", + "3C", "C Library Functions", + "3c", "C Library Functions", + "3E", "C Library Functions", + "3e", "C Library Functions", + "3F", "Fortran Library Routines", + "3f", "Fortran Library Routines", + "3G", "C Library Functions", + "3g", "C Library Functions", + "3I", "Wide Character Functions", + "3i", "Wide Character Functions", + "3K", "Kernel VM Library Functions", + "3k", "Kernel VM Library Functions", + "3L", "Lightweight Processes Library", + "3l", "Lightweight Processes Library", + "3M", "Mathematical Library", + "3m", "Mathematical Library", + "3N", "Network Functions", + "3n", "Network Functions", + "3R", "Realtime Library", + "3r", "Realtime Library", + "3S", "Standard I/O Functions", + "3s", "Standard I/O Functions", + "3T", "Threads Library", + "3t", "Threads Library", + "3W", "C Library Functions", + "3w", "C Library Functions", + "3X", "Miscellaneous Library Functions", + "3x", "Miscellaneous Library Functions", + "4", "File Formats", + "4B", "SunOS/BSD Compatibility Package File Formats", + "4b", "SunOS/BSD Compatibility Package File Formats", + "5", "Headers, Tables, and Macros", + "6", "Games and Demos", + "7", "Special Files", + "7B", "SunOS/BSD Compatibility Special Files", + "7b", "SunOS/BSD Compatibility Special Files", + "8", "Maintenance Procedures", + "8C", "Maintenance Procedures", + "8c", "Maintenance Procedures", + "8S", "Maintenance Procedures", + "8s", "Maintenance Procedures", + "9", "DDI and DKI", + "9E", "DDI and DKI Driver Entry Points", + "9e", "DDI and DKI Driver Entry Points", + "9F", "DDI and DKI Kernel Functions", + "9f", "DDI and DKI Kernel Functions", + "9S", "DDI and DKI Data Structures", + "9s", "DDI and DKI Data Structures", + "L", "Local Commands", +*/ + NULL, "Misc. Reference Manual Pages", + NULL, NULL +}; + +static char * +section_name(char *c) +{ + int i=0; + + if (!c) return ""; + while (section_list[i] && strcmp(c,section_list[i])) i=i+2; + if (section_list[i+1]) return section_list[i+1]; + else return c; +} + +int manidxlen = 0; +char *manidx = NULL; +int subs = 0; +int mip = 0; /* current offset in manidx[] */ +char label[5]="lbAA"; + +static void +manidx_need(int m) { + if (mip + m >= manidxlen) { + manidxlen += 10000; + manidx = xrealloc(manidx, manidxlen); + } +} + +static void +add_to_index(int level, char *item) +{ + char *c = NULL; + + label[3]++; + if (label[3]>'Z') { + label[3]='A'; + label[2]++; + } + + if (level != subs) { + manidx_need(6); + if (subs) { + strcpy(manidx+mip, "\n"); + mip += 6; + } else { + strcpy(manidx+mip, " \n"); + mip += 5; + } + } + subs = level; + + scan_troff(item, 1, &c); + manidx_need(100 + strlen(c)); + sprintf(manidx+mip, "
- %s
- \n", label, c); + if (c) free(c); + while (manidx[mip]) mip++; +} + +static char * +skip_till_newline(char *c) +{ + int lvl=0; + + while (*c && (*c!='\n' || lvl>0)) { + if (*c=='\\') { + c++; + if (*c=='}') lvl--; else if (*c=='{') lvl++; + } + c++; + } + c++; + if (lvl<0 && newline_for_fun) { + newline_for_fun = newline_for_fun+lvl; + if (newline_for_fun<0) newline_for_fun=0; + } + return c; +} + +int ifelseval=0; + +static char * +scan_request(char *c) { + /* BSD Mandoc stuff - by Michael Hamilton */ + static int mandoc_synopsis=0; /* True if we are in the synopsis section */ + static int mandoc_command=0; /* True if this is mandoc page */ + static int mandoc_bd_options; /* Only copes with non-nested Bd's */ + static int inXo=0; + + int i,j,mode = 0; + char *h; + char *wordlist[20]; + int words; + char *sl; + STRDEF *owndef; + + while (*c == ' ' || *c == '\t') + c++; + if (c[0] == '\n') + return c+1; + if (c[1] == '\n') + j = 1; + else + j = 2; + while (c[j] == ' ' || c[j] == '\t') + j++; + if (c[0] == escapesym) { + /* some pages use .\" .\$1 .\} */ + /* .\$1 is too difficult/stupid */ + if (c[1] == '$') + c = skip_till_newline(c); + else + c = scan_escape(c+1); + } else { + i=V(c[0],c[1]); + switch (i) { + case V('a','b'): + h=c+j; + while (*h && *h !='\n') h++; + *h=0; + if (scaninbuff && buffpos) { + buffer[buffpos]=0; + printf("%s\n", buffer); + } + fprintf(stderr, "%s\n", c+2); /* XXX */ + exit(0); + break; + case V('d','i'): + { + STRDEF *de; + c=c+j; + i=V(c[0],c[1]); + if (*c == '\n') { c++;break; } + while (*c && *c!='\n') c++; + c++; + h=c; + while (*c && strncmp(c,".di",3)) while (*c && *c++!='\n'); + *c=0; + de=strdef; + while (de && de->nr !=i) de=de->next; + if (!de) { + de=(STRDEF*) xmalloc(sizeof(STRDEF)); + de->nr=i; + de->slen=0; + de->next=strdef; + de->st=NULL; + strdef=de; + } else { + if (de->st) free(de->st); + de->slen=0; + de->st=NULL; + } + scan_troff(h,0,&de->st); + *c='.'; + while (*c && *c++!='\n'); + break; + } + case V('d','s'): + mode=1; + case V('a','s'): + { + STRDEF *de; + int oldcurpos=curpos; + c=c+j; + while (*c == ' ') c++; + i=V(c[0],c[1]); + j=0; + while (c[j] && c[j]!='\n') j++; + if (j<3) { c=c+j; break; } + if (c[1] == ' ') c=c+1; else c=c+2; + while (isspace(*c)) c++; + if (*c == '"') c++; + de=strdef; + while (de && de->nr != i) de=de->next; + single_escape=1; + curpos=0; + if (!de) { + char *h; + de=(STRDEF*) xmalloc(sizeof(STRDEF)); + de->nr=i; + de->slen=0; + de->next=strdef; + de->st=NULL; + strdef=de; + h=NULL; + c=scan_troff(c, 1, &h); + de->st=h; + de->slen=curpos; + } else { + if (mode) { /* .ds */ + char *h=NULL; + c=scan_troff(c, 1, &h); + free(de->st); /* segfault XXX */ + de->slen=curpos; + de->st=h; + } else { /* .as */ + c=scan_troff(c,1,&de->st); /* XXX */ + de->slen+=curpos; + } + } + single_escape=0; + curpos=oldcurpos; + } + break; + case V('b','r'): + if (still_dd) out_html("
- "); + else out_html("
\n"); + curpos=0; + c=c+j; + if (c[0] == escapesym) { c=scan_escape(c+1); } + c=skip_till_newline(c);break; + case V('c','2'): + c=c+j; + if (*c!='\n') { nobreaksym=*c; } + else nobreaksym='\''; + c=skip_till_newline(c); + break; + case V('c','c'): + c=c+j; + if (*c!='\n') { controlsym=*c; } + else controlsym='.'; + c=skip_till_newline(c); + break; + case V('c','e'): + c=c+j; + if (*c == '\n') { i=1; } + else { + i=0; + while ('0'<=*c && *c<='9') { + i=i*10+*c-'0'; + c++; + } + } + c=skip_till_newline(c); + /* center next i lines */ + if (i>0) { + out_html("\n"); + while (i && *c) { + char *line=NULL; + c=scan_troff(c,1, &line); + if (line && strncmp(line, " \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("
", 4)) { + out_html(line); + out_html("
\n"); + i--; + } + } + out_html("
\n"); + } + curpos=0; + fillout=0; + c=skip_till_newline(c); + break; + case V('p','s'): + c=c+j; + if (*c == '\n') { + out_html(change_to_size('0')); + } else { + j=0;i=0; + if (*c == '-') { j= -1;c++; } else if (*c == '+') { j=1;c++;} + c=scan_expression(c, &i); + if (!j) { j=1; if (i>5) i=i-10; } + out_html(change_to_size(i*j)); + } + c=skip_till_newline(c); + break; + case V('s','p'): + c=c+j; + if (fillout) out_html(""); + } + trans_char(c,'"', '\a'); + add_to_index(mode, c); + out_html(" \n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('s','o'): + { + FILE *f; + int l; char *buf; + char *name = NULL; + + curpos=0; + c += j; /* skip .so part and whitespace */ + if (*c == '/') { + h = c; + } else { /* .so man3/cpow.3 -> ../man3/cpow.3 */ + h = c-3; + h[0] = '.'; + h[1] = '.'; + h[2] = '/'; + } + while (*c != '\n') c++; + while (c[-1] == ' ') c--; + while (*c != '\n') *c++ = 0; + *c = 0; + scan_troff(h,1, &name); + if (name[3] == '/') h=name+3; else h=name; + l = 0; +#ifdef _KOLIBRI + ksys_bdfe_t bdfe; + _ksys_file_get_info(h, &bdfe); + l = bdfe.size; +#else + struct stat stbuf; + if (stat(h, &stbuf)!=-1) l=stbuf.st_size; +#endif + + buf = (char*) xmalloc((l+4)*sizeof(char)); +#if NOCGI + if (!out_length) { + char *t,*s; + t=strrchr(fname, '/'); + if (!t) t=fname; + fprintf(stderr, "ln -s %s.html %s.html\n", h, t); + s=strrchr(t, '.');if (!s) s=t; + printf("
Manpage of %s \n" + "\n" + "See the manpage for %s.\n" + "\n", + s, h, h); + } else +#endif + { + /* this works alright, except for section 3 */ + if (!l || !(f = fopen(h,"r"))) { + fprintf(stderr, + "man2html: unable to open or read file %s\n", h); + out_html("" + "man2html: unable to open or read file\n"); + out_html(h); + out_html("\n"); + } else { + i=fread(buf+1,1,l,f); + fclose(f); + buf[0]=buf[l]='\n'; + buf[l+1]=buf[l+2]=0; + scan_troff(buf+1,0,NULL); + } + if (buf) free(buf); + } + *c++='\n'; + break; + } + case V('t','a'): + c=c+j; + j=0; + while (*c!='\n') { + sl=scan_expression(c, &tabstops[j]); + if (*c == '-' || *c == '+') tabstops[j]+=tabstops[j-1]; + c=sl; + while (*c == ' ' || *c == '\t') c++; + if (j+1 < SIZE(tabstops)) + j++; + } + maxtstop=j; + curpos=0; + break; + case V('t','i'): +#if 0 + dl_down(); +#endif + out_html("
\n"); + c=c+j; + c=scan_expression(c, &j); + for (i=0; ia b ] */ + mode=1; + c[0]='B'; c[1]='I'; + out_html(change_to_font('R')); + out_html("["); + curpos++; + case V('B','R'): + case V('B','I'): + case V('I','B'): + case V('I','R'): + case V('R','B'): + case V('R','I'): + { + char font[2]; + font[0] = c[0]; font[1] = c[1]; + c = c+j; + if (*c == '\n') c++; + sl = fill_words(c, wordlist, SIZE(wordlist), &words, '\n'); + c = sl+1; + /* .BR name (section) + ** indicates a link. It will be added in the output routine. + */ + for (i=0; i "); + curpos = 0; + break; + case V('T','P'): + dl_begin(); + c=skip_till_newline(c); + /* somewhere a definition ends with '.TP' */ + if (!*c) still_dd=1; else { + c=scan_troff(c,1,NULL); + out_html(" "); + } + curpos=0; + break; + case V('I','X'): + /* general index */ + sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + c = sl+1; + j = 4; + while (idxlabel[j] == 'Z') idxlabel[j--]='A'; + idxlabel[j]++; +#ifdef MAKEINDEX + if (idxfile) { + fprintf(idxfile, "%s@%s@", fname, idxlabel); + for (j=0; j ' and '<' solves it, but creates + ** some space. A normal space does not work. + */ + out_html("\">"); + break; + case V('L','P'): + case V('P','P'): + dl_end(); + if (fillout) out_html(" \n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('H','P'): + dl_begin(); + still_dd=1; + c=skip_till_newline(c); + curpos=0; + break; + case V('P','D'): + c=skip_till_newline(c); + break; + case V('R','s'): /* BSD mandoc */ + case V('R','S'): + sl = fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n'); + j = 1; + if (words>0) scan_expression(wordlist[0], &j); + if (j>=0) { + dl_newlevel(); + c=skip_till_newline(c); + curpos=0; + break; + } + case V('R','e'): /* BSD mandoc */ + case V('R','E'): + dl_endlevel(); + c=skip_till_newline(c); + curpos=0; + break; + case V('S','B'): + out_html(change_to_size(-1)); + out_html(change_to_font('B')); + c=scan_troff(c+j, 1, NULL); + out_html(change_to_font('R')); + out_html(change_to_size('0')); + break; + case V('S','M'): + c=c+j; + if (*c == '\n') c++; + out_html(change_to_size(-1)); + trans_char(c,'"','\a'); + c=scan_troff(c,1,NULL); + out_html(change_to_size('0')); + break; + case V('S','s'): /* BSD mandoc */ + mandoc_command = 1; + case V('S','S'): + mode=1; + goto sh_below; + case V('S','h'): /* BSD mandoc */ + mandoc_command = 1; + case V('S','H'): + sh_below: + c=c+j; + if (*c == '\n') c++; + dl_down(); + out_html(change_to_font(0)); + out_html(change_to_size(0)); + if (!fillout) { + fillout=1; + out_html("
\n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + } + case V('E','l'): /* BSD mandoc */ + c=c+j; + dl_endlevel_type(); + if (fillout) out_html("
\n"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('I','t'): /* BSD mandoc */ + c=c+j; + if (dl_type(DL)) { + out_html("
"); + out_html(change_to_font('L')); + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + out_html(""); + if (fillout) curpos++; else curpos=0; + break; + case V('B','d'): /* BSD mandoc */ + { /* Seems like a kind of example/literal mode */ + char *nl, t=0 /* just for gcc */; + c=c+j; + nl = strchr(c,'\n'); + if (nl) { + t = *nl; + *nl = 0; + } + out_html(NEWLINE); + mandoc_bd_options = 0; /* Remember options for terminating Bl */ + if (strstr(c, "-offset indent")) { + mandoc_bd_options |= BD_INDENT; + out_html("
\n"); + } + if (strstr(c, "-literal") || strstr(c, "-unfilled")) { + if (fillout) { + mandoc_bd_options |= BD_LITERAL; + out_html(change_to_font(0)); + out_html(change_to_size('0')); + out_html("\n"); + curpos=0; + fillout=1; + c=skip_till_newline(c); + break; + case V('B','e'): /* BSD mandoc */ + c=c+j; + if (fillout) out_html("\n"); + } + curpos=0; + fillout=0; + } + if (nl) + *nl = t; + c=skip_till_newline(c); + break; + } + case V('E','d'): /* BSD mandoc */ + if (mandoc_bd_options & BD_LITERAL) { + if (!fillout) { + out_html(change_to_font(0)); + out_html(change_to_size('0')); + out_html("\n"); + } + } + if (mandoc_bd_options & BD_INDENT) + out_html("
"); else { + out_html(NEWLINE); + NEWLINE[0]='\n'; + } + curpos=0; + c=skip_till_newline(c); + break; + case V('X','r'): /* BSD mandoc */ + { + /* Translate xyz 1 to xyz(1) + * Allow for multiple spaces. Allow the section to be missing. + */ + char buff[100]; + char *bufptr; + trans_char(c,'"','\a'); + bufptr = buff; + c = c+j; + if (*c == '\n') c++; /* Skip spaces */ + while (isspace(*c) && *c != '\n') c++; + while (isalnum(*c) && bufptr < buff + SIZE(buff)-4) { + /* Copy the xyz part */ + *bufptr++ = *c++; + } + while (isspace(*c) && *c != '\n') c++; /* Skip spaces */ + if (isdigit(*c)) { /* Convert the number if there is one */ + *bufptr++ = '('; + while (isalnum(*c) && bufptr < buff + SIZE(buff)-3) { + *bufptr++ = *c++; + } + *bufptr++ = ')'; + } + while (*c != '\n' && bufptr < buff + SIZE(buff)-2) { + /* Copy the remainder */ + if (!isspace(*c)) { + *bufptr++ = *c; + } + c++; + } + *bufptr++ = '\n'; + *bufptr = 0; + scan_troff_mandoc(buff, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + } + break; + case V('F','l'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + out_html("-"); + if (*c!='\n') { + out_html(change_to_font('B')); + c=scan_troff_mandoc(c, 1, NULL); + out_html(change_to_font('R')); + } + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('P','a'): /* BSD mandoc */ + case V('P','f'): /* BSD mandoc */ + trans_char(c,'"','\a'); + c=c+j; + if (*c == '\n') c++; + c=scan_troff_mandoc(c, 1, NULL); + out_html(NEWLINE); + if (fillout) curpos++; else curpos=0; + break; + case V('P','p'): /* BSD mandoc */ + if (fillout) out_html("
\n"); else {
+ out_html(NEWLINE);
+ NEWLINE[0]='\n';
+ }
+ curpos=0;
+ c=skip_till_newline(c);
+ break;
+ case V('D','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("``");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("''");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','p'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('R'));
+ out_html("[");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html("]");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','o'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('R'));
+ out_html("[");
+ c=scan_troff_mandoc(c, 1, NULL);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('O','c'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html("]");
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('P','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("(");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(")");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('Q','l'): /* BSD mandoc */
+ { /* Single quote first word in the line */
+ char *sp;
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ sp = c;
+ do { /* Find first whitespace after the
+ * first word that isn't a mandoc macro
+ */
+ while (*sp && isspace(*sp)) sp++;
+ while (*sp && !isspace(*sp)) sp++;
+ } while (*sp && isupper(*(sp-2)) && islower(*(sp-1)));
+
+ /* Use a newline to mark the end of text to
+ * be quoted
+ */
+ if (*sp) *sp = '\n';
+ out_html("`"); /* Quote the text */
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("'");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ }
+ case V('S','q'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html("`");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html("'");
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('A','r'): /* BSD mandoc */
+ /* parse one line in italics */
+ out_html(change_to_font('I'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') { /* An empty Ar means "file ..." */
+ out_html("file ...");
+ } else {
+ c=scan_troff_mandoc(c, 1, NULL);
+ }
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('A','d'): /* BSD mandoc */
+ case V('E','m'): /* BSD mandoc */
+ case V('V','a'): /* BSD mandoc */
+ /* parse one line in italics */
+ out_html(change_to_font('I'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('N','d'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(" - ");
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('N','m'): /* BSD mandoc */
+ {
+ static char *mandoc_name = 0;
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (mandoc_synopsis) {
+ /*
+ * Break lines only in the Synopsis.
+ * The Synopsis section seems to be treated
+ * as a special case - Bummer!
+ */
+ static int count = 0; /* Don't break on the first Nm */
+ if (count) {
+ out_html("
");
+ } else {
+ char *end, t=0 /* just for gcc */;
+ end = strchr(c, '\n');
+ if (end) {
+ t = *end;
+ *end = 0;
+ }
+ if (mandoc_name)
+ free(mandoc_name);
+ mandoc_name = xstrdup(c);
+ if (end)
+ *end = t;
+ }
+ count++;
+ }
+ out_html(change_to_font('B'));
+ while (*c == ' ' || *c == '\t') c++;
+ if (*c == '\n') {
+ /*
+ * If Nm has no argument, use one from an earlier
+ * Nm command that did have one. Hope there aren't
+ * too many commands that do this.
+ */
+ if (mandoc_name)
+ out_html(mandoc_name);
+ } else {
+ c=scan_troff_mandoc(c, 1, NULL);
+ }
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ }
+ case V('C','d'): /* BSD mandoc */
+ case V('C','m'): /* BSD mandoc */
+ case V('I','c'): /* BSD mandoc */
+ case V('M','s'): /* BSD mandoc */
+ case V('O','r'): /* BSD mandoc */
+ case V('S','y'): /* BSD mandoc */
+ /* parse one line in bold */
+ out_html(change_to_font('B'));
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('D','v'): /* BSD mandoc */
+ case V('E','v'): /* BSD mandoc */
+ case V('F','r'): /* BSD mandoc */
+ case V('L','i'): /* BSD mandoc */
+ case V('N','o'): /* BSD mandoc */
+ case V('N','s'): /* BSD mandoc */
+ case V('T','n'): /* BSD mandoc */
+ case V('n','N'): /* BSD mandoc */
+ trans_char(c,'"','\a');
+ c=c+j;
+ if (*c == '\n') c++;
+ out_html(change_to_font('B'));
+ c=scan_troff_mandoc(c, 1, NULL);
+ out_html(change_to_font('R'));
+ out_html(NEWLINE);
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('%','A'): /* BSD mandoc biblio stuff */
+ case V('%','D'):
+ case V('%','N'):
+ case V('%','O'):
+ case V('%','P'):
+ case V('%','Q'):
+ case V('%','V'):
+ c=c+j;
+ if (*c == '\n') c++;
+ c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */
+ if (fillout) curpos++; else curpos=0;
+ break;
+ case V('%','B'):
+ case V('%','J'):
+ case V('%','R'):
+ case V('%','T'):
+ c=c+j;
+ out_html(change_to_font('I'));
+ if (*c == '\n') c++;
+ c=scan_troff(c, 1, NULL); /* Don't allow embedded mandoc coms */
+ out_html(change_to_font('R'));
+ if (fillout) curpos++; else curpos=0;
+ break;
+ /* ----- end of BSD mandoc stuff ----- */
+
+ default:
+ /* search macro database of self-defined macros */
+ owndef = defdef;
+ while (owndef && owndef->nr!=i) owndef=owndef->next;
+ if (owndef) {
+ char **oldargument;
+ int deflen;
+ int onff;
+ sl=fill_words(c+j, wordlist, SIZE(wordlist), &words, '\n');
+ c=sl+1;
+ *sl=0;
+ for (i=1; i
");
+ curpos=0;
+ }
+ usenbsp=fillout;
+ if (usenbsp) out_html(" "); else intbuff[ibp++]=' ';
+ } else if (*h > 31 && *h < 127) {
+ intbuff[ibp++]=*h;
+ } else if (((unsigned char)(*h)) > 127) {
+#ifdef NO_8BIT
+ intbuff[ibp++]='&';
+ intbuff[ibp++]='#';
+ intbuff[ibp++]='0'+((unsigned char)(*h))/100;
+ intbuff[ibp++]='0'+(((unsigned char)(*h))%100)/10;
+ intbuff[ibp++]='0'+((unsigned char)(*h))%10;
+ intbuff[ibp++]=';';
+#else
+ intbuff[ibp++]=*h;
+#endif
+ }
+ curpos++;
+ break;
+ }
+ if (ibp>480) FLUSHIBP;
+ h++;
+ }
+ }
+ FLUSHIBP;
+ if (buffer) buffer[buffpos]=0;
+ if (san && *h) h++;
+ newline_for_fun=exnewline_for_fun;
+ if (result) {
+ *result = buffer;
+ buffer=exbuffer;
+ buffpos=exbuffpos;
+ buffmax=exbuffmax;
+ scaninbuff=exscaninbuff;
+ }
+ return h;
+}
+
+static char *scan_troff_mandoc(char *c, int san, char **result) {
+ char *ret, *end = c;
+ int oldval = mandoc_line;
+ mandoc_line = 1;
+ while (*end && *end != '\n') {
+ end++;
+ }
+
+ if (end > c + 2
+ && ispunct(*(end - 1))
+ && isspace(*(end - 2)) && *(end - 2) != '\n') {
+ /*
+ * Don't format lonely punctuation. E.g. in "xyz ," format
+ * the xyz and then append the comma removing the space.
+ */
+ *(end - 2) = '\n';
+ ret = scan_troff(c, san, result);
+ *(end - 2) = *(end - 1);
+ *(end - 1) = ' ';
+ } else {
+ ret = scan_troff(c, san, result);
+ }
+ mandoc_line = oldval;
+ return ret;
+}
+
+STRDEF *foundpages=NULL;
+
+#define BUFSMSG 1024
+#define MSGLEN 2048
+static void
+error_page(char *s, char *t, ...) {
+ va_list p;
+ char msg[MSGLEN];
+ char buf[BUFSMSG];
+
+ sprintf(msg, "'%s\n", s, s);
+ va_start(p, t);
+ vsprintf(buf, t, p);
+ va_end(p);
+#ifdef _KOLIBRI
+ sprintf(msg, "%s%s%s", msg, buf, "' -E");
+ _ksys_exec("/sys/@notify", buf);
+#else
+ sprintf(msg, "%s%s%s", msg, buf, "'");
+ printf("%s", msg);
+#endif
+ exit(0);
+}
+
+char *
+xstrdup(const char *s) {
+ char *p = strdup(s);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+void *
+xmalloc(size_t size) {
+ void *p = malloc(size);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+void *
+xrealloc(void *ptr, size_t size) {
+ void *p = realloc(ptr,size);
+ if (p == NULL)
+ error_page("Out of memory",
+ "Sorry, out of memory, aborting...\n");
+ return p;
+}
+
+static void
+usage(void) {
+ error_page("man2html: bad invocation",
+ "Usage: man2html in_file [out_file.html]\n");
+}
+
+static void
+goto_dir(char *path, char **dir, char **name) {
+ char *s, *t, *u;
+
+ s = xstrdup(path);
+ t = strrchr(s, '/');
+ if (t) {
+ *t = 0;
+ u = strrchr(s, '/');
+ *t = '/';
+ if (u) {
+ *u = 0;
+#ifdef _KOLIBRI
+ setcwd(s);
+#else
+ chdir(s);
+#endif
+ if (dir)
+ *dir = s;
+ if (name)
+ *name = u+1;
+#if 0
+ else /* complain or not - this need not be fatal */
+ error_page("Error", "man2html: could not chdir to %s", s);
+#endif
+ }
+ }
+}
+
+/*
+ * Call: man2html [-l] [filename]
+ *
+ * The contents of FILENAME (or STDIN, in case FILENAME is "-" or absent)
+ * are converted from man-style nroff to html, and printed on STDOUT.
+ *
+ * Possible errors are reflected in the output. The return status is 0.
+ */
+int
+main(int argc, char **argv) {
+ FILE *f;
+ int l, c;
+ char *buf, *filename, *fnam = NULL;
+ char *outfilename;
+
+#ifdef _KOLIBRI
+ outfilename = "/tmp0/1/out.html";
+#else
+ outfilename = "./out.html";
+#endif
+
+// printf("Content-type: text/html\n\n");
+
+
+ /* Find filename */
+ if (argc > 2) {
+ outfilename = argv[2];
+ } if (argc > 1) {
+ fnam = argv[1];
+ } else {
+ usage();
+ }
+
+ if ((out = fopen(outfilename, "w")) == NULL) {
+ printf("Cannot open file %s", outfilename);
+ return 0;
+ }
+
+ filename = fnam;
+ directory = 0;
+
+ /* Open input file */
+ goto_dir(fnam, &directory, &fnam);
+
+ f = fopen(fnam, "r");
+ if (f == NULL)
+ error_page("File not found", "Could not open %s\n", filename);
+ fname = fnam;
+
+ /* Read entire file into buf[1..l] */
+#define XTRA 5
+ /* buf has 1 extra byte at the start, and XTRA extra bytes at the end */
+ int ct;
+
+ l = 0;
+
+#ifdef _KOLIBRI
+ ksys_bdfe_t bdfe;
+ _ksys_file_get_info(filename, &bdfe);
+ l = bdfe.size;
+#else
+ struct stat stbuf;
+ if (stat(filename, &stbuf) != -1) l=stbuf.st_size;
+#endif
+
+ buf = (char *) xmalloc((l+1+XTRA)*sizeof(char));
+ ct = fread(buf+1,1,l,f);
+ if (ct < l)
+ l = ct;
+ fclose(f);
+
+ buf[0] = '\n';
+ buf[l+1] = '\n';
+ buf[l+2] = buf[l+3] = 0;
+
+#ifdef MAKEINDEX
+ idxfile = fopen(INDEXFILE, "a");
+#endif
+ stdinit();
+ scan_troff(buf+1,0,NULL);
+ dl_down();
+ out_html(change_to_font(0));
+ out_html(change_to_size(0));
+ if (!fillout) {
+ fillout=1;
+ out_html("");
+ }
+ out_html(NEWLINE);
+ if (output_possible) {
+ /* for mosaic users */
+ fprintf(out, "
\n Index
\n\n");
+ manidx[mip]=0;
+ fprintf(out, "%s", manidx);
+ if (subs) printf("
\n");
+ fprintf(out, "\n");
+ print_sig();
+ fprintf(out, "\n\n");
+ } else {
+ if (!filename)
+ filename = fname;
+ if (*filename == '/')
+ error_page("Invalid Manpage",
+ "The requested file %s is not a valid (unformatted) "
+ "man page.\nIf the file is a formatted manpage, "
+ "you could try to load the\n"
+ "plain file.\n",
+ filename, filename);
+ else
+ error_page("Invalid Manpage",
+ "The requested file %s is not a valid (unformatted) "
+ "man page.", filename);
+ }
+ if (idxfile)
+ fclose(idxfile);
+ if (buf)
+ free(buf);
+ return 0;
+}
diff --git a/programs/other/man2html/strdefs.c b/programs/other/man2html/strdefs.c
new file mode 100644
index 0000000000..bcbc366b1c
--- /dev/null
+++ b/programs/other/man2html/strdefs.c
@@ -0,0 +1,176 @@
+#include "defs.h"
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+int nroff = 1;
+
+#define NROFF (-666)
+#define TROFF (-667)
+
+STRDEF *chardef, *strdef, *defdef;
+INTDEF *intdef;
+
+static INTDEF standardint[] = {
+ { V('n',' '), NROFF, 0, NULL },
+ { V('t',' '), TROFF, 0, NULL },
+ { V('o',' '), 1, 0, NULL },
+ { V('e',' '), 0, 0, NULL },
+ { V('.','l'), 70, 0, NULL },
+ { V('.','$'), 0, 0, NULL },
+ { V('.','A'), NROFF, 0, NULL },
+ { V('.','T'), TROFF, 0, NULL },
+ { V('.','V'), 1, 0, NULL }, /* the me package tests for this */
+ { 0, 0, 0, NULL } };
+
+static STRDEF standardstring[] = {
+ { V('R',' '), 1, "®", NULL },
+ { V('l','q'), 2, "``", NULL },
+ { V('r','q'), 2, "''", NULL },
+ { 0, 0, NULL, NULL}
+};
+
+
+static STRDEF standardchar[] = {
+ { V('*','*'), 1, "*", NULL }, /* math star */
+ { V('*','A'), 1, "A", NULL },
+ { V('*','B'), 1, "B", NULL },
+ { V('*','C'), 2, "Xi", NULL },
+ { V('*','D'), 5, "Delta", NULL },
+ { V('*','E'), 1, "E", NULL },
+ { V('*','F'), 3, "Phi", NULL },
+ { V('*','G'), 5, "Gamma", NULL },
+ { V('*','H'), 5, "Theta", NULL },
+ { V('*','I'), 1, "I", NULL },
+ { V('*','K'), 1, "K", NULL },
+ { V('*','L'), 6, "Lambda", NULL },
+ { V('*','M'), 1, "M", NULL },
+ { V('*','N'), 1, "N", NULL },
+ { V('*','O'), 1, "O", NULL },
+ { V('*','P'), 2, "Pi", NULL },
+ { V('*','Q'), 3, "Psi", NULL },
+ { V('*','R'), 1, "P", NULL },
+ { V('*','S'), 5, "Sigma", NULL },
+ { V('*','T'), 1, "T", NULL },
+ { V('*','U'), 1, "Y", NULL },
+ { V('*','W'), 5, "Omega", NULL },
+ { V('*','X'), 1, "X", NULL },
+ { V('*','Y'), 1, "H", NULL },
+ { V('*','Z'), 1, "Z", NULL },
+ { V('*','a'), 5, "alpha", NULL },
+ { V('*','b'), 4, "beta", NULL },
+ { V('*','c'), 2, "xi", NULL },
+ { V('*','d'), 5, "delta", NULL },
+ { V('*','e'), 7, "epsilon", NULL },
+ { V('*','f'), 3, "phi", NULL },
+ { V('*','g'), 5, "gamma", NULL },
+ { V('*','h'), 5, "theta", NULL },
+ { V('*','i'), 4, "iota", NULL },
+ { V('*','k'), 5, "kappa", NULL },
+ { V('*','l'), 6, "lambda", NULL },
+ { V('*','m'), 1, "µ", NULL },
+ { V('*','n'), 2, "nu", NULL },
+ { V('*','o'), 1, "o", NULL },
+ { V('*','p'), 2, "pi", NULL },
+ { V('*','q'), 3, "psi", NULL },
+ { V('*','r'), 3, "rho", NULL },
+ { V('*','s'), 5, "sigma", NULL },
+ { V('*','t'), 3, "tau", NULL },
+ { V('*','u'), 7, "upsilon", NULL },
+ { V('*','w'), 5, "omega", NULL },
+ { V('*','x'), 3, "chi", NULL },
+ { V('*','y'), 3, "eta", NULL },
+ { V('*','z'), 4, "zeta", NULL },
+ { V('+','-'), 1, "±", NULL },
+ { V('1','2'), 1, "½", NULL },
+ { V('1','4'), 1, "¼", NULL },
+ { V('3','4'), 1, "¾", NULL },
+ { V('F','i'), 3, "ffi", NULL },
+ { V('F','l'), 3, "ffl", NULL },
+ { V('a','a'), 1, "´", NULL },
+ { V('a','p'), 1, "~", NULL },
+ { V('b','r'), 1, "|", NULL },
+ { V('b','u'), 1, "*", NULL }, /* bullet */
+ { V('b','v'), 1, "|", NULL },
+ { V('c','i'), 1, "o", NULL }, /* circle */
+ { V('c','o'), 1, "©", NULL },
+ { V('c','t'), 1, "¢", NULL },
+ { V('d','e'), 1, "°", NULL },
+ { V('d','g'), 1, "+", NULL }, /* dagger */
+ { V('d','i'), 1, "÷", NULL },
+ { V('e','m'), 3, "---", NULL }, /* em dash */
+ { V('e','n'), 1, "-", NULL }, /* en dash */
+ { V('e','q'), 1, "=", NULL },
+ { V('e','s'), 1, "Ø", NULL },
+ { V('f','f'), 2, "ff", NULL },
+ { V('f','i'), 2, "fi", NULL },
+ { V('f','l'), 2, "fl", NULL },
+ { V('f','m'), 1, "´", NULL },
+ { V('g','a'), 1, "`", NULL },
+ { V('h','y'), 1, "-", NULL },
+ { V('l','c'), 2, "|¯", NULL },
+ { V('i','f'), 8, "Infinity", NULL }, /* infinity sign */
+ { V('i','s'), 8, "Integral", NULL }, /* integral sign */
+ { V('l','f'), 2, "|_", NULL },
+ { V('l','k'), 1, "{", NULL },
+ { V('m','i'), 1, "-", NULL },
+ { V('m','u'), 1, "×", NULL },
+ { V('n','o'), 1, "¬", NULL },
+ { V('o','r'), 1, "|", NULL },
+ { V('p','d'), 1, "d", NULL }, /* partial derivative */
+ { V('p','l'), 1, "+", NULL },
+ { V('r','c'), 2, "¯|", NULL },
+ { V('r','f'), 2, "_|", NULL },
+ { V('r','g'), 1, "®", NULL },
+ { V('r','k'), 1, "}", NULL },
+ { V('r','n'), 1, "¯", NULL },
+ { V('r','u'), 1, "_", NULL },
+ { V('s','c'), 1, "§", NULL },
+ { V('s','l'), 1, "/", NULL },
+ { V('s','q'), 2, "[]", NULL },
+ { V('t','s'), 1, "s", NULL }, /* should be terminal sigma */
+ { V('u','l'), 1, "_", NULL },
+ { V('>','='), 1, ">", NULL },
+ { V('<','='), 1, "<", NULL },
+ { 0, 0, NULL, NULL }
+};
+
+void stdinit(void) {
+ STRDEF *stdf;
+ int i;
+
+ stdf = &standardchar[0];
+ i = 0;
+ while (stdf->nr) {
+ if (stdf->st) stdf->st = xstrdup(stdf->st);
+ stdf->next = &standardchar[i];
+ stdf = stdf->next;
+ i++;
+ }
+ chardef=&standardchar[0];
+
+ stdf=&standardstring[0];
+ i=0;
+ while (stdf->nr) {
+ /* waste a little memory, and make a copy, to avoid
+ the segfault when we free non-malloced memory */
+ if (stdf->st) stdf->st = xstrdup(stdf->st);
+ stdf->next = &standardstring[i];
+ stdf = stdf->next;
+ i++;
+ }
+ strdef=&standardstring[0];
+
+ intdef=&standardint[0];
+ i=0;
+ while (intdef->nr) {
+ if (intdef->nr == NROFF) intdef->nr = nroff; else
+ if (intdef->nr == TROFF) intdef->nr = !nroff;
+ intdef->next = &standardint[i];
+ intdef = intdef->next;
+ i++;
+ }
+ intdef = &standardint[0];
+ defdef = NULL;
+}