// ------------------------------------------------------------------ // GoldED+ // Copyright (C) 1990-1999 Odinn Sorensen // Copyright (C) 1999-2000 Alexander S. Aganichev // ------------------------------------------------------------------ // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307 USA // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ // Compilers for help, screen and xlat. // ------------------------------------------------------------------ #include // ------------------------------------------------------------------ int ReadHelpCfg(int force) { char* ptr; long offset; char buf[1024]; Hlpr* HlpL; int count; int counter; int comment; if ((force > 1) or (FiletimeCmp(CFG->helpcfg.fn, CFG->helpged) > 0)) { gfile ifp(AddPath(CFG->goldpath, CFG->helpcfg.fn), "rb", CFG->sharemode); if (ifp.isopen()) { ifp.SetvBuf(NULL, _IOFBF, 8192); gfile ofp(AddPath(CFG->goldpath, CFG->helpged), "wb", CFG->sharemode); if (ofp.isopen()) { offset = 0L; CFG->helpcfg.ft = GetFiletime(AddPath(CFG->goldpath, CFG->helpcfg.fn)); if (not quiet) STD_PRINTNL("* Reading " << AddPath(CFG->goldpath, CFG->helpcfg.fn)); ofp.SetvBuf(NULL, _IOFBF, 8192); count = 0; ifp.Rewind(); while (ifp.Fgets(buf, sizeof(buf))) { if(strnieql(buf, "*B ", 3)) count++; } HlpL = (Hlpr*)throw_calloc(count+2, sizeof(Hlpr)); ifp.Rewind(); ofp.Fputs("*I\r\n"); ofp.Fwrite(HlpL, count+1, sizeof(Hlpr)); ofp.Fputs("\r\n\r\n"); offset += 4 + ((count+1)*sizeof(Hlpr)) + 4; counter = 0; comment = YES; while (ifp.Fgets(buf, sizeof(buf))) { if(strnieql(buf, "*B ", 3)) { comment = NO; HlpL[counter].help = atow(buf+3); ptr = strchr(buf, ','); strbtrim(strcpy(HlpL[counter].category, ptr ? ptr+1 : "")); HlpL[counter].offset = offset + strlen(buf); counter++; } if (not comment) { ofp.Fputs(buf); offset += strlen(buf); } if(strnieql(buf, "*E", 2)) comment = YES; } HlpL[counter].offset = -1L; ofp.FseekSet(0); ofp.Fputs("*I\r\n"); ofp.Fwrite(HlpL, count+1, sizeof(Hlpr)); throw_free(HlpL); } } } // Init the help system whelpdef(CFG->helpged, Key_F1, C_HELPB, C_HELPW, C_HELPQ, C_HELPS, NULL); whelpwin(0, 0, MAXROW-2, MAXCOL-1, W_BHELP, NO); whelpcat(H_General); return 0; } // ------------------------------------------------------------------ // Window parts const word CRC_BLOCK = 0xC10C; const word CRC_BORDER = 0x97A7; const word CRC_BTYPE = 0x2A2F; const word CRC_CURSOR = 0x0D67; const word CRC_EDIT = 0xB32D; const word CRC_HEADER = 0x6EED; const word CRC_HIGHLIGHT = 0x5EBF; const word CRC_INPUT = 0xA25E; const word CRC_KLUDHIDD = 0x222E; const word CRC_NOSELECT = 0x950C; const word CRC_QUOTE = 0x75DA; const word CRC_SELECTOR = 0x5604; const word CRC_STATUS = 0x1D36; const word CRC_TEARORIG = 0x428E; const word CRC_TITLE = 0x636E; const word CRC_WINDOW = 0xCEFE; const word CRC_FROM = 0x9290; const word CRC_TO = 0x544F; const word CRC_SUBJECT = 0xF861; const word CRC_LOCATION = 0x9E67; const word CRC_KLUDGE = 0xA600; const word CRC_HIDDEN = 0xE465; const word CRC_TAGLINE = 0xC328; const word CRC_TEARLINE = 0xB385; const word CRC_ORIGIN = 0x4CE5; const word CRC_PAGEBAR = 0x4ECA; const word CRC_UNREAD = 0xFE2A; const word CRC_UNSENT = 0xC20B; const word CRC_UNREADHIGH = 0x66D0; const word CRC_UNSENTHIGH = 0xB4FD; const word CRC_QUOTE2 = 0xF400; const word CRC_QUOTE1 = 0xF403; const word CRC_SIGNATURE = 0x1A6E; const word CRC_URL = 0x581C; const word CRC_B = 0x0042; const word CRC_I = 0x0049; const word CRC_BI = 0x4249; const word CRC_U = 0x0055; const word CRC_BU = 0x4255; const word CRC_IU = 0x4955; const word CRC_BIU = 0x21D3; const word CRC_R = 0x0052; const word CRC_RB = 0x5242; const word CRC_RI = 0x5249; const word CRC_RBI = 0x38FE; const word CRC_RU = 0x5255; const word CRC_RBU = 0x38E2; const word CRC_RIU = 0x33E2; const word CRC_RBIU = 0x490E; const word CRC_ALL = 0x14A9; // ------------------------------------------------------------------ // Colors const word CRC_BLACK = 0x20C2; const word CRC_BLUE = 0xB7A3; const word CRC_BROWN = 0xF575; const word CRC_CYAN = 0xD20D; const word CRC_DARKGRAY = 0x0D32; const word CRC_DARKGREY = 0x0932; const word CRC_DGRAY = 0x6ED8; const word CRC_DGREY = 0x6AD8; const word CRC_GREEN = 0xADCF; const word CRC_LBLUE = 0xDF6F; const word CRC_LCYAN = 0xBAC1; const word CRC_LGRAY = 0xC779; const word CRC_LGREEN = 0x8C61; const word CRC_LGREY = 0xC379; const word CRC_LIGHTBLUE = 0x053B; const word CRC_LIGHTCYAN = 0x6095; const word CRC_LIGHTGRAY = 0x1D2D; const word CRC_LIGHTGREEN = 0xB256; const word CRC_LIGHTGREY = 0x192D; const word CRC_LIGHTMAGENTA = 0xBEA8; const word CRC_LIGHTRED = 0xAED2; const word CRC_LMAGENTA = 0xDE86; const word CRC_LRED = 0x7752; const word CRC_MAGENTA = 0xBF75; const word CRC_NORMAL = 0x4DA2; const word CRC_RED = 0x3FF3; const word CRC_REVERSE = 0xB4CD; const word CRC_UNDERLINE = 0xDC93; const word CRC_WHITE = 0xD293; const word CRC_YELLOW = 0xFEAF; // ------------------------------------------------------------------ // Window areas const word CRC_AREA = 0x010B; const word CRC_ASK = 0x0BAE; const word CRC_BACKGROUND = 0x1365; const word CRC_BRAG = 0x505E; const word CRC_HELP = 0xD054; const word CRC_INFO = 0x5811; const word CRC_MENU = 0x2DA4; const word CRC_READER = 0x1DE1; const word CRC_SHADOW = 0x2301; const word CRC_STYLECODE = 0x8B6C; const word CRC_STYLECODES = 0x4CB0; // ------------------------------------------------------------------ #if defined(GCFG_SPELL_INCLUDED) const word CRC_SPELL = 0xB8AE; const word CRC_SCERROR = 0xAB65; #endif // ------------------------------------------------------------------ // Get color value vattr GetColor(char* ink) { word crc; vattr color = BLACK_|_BLACK; crc = strCrc16(strupr(ink)); switch(crc) { // Black is the default case CRC_BLACK: color = BLACK_|_BLACK; break; case CRC_BLUE: color = BLUE_|_BLACK; break; case CRC_GREEN: color = GREEN_|_BLACK; break; case CRC_CYAN: color = CYAN_|_BLACK; break; case CRC_RED: color = RED_|_BLACK; break; case CRC_MAGENTA: color = MAGENTA_|_BLACK; break; case CRC_BROWN: color = BROWN_|_BLACK; break; case CRC_LGRAY: case CRC_LGREY: case CRC_LIGHTGRAY: case CRC_LIGHTGREY: color = LGREY_|_BLACK; break; case CRC_DGRAY: case CRC_DGREY: case CRC_DARKGRAY: case CRC_DARKGREY: color = DGREY_|_BLACK; break; case CRC_LBLUE: case CRC_LIGHTBLUE: color = LBLUE_|_BLACK; break; case CRC_LGREEN: case CRC_LIGHTGREEN: color = LGREEN_|_BLACK; break; case CRC_LCYAN: case CRC_LIGHTCYAN: color = LCYAN_|_BLACK; break; case CRC_LRED: case CRC_LIGHTRED: color = LRED_|_BLACK; break; case CRC_LMAGENTA: case CRC_LIGHTMAGENTA: color = LMAGENTA_|_BLACK; break; case CRC_YELLOW: color = YELLOW_|_BLACK; break; case CRC_WHITE: color = WHITE_|_BLACK; break; case CRC_UNDERLINE: color = UNDERLINE; break; case CRC_NORMAL: color = NORMAL; break; case CRC_HIGHLIGHT: color = HIGHLIGHT; break; case CRC_REVERSE: color = REVERSE; break; } return(color); } // ------------------------------------------------------------------ // Evaluates a color string vattr MakeColor(char* colors) { static int paper=0; int ink=0, blink; char* ink_; char* paper_; #if defined(__UNIX__) || defined(__USE_NCURSES__) blink = 0; #else blink = (stridela("blinking", colors) ? 128 : 0); #endif ink_ = strtok(colors, " \t"); // Get the Ink color if(ink_) { ink = GetColor(ink_); paper_ = strtok(NULL, " \t"); // Skip the "On" if(paper_) { paper_ = strtok(NULL, " \t"); // Get the Paper color if(paper_) paper = GetColor(paper_); } } if(paper > 7) CFG->intensecolors = true; return ink | paper*16 | blink; } // ------------------------------------------------------------------ // Get color values void GetColors(char* value) { word crc; Win* wptr; vattr attr; char buf[256]; char* win; char* colors; char* part=NULL; *buf = NUL; if((win = strtok(value, " \t")) == NULL) return; if(stricmp(win, "shadow")) { part = strtok(NULL, " \t"); if(part == NULL) return; } do { colors = strtok(NULL, " \t\n"); if(colors != NULL) { strcat(buf, colors); strcat(buf, " "); } } while(colors != NULL); crc = strCrc16(strupr(win)); attr = MakeColor(buf); switch(crc) { case CRC_SHADOW: C_SHADOW = attr; return; case CRC_BACKGROUND: wptr = &GC_BACK_; break; case CRC_STATUS: wptr = &GC_STAT_; break; case CRC_BRAG: wptr = &GC_BRAG_; break; case CRC_AREA: wptr = &GC_AREA_; break; case CRC_READER: wptr = &GC_READ_; break; case CRC_HEADER: wptr = &GC_HEAD_; break; case CRC_ASK: wptr = &GC_ASK__; break; case CRC_MENU: wptr = &GC_MENU_; break; case CRC_HELP: wptr = &GC_HELP_; break; case CRC_INFO: wptr = &GC_INFO_; break; case CRC_STYLECODE: case CRC_STYLECODES: wptr = &GC_STYLE_; break; #if defined(GCFG_SPELL_INCLUDED) case CRC_SPELL: wptr = &GC_SPELL_; break; #endif default: return; } crc = strCrc16(strupr(part)); switch(crc) { case CRC_WINDOW: wptr->_Window = attr; if(wptr == &GC_HEAD_) { wptr->_From = attr; wptr->_To = attr; wptr->_Subject = attr; } if(wptr == &GC_READ_) { wptr->_Tagline = attr; GC_STYLE_._Bold = attr; GC_STYLE_._Italic = attr; GC_STYLE_._BoldItalic = attr; GC_STYLE_._Underscore = attr; GC_STYLE_._BoldUnderscore = attr; GC_STYLE_._ItalicUnderscore = attr; GC_STYLE_._BoldItalicUnderscore = attr; GC_STYLE_._Reverse = attr; GC_STYLE_._ReverseBold = attr; GC_STYLE_._ReverseItalic = attr; GC_STYLE_._ReverseBoldItalic = attr; GC_STYLE_._ReverseUnderscore = attr; GC_STYLE_._ReverseBoldUnderscore = attr; GC_STYLE_._ReverseItalicUnderscore = attr; GC_STYLE_._ReverseBoldItalicUnderscore = attr; } break; case CRC_BORDER: wptr->_Border = attr; wptr->_Pagebar = attr; break; case CRC_BTYPE: wptr->btype = atoi(buf); break; case CRC_TITLE: wptr->_Title = attr; break; case CRC_SELECTOR: wptr->_Selector = attr; break; case CRC_HIGHLIGHT: wptr->_Highlight = attr; break; case CRC_NOSELECT: wptr->_Noselect = attr; break; case CRC_QUOTE: wptr->_Quote = attr; wptr->_Quote2 = attr; break; case CRC_CURSOR: wptr->_Cursor = attr; break; case CRC_KLUDHIDD: wptr->_Kludge = attr; wptr->_Hidden = attr; break; case CRC_TEARORIG: wptr->_Tearline = attr; wptr->_Origin = attr; break; case CRC_EDIT: wptr->_Edit = attr; break; case CRC_BLOCK: wptr->_Block = attr; break; case CRC_INPUT: wptr->_Input = attr; break; case CRC_FROM: wptr->_From = attr; break; case CRC_TO: wptr->_To = attr; break; case CRC_SUBJECT: wptr->_Subject = attr; break; case CRC_LOCATION: wptr->_Location = attr; break; case CRC_KLUDGE: wptr->_Kludge = attr; break; case CRC_HIDDEN: wptr->_Hidden = attr; break; case CRC_TAGLINE: wptr->_Tagline = attr; break; case CRC_TEARLINE: wptr->_Tearline = attr; break; case CRC_ORIGIN: wptr->_Origin = attr; break; case CRC_PAGEBAR: wptr->_Pagebar = attr; break; case CRC_UNREAD: wptr->_WindowUnread = attr; break; case CRC_UNSENT: wptr->_WindowUnsent = attr; break; case CRC_UNREADHIGH: wptr->_HighlightUnread = attr; break; case CRC_QUOTE1: wptr->_Quote = attr; break; case CRC_QUOTE2: wptr->_Quote2 = attr; break; case CRC_SIGNATURE: wptr->_Signature = attr; break; case CRC_URL: wptr->_URL = attr; break; case CRC_UNSENTHIGH: wptr->_HighlightUnsent = attr; break; case CRC_B: wptr->_Bold = attr; break; case CRC_I: wptr->_Italic = attr; break; case CRC_BI: wptr->_BoldItalic = attr; break; case CRC_U: wptr->_Underscore = attr; break; case CRC_BU: wptr->_BoldUnderscore = attr; break; case CRC_IU: wptr->_ItalicUnderscore = attr; break; case CRC_BIU: wptr->_BoldItalicUnderscore = attr; break; case CRC_R: wptr->_Reverse = attr; break; case CRC_RB: wptr->_ReverseBold = attr; break; case CRC_RI: wptr->_ReverseItalic = attr; break; case CRC_RBI: wptr->_ReverseBoldItalic = attr; break; case CRC_RU: wptr->_ReverseUnderscore = attr; break; case CRC_RBU: wptr->_ReverseBoldUnderscore = attr; break; case CRC_RIU: wptr->_ReverseItalicUnderscore = attr; break; case CRC_RBIU: wptr->_ReverseBoldItalicUnderscore = attr; break; case CRC_ALL: if(wptr == &GC_STYLE_) { wptr->_Bold = attr; wptr->_Italic = attr; wptr->_BoldItalic = attr; wptr->_Underscore = attr; wptr->_BoldUnderscore = attr; wptr->_ItalicUnderscore = attr; wptr->_BoldItalicUnderscore = attr; wptr->_Reverse = attr; wptr->_ReverseBold = attr; wptr->_ReverseItalic = attr; wptr->_ReverseBoldItalic = attr; wptr->_ReverseUnderscore = attr; wptr->_ReverseBoldUnderscore = attr; wptr->_ReverseItalicUnderscore = attr; wptr->_ReverseBoldItalicUnderscore = attr; } break; #if defined(GCFG_SPELL_INCLUDED) case CRC_SCERROR: wptr->_SpellError = attr; break; #endif default: return; } } // ------------------------------------------------------------------ // Compare escape table items static int CmpEsc(const char* a, const char* b) { return strncmp(a, b, 5); } // ------------------------------------------------------------------ // Read the translation tables void ReadXlatTables() { if (not CFG->xlatcharset.empty() or not CFG->xlatescset.empty()) { Esc EscTable; Chs ChsTable; char buf[256]; char* ptr; char* ptr2; int line, n, x, y, ch=0; gfile ofp(AddPath(CFG->goldpath, CFG->xlatged), "wb", CFG->sharemode); if (ofp.isopen()) { // Compile CHARSET tables std::vector::iterator xlt; for (xlt = CFG->xlatcharset.begin(); xlt != CFG->xlatcharset.end(); xlt++) { // Assign table defaults memset(&ChsTable, 0, sizeof(Chs)); for(n=0; n<256; n++) { ChsTable.t[n][0] = 1; ChsTable.t[n][1] = (uint8_t)n; // The character } strcpy(buf, AddPath(CFG->xlatpath, xlt->mapfile)); gfile ifp(buf, "rb", CFG->sharemode); if (ifp.isopen()) { if (not quiet) STD_PRINTNL("* Reading " << buf); // Read the definition file line = 1; while (ifp.Fgets(buf, sizeof(buf))) { ptr = buf; if(*ptr != ';' and not strblank(ptr)) { if((ptr2 = strchr(ptr+2, ';')) != NULL) *ptr2 = NUL; strtrim(ptr); if(line < 6) { switch(line) { case 1: ChsTable.id = atol(ptr); break; case 2: ChsTable.version = atoi(ptr); break; case 3: ChsTable.level = atoi(ptr); if((ChsTable.level == 1) or (ChsTable.id > 65535L)) ch = 0; else ch = 128; if(ChsTable.level) { for(;*ptr&&isdigit(*ptr);ptr++); for(;*ptr&&isspace(*ptr);ptr++); if(*ptr&&isdigit(*ptr)) { ChsTable.displaylevel = atoi(ptr); if(!ChsTable.displaylevel) ChsTable.displaylevel = ChsTable.level; } else ChsTable.displaylevel = ChsTable.level; } break; case 4: { char *tp = strbtrim(ptr); if(strlen(tp) >= sizeof(ChsTable.imp)) { STD_PRINTNL("* " << AddPath(CFG->xlatpath, xlt->mapfile) << ": At line 4 charset name '" << tp << "' too long. It is supposed no more than " << sizeof(ChsTable.imp)-1 << " characters. A file ignored."); cfgerrors++; ifp.Lseek(0, SEEK_END); ChsTable.displaylevel = 0; ChsTable.level = 0; ChsTable.version = 0; ChsTable.id = 0; } else strcpy(ChsTable.imp, strbtrim(ptr)); } break; case 5: if (ChsTable.level && ChsTable.version!=-1) { gsprintf(PRINTF_DECLARE_BUFFER(ChsTable.exp), "%s %d", strbtrim(ptr), ChsTable.level); } else { char *tp = strbtrim(ptr); if(strlen(tp) >= sizeof(ChsTable.exp)) { STD_PRINTNL("* " << AddPath(CFG->xlatpath, xlt->mapfile) << ": At line 4 charset name '" << tp << "' too long. It is supposed no more than " << sizeof(ChsTable.exp)-1 << " characters. A file ignored."); cfgerrors++; ifp.Lseek(0, SEEK_END); ChsTable.displaylevel = 0; ChsTable.level = 0; ChsTable.version = 0; ChsTable.id = 0; ChsTable.imp[0] = '\0'; } else strcpy(ChsTable.exp, strbtrim(ptr)); } break; } } else { ptr = strskip_wht(ptr); if(ch > 255 or strieql(ptr, "END")) // End of table reached break; x = 0; ChsTable.t[ch][0] = (byte)x; while(*ptr and x < 3) { if(*ptr == '\\') { ptr++; switch(*ptr) { case '\\': ChsTable.t[ch][++x] = (byte)'\\'; ChsTable.t[ch][0] = (byte)x; ptr = strskip_txt(ptr); break; case 'd': y = (uint8_t)atoi(ptr+1); ChsTable.t[ch][++x] = (byte)y; ChsTable.t[ch][0] = (byte)x; ptr = strskip_txt(ptr); break; case 'x': y = (uint8_t)atox(ptr+1); ChsTable.t[ch][++x] = (byte)y; ChsTable.t[ch][0] = (byte)x; ptr = strskip_txt(ptr); break; case '0': ptr = strskip_txt(ptr); break; } } else { ChsTable.t[ch][++x] = (byte)*ptr++; ChsTable.t[ch][0] = (byte)x; } ptr = strskip_wht(ptr); } ch++; } line++; } } } else STD_PRINTNL("* XLAT table " << buf << " could not be opened."); ofp.Fwrite(&ChsTable, sizeof(Chs)); } // Compile ESCSET tables for (xlt = CFG->xlatescset.begin(); xlt != CFG->xlatescset.end(); xlt++) { // Assign defaults memset(&EscTable, 0, sizeof(Esc)); strcpy(buf, AddPath(CFG->xlatpath, xlt->mapfile)); gfile ifp(buf, "rb", CFG->sharemode); if (ifp.isopen()) { if (not quiet) STD_PRINTNL("* Reading " << buf); // Read the definition file line = 1; while (ifp.Fgets(buf, sizeof(buf))) { ptr = buf; if(*ptr != ';' and not strblank(ptr)) { if((ptr2 = strchr(ptr+2, ';')) != NULL) *ptr2 = NUL; strtrim(ptr); if(line < 2) { switch(line) { case 1: strcpy(EscTable.exp, strbtrim(ptr)); break; } } else { n = EscTable.size; if(n > 255 or strieql(ptr, "END")) // End of table reached break; EscTable.t[n][0] = ptr[0]; EscTable.t[n][1] = ptr[1]; x = 2; ptr += 2; ptr = strskip_wht(ptr); while(*ptr and x < 5) { if(*ptr == '\\') { ptr++; switch(*ptr) { case '\\': EscTable.t[n][x++] = '\\'; ptr = strskip_txt(ptr); break; case 'd': EscTable.t[n][x++] = (uint8_t)atoi(ptr+1); ptr = strskip_txt(ptr); break; case 'x': EscTable.t[n][x++] = (uint8_t)atox(ptr+1); ptr = strskip_txt(ptr); break; case '0': EscTable.t[n][x++] = NUL; ptr = strskip_txt(ptr); break; } } else { EscTable.t[n][x++] = *ptr++; } ptr = strskip_wht(ptr); } EscTable.size++; } line++; } } qsort(EscTable.t, EscTable.size, 5, (StdCmpCP)CmpEsc); } else STD_PRINTNL("* XLAT table " << buf << " could not be opened."); ofp.Fwrite(&EscTable, sizeof(Esc)); } } } } // ------------------------------------------------------------------ void CookieIndex(char* textfile, char* indexfile) { gfile ifp(textfile, "rb", CFG->sharemode); if (ifp.isopen()) { ifp.SetvBuf(NULL, _IOFBF, 32000); gfile ofp(indexfile, "wb", CFG->sharemode); if (ofp.isopen()) { ofp.SetvBuf(NULL, _IOFBF, 16000); char buf[256]; long fpos = 0; long tpos = 0; bool was_blank = false; while (ifp.Fgets(buf, sizeof(buf))) { if (strblank(buf)) { ofp.Fwrite(&fpos, sizeof(long)); fpos = tpos + strlen(buf); was_blank = true; } else { was_blank = false; } tpos += strlen(buf); } if (not was_blank) ofp.Fwrite(&fpos, sizeof(long)); } } } // ------------------------------------------------------------------