/* remove tags from start and end of a string, for innerHTML */ static void tagStrip(char *line) { char *s = line; if (*s != '<') { /* this shouldn't happen, don't know what to do. */ return; } s = strchr(line, '>'); if (!s) return; ++s; skipWhite2(&s); strmove(line, s); trimWhite(line); s = line + strlen(line); if (s == line || s[-1] != '>') return; /* back up over </foo> */ --s; while (s >= line) { if (*s == '<') { *s = 0; return; } --s; } } /* tagStrip */
/* Strips off any leading and trailing whitespace from a string, and trims * its memory allocation down to the bare minimum */ char * xstrstrip( char *string ) { int i; char *string2; /* Remove leading whitespace */ i = strspn( string, " \t" ); if (i > 0) strmove( string, &string[i] ); /* Remove trailing whitespace */ for (i = strlen( string ) - 1; i >= -1; --i) { switch (string[MAX(0, i)]) { case ' ': case '\t': /* Whitespace */ continue; default: /* Non-whitespace character */ break; } break; } string[i + 1] = '\0'; /* Minimize memory allocation */ string2 = xrealloc( string, (strlen( string ) + 1) * sizeof(char) ); return string2; }
char * strtrim (char *str, int (*left) (int), int (*right) (int)) { if (left) { char *p = str; while (*p && left ((int) *p)) p++; if (p - str) strmove (str, p); } if (right) { char *p = strchr (str, 0); while ((p - 1) - str && right ((int) *(p - 1))) p--; *p = 0; } return str; }
bool ReadLanguage ( char *&lpRealStart, char **lpLngName, char **lpLngDesc ) { char *lpStart = lpRealStart; char *lpParam = NULL; bool bResult = false; *lpLngName = (char*)malloc(100); *lpLngDesc = (char*)malloc(100); strcpy (*lpLngName, "none"); strcpy (*lpLngDesc, "none"); if ( ReadFromBufferEx ( lpStart, &lpParam, true, true ) && strstr (lpParam,".Language") ) { strmove (*lpLngName, strstr (lpParam, "=")+1); strmove (*lpLngDesc, "\""); strcat (*lpLngDesc, strstr (*lpLngName, ",")+1); strcat (*lpLngDesc, "\""); char *lpComa = strchr(*lpLngName, ','); if ( lpComa ) *lpComa = 0; lpRealStart = lpStart; while ( *lpRealStart=='\r' || *lpRealStart=='\n' ) lpRealStart++; bResult = true; } if ( lpParam ) free (lpParam); return bResult; }
void stripWhite(char *s) { const char *t = s; skipWhite(&t); if (t > s) strmove(s, t); trimWhite(s); } /* stripWhite */
char * strins (char *dest, const char *ins) { strmove (dest + strlen (ins), dest); memcpy (dest, ins, strlen (ins)); return dest; }
void FixQuotes (char *lpStr) { char *lpStart = lpStr; char *lpEnd = lpStr+strlen(lpStr)-1; char *lpTmp = (char *)malloc(strlen(lpStr)*2); char *lpPtr = lpTmp; memset (lpTmp, 0, strlen(lpStr)*2); while ( *lpStart && *lpStart != '"' ) lpStart++; while ( lpEnd > lpStart && *lpEnd != '"' ) lpEnd--; if ( lpEnd == lpStart ) { strmove (lpTmp, lpStart); strcat (lpTmp, "\""); strmove (lpStr, lpTmp); free (lpTmp); return; } *(lpPtr++) = '"'; lpStart++; while ( lpStart < lpEnd ) { if ( *lpStart == '"' && *(lpStart-1) != '\\' ) *(lpPtr++) = '\\'; *(lpPtr++) = *(lpStart++); } *lpPtr = '"'; strmove (lpStr, lpTmp); free (lpTmp); }
char * strrep (char *str, const char *orig, const char *rep) { int o_len = strlen (orig); int r_len = strlen (rep); char *p = str; // if (r_len) while ((p = strstr (p, orig))) { strmove (p + r_len, p + o_len); memcpy (p, rep, r_len); p += r_len; } return str; }
void unpackUploadedFile(const char *post, const char *boundary, char **postb, int *postb_l) { static const char message64[] = "Content-Transfer-Encoding: base64"; const int boundlen = strlen(boundary); const int m64len = strlen(message64); char *post2; char *b1, *b2, *b3, *b4; /* boundary points */ *postb = 0; *postb_l = 0; if (!strstr(post, message64)) return; post2 = cloneString(post); b2 = strstr(post2, boundary); while (true) { b1 = b2 + boundlen; if (*b1 != '\r') break; b1 += 2; b1 = strstr(b1, "Content-Transfer"); b2 = strstr(b1, boundary); if (memcmp(b1, message64, m64len)) continue; b1 += m64len - 6; strcpy(b1, "8bit\r\n\r\n"); b1 += 8; b1[0] = b1[1] = ' '; b3 = b2 - 4; b4 = b3; int unpack_ret = base64Decode(b1, &b4); if (unpack_ret != GOOD_BASE64_DECODE) mail64Error(unpack_ret); /* Should we *really* keep going at this point? */ strmove(b4, b3); b2 = b4 + 4; } b1 += strlen(b1); *postb = post2; *postb_l = b1 - post2; } /* unpackUploadedFile */
char * stritrim_s (char *str, const char *left, const char *right) { if (left) { char *p = stristr (str, left); if (p) strmove (str, p + strlen (left)); } if (right) { char *p = strristr (str, right); if (p) *p = 0; } return str; }
/* Helper function for absname_merge( ). This takes an absolute name, and * the position of a slash or null terminator in the string. It removes the * directory component preceding that position, and returns the position of * the slash preceding the next component in the name. Examples: * int i; * char absname[16]; * strcpy( absname, "/abc/def/ghi" ); * i = remove_component( absname, 8 ); // i => 4, absname => "/abc/ghi" * strcpy( absname, "/abc/def/ghi" ); * i = remove_component( absname, 12 ); // i => 8, absname => "/abc/def" */ static int remove_component( char *absname, int pos ) { int i; g_assert( (absname[pos] == '/') || (absname[pos] == '\0') ); if (pos == 0) { /* Warning: attempting to remove a component higher than * the root directory! Silently ignore this foolishness */ return 0; } for (i = pos - 1; i >= 0; --i) { if (absname[i] == '/') { /* Collapse string */ strmove( &absname[i], &absname[pos] ); break; } } return i; }
/* set document.cookie to the cookies relevant to this url */ static void docCookie(jsobjtype d) { int cook_l; char *cook = initString(&cook_l); const char *url = cw->fileName; bool secure = false; const char *proto; char *s; if (url) { proto = getProtURL(url); if (proto && stringEqualCI(proto, "https")) secure = true; sendCookies(&cook, &cook_l, url, secure); if (memEqualCI(cook, "cookie: ", 8)) { /* should often happen */ strmove(cook, cook + 8); } if (s = strstr(cook, "\r\n")) *s = 0; } set_property_string(d, "cookie", cook); nzFree(cook); } /* docCookie */
/* read a file for the domain */ static char * look4domain(char *file, char *buf, int size) { char *ret = 0; FILE *fp = fopen(file, "r"); if (!fp) return (0); while (fgets(buf, size, fp)) if (strncmp(buf, "domain", 6) == 0) if (spacechar(buf[6]&0377)) { char *x = skipspace(buf + 6); if (graphchar(*x&0377)) { trimnl(x); strmove(buf, x); ret = buf; break; } } fclose(fp); return (ret); }
/* convert string to uppercase before this call */ int phonet (const char * inword, char * target, int len, phonetable & parms) { /** Do phonetic transformation. **/ /** "len" = length of "inword" incl. '\0'. **/ /** result: >= 0: length of "target" **/ /** otherwise: error **/ int i,j,k=0,n,p,z; int k0,n0,p0=-333,z0; char c, c0; const char * s; typedef unsigned char uchar; char word[MAXPHONETUTF8LEN + 1]; if (len == -1) len = strlen(inword); if (len > MAXPHONETUTF8LEN) return 0; strcpy(word, inword); /** check word **/ i = j = z = 0; while ((c = word[i]) != '\0') { n = parms.hash[(uchar) c]; z0 = 0; if (n >= 0) { /** check all rules for the same letter **/ while (parms.rules[n][0] == c) { /** check whole string **/ k = 1; /** number of found letters **/ p = 5; /** default priority **/ s = parms.rules[n]; s++; /** important for (see below) "*(s-1)" **/ while (*s != '\0' && word[i+k] == *s && !isdigit (*s) && strchr ("(-<^$", *s) == NULL) { k++; s++; } if (*s == '(') { /** check letters in "(..)" **/ if (isalpha(word[i+k]) // ...could be implied? && strchr(s+1, word[i+k]) != NULL) { k++; while (*s != ')') s++; s++; } } p0 = (int) *s; k0 = k; while (*s == '-' && k > 1) { k--; s++; } if (*s == '<') s++; if (isdigit (*s)) { /** determine priority **/ p = *s - '0'; s++; } if (*s == '^' && *(s+1) == '^') s++; if (*s == '\0' || (*s == '^' && (i == 0 || ! isalpha(word[i-1])) && (*(s+1) != '$' || (! isalpha(word[i+k0]) ))) || (*s == '$' && i > 0 && isalpha(word[i-1]) && (! isalpha(word[i+k0]) ))) { /** search for followup rules, if: **/ /** parms.followup and k > 1 and NO '-' in searchstring **/ c0 = word[i+k-1]; n0 = parms.hash[(uchar) c0]; // if (parms.followup && k > 1 && n0 >= 0 if (k > 1 && n0 >= 0 && p0 != (int) '-' && word[i+k] != '\0') { /** test follow-up rule for "word[i+k]" **/ while (parms.rules[n0][0] == c0) { /** check whole string **/ k0 = k; p0 = 5; s = parms.rules[n0]; s++; while (*s != '\0' && word[i+k0] == *s && ! isdigit(*s) && strchr("(-<^$",*s) == NULL) { k0++; s++; } if (*s == '(') { /** check letters **/ if (isalpha(word[i+k0]) && strchr (s+1, word[i+k0]) != NULL) { k0++; while (*s != ')' && *s != '\0') s++; if (*s == ')') s++; } } while (*s == '-') { /** "k0" gets NOT reduced **/ /** because "if (k0 == k)" **/ s++; } if (*s == '<') s++; if (isdigit (*s)) { p0 = *s - '0'; s++; } if (*s == '\0' /** *s == '^' cuts **/ || (*s == '$' && ! isalpha(word[i+k0]))) { if (k0 == k) { /** this is just a piece of the string **/ n0 += 2; continue; } if (p0 < p) { /** priority too low **/ n0 += 2; continue; } /** rule fits; stop search **/ break; } n0 += 2; } /** End of "while (parms.rules[n0][0] == c0)" **/ if (p0 >= p && parms.rules[n0][0] == c0) { n += 2; continue; } } /** end of follow-up stuff **/ /** replace string **/ s = parms.rules[n+1]; p0 = (parms.rules[n][0] != '\0' && strchr (parms.rules[n]+1,'<') != NULL) ? 1:0; if (p0 == 1 && z == 0) { /** rule with '<' is used **/ if (j > 0 && *s != '\0' && (target[j-1] == c || target[j-1] == *s)) { j--; } z0 = 1; z = 1; k0 = 0; while (*s != '\0' && word[i+k0] != '\0') { word[i+k0] = *s; k0++; s++; } if (k > k0) strmove (&word[0]+i+k0, &word[0]+i+k); /** new "actual letter" **/ c = word[i]; } else { /** no '<' rule used **/ i += k - 1; z = 0; while (*s != '\0' && *(s+1) != '\0' && j < len) { if (j == 0 || target[j-1] != *s) { target[j] = *s; j++; } s++; } /** new "actual letter" **/ c = *s; if (parms.rules[n][0] != '\0' && strstr (parms.rules[n]+1, "^^") != NULL) { if (c != '\0') { target[j] = c; j++; } strmove (&word[0], &word[0]+i+1); i = 0; z0 = 1; } } break; } /** end of follow-up stuff **/ n += 2; } /** end of while (parms.rules[n][0] == c) **/ } /** end of if (n >= 0) **/ if (z0 == 0) { // if (k && (assert(p0!=-333),!p0) && j < len && c != '\0' // && (!parms.collapse_result || j == 0 || target[j-1] != c)){ if (k && !p0 && j < len && c != '\0' && (1 || j == 0 || target[j-1] != c)){ /** condense only double letters **/ target[j] = c; ///printf("\n setting \n"); j++; } i++; z = 0; k=0; } } /** end of while ((c = word[i]) != '\0') **/ target[j] = '\0'; return (j); } /** end of function "phonet" **/
int main_convertor (int argc, char** argv) { printf (".LNG Convertor " VERSION "\n"); printf ("Copyright (C) 2005-2006 WARP ItSelf & Alex Yaroslavsky\n\n"); if ( argc < 5 ) { printf ("Usage: convertor feed_file hpp_file num_of_lng lng_file1 lng_file2 ...\n\r"); return 0; } HANDLE hFeedFile = WINPORT(CreateFile) ( MB2Wide(argv[1]).c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL ); if ( hFeedFile == INVALID_HANDLE_VALUE ) { printf ("ERROR: Can't create the feed file, exiting.\n\r"); return 0; } HANDLE hHFile = WINPORT(CreateFile) ( MB2Wide(argv[2]).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if ( hHFile == INVALID_HANDLE_VALUE ) { printf ("ERROR: Can't open the header file, exiting.\n\r"); return 0; } int dwLangs = atol(argv[3]); if ( dwLangs<=0 ) { printf ("ERROR: Zero language files to process, exiting.\n\r"); return 0; } DWORD dwRead; DWORD dwSize = WINPORT(GetFileSize) (hHFile, NULL); char *pHBuffer = (char*)malloc (dwSize+1); memset (pHBuffer, 0, dwSize+1); WINPORT(ReadFile) (hHFile, pHBuffer, dwSize, &dwRead, NULL); WINPORT(CloseHandle) (hHFile); char *lpStart = pHBuffer; LanguageEntry *pLangEntries = (LanguageEntry*)malloc (dwLangs*sizeof (LanguageEntry)); memset (pLangEntries, 0, dwLangs*sizeof (LanguageEntry)); HANDLE hFile; for (int i = 0; i < dwLangs; i++) { hFile = WINPORT(CreateFile) ( MB2Wide(argv[4+i]).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile != INVALID_HANDLE_VALUE ) { dwSize = WINPORT(GetFileSize) (hFile, NULL); pLangEntries[i].lpBuffer = (char*)malloc (dwSize+1); pLangEntries[i].lpStart = pLangEntries[i].lpBuffer; memset (pLangEntries[i].lpBuffer, 0, dwSize+1); WINPORT(ReadFile) (hFile, pLangEntries[i].lpBuffer, dwSize, &dwRead, NULL); WINPORT(CloseHandle) (hFile); } else printf ("WARNING: Can't open the language file \"%s\", skiping\n\r", argv[4+i]); } char *lpTmp = (char*)malloc (2048); char *lpString; sprintf (lpTmp, "#hpp file name\r\n%s\r\n#number of languages\r\n%s\r\n", argv[2], argv[3]); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); for (int i = 0; i < dwLangs; i++) { if ( pLangEntries[i].lpBuffer ) //or we skipping { char *lpLngName, *lpLngDesc; sprintf (lpTmp, "#id:%d language file name, language name, language description\r\n%s", i, argv[4+i]); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); ReadLanguage (pLangEntries[i].lpStart, &lpLngName, &lpLngDesc); sprintf (lpTmp," %s %s\r\n", lpLngName, lpLngDesc); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); free (lpLngName); free (lpLngDesc); } } sprintf(lpTmp,"\r\n#head of the hpp file\r\n"); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); while ( ReadFromBufferEx (lpStart, &lpString) ) { if ( !strncmp (lpString,"enum",4) ) { free(lpString); char *lpOldStart = lpStart; ReadFromBufferEx (lpStart, &lpString); if ( strstr(lpString, "{") ) lpOldStart = lpStart; free(lpString); while ( ReadFromBufferEx (lpStart, &lpString,true,true) && !strstr (lpString, "};") ) free(lpString); char *lpEnd = lpStart-2; while ( *lpEnd != '\r' && *lpEnd != '\n') lpEnd--; while ( *lpEnd == '\r' || *lpEnd == '\n') lpEnd--; while ( *lpEnd != '\r' && *lpEnd != '\n') lpEnd--; *(lpEnd+1)=0; sprintf (lpTmp, "\r\n#tail of the hpp file\r\n"); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); while ( ReadFromBufferEx (lpStart, &lpString) ) { sprintf (lpTmp, "htail:%s\r\n", lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); free(lpString); } lpStart = lpOldStart; break; } else { sprintf(lpTmp, "hhead:%s\r\n", lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); } free(lpString); } char *lpOldStart = lpStart; while ( true ) { WINPORT(WriteFile) (hFeedFile, "\r\n", 2, &dwRead, NULL); lpOldStart = lpStart; while ( ReadFromBufferEx (lpStart, &lpString) ) { TrimStart (lpString); if ( strstr (lpString, "//") != lpString ) // "//" at the beginning at the string -> copy, else it will be discarded { free(lpString); lpStart = lpOldStart; break; } else { sprintf (lpTmp, "h:%s\r\n", lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); } free(lpString); lpOldStart = lpStart; } if ( ReadFromBufferEx (lpStart, &lpString) ) { char *lpComment = strstr (lpString, "//"); if ( lpComment ) *lpComment = 0; char *lpComa = strchr (lpString, ','); if ( lpComa ) *lpComa = 0; Trim (lpString); if ( !*lpString ) continue; sprintf (lpTmp, "%s\r\n", lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); free(lpString); while ( true ) { bool bSame=true; for (int i = 0; i < dwLangs; i++) { if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read { pLangEntries[i].lpOldStart = pLangEntries[i].lpStart; bSame = bSame && ReadFromBufferEx (pLangEntries[i].lpStart, &pLangEntries[i].lpString); } } for (int i = 1; bSame && i < dwLangs; i++) { if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read { if ( !pLangEntries[i].lpString || (pLangEntries[i].lpString[0] == '"') || strcmp (pLangEntries[0].lpString,pLangEntries[i].lpString) ) bSame=false; } } if ( !bSame ) { for (int i = 0; i < dwLangs; i++) { pLangEntries[i].lpStart = pLangEntries[i].lpOldStart; if ( pLangEntries[i].lpString ) free(pLangEntries[i].lpString); } break; } if ( *pLangEntries[0].lpString ) { sprintf (lpTmp, "l:%s\r\n", pLangEntries[0].lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); } for (int i = 0; i < dwLangs; i++) free (pLangEntries[i].lpString); } for (int i = 0; i < dwLangs; i++) { if ( pLangEntries[i].lpBuffer ) // or we skipping, no file read { while ( ReadFromBufferEx ( pLangEntries[i].lpStart, &pLangEntries[i].lpString ) && pLangEntries[i].lpString[0] != '"' ) { sprintf(lpTmp,"ls:%s\r\n",pLangEntries[i].lpString); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); free(pLangEntries[i].lpString); } strmove(lpTmp,pLangEntries[i].lpString); FixQuotes(lpTmp); strcat(lpTmp,"\r\n"); WINPORT(WriteFile) (hFeedFile, lpTmp, strlen (lpTmp), &dwRead, NULL); free(pLangEntries[i].lpString); } } } else break; } WINPORT(CloseHandle)(hFeedFile); free(pHBuffer); for (int i = 0; i < dwLangs; i++) free(pLangEntries[i].lpBuffer); return 0; }
/* This takes two names: an absolute directory name, and a name relative * to the directory, and it runs them together into one absolute name. * This can be (and is) used to find symlink targets. Some examples: * absname_merge( "/usr/bin", "gcc" ) => "/usr/bin/gcc" * absname_merge( "/usr/local/lib", "../../lib/libblah.so" ) => "/usr/lib/libblah.so" * absname_merge( "/home/fox", "./../skunk/./././weird" ) => "/home/skunk/weird" * absname_merge( "/home/skunk", "../fox////./cool" ) => "/home/fox/cool" */ static char * absname_merge( const char *dirname, const char *rel_name ) { static char *absname = NULL; int i, len, dot_count = 0; boolean prev_char_is_slash = FALSE; len = strlen( dirname ) + strlen( rel_name ) + 2; RESIZE(absname, len, char); if (strlen( rel_name ) == 0) { /* Relative part is empty. This is weird. */ strcpy( absname, dirname ); } else if (rel_name[0] == '/') { /* Relative part is an absolute name in itself, thus the * directory name is completely irrelevant */ strcpy( absname, rel_name ); } else { /* Concatenate the two names together */ strcpy( absname, dirname ); strcat( absname, "/" ); strcat( absname, rel_name ); } /* Get rid of all ".." components, extra slashes, etc. */ for (i = 0; ; ++i) { switch (absname[i]) { case '.': prev_char_is_slash = FALSE; ++dot_count; break; case '/': /* End of component reached */ if (prev_char_is_slash) { /* Remove superfluous slash */ strmove( &absname[i], &absname[i + 1] ); --i; break; } else prev_char_is_slash = TRUE; /* !break */ case '\0': /* End of absolute name reached */ switch (dot_count) { case 1: /* Remove superfluous "." component */ i = remove_component( absname, i ); break; case 2: /* ".." component cancels out itself and * the previous component */ i = remove_component( absname, i ); i = remove_component( absname, i ); break; case 0: default: /* Nothing to do at this point */ break; } dot_count = 0; break; default: /* Normal character */ prev_char_is_slash = FALSE; dot_count = 0; break; } if (absname[i] == '\0') break; } absname = xstrstrip( absname ); return absname; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { FILE *infile, /* Input file */ *outfile; /* Output file */ char line[1024], /* Line from file */ *lineptr, /* Pointer into line */ *endptr, /* Pointer to end of current */ endchar, /* End character */ *paren, /* Pointer to parenthesis */ name[1024]; /* Man page name */ int section, /* Man page section */ pre, /* Preformatted */ font, /* Current font */ blist, /* In a bullet list? */ list, /* In a list? */ linenum; /* Current line number */ const char *post; /* Text to add after the current line */ static const char /* Start/end tags for fonts */ * const start_fonts[] = { "", "<b>", "<i>" }, * const end_fonts[] = { "", "</b>", "</i>" }; /* * Check arguments... */ if (argc > 3) { fputs("Usage: mantohtml [filename.man [filename.html]]\n", stderr); return (1); } /* * Open files as needed... */ if (argc > 1) { if ((infile = fopen(argv[1], "r")) == NULL) { perror(argv[1]); return (1); } } else infile = stdin; if (argc > 2) { if ((outfile = fopen(argv[2], "w")) == NULL) { perror(argv[2]); fclose(infile); return (1); } } else outfile = stdout; /* * Read from input and write the output... */ fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" " "\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n" "<html>\n" "<!-- SECTION: Man Pages -->\n" "<head>\n" "\t<style type='text/css'><!--\n" "\th1, h2, h3, p { font-family: sans-serif; text-align: justify; }\n" "\ttt, pre a:link, pre a:visited, tt a:link, tt a:visited { font-weight: bold; color: #7f0000; }\n" "\tpre { font-weight: bold; color: #7f0000; margin-left: 2em; }\n" "\th1.title, h2.title, h3.title { border-bottom: solid 2px #000000; }\n" "\t--></style>\n", outfile); blist = 0; font = 0; list = 0; linenum = 0; pre = 0; post = NULL; section = -1; while (fgets(line, sizeof(line), infile)) { linenum ++; if (line[0] == '.') { /* * Strip leading whitespace... */ while (line[1] == ' ' || line[1] == '\t') strmove(line + 1, line + 2); /* * Process man page commands... */ if (!strncmp(line, ".TH ", 4) && section < 0) { /* * Grab man page title... */ sscanf(line + 4, "%s%d", name, §ion); fprintf(outfile, "\t<title>%s(%d)</title>\n" "</head>\n" "<body>\n" "%s", name, section, start_fonts[font]); } else if (section < 0) continue; else if (!strncmp(line, ".SH ", 4) || !strncmp(line, ".Sh ", 4)) { /* * Grab heading... */ int first = 1; fputs(end_fonts[font], outfile); if (blist) { fputs("</li>\n</ul>\n", outfile); blist = 0; } if (list) { if (list == 1) fputs("</dt>\n", outfile); else if (list) fputs("</dd>\n", outfile); fputs("</dl>\n", outfile); list = 0; } line[strlen(line) - 1] = '\0'; /* Strip LF */ if (line[2] == 'H') fputs("<h2><a name='", outfile); else fputs("<h3><a name='", outfile); for (lineptr = line + 4; *lineptr; lineptr ++) if (*lineptr == '\"') continue; else if (*lineptr == ' ') putc_entity('_', outfile); else putc_entity(*lineptr, outfile); fputs("'>", outfile); for (lineptr = line + 4; *lineptr; lineptr ++) if (*lineptr == '\"') continue; else if (*lineptr == ' ') { putc_entity(' ', outfile); first = 1; } else { if (first) putc_entity(*lineptr, outfile); else putc_entity(tolower(*lineptr), outfile); first = 0; } if (line[2] == 'H') fprintf(outfile, "</a></h2>\n%s", start_fonts[font]); else fprintf(outfile, "</a></h3>\n%s", start_fonts[font]); } else if (!strncmp(line, ".LP", 3) || !strncmp(line, ".PP", 3)) { /* * New paragraph... */ fputs(end_fonts[font], outfile); if (blist) { fputs("</li>\n</ul>\n", outfile); blist = 0; } if (list) { if (list == 1) fputs("</dt>\n", outfile); else if (list) fputs("</dd>\n", outfile); fputs("</dl>\n", outfile); list = 0; } fputs("<p>", outfile); font = 0; } else if (!strncmp(line, ".TP ", 4)) { /* * Grab list... */ fputs(end_fonts[font], outfile); if (blist) { fputs("</li>\n</ul>\n", outfile); blist = 0; } if (!list) fputs("<dl>\n", outfile); else if (list == 1) fputs("</dt>\n", outfile); else if (list) fputs("</dd>\n", outfile); fputs("<dt>", outfile); list = 1; font = 0; } else if (!strncmp(line, ".br", 3)) { /* * Grab line break... */ if (list == 1) { fputs("</dt>\n<dd>", outfile); list = 2; } else if (list) fputs("</dd>\n<dd>", outfile); else fputs("<br>\n", outfile); } else if (!strncmp(line, ".de ", 4)) { /* * Define macro - ignore... */ while (fgets(line, sizeof(line), infile)) { linenum ++; if (!strncmp(line, "..", 2)) break; } } else if (!strncmp(line, ".RS", 3)) { /* * Indent... */ fputs("<div style='margin-left: 3em;'>\n", outfile); } else if (!strncmp(line, ".RE", 3)) { /* * Unindent... */ fputs("</div>\n", outfile); } else if (!strncmp(line, ".ds ", 4) || !strncmp(line, ".rm ", 4) || !strncmp(line, ".tr ", 4) || !strncmp(line, ".hy ", 4) || !strncmp(line, ".IX ", 4) || !strncmp(line, ".PD", 3) || !strncmp(line, ".Sp", 3)) { /* * Ignore unused commands... */ } else if (!strncmp(line, ".Vb", 3) || !strncmp(line, ".nf", 3)) { /* * Start preformatted... */ pre = 1; fputs("<pre>\n", outfile); } else if (!strncmp(line, ".Ve", 3) || !strncmp(line, ".fi", 3)) { /* * End preformatted... */ if (pre) { pre = 0; fputs("</pre>\n", outfile); } } else if (!strncmp(line, ".IP \\(bu", 8)) { /* * Bullet list... */ if (blist) fputs("</li>\n", outfile); else { fputs("<ul>\n", outfile); blist = 1; } fputs("<li>", outfile); } else if (!strncmp(line, ".IP ", 4)) { /* * Indented paragraph... */ if (blist) { fputs("</li>\n</ul>\n", outfile); blist = 0; } fputs("<p style='margin-left: 3em;'>", outfile); for (lineptr = line + 4; isspace(*lineptr); lineptr ++); if (*lineptr == '\"') { strmove(line, lineptr + 1); if ((lineptr = strchr(line, '\"')) != NULL) *lineptr = '\0'; } else { strmove(line, lineptr); if ((lineptr = strchr(line, ' ')) != NULL) *lineptr = '\0'; } /* * Process the text as if it was in-line... */ post = "\n<br />\n<br />"; goto process_text; } else if (!strncmp(line, ".\\}", 3)) { /* * Ignore close block... */ } else if (!strncmp(line, ".ie", 3) || !strncmp(line, ".if", 3) || !strncmp(line, ".el", 3)) { /* * If/else - ignore... */ if (strchr(line, '{') != NULL) { /* * Skip whole block... */ while (fgets(line, sizeof(line), infile)) { linenum ++; if (strchr(line, '}') != NULL) break; } } } #if 0 else if (!strncmp(line, ". ", 4)) { /* * Grab ... */ } #endif /* 0 */ else if (!strncmp(line, ".B ", 3)) { /* * Grab bold text... */ fprintf(outfile, "%s<b>%s</b>%s", end_fonts[font], line + 3, start_fonts[font]); } else if (!strncmp(line, ".I ", 3)) { /* * Grab italic text... */ fprintf(outfile, "%s<i>%s</i>%s", end_fonts[font], line + 3, start_fonts[font]); } else if (strncmp(line, ".\\\"", 3)) { /* * Unknown... */ if ((lineptr = strchr(line, ' ')) != NULL) *lineptr = '\0'; else if ((lineptr = strchr(line, '\n')) != NULL) *lineptr = '\0'; fprintf(stderr, "mantohtml: Unknown man page command \'%s\' on line %d!\n", line, linenum); } /* * Skip continuation lines... */ lineptr = line + strlen(line) - 2; if (lineptr >= line && *lineptr == '\\') { while (fgets(line, sizeof(line), infile)) { linenum ++; lineptr = line + strlen(line) - 2; if (lineptr < line || *lineptr != '\\') break; } } } else { /* * Process man page text... */ process_text: for (lineptr = line; *lineptr; lineptr ++) { if (!strncmp(lineptr, "http://", 7)) { /* * Embed URL... */ for (endptr = lineptr + 7; *endptr && !isspace(*endptr & 255); endptr ++); endchar = *endptr; *endptr = '\0'; fprintf(outfile, "<a href='%s'>%s</a>", lineptr, lineptr); *endptr = endchar; lineptr = endptr - 1; } else if (!strncmp(lineptr, "\\fI", 3) && (endptr = strstr(lineptr, "\\fR")) != NULL && (paren = strchr(lineptr, '(')) != NULL && paren < endptr) { /* * Link to man page? */ char manfile[1024], /* Man page filename */ manurl[1024]; /* Man page URL */ /* * See if the man file is available locally... */ lineptr += 3; endchar = *paren; *paren = '\0'; snprintf(manfile, sizeof(manfile), "%s.man", lineptr); snprintf(manurl, sizeof(manurl), "man-%s.html?TOPIC=Man+Pages", lineptr); *paren = endchar; endchar = *endptr; *endptr = '\0'; if (access(manfile, 0)) { /* * Not a local man page, just do it italic... */ fputs("<i>", outfile); while (*lineptr) putc_entity(*lineptr++, outfile); fputs("</i>", outfile); } else { /* * Local man page, do a link... */ fprintf(outfile, "<a href='%s'>", manurl); while (*lineptr) putc_entity(*lineptr++, outfile); fputs("</a>", outfile); } *endptr = endchar; lineptr = endptr + 2; } else if (*lineptr == '\\') { lineptr ++; if (!*lineptr) break; else if (isdigit(lineptr[0]) && isdigit(lineptr[1]) && isdigit(lineptr[2])) { fprintf(outfile, "&#%d;", ((lineptr[0] - '0') * 8 + lineptr[1] - '0') * 8 + lineptr[2] - '0'); lineptr += 2; } else if (*lineptr == '&') continue; else if (*lineptr == 's') { while (lineptr[1] == '-' || isdigit(lineptr[1])) lineptr ++; } else if (*lineptr == '*') { lineptr += 2; } else if (*lineptr != 'f') putc_entity(*lineptr, outfile); else { lineptr ++; if (!*lineptr) break; else { fputs(end_fonts[font], outfile); switch (*lineptr) { default : /* Regular */ font = 0; break; case 'B' : /* Bold */ case 'b' : font = 1; break; case 'I' : /* Italic */ case 'i' : font = 2; break; } fputs(start_fonts[font], outfile); } } } else putc_entity(*lineptr, outfile); } if (post) { fputs(post, outfile); post = NULL; } } } fprintf(outfile, "%s\n", end_fonts[font]); if (blist) { fputs("</li>\n</ul>\n", outfile); } if (list) { if (list == 1) fputs("</dt>\n", outfile); else if (list) fputs("</dd>\n", outfile); fputs("</dl>\n", outfile); } fputs("</body>\n" "</html>\n", outfile); /* * Close files... */ if (infile != stdin) fclose(infile); if (outfile != stdout) fclose(outfile); /* * Return with no errors... */ return (0); }