00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035
00036 #include "helpfile.h"
00037
00038 flagmap_t if_flagmap[] = {
00039 { "oper", HELPFILE_FLAG_OPER, HELPFILE_FLAG_OPER },
00040 { "!oper", 0, HELPFILE_FLAG_OPER },
00041 { "servop", HELPFILE_FLAG_SERVOP, HELPFILE_FLAG_SERVOP },
00042 { "!servop", 0, HELPFILE_FLAG_SERVOP },
00043 { "sra", HELPFILE_FLAG_SRA, HELPFILE_FLAG_SRA },
00044 { "!sra", 0, HELPFILE_FLAG_SRA },
00045 { NULL, 0, 0 }
00046 };
00047
00048 helpline_t::helpline_t(void)
00049 {
00050 flags = 0;
00051 mask = 0;
00052 cmd = 0;
00053 text = NULL;
00054 next = NULL;
00055 }
00056
00057 helpline_t::helpline_t(u_int32_t x_cmd, u_int32_t x_flags, u_int32_t x_mask,
00058 char *x_text)
00059 {
00060 flags = x_flags;
00061 mask = x_mask;
00062 cmd = x_cmd;
00063 next = NULL;
00064
00065 if (x_text == NULL || *x_text == '\0')
00066 text = NULL;
00067 else
00068 text = strdup(x_text);
00069 }
00070
00071 helpline_t::~helpline_t()
00072 {
00073 if (text != NULL)
00074 delete text;
00075 }
00076
00077 void
00078 helpline_t::delchain(void)
00079 {
00080 helpline_t *hl;
00081 helpline_t *hl2;
00082
00083 hl = this;
00084
00085 while (hl != NULL) {
00086 hl2 = hl;
00087 hl = hl->get_next();
00088 delete hl2;
00089 }
00090 }
00091
00092 helpfile_t::helpfile_t(void)
00093 {
00094 first = NULL;
00095 last = NULL;
00096 fname = NULL;
00097 }
00098
00099 helpfile_t::~helpfile_t()
00100 {
00101 if (first != NULL)
00102 first->delchain();
00103 }
00104
00105 void
00106 helpfile_t::addline(u_int32_t x_cmd, u_int32_t x_flags,
00107 u_int32_t x_mask, char *x_text)
00108 {
00109 helpline_t *hl;
00110
00111 hl = new helpline_t(x_cmd, x_flags, x_mask, x_text);
00112
00113 if (first == NULL) {
00114 last = hl;
00115 first = hl;
00116
00117 return;
00118 }
00119
00120 last->set_next(hl);
00121 last = hl;
00122 }
00123
00124 void
00125 helpfile_t::display(u_int32_t flags)
00126 {
00127 helpline_t *hl;
00128 int last_blank;
00129
00130 last_blank = 0;
00131
00132 for (hl = first ; hl != NULL ; hl = hl->get_next()) {
00133 if ((hl->get_mask() & flags) != hl->get_flags())
00134 continue;
00135
00136 switch (hl->get_cmd()) {
00137 case HELPFILE_CMD_PRINTF:
00138 if (hl->get_text() == NULL) {
00139 last_blank = 1;
00140 } else {
00141 if (last_blank == 1) {
00142 printf("\n");
00143 last_blank = 0;
00144 }
00145 printf("%s\n", hl->get_text());
00146 last_blank = 0;
00147 }
00148 break;
00149 case HELPFILE_CMD_EXIT:
00150 if (hl->get_text() != NULL) {
00151 if (last_blank == 1) {
00152 printf("\n");
00153 last_blank = 0;
00154 }
00155 printf("exit: %s\n", hl->get_text());
00156 }
00157 return;
00158 break;
00159 }
00160 }
00161 }
00162
00163 void
00164 helpfile_t::readfile(char *x_fname)
00165 {
00166 int i;
00167 FILE *f;
00168 static char inbuf[512];
00169 char *p;
00170 int flag_change;
00171 u_int32_t flags0;
00172 u_int32_t mask0;
00173 u_int32_t flags1;
00174 u_int32_t mask1;
00175
00176 f = fopen(x_fname, "r");
00177 if (f == NULL)
00178 return;
00179
00180 i = 0;
00181 flags0 = flags1 = 0;
00182 mask0 = mask1 = 0;
00183 flag_change = 1;
00184
00185 for (;;) {
00186 if (fgets(inbuf, sizeof(inbuf), f) == 0)
00187 break;
00188
00189 inbuf[strlen(inbuf) - 1] = '\0';
00190 if (inbuf[0] == '\0' && flag_change == 0)
00191 continue;
00192
00193 if (inbuf[0] == '.') {
00194 if (strncmp(inbuf + 1, "if", 2) == 0) {
00195 mask0 = mask1;
00196 flags0 = flags1;
00197 flag_change = 1;
00198 helpfile_parse_if(&flags1, &mask1, inbuf + 4);
00199 } else if (strncmp(inbuf + 1, "endif", 5) == 0) {
00200 mask1 = mask0;
00201 flags1 = flags0;
00202 flag_change = 1;
00203 } else if (strncmp(inbuf + 1, "exit", 4) == 0) {
00204
00205
00206
00207
00208 p = inbuf + 5;
00209
00210 while (*p == ' ')
00211 p++;
00212
00213 if (*p == '\0')
00214 p = NULL;
00215
00216 addline(HELPFILE_CMD_EXIT, flags1, mask1, p);
00217 i++;
00218 } else if (strncmp(inbuf + 1, "#", 1) == 0) {
00219 continue;
00220 } else {
00221 fprintf(stderr, "%s not understood\n", inbuf);
00222 exit(1);
00223 }
00224
00225 continue;
00226 }
00227
00228 addline(HELPFILE_CMD_PRINTF, flags1, mask1, inbuf);
00229 i++;
00230 }
00231
00232 fclose(f);
00233 fname = strdup(x_fname);
00234 }
00235
00236
00237 void
00238 helpfile_parse_if(u_int32_t *flags, u_int32_t *mask, char *statement)
00239 {
00240 flagmap_t *cmds = NULL;
00241 char *line;
00242 char *cline;
00243
00244 line = statement;
00245
00246 cline = strsep(&line, " ");
00247
00248 while (cline != NULL) {
00249 if (*cline == '\0')
00250 goto nextline;
00251
00252 cmds = if_flagmap;
00253 while (cmds->name != NULL) {
00254 if (strcmp(cline, cmds->name) == 0) {
00255 *flags |= cmds->flags;
00256 *mask |= cmds->mask;
00257 break;
00258 }
00259 cmds++;
00260 }
00261 nextline:
00262 cline = strsep(&line, " ");
00263 }
00264
00265 if (cmds->name == NULL) {
00266 fprintf(stderr, "if statement %s not understood\n", statement);
00267 exit(1);
00268 }
00269 }
00270
00271 #ifdef TEST_HELPFILE
00272
00273 int
00274 main(int argc, char **argv)
00275 {
00276 helpfile_t hf;
00277 u_int32_t flags;
00278 u_int32_t mask;
00279 int i;
00280
00281 if (argc < 2) {
00282 fprintf(stderr, "Usage: %s infile.help [flag [flag...]]\n",
00283 argv[0]);
00284 exit(1);
00285 }
00286
00287 flags = 0;
00288 mask = 0;
00289
00290 for (i = 2 ; i < argc ; i++)
00291 helpfile_parse_if(&flags, &mask, argv[i]);
00292
00293 hf.readfile(argv[1]);
00294
00295 hf.display(flags);
00296
00297 return 0;
00298 }
00299 #endif