1 /*
2 AutoHelp file reader.
3 Copyright 2000 Randall Maas (randym@acm.org)
4 Copyright 1998-2000 Fraser Mc
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22
23 #include "dillib.h"
24
25 #define BUFSIZE 1024
26 #define COMMENT '#' /* comment character in rc files */
27 #define SAMEAS "=" /* entries with this get set to the previous equivalent */
28
29 static int AppendText(__AutoHelpEntry_t* Ptr, const char* Str);
30
31 /* @txh */
__AutoHelp_load(const char * Path,__AutoHelpEntry_t ** Rules,size_t * NRules)32 int __AutoHelp_load(const char *Path, __AutoHelpEntry_t**Rules, size_t* NRules)
33 {
34 /*
35 Description
36 Opens the specified file and reads in the table of help information
37
38 Return Value
39 -1 on error, 0 on success
40 @end txh
41 */
42
43 FILE *fp;
44 char in[BUFSIZE];
45 unsigned int lineno=0;
46 char hl[BUFSIZE], regex[BUFSIZE];
47 size_t NAllocd=*NRules;
48
49 if ((fp = fopen(Path, "r")) == NULL) {
50 if (errno != ENOENT) {
51 Err_cmdline("unable to open \"%s\" (%s)\n", Path, strerror(errno));
52 }
53 return -1;
54 }
55
56 while (fgets(in, sizeof(in), fp) != NULL) {
57 ++lineno;
58 if (in[0] == COMMENT) continue;
59 if (sscanf(in, ":%s %[^\n]\n", hl, regex) == 2) {
60 /* a control line, make a new help entry */
61 __AutoHelpEntry_t *new;
62 if (NAllocd <= *NRules)
63 {
64 NAllocd = (NAllocd+1)<<1;
65 if (!(*Rules = realloc(*Rules, sizeof(**Rules)*NAllocd)))
66 {
67 fprintf(stderr, "%s:%u hl %s regex %s\n", Path, lineno,
68 hl, regex);
69 return -1;
70 }
71 }
72 new = *Rules+(*NRules)++;
73 new->Hint = NULL;
74 #if 0
75 new->helplevel = 0;
76 if (strcmp(hl, SAMEAS) == 0 && current != NULL) {
77 new->helplevel = current->helplevel;
78 }
79 else {
80 for (i = hl; *i != '\0'; ++i) {
81 if (*i >= '0' && *i <= '9') {
82 new->helplevel |= 1 << (*i - '0');
83 }
84 }
85 }
86 #endif
87 if (strcmp(regex, SAMEAS) == 0 && *NRules) {
88 new->Reg = new[-1].Reg;
89 }
90 else if (regcomp(&(new->Reg), regex,
91 REG_EXTENDED|REG_NOSUB) != 0) {
92 Err_cmdline("%s:%u: bad regular expression \"%s\"\n", Path, lineno,
93 regex);
94 }
95 continue;
96 }
97
98 /* not a control line, must be a help text line */
99 if (!*NRules) {
100 Err_cmdline("%s:%u: help text without control line\n", Path, lineno);
101 continue;
102 }
103
104 if (AppendText(*Rules + *NRules -1, in)) return -1;
105 }
106
107 fclose(fp);
108 return 0;
109 }
110
AppendText(__AutoHelpEntry_t * Ptr,const char * Str)111 static int AppendText(__AutoHelpEntry_t* Ptr, const char* Str)
112 {
113 /*
114 Description
115 Return Value
116 0 on success, otherwise error
117 */
118 char *newhint;
119 if (Ptr->Hint == NULL) { /* nothing yet */
120 if ((Ptr->Hint = (char *) malloc(strlen(Str)+1)) == NULL)
121 return -1;
122 strcpy(Ptr->Hint, Str);
123 return 0;
124 }
125
126 /* stuff exists, append to it */
127 if ((newhint = (char *) realloc(Ptr->Hint,
128 strlen(Ptr->Hint) +
129 strlen(Str) + 1)) == NULL)
130 return -1;
131 strcpy(newhint + strlen(newhint), Str);
132 Ptr->Hint = newhint;
133 return 0;
134 }
135