1 /* c_config.cpp
2 *
3 * Copyright (c) 1994-1996, Marko Macek
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
10 #include "c_config.h"
11
12 #include "c_bind.h"
13 #include "c_color.h"
14 #include "c_fconfig.h"
15 #include "ftever.h"
16 #include "log.h"
17 #include "o_buflist.h"
18 #include "o_cvsbase.h"
19 #include "o_svnbase.h"
20 #include "s_string.h"
21
22 #include <fcntl.h>
23 #include <stdio.h>
24
25 struct GUICharactersEntry {
26 struct GUICharactersEntry *next;
27 char *name;
28 char *chars;
29 };
30
31 struct CurPos {
32 off_t sz;
33 const char *a;
34 const char *c;
35 const char *z;
36 int line;
37 const char *name; // filename
38 };
39
40 #ifdef CONFIG_INDENT_C
41 extern int C_Indent;
42 extern int C_BraceOfs;
43 extern int C_CaseOfs;
44 extern int C_CaseDelta;
45 extern int C_ClassOfs;
46 extern int C_ClassDelta;
47 extern int C_ColonOfs;
48 extern int C_CommentOfs;
49 extern int C_CommentDelta;
50 extern int C_FirstLevelWidth;
51 extern int C_FirstLevelIndent;
52 extern int C_Continuation;
53 extern int C_ParenDelta;
54 extern int FunctionUsesContinuation;
55 #endif
56
57 #ifdef CONFIG_INDENT_REXX
58 extern int REXX_Base_Indent;
59 extern int REXX_Do_Offset;
60 #endif
61
62 extern int ShowVScroll;
63 extern int ShowHScroll;
64 extern int ShowMenuBar;
65
66 int SystemClipboard = 0;
67 int ScreenSizeX = -1, ScreenSizeY = -1;
68 int ScrollBarWidth = 1;
69 int CursorInsSize[2] = { 90, 100 };
70 int CursorOverSize[2] = { 0, 100 };
71 bool CursorBlink = 0; // default is "no" (same as before)
72 int OpenAfterClose = 1;
73 int SelectPathname = 0;
74 char DefaultModeName[32] = "";
75 RxNode *CompletionFilter = NULL;
76 #if defined(DOS) || defined(DOSP32)
77 char PrintDevice[MAXPATH] = "PRN";
78 #else
79 char PrintDevice[MAXPATH] = "\\DEV\\PRN";
80 #endif
81 char CompileCommand[256] = "make";
82 int KeepHistory = 0;
83 int LoadDesktopOnEntry = 0;
84 int SaveDesktopOnExit = 0;
85 char WindowFont[64] = "";
86 // Custom RGB colors (if console driver supports them)
87 TRGBColor RGBColor[16];
88 // true if corresponding triplet in RGBColor is valid
89 bool RGBColorValid [16];
90 int KeepMessages = 0;
91 int ScrollBorderX = 0;
92 int ScrollBorderY = 0;
93 int ScrollJumpX = 8;
94 int ScrollJumpY = 1;
95 int GUIDialogs = 1;
96 int PMDisableAccel = 0;
97 int SevenBit = 0;
98 int WeirdScroll = 0;
99 int LoadDesktopMode = 0;
100 char HelpCommand[128] = "man -a";
101 char *ConfigSourcePath = 0;
102 int IgnoreBufferList = 0;
103 static GUICharactersEntry *GUICharacters = NULL;
104 #ifdef CONFIG_OBJ_CVS
105 char CvsCommand[256] = "cvs";
106 char CvsLogMode[32] = "PLAIN";
107 #endif
108 #ifdef CONFIG_OBJ_SVN
109 char SvnCommand[256] = "svn";
110 char SvnLogMode[32] = "PLAIN";
111 #endif
112 int ReassignModelIds = 0;
113 int RecheckReadOnly = 0;
114 char XShellCommand[256] = "xterm";
115 int ShowTildeFilesInDirList = 1;
116
117 // Which characters to get. defaultCharacters if not set, rest filled
118 // with defaultCharacters if too short
119 // List of GUICharacters is freed, only one item remains
GetGUICharacters(const char * which,const char * defChars)120 const char *GetGUICharacters(const char *which, const char *defChars) {
121 GUICharactersEntry *g, *gg, *found = NULL;
122 char *s;
123 size_t i;
124
125 for (g = GUICharacters; g; g=gg) {
126 gg = g->next;
127 if (strcmp(g->name, which) == 0) {
128 if ((i = strlen(g->chars)) < strlen(defChars)) {
129 s = new char [strlen(defChars) + 1];
130 assert(s != NULL);
131 strcpy(s, g->chars);
132 strcpy(s + i, defChars + i);
133 delete g->chars;
134 g->chars = s;
135 }
136 if (found) {
137 free(found->chars); free(found->name); free(found);
138 }
139 found = g;
140 } else {
141 free(g->name); free(g->chars); free(g);
142 }
143 }
144 GUICharacters = found;
145 return found ? found->chars : defChars;
146 }
147
AppendGUICharacters(const char * string)148 static void AppendGUICharacters(const char *string) {
149 const char *s;
150 GUICharactersEntry *g;
151
152 s = strchr(string, ':');
153 if (s) {
154 g = new GUICharactersEntry;
155 assert(g != NULL);
156
157 // allocate memory for name +1 for strncat
158 g->name = (char *)malloc((s-string) + 1);
159 assert(g->name != NULL);
160
161 // make sure we have zero at start of string
162 *(g->name) = 0;
163
164 // strncat makes sure that we have zero at the end...
165 strncat(g->name, string, (s-string));
166
167 // copy text after ':' to chars...
168 g->chars = strdup(s+1);
169 assert(g->chars != NULL);
170
171 g->next = GUICharacters;
172 GUICharacters = g;
173 }
174 }
175
176 #ifdef CONFIG_SYNTAX_HILIT
AddKeyword(ColorKeywords * tab,char color,const char * keyword)177 static int AddKeyword(ColorKeywords *tab, char color, const char *keyword) {
178 size_t len = strlen(keyword);
179 if (len < 1 || len >= CK_MAXLEN) return 0;
180
181 if (tab->key[len]) {
182 size_t lx = strlen(tab->key[len]);
183 char *key;
184
185 key = (char *)realloc(tab->key[len], lx + len + 1 + 1);
186 assert(key != NULL);
187
188 tab->key[len] = key;
189 assert(tab->key[len] != 0);
190 strcpy(tab->key[len] + lx, keyword);
191 tab->key[len][lx + len] = color;
192 tab->key[len][lx + len + 1] = 0;
193 } else {
194 tab->key[len] = (char *)malloc(len + 2);
195 assert(tab->key[len] != 0);
196 strcpy(tab->key[len], keyword);
197 tab->key[len][len] = color;
198 tab->key[len][len + 1] = 0;
199 }
200 tab->count[len]++;
201 tab->TotalCount++;
202 return 1;
203 }
204 #endif
205
SetModeNumber(EMode * mode,int what,int number)206 static int SetModeNumber(EMode *mode, int what, int number) {
207 int j = what;
208
209 if (j == BFI_LeftMargin || j == BFI_RightMargin) number--;
210 mode->Flags.num[j] = number;
211 return 0;
212 }
213
SetModeString(EMode * mode,int what,const char * string)214 static int SetModeString(EMode *mode, int what, const char *string) {
215 int j = what;
216
217 #ifdef CONFIG_SYNTAX_HILIT
218 if (j == BFI_Colorizer) {
219 mode->fColorize = FindColorizer(string);
220 } else
221 #endif
222 if (j == BFI_EventMap) {
223 mode->fEventMap = FindEventMap(string);
224 #ifdef CONFIG_INDENT
225 } else if (j == BFI_IndentMode) {
226 mode->Flags.num[j] = GetIndentMode(string);
227 #endif
228 } else if (j == BFS_WordChars) {
229 SetWordChars(mode->Flags.WordChars, string);
230 } else if (j == BFS_CapitalChars) {
231 SetWordChars(mode->Flags.CapitalChars, string);
232 } else if (j == BFS_FileNameRx) {
233 if (mode->MatchName)
234 free(mode->MatchName);
235 if (mode->MatchNameRx)
236 RxFree(mode->MatchNameRx);
237 mode->MatchName = strdup(string);
238 mode->MatchNameRx = RxCompile(string);
239 } else if (j == BFS_FirstLineRx) {
240 if (mode->MatchLine)
241 free(mode->MatchLine);
242 if (mode->MatchLineRx)
243 RxFree(mode->MatchLineRx);
244 mode->MatchLine = strdup(string);
245 mode->MatchLineRx = RxCompile(string);
246 } else {
247 if (mode->Flags.str[j & 0xFF])
248 free(mode->Flags.str[j & 0xFF]);
249 mode->Flags.str[j & 0xFF] = strdup(string);
250 }
251 return 0;
252 }
253
254 // *INDENT-OFF*
SetGlobalNumber(int what,int number)255 static int SetGlobalNumber(int what, int number)
256 {
257 STARTFUNC("SetGlobalNumber");
258 LOG << "What: " << what << " Number: " << number << ENDLINE;
259 switch (what) {
260 #ifdef CONFIG_INDENT_C
261 case FLAG_C_Indent: C_Indent = number; break;
262 case FLAG_C_BraceOfs: C_BraceOfs = number; break;
263 case FLAG_C_CaseOfs: C_CaseOfs = number; break;
264 case FLAG_C_CaseDelta: C_CaseDelta = number; break;
265 case FLAG_C_ClassOfs: C_ClassOfs = number; break;
266 case FLAG_C_ClassDelta: C_ClassDelta = number; break;
267 case FLAG_C_ColonOfs: C_ColonOfs = number; break;
268 case FLAG_C_CommentOfs: C_CommentOfs = number; break;
269 case FLAG_C_CommentDelta: C_CommentDelta = number; break;
270 case FLAG_C_FirstLevelIndent: C_FirstLevelIndent = number; break;
271 case FLAG_C_FirstLevelWidth: C_FirstLevelWidth = number; break;
272 case FLAG_C_Continuation: C_Continuation = number; break;
273 case FLAG_C_ParenDelta: C_ParenDelta = number; break;
274 case FLAG_FunctionUsesContinuation: FunctionUsesContinuation = number; break;
275 #endif
276 #ifdef CONFIG_INDENT_REXX
277 case FLAG_REXX_Indent: REXX_Base_Indent = number; break;
278 case FLAG_REXX_Do_Offset: REXX_Do_Offset = number; break;
279 #endif
280 case FLAG_ScreenSizeX: ScreenSizeX = number; break;
281 case FLAG_ScreenSizeY: ScreenSizeY = number; break;
282 case FLAG_CursorInsertStart: CursorInsSize[0] = number; break;
283 case FLAG_CursorInsertEnd: CursorInsSize[1] = number; break;
284 case FLAG_CursorOverStart: CursorOverSize[0] = number; break;
285 case FLAG_CursorOverEnd: CursorOverSize[1] = number; break;
286 case FLAG_CursorBlink: CursorBlink = number; break;
287 case FLAG_SysClipboard: SystemClipboard = number; break;
288 case FLAG_OpenAfterClose: OpenAfterClose = number; break;
289 case FLAG_ShowVScroll: ShowVScroll = number; break;
290 case FLAG_ShowHScroll: ShowHScroll = number; break;
291 case FLAG_ScrollBarWidth: ScrollBarWidth = number; break;
292 case FLAG_SelectPathname: SelectPathname = number; break;
293 case FLAG_ShowMenuBar: ShowMenuBar = number; break;
294 case FLAG_ShowToolBar: ShowToolBar = number; break;
295 case FLAG_KeepHistory: KeepHistory = number; break;
296 case FLAG_LoadDesktopOnEntry: LoadDesktopOnEntry = number; break;
297 case FLAG_SaveDesktopOnExit: SaveDesktopOnExit = number; break;
298 case FLAG_KeepMessages: KeepMessages = number; break;
299 case FLAG_ScrollBorderX: ScrollBorderX = number; break;
300 case FLAG_ScrollBorderY: ScrollBorderY = number; break;
301 case FLAG_ScrollJumpX: ScrollJumpX = number; break;
302 case FLAG_ScrollJumpY: ScrollJumpY = number; break;
303 case FLAG_GUIDialogs: GUIDialogs = number; break;
304 case FLAG_PMDisableAccel: PMDisableAccel = number; break;
305 case FLAG_SevenBit: SevenBit = number; break;
306 case FLAG_WeirdScroll: WeirdScroll = number; break;
307 case FLAG_LoadDesktopMode: LoadDesktopMode = number; break;
308 case FLAG_IgnoreBufferList: IgnoreBufferList = number; break;
309 case FLAG_ReassignModelIds: ReassignModelIds = number; break;
310 case FLAG_RecheckReadOnly: RecheckReadOnly = number; break;
311 case FLAG_ShowTildeFilesInDirList: ShowTildeFilesInDirList = number; break;
312 default:
313 //printf("Unknown global number: %d\n", what);
314 ENDFUNCRC(-1);
315 }
316 ENDFUNCRC(0);
317 }
318 // *INDENT-ON*
319
SetRGBColor(const char * string)320 static void SetRGBColor(const char *string) {
321 int idx,r,g,b;
322 if (sscanf (string, "%x:%x,%x,%x", &idx, &r, &g, &b) != 4) {
323 fprintf(stderr, "Invalid RGB Definition: %s\n", string);
324 return;
325 }
326 if (idx < 0 || idx > 15) {
327 fprintf(stderr, "Invalid RGB index: (0-f only) (%s)\n", string);
328 return;
329 }
330 if (r < 0 || r > 255 ||
331 g < 0 || g > 255 ||
332 b < 0 || b > 255) {
333 fprintf(stderr, "Invalid RGB palette values (00-ff only): %s\n", string);
334 return;
335 }
336 RGBColorValid[idx] = true;
337 RGBColor[idx].r = (unsigned char) r;
338 RGBColor[idx].g = (unsigned char) g;
339 RGBColor[idx].b = (unsigned char) b;
340 }
341
SetGlobalString(long what,const char * string)342 static int SetGlobalString(long what, const char *string) {
343 STARTFUNC("SetGlobalString");
344 LOG << "What: " << what << " String: " << string << ENDLINE;
345
346 switch (what) {
347 case FLAG_DefaultModeName: strlcpy(DefaultModeName, string, sizeof(DefaultModeName)); break;
348 case FLAG_CompletionFilter: if ((CompletionFilter = RxCompile(string)) == NULL) return -1; break;
349 case FLAG_PrintDevice: strlcpy(PrintDevice, string, sizeof(PrintDevice)); break;
350 case FLAG_CompileCommand: strlcpy(CompileCommand, string, sizeof(CompileCommand)); break;
351 case FLAG_WindowFont: strlcpy(WindowFont, string, sizeof(WindowFont)); break;
352 case FLAG_HelpCommand: strlcpy(HelpCommand, string, sizeof(HelpCommand)); break;
353 case FLAG_GUICharacters: AppendGUICharacters (string); break;
354 #ifdef CONFIG_OBJ_CVS
355 case FLAG_CvsCommand: strlcpy(CvsCommand, string, sizeof(CvsCommand)); break;
356 case FLAG_CvsLogMode: strlcpy(CvsLogMode, string, sizeof(CvsLogMode)); break;
357 #endif
358 #ifdef CONFIG_OBJ_SVN
359 case FLAG_SvnCommand: strlcpy(SvnCommand, string, sizeof(SvnCommand)); break;
360 case FLAG_SvnLogMode: strlcpy(SvnLogMode, string, sizeof(SvnLogMode)); break;
361 #endif
362 case FLAG_RGBColor: SetRGBColor(string); break;
363 case FLAG_XShellCommand: strlcpy(XShellCommand, string, sizeof(XShellCommand)); break;
364 default:
365 //printf("Unknown global string: %ld\n", what);
366 ENDFUNCRC(-1);
367 }
368 ENDFUNCRC(0);
369 }
370
SetEventString(EEventMap * Map,int what,const char * string)371 static int SetEventString(EEventMap *Map, int what, const char *string) {
372 STARTFUNC("SetEventString");
373 LOG << "What: " << what << " String: " << string << ENDLINE;
374 switch (what) {
375 case EM_MainMenu:
376 case EM_LocalMenu:
377 Map->SetMenu(what, string);
378 break;
379 default:
380 ENDFUNCRC(-1);
381 }
382 ENDFUNCRC(0);
383 }
384
385 #ifdef CONFIG_SYNTAX_HILIT
SetColorizeString(EColorize * Colorize,long what,const char * string)386 static int SetColorizeString(EColorize *Colorize, long what, const char *string) {
387 STARTFUNC("SetColorizeString");
388 LOG << "What: " << what << " String: " << string << ENDLINE;
389 switch (what) {
390 case COL_SyntaxParser:
391 Colorize->SyntaxParser = GetHilitMode(string);
392 break;
393 default:
394 ENDFUNCRC(-1);
395 }
396 ENDFUNCRC(0);
397 }
398 #endif
399
GetObj(CurPos & cp,unsigned short & len)400 static unsigned char GetObj(CurPos &cp, unsigned short &len) {
401 len = 0;
402 if (cp.c + 3 <= cp.z) {
403 unsigned char c;
404 unsigned char l[2];
405 c = *cp.c++;
406 memcpy(l, cp.c, 2);
407 len = (l[1] << 8) + l[0];
408 cp.c += 2;
409 return c;
410 }
411 return 0xFF;
412 }
413
GetCharStr(CurPos & cp,unsigned short len)414 static const char *GetCharStr(CurPos &cp, unsigned short len) {
415 STARTFUNC("GetCharStr");
416 LOG << "Length: " << len << ENDLINE;
417
418 const char *p = cp.c;
419 if (cp.c + len > cp.z)
420 {
421 LOG << "End of config file in GetCharStr" << ENDLINE;
422 ENDFUNCRC(0);
423 }
424 cp.c += len;
425 ENDFUNCRC(p);
426 }
427
GetNum(CurPos & cp,long & num)428 static int GetNum(CurPos &cp, long &num) {
429 unsigned char n[4];
430 if (cp.c + 4 > cp.z) return 0;
431 memcpy(n, cp.c, 4);
432 num =
433 (n[3] << 24) +
434 (n[2] << 16) +
435 (n[1] << 8) +
436 n[0];
437
438 if ((n[3] > 127) && sizeof(long) > 4)
439 num = num | (~0xFFFFFFFFUL);
440 cp.c += 4;
441 return 1;
442 }
443
ReadCommands(CurPos & cp,const char * Name)444 static int ReadCommands(CurPos &cp, const char *Name) {
445 STARTFUNC("ReadCommands");
446 LOG << "Name = " << (Name != NULL ? Name : "(null)") << ENDLINE;
447
448 unsigned char obj;
449 unsigned short len;
450 long Cmd = NewCommand(Name);
451 long cmdno;
452
453 if (GetObj(cp, len) != CF_INT) ENDFUNCRC(-1);
454 if (GetNum(cp, cmdno) == 0) ENDFUNCRC(-1);
455 if (cmdno != (Cmd | CMD_EXT)) {
456 fprintf(stderr, "Bad Command map %s -> %ld != %ld\n", Name, Cmd, cmdno);
457 ENDFUNCRC(-1);
458 }
459
460 while ((obj = GetObj(cp, len)) != 0xFF) {
461 switch (obj) {
462 case CF_COMMAND:
463 {
464 // char *s;
465 long cnt;
466 long ign;
467 long cmd;
468
469 // if ((s = GetCharStr(cp, len)) == 0) return -1;
470 if (GetNum(cp, cmd) == 0) ENDFUNCRC(-1);
471 if (GetObj(cp, len) != CF_INT) ENDFUNCRC(-1);
472 if (GetNum(cp, cnt) == 0) ENDFUNCRC(-1);
473 if (GetObj(cp, len) != CF_INT) ENDFUNCRC(-1);
474 if (GetNum(cp, ign) == 0) ENDFUNCRC(-1);
475
476 // if (cmd != CmdNum(s)) {
477 // fprintf(stderr, "Bad Command Id: %s -> %d\n", s, cmd);
478 // return -1;
479 // }
480
481 if (AddCommand(Cmd, cmd, cnt, ign) == 0) {
482 if (Name == 0 || strcmp(Name, "xx") != 0) {
483 fprintf(stderr, "Bad Command Id: %ld\n", cmd);
484 ENDFUNCRC(-1);
485 }
486 }
487 }
488 break;
489 case CF_STRING:
490 {
491 const char *s = GetCharStr(cp, len);
492
493 if (s == 0) ENDFUNCRC(-1);
494 if (AddString(Cmd, s) == 0) ENDFUNCRC(-1);
495 }
496 break;
497 case CF_INT:
498 {
499 long num;
500
501 if (GetNum(cp, num) == 0) ENDFUNCRC(-1);
502 if (AddNumber(Cmd, num) == 0) ENDFUNCRC(-1);
503 }
504 break;
505 case CF_VARIABLE:
506 {
507 long num;
508
509 if (GetNum(cp, num) == 0) ENDFUNCRC(-1);
510 if (AddVariable(Cmd, num) == 0) ENDFUNCRC(-1);
511 }
512 break;
513 case CF_CONCAT:
514 if (AddConcat(Cmd) == 0) ENDFUNCRC(-1);
515 break;
516 case CF_END:
517 ENDFUNCRC(Cmd);
518 default:
519 ENDFUNCRC(-1);
520 }
521 }
522 ENDFUNCRC(-1);
523 }
524
ReadMenu(CurPos & cp,const char * MenuName)525 static int ReadMenu(CurPos &cp, const char *MenuName) {
526 unsigned char obj;
527 unsigned short len;
528
529 int menu = -1, item = -1;
530
531 menu = NewMenu(MenuName);
532
533 while ((obj = GetObj(cp, len)) != 0xFF) {
534 switch (obj) {
535 case CF_ITEM:
536 {
537 if (len == 0) {
538 item = NewItem(menu, 0);
539 } else {
540 const char *s = GetCharStr(cp, len);
541 int Cmd;
542 if (s == 0) return -1;
543 item = NewItem(menu, s);
544 if ((obj = GetObj(cp, len)) != CF_MENUSUB) return -1;
545 if ((Cmd = ReadCommands(cp, 0)) == -1) return -1;
546 Menus[menu].Items[item].Cmd = Cmd + 65536;
547 }
548 }
549 break;
550 case CF_SUBMENU:
551 {
552 const char *s = GetCharStr(cp, len);
553 const char *w;
554
555 if ((obj = GetObj(cp, len)) != CF_STRING) return -1;
556 if ((w = GetCharStr(cp, len)) == 0) return -1;
557 item = NewSubMenu(menu, s, GetMenuId(w), SUBMENU_NORMAL);
558 }
559 break;
560
561 case CF_SUBMENUCOND:
562 {
563 const char *s = GetCharStr(cp, len);
564 const char *w;
565
566 if ((obj = GetObj(cp, len)) != CF_STRING) return -1;
567 if ((w = GetCharStr(cp, len)) == 0) return -1;
568 item = NewSubMenu(menu, s, GetMenuId(w), SUBMENU_CONDITIONAL);
569 }
570 break;
571
572 case CF_END:
573 return 0;
574 default:
575 return -1;
576 }
577 }
578 return -1;
579 }
580
ReadColors(CurPos & cp,const char * ObjName)581 static int ReadColors(CurPos &cp, const char *ObjName) {
582 unsigned char obj;
583 unsigned short len;
584
585 while ((obj = GetObj(cp, len)) != 0xFF) {
586 switch (obj) {
587 case CF_STRING:
588 {
589 const char *sname = GetCharStr(cp, len);
590 const char *svalue;
591 if (sname == 0) return -1;
592 if ((obj = GetObj(cp, len)) != CF_STRING) return -1;
593 if ((svalue = GetCharStr(cp, len)) == 0) return -1;
594
595 StlString cl(ObjName);
596
597 cl += '.';
598 cl += sname;
599
600 if (SetColor(cl.c_str(), svalue) == 0)
601 return -1;
602 }
603 break;
604 case CF_END:
605 return 0;
606 default:
607 return -1;
608 }
609 }
610 return -1;
611 }
612
613 #ifdef CONFIG_SYNTAX_HILIT
ReadHilitColors(CurPos & cp,EColorize * Colorize,const char *)614 static int ReadHilitColors(CurPos &cp, EColorize *Colorize, const char * /*ObjName*/) {
615 unsigned char obj;
616 unsigned short len;
617
618 while ((obj = GetObj(cp, len)) != 0xFF) {
619 switch (obj) {
620 case CF_INT:
621 {
622 long cidx;
623 const char *svalue;
624
625 if (GetNum(cp, cidx) == 0) return -1;
626 if ((obj = GetObj(cp, len)) != CF_STRING)
627 return -1;
628 if ((svalue = GetCharStr(cp, len)) == 0)
629 return -1;
630 if (Colorize->SetColor(cidx, svalue) == 0)
631 return -1;
632 }
633 break;
634 case CF_END:
635 return 0;
636 default:
637 return -1;
638 }
639 }
640 return -1;
641 }
642
ReadKeywords(CurPos & cp,ColorKeywords * keywords,int color)643 static int ReadKeywords(CurPos &cp, ColorKeywords *keywords, int color) {
644 unsigned char obj;
645 unsigned short len;
646
647 while ((obj = GetObj(cp, len)) != 0xFF) {
648 switch (obj) {
649 case CF_STRING:
650 {
651 const char *kname = GetCharStr(cp, len);
652 if (kname == 0) return -1;
653 if (AddKeyword(keywords, (char) color, kname) != 1) return -1;
654 }
655 break;
656 case CF_END:
657 return 0;
658 default:
659 return -1;
660 }
661 }
662 return -1;
663 }
664 #endif
665
ReadEventMap(CurPos & cp,EEventMap * Map,const char *)666 static int ReadEventMap(CurPos &cp, EEventMap *Map, const char * /*MapName*/) {
667 unsigned char obj;
668 unsigned short len;
669
670 while ((obj = GetObj(cp, len)) != 0xFF) {
671 switch (obj) {
672 case CF_KEY:
673 {
674 EKey *Key;
675 const char *s;
676 int Cmd;
677
678 if ((s = GetCharStr(cp, len)) == 0) return -1;
679 if ((Key = SetKey(Map, s)) == 0) return -1;
680 if ((obj = GetObj(cp, len)) != CF_KEYSUB) return -1;
681 if ((Cmd = ReadCommands(cp, 0)) == -1) return -1;
682 Key->Cmd = Cmd;
683 }
684 break;
685
686 #ifdef CONFIG_ABBREV
687 case CF_ABBREV:
688 {
689 EAbbrev *Ab;
690 const char *s;
691 const char *x;
692 int Cmd;
693
694 if ((s = GetCharStr(cp, len)) == 0) return -1;
695 obj = GetObj(cp, len);
696 if (obj == CF_KEYSUB) {
697 if ((Cmd = ReadCommands(cp, 0)) == -1) return -1;
698 Ab = new EAbbrev(s, Cmd);
699 } else if (obj == CF_STRING) {
700 x = GetCharStr(cp, len);
701 Ab = new EAbbrev(s, x);
702 } else
703 return -1;
704 if (Ab) {
705 Map->AddAbbrev(Ab);
706 }
707 }
708 break;
709 #endif
710
711 case CF_SETVAR:
712 {
713 long what;
714
715 if (GetNum(cp, what) == 0) return -1;
716 switch (GetObj(cp, len)) {
717 case CF_STRING:
718 {
719 const char *val = GetCharStr(cp, len);
720 if (len == 0) return -1;
721 if (SetEventString(Map, what, val) != 0) return -1;
722 }
723 break;
724 /* case CF_INT:
725 {
726 long num;
727
728 if (GetNum(cp, num) == 0) return -1;
729 if (SetModeNumber(Mode, what, num) != 0) return -1;
730 }
731 break;*/
732 default:
733 return -1;
734 }
735 }
736 break;
737 case CF_END:
738 return 0;
739 default:
740 return -1;
741 }
742 }
743 return -1;
744 }
745
746 #ifdef CONFIG_SYNTAX_HILIT
ReadColorize(CurPos & cp,EColorize * Colorize,const char * ModeName)747 static int ReadColorize(CurPos &cp, EColorize *Colorize, const char *ModeName) {
748 unsigned char obj;
749 unsigned short len;
750
751 long LastState = -1;
752
753 while ((obj = GetObj(cp, len)) != 0xFF) {
754 switch (obj) {
755 case CF_COLOR:
756 if (ReadHilitColors(cp, Colorize, ModeName) == -1) return -1;
757 break;
758
759 case CF_KEYWORD:
760 {
761 const char *colorstr;
762
763 if ((colorstr = GetCharStr(cp, len)) == 0) return -1;
764
765 unsigned int Col;
766 unsigned int ColBg, ColFg;
767
768 if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2)
769 return 0;
770
771 Col = ColFg | (ColBg << 4);
772
773 int color = ChColor(Col);
774 if (ReadKeywords(cp, &Colorize->Keywords, color) == -1) return -1;
775 }
776 break;
777
778 case CF_HSTATE:
779 {
780 long stateno;
781 long color;
782
783 if (Colorize->hm == 0)
784 Colorize->hm = new HMachine();
785
786 assert(Colorize->hm != 0);
787
788 if (GetNum(cp, stateno) == 0)
789 return -1;
790
791 assert(stateno == LastState + 1);
792
793 obj = GetObj(cp, len);
794 assert(obj == CF_INT);
795
796 if (GetNum(cp, color) == 0)
797 return -1;
798
799 HState newState;
800
801 newState.InitState();
802
803 newState.color = color;
804
805 Colorize->hm->AddState(newState);
806 LastState = stateno;
807 }
808 break;
809
810 case CF_HTRANS:
811 {
812 HTrans newTrans;
813 long nextState;
814 long matchFlags;
815 const char *match;
816 long color;
817
818 if (GetNum(cp, nextState) == 0)
819 return -1;
820 obj = GetObj(cp, len);
821 assert(obj == CF_INT);
822 if (GetNum(cp, matchFlags) == 0)
823 return -1;
824 obj = GetObj(cp, len);
825 assert(obj == CF_INT);
826 if (GetNum(cp, color) == 0)
827 return -1;
828 obj = GetObj(cp, len);
829 assert(matchFlags & MATCH_REGEXP ? obj == CF_REGEXP : obj == CF_STRING);
830 if ((match = GetCharStr(cp, len)) == 0)
831 return -1;
832
833 newTrans.InitTrans();
834
835 newTrans.matchFlags = matchFlags;
836 newTrans.nextState = nextState;
837 newTrans.color = color;
838
839 if (newTrans.matchFlags & MATCH_REGEXP) {
840 newTrans.regexp = RxCompile(match);
841 newTrans.matchLen = 0;
842 } else if ((newTrans.matchFlags & MATCH_SET) ||
843 (newTrans.matchFlags & MATCH_NOTSET))
844 {
845 newTrans.matchLen = 1;
846 newTrans.match = (char *)malloc(256/8);
847 assert(newTrans.match != NULL);
848 SetWordChars(newTrans.match, match);
849 } else {
850 newTrans.match = strdup(match);
851 newTrans.matchLen = strlen(match);
852 }
853
854 Colorize->hm->AddTrans(newTrans);
855 }
856 break;
857
858 case CF_HWTYPE:
859 {
860 long nextKwdMatchedState;
861 long nextKwdNotMatchedState;
862 long nextKwdNoCharState;
863 long options;
864 const char *wordChars;
865
866 obj = GetObj(cp, len);
867 assert(obj == CF_INT);
868 if (GetNum(cp, nextKwdMatchedState) == 0)
869 return -1;
870
871 obj = GetObj(cp, len);
872 assert(obj == CF_INT);
873 if (GetNum(cp, nextKwdNotMatchedState) == 0)
874 return -1;
875
876 obj = GetObj(cp, len);
877 assert(obj == CF_INT);
878 if (GetNum(cp, nextKwdNoCharState) == 0)
879 return -1;
880
881 obj = GetObj(cp, len);
882 assert(obj == CF_INT);
883 if (GetNum(cp, options) == 0)
884 return -1;
885
886 obj = GetObj(cp, len);
887 assert(obj == CF_STRING);
888 if ((wordChars = GetCharStr(cp, len)) == 0)
889 return -1;
890
891 Colorize->hm->LastState()->options = options;
892 Colorize->hm->LastState()->nextKwdMatchedState = nextKwdMatchedState;
893 Colorize->hm->LastState()->nextKwdNotMatchedState = nextKwdNotMatchedState;
894 Colorize->hm->LastState()->nextKwdNoCharState = nextKwdNoCharState;
895
896 if (wordChars && *wordChars) {
897 Colorize->hm->LastState()->wordChars = (char *)malloc(256/8);
898 assert(Colorize->hm->LastState()->wordChars != NULL);
899 SetWordChars(Colorize->hm->LastState()->wordChars, wordChars);
900 }
901 }
902 break;
903
904 case CF_HWORDS:
905 {
906 const char *colorstr;
907 int color;
908
909 if ((colorstr = GetCharStr(cp, len)) == 0) return -1;
910
911 color = hcPlain_Keyword;
912
913 if (strcmp(colorstr, "-") != 0) {
914 const char *Value = colorstr;
915 int Col;
916
917 if (*Value == '-') {
918 Value++;
919 if (sscanf(Value, "%1X", &Col) != 1) return -1;
920 Col |= (hcPlain_Background & 0xF0);
921 } else if (Value[1] == '-') {
922 if (sscanf(Value, "%1X", &Col) != 1) return -1;
923 Col <<= 4;
924 Col |= (hcPlain_Background & 0x0F);
925 } else {
926 unsigned int ColBg, ColFg;
927
928 if (sscanf(colorstr, "%1X %1X", &ColFg, &ColBg) != 2)
929 return 0;
930
931 Col = ColFg | (ColBg << 4);
932 }
933 color = Col;
934 }
935 if (ReadKeywords(cp, &Colorize->hm->LastState()->keywords, color) == -1) return -1;
936 }
937 break;
938
939 case CF_SETVAR:
940 {
941 long what;
942
943 if (GetNum(cp, what) == 0) return -1;
944 switch (GetObj(cp, len)) {
945 case CF_STRING:
946 {
947 const char *val = GetCharStr(cp, len);
948 if (len == 0) return -1;
949 if (SetColorizeString(Colorize, what, val) != 0) return -1;
950 }
951 break;
952 /* case CF_INT:
953 {
954 long num;
955
956 if (GetNum(cp, num) == 0) return -1;
957 if (SetModeNumber(Mode, what, num) != 0) return -1;
958 }
959 break;*/
960 default:
961 return -1;
962 }
963 }
964 break;
965 case CF_END:
966 return 0;
967 default:
968 return -1;
969 }
970 }
971 return -1;
972 }
973 #endif
974
ReadMode(CurPos & cp,EMode * Mode,const char *)975 static int ReadMode(CurPos &cp, EMode *Mode, const char * /*ModeName*/) {
976 unsigned char obj;
977 unsigned short len;
978
979 while ((obj = GetObj(cp, len)) != 0xFF) {
980 switch (obj) {
981 case CF_SETVAR:
982 {
983 long what;
984
985 if (GetNum(cp, what) == 0) return -1;
986 switch (GetObj(cp, len)) {
987 case CF_STRING:
988 {
989 const char *val = GetCharStr(cp, len);
990 if (len == 0) return -1;
991 if (SetModeString(Mode, what, val) != 0) return -1;
992 }
993 break;
994 case CF_INT:
995 {
996 long num;
997
998 if (GetNum(cp, num) == 0) return -1;
999 if (SetModeNumber(Mode, what, num) != 0) return -1;
1000 }
1001 break;
1002 default:
1003 return -1;
1004 }
1005 }
1006 break;
1007 case CF_END:
1008 return 0;
1009 default:
1010 return -1;
1011 }
1012 }
1013 return -1;
1014 }
1015
ReadObject(CurPos & cp,const char * ObjName)1016 static int ReadObject(CurPos &cp, const char *ObjName) {
1017 unsigned char obj;
1018 unsigned short len;
1019
1020 while ((obj = GetObj(cp, len)) != 0xFF) {
1021 switch (obj) {
1022 case CF_COLOR:
1023 if (ReadColors(cp, ObjName) == -1) return -1;
1024 break;
1025 #ifdef CONFIG_OBJ_MESSAGES
1026 case CF_COMPRX:
1027 {
1028 long file, line, msg;
1029 const char *regexp;
1030
1031 if (GetObj(cp, len) != CF_INT) return -1;
1032 if (GetNum(cp, file) == 0) return -1;
1033 if (GetObj(cp, len) != CF_INT) return -1;
1034 if (GetNum(cp, line) == 0) return -1;
1035 if (GetObj(cp, len) != CF_INT) return -1;
1036 if (GetNum(cp, msg) == 0) return -1;
1037 if (GetObj(cp, len) != CF_REGEXP) return -1;
1038 if ((regexp = GetCharStr(cp, len)) == 0) return -1;
1039
1040 if (AddCRegexp(file, line, msg, regexp) == 0) return -1;
1041 }
1042 break;
1043 #endif
1044 #ifdef CONFIG_OBJ_CVS
1045 case CF_CVSIGNRX:
1046 {
1047 const char *regexp;
1048
1049 if (GetObj(cp, len) != CF_REGEXP) return -1;
1050 if ((regexp = GetCharStr(cp, len)) == 0) return -1;
1051
1052 if (AddCvsIgnoreRegexp(regexp) == 0) return -1;
1053 }
1054 break;
1055 #endif
1056
1057 #ifdef CONFIG_OBJ_SVN
1058 case CF_SVNIGNRX:
1059 {
1060 const char *regexp;
1061
1062 if (GetObj(cp, len) != CF_REGEXP) return -1;
1063 if ((regexp = GetCharStr(cp, len)) == 0) return -1;
1064
1065 if (AddSvnIgnoreRegexp(regexp) == 0) return -1;
1066 }
1067 break;
1068 #endif
1069 case CF_SETVAR:
1070 {
1071 long what;
1072 if (GetNum(cp, what) == 0) return -1;
1073
1074 switch (GetObj(cp, len)) {
1075 case CF_STRING:
1076 {
1077 const char *val = GetCharStr(cp, len);
1078 if (len == 0) return -1;
1079 if (SetGlobalString(what, val) != 0) return -1;
1080 }
1081 break;
1082 case CF_INT:
1083 {
1084 long num;
1085
1086 if (GetNum(cp, num) == 0) return -1;
1087 if (SetGlobalNumber(what, num) != 0) return -1;
1088 }
1089 break;
1090 default:
1091 return -1;
1092 }
1093 }
1094 break;
1095 case CF_END:
1096 return 0;
1097 default:
1098 return -1;
1099 }
1100 }
1101 return -1;
1102 }
1103
ReadConfigFile(CurPos & cp)1104 static int ReadConfigFile(CurPos &cp) {
1105 unsigned char obj;
1106 unsigned short len;
1107
1108 {
1109 const char *p;
1110
1111 obj = GetObj(cp, len);
1112 assert(obj == CF_STRING);
1113 if ((p = GetCharStr(cp, len)) == 0)
1114 return -1;
1115
1116 if (ConfigSourcePath)
1117 free(ConfigSourcePath);
1118
1119 ConfigSourcePath = strdup(p);
1120 }
1121
1122 while ((obj = GetObj(cp, len)) != 0xFF) {
1123 switch (obj) {
1124 case CF_SUB:
1125 {
1126 const char *CmdName = GetCharStr(cp, len);
1127
1128 if (ReadCommands(cp, CmdName) == -1) return -1;
1129 }
1130 break;
1131 case CF_MENU:
1132 {
1133 const char *MenuName = GetCharStr(cp, len);
1134
1135 if (ReadMenu(cp, MenuName) == -1) return -1;
1136 }
1137 break;
1138 case CF_EVENTMAP:
1139 {
1140 EEventMap *EventMap = 0;
1141 const char *MapName = GetCharStr(cp, len);
1142 const char *UpMap = 0;
1143
1144 if ((obj = GetObj(cp, len)) != CF_PARENT) return -1;
1145 if (len > 0)
1146 if ((UpMap = GetCharStr(cp, len)) == 0) return -1;
1147
1148 // add new mode
1149 if ((EventMap = FindEventMap(MapName)) == 0) {
1150 EEventMap *OrgMap = 0;
1151
1152 if (strcmp(UpMap, "") != 0)
1153 OrgMap = FindEventMap(UpMap);
1154 EventMap = new EEventMap(MapName, OrgMap);
1155 } else {
1156 if (EventMap->Parent == 0)
1157 EventMap->Parent = FindEventMap(UpMap);
1158 }
1159 if (ReadEventMap(cp, EventMap, MapName) == -1) return -1;
1160 }
1161 break;
1162 #ifdef CONFIG_SYNTAX_HILIT
1163 case CF_COLORIZE:
1164 {
1165 EColorize *Mode = 0;
1166 const char *ModeName = GetCharStr(cp, len);
1167 const char *UpMode = 0;
1168
1169 if ((obj = GetObj(cp, len)) != CF_PARENT) return -1;
1170 if (len > 0)
1171 if ((UpMode = GetCharStr(cp, len)) == 0) return -1;
1172
1173 // add new mode
1174 if ((Mode = FindColorizer(ModeName)) == 0)
1175 Mode = new EColorize(ModeName, UpMode);
1176 else {
1177 if (Mode->Parent == 0)
1178 Mode->Parent = FindColorizer(UpMode);
1179 }
1180 if (ReadColorize(cp, Mode, ModeName) == -1)
1181 return -1;
1182 }
1183 break;
1184 #endif
1185 case CF_MODE:
1186 {
1187 EMode *Mode = 0;
1188 const char *ModeName = GetCharStr(cp, len);
1189 const char *UpMode = 0;
1190
1191 if ((obj = GetObj(cp, len)) != CF_PARENT) return -1;
1192 if (len > 0)
1193 if ((UpMode = GetCharStr(cp, len)) == 0) return -1;
1194
1195 // add new mode
1196 if ((Mode = FindMode(ModeName)) == 0) {
1197 EMode *OrgMode = 0;
1198 EEventMap *Map;
1199
1200 if (strcmp(UpMode, "") != 0)
1201 OrgMode = FindMode(UpMode);
1202 Map = FindEventMap(ModeName);
1203 if (Map == 0) {
1204 EEventMap *OrgMap = 0;
1205
1206 if (strcmp(UpMode, "") != 0)
1207 OrgMap = FindEventMap(UpMode);
1208 Map = new EEventMap(ModeName, OrgMap);
1209 }
1210 Mode = new EMode(OrgMode, Map, ModeName);
1211 Mode->fNext = Modes;
1212 Modes = Mode;
1213 } else {
1214 if (Mode->fParent == 0)
1215 Mode->fParent = FindMode(UpMode);
1216 }
1217 if (ReadMode(cp, Mode, ModeName) == -1)
1218 return -1;
1219 }
1220 break;
1221 case CF_OBJECT:
1222 {
1223 const char *ObjName;
1224
1225 if ((ObjName = GetCharStr(cp, len)) == 0)
1226 return -1;
1227 if (ReadObject(cp, ObjName) == -1)
1228 return -1;
1229 }
1230 break;
1231 case CF_EOF:
1232 return 0;
1233 default:
1234 return -1;
1235 }
1236 }
1237 return -1;
1238 }
1239
LoadConfig(int,char **,char * CfgFileName)1240 int LoadConfig(int /*argc*/, char ** /*argv*/, char *CfgFileName) {
1241 STARTFUNC("LoadConfig");
1242 LOG << "Config file: " << CfgFileName << ENDLINE;
1243
1244 int fd, rc;
1245 char *buffer = 0;
1246 struct stat statbuf;
1247 CurPos cp;
1248
1249 if ((fd = open(CfgFileName, O_RDONLY | O_BINARY)) == -1)
1250 ENDFUNCRC(-1);
1251 if (fstat(fd, &statbuf) != 0) {
1252 close(fd);
1253 ENDFUNCRC(-1);
1254 }
1255
1256 // check that we have enough room for signature (CONFIG_ID + VERNUM)
1257 if (statbuf.st_size < (4+4)) {
1258 close(fd);
1259 DieError(0, "Bad .CNF signature");
1260 ENDFUNCRC(-1);
1261 }
1262
1263 buffer = (char *) malloc((size_t)statbuf.st_size);
1264 if (buffer == 0) {
1265 close(fd);
1266 ENDFUNCRC(-1);
1267 }
1268 if (read(fd, buffer, (size_t)statbuf.st_size) != statbuf.st_size) {
1269 close(fd);
1270 free(buffer);
1271 ENDFUNCRC(-1);
1272 }
1273 close(fd);
1274
1275 unsigned char l[4];
1276 unsigned long ln;
1277
1278 memcpy(l, buffer, 4);
1279 ln = (l[3] << 24) + (l[2] << 16) + (l[1] << 8) + l[0];
1280
1281 if (ln != CONFIG_ID) {
1282 free(buffer);
1283 DieError(0, "Bad .CNF signature");
1284 ENDFUNCRC(-1);
1285 }
1286
1287 memcpy(l, buffer + 4, 4);
1288 ln = (l[3] << 24) + (l[2] << 16) + (l[1] << 8) + l[0];
1289
1290 if (ln != VERNUM) {
1291 LOG << std::hex << ln << " != " << VERNUM << ENDLINE;
1292 free(buffer);
1293 DieError(0, "Bad .CNF version.");
1294 ENDFUNCRC(-1);
1295 }
1296
1297 cp.name = CfgFileName;
1298 cp.sz = statbuf.st_size;
1299 cp.a = buffer;
1300 cp.c = cp.a + 2 * 4;
1301 cp.z = cp.a + cp.sz;
1302 cp.line = 1;
1303
1304 rc = ReadConfigFile(cp);
1305
1306 free(buffer);
1307
1308 if (rc == -1) {
1309 DieError(1, "Error %s offset %d\n", CfgFileName, cp.c - cp.a);
1310 }
1311 ENDFUNCRC(rc);
1312 }
1313
1314 #include "defcfg.h"
1315
UseDefaultConfig()1316 int UseDefaultConfig() {
1317 CurPos cp;
1318 int rc;
1319
1320 cp.name = "Internal Configuration";
1321 cp.sz = sizeof(DefaultConfig);
1322 cp.a = (char *)DefaultConfig;
1323 cp.c = (char *)DefaultConfig + 2 * 4;
1324 cp.z = cp.a + cp.sz;
1325 cp.line = 1;
1326
1327 rc = ReadConfigFile(cp);
1328
1329 if (rc == -1)
1330 DieError(1, "Error %s offset %d\n", cp.name, cp.c - cp.a);
1331 return rc;
1332 }
1333