This source file includes following definitions.
- opal_show_help_init
- opal_show_help_finalize
- array2string
- open_file
- find_topic
- read_topic
- load_array
- opal_show_help_vstring
- opal_show_help_string
- opal_show_vhelp_internal
- opal_show_help_internal
- opal_show_help_add_dir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include "opal_config.h"
27
28 #include <stdio.h>
29 #include <string.h>
30 #include <locale.h>
31 #include <errno.h>
32
33 #include "opal/runtime/opal.h"
34 #include "opal/mca/installdirs/installdirs.h"
35 #include "opal/util/show_help.h"
36 #include "opal/util/show_help_lex.h"
37 #include "opal/util/printf.h"
38 #include "opal/util/argv.h"
39 #include "opal/util/os_path.h"
40 #include "opal/util/output.h"
41 #include "opal/constants.h"
42
43
44
45
46
47 static const char *default_filename = "help-messages";
48 static const char *dash_line = "--------------------------------------------------------------------------\n";
49 static int output_stream = -1;
50 static char **search_dirs = NULL;
51
52
53
54
55 static int opal_show_vhelp_internal(const char *filename, const char *topic,
56 int want_error_header, va_list arglist);
57 static int opal_show_help_internal(const char *filename, const char *topic,
58 int want_error_header, ...);
59 static void opal_show_help_finalize (void);
60
61 opal_show_help_fn_t opal_show_help = opal_show_help_internal;
62 opal_show_vhelp_fn_t opal_show_vhelp = opal_show_vhelp_internal;
63
64
65 int opal_show_help_init(void)
66 {
67 opal_output_stream_t lds;
68
69 OBJ_CONSTRUCT(&lds, opal_output_stream_t);
70 lds.lds_want_stderr = true;
71 output_stream = opal_output_open(&lds);
72
73 opal_argv_append_nosize(&search_dirs, opal_install_dirs.opaldatadir);
74
75 opal_finalize_register_cleanup (opal_show_help_finalize);
76
77 return OPAL_SUCCESS;
78 }
79
80 static void opal_show_help_finalize (void)
81 {
82 opal_output_close(output_stream);
83 output_stream = -1;
84
85
86 if (NULL != search_dirs) {
87 opal_argv_free(search_dirs);
88 search_dirs = NULL;
89 }
90 }
91
92
93
94
95
96
97 static int array2string(char **outstring,
98 int want_error_header, char **lines)
99 {
100 int i, count;
101 size_t len;
102
103
104
105 len = want_error_header ? 2 * strlen(dash_line) : 0;
106 count = opal_argv_count(lines);
107 for (i = 0; i < count; ++i) {
108 if (NULL == lines[i]) {
109 break;
110 }
111 len += strlen(lines[i]) + 1;
112 }
113
114
115
116 (*outstring) = (char*) malloc(len + 1);
117 if (NULL == *outstring) {
118 return OPAL_ERR_OUT_OF_RESOURCE;
119 }
120
121
122
123 *(*outstring) = '\0';
124 if (want_error_header) {
125 strcat(*outstring, dash_line);
126 }
127 for (i = 0; i < count; ++i) {
128 if (NULL == lines[i]) {
129 break;
130 }
131 strcat(*outstring, lines[i]);
132 strcat(*outstring, "\n");
133 }
134 if (want_error_header) {
135 strcat(*outstring, dash_line);
136 }
137
138 return OPAL_SUCCESS;
139 }
140
141
142
143
144
145 static int open_file(const char *base, const char *topic)
146 {
147 char *filename;
148 char *err_msg = NULL;
149 size_t base_len;
150 int i;
151
152
153
154 if (NULL == base) {
155 base = default_filename;
156 }
157
158
159
160
161 if (NULL != search_dirs) {
162
163
164
165 for (i=0; NULL != search_dirs[i]; i++) {
166 filename = opal_os_path( false, search_dirs[i], base, NULL );
167 opal_show_help_yyin = fopen(filename, "r");
168 if (NULL == opal_show_help_yyin) {
169 opal_asprintf(&err_msg, "%s: %s", filename, strerror(errno));
170 base_len = strlen(base);
171 if (4 > base_len || 0 != strcmp(base + base_len - 4, ".txt")) {
172 free(filename);
173 opal_asprintf(&filename, "%s%s%s.txt", search_dirs[i], OPAL_PATH_SEP, base);
174 opal_show_help_yyin = fopen(filename, "r");
175 }
176 }
177 free(filename);
178 if (NULL != opal_show_help_yyin) {
179 break;
180 }
181 }
182 }
183
184
185 if (NULL == opal_show_help_yyin) {
186 opal_output(output_stream, "%sSorry! You were supposed to get help about:\n %s\nBut I couldn't open the help file:\n %s. Sorry!\n%s", dash_line, topic, err_msg, dash_line);
187 free(err_msg);
188 return OPAL_ERR_NOT_FOUND;
189 }
190
191 if (NULL != err_msg) {
192 free(err_msg);
193 }
194
195
196
197 opal_show_help_init_buffer(opal_show_help_yyin);
198
199
200
201 return OPAL_SUCCESS;
202 }
203
204
205
206
207
208
209 static int find_topic(const char *base, const char *topic)
210 {
211 int token, ret;
212 char *tmp;
213
214
215
216 while (1) {
217 token = opal_show_help_yylex();
218 switch (token) {
219 case OPAL_SHOW_HELP_PARSE_TOPIC:
220 tmp = strdup(opal_show_help_yytext);
221 if (NULL == tmp) {
222 return OPAL_ERR_OUT_OF_RESOURCE;
223 }
224 tmp[strlen(tmp) - 1] = '\0';
225 ret = strcmp(tmp + 1, topic);
226 free(tmp);
227 if (0 == ret) {
228 return OPAL_SUCCESS;
229 }
230 break;
231
232 case OPAL_SHOW_HELP_PARSE_MESSAGE:
233 break;
234
235 case OPAL_SHOW_HELP_PARSE_DONE:
236 opal_output(output_stream, "%sSorry! You were supposed to get help about:\n %s\nfrom the file:\n %s\nBut I couldn't find that topic in the file. Sorry!\n%s", dash_line, topic, base, dash_line);
237 return OPAL_ERR_NOT_FOUND;
238 break;
239
240 default:
241 break;
242 }
243 }
244
245
246 }
247
248
249
250
251
252
253 static int read_topic(char ***array)
254 {
255 int token, rc;
256
257 while (1) {
258 token = opal_show_help_yylex();
259 switch (token) {
260 case OPAL_SHOW_HELP_PARSE_MESSAGE:
261
262 rc = opal_argv_append_nosize(array, opal_show_help_yytext);
263 if (rc != OPAL_SUCCESS) {
264 return rc;
265 }
266 break;
267
268 default:
269 return OPAL_SUCCESS;
270 break;
271 }
272 }
273
274
275 }
276
277
278 static int load_array(char ***array, const char *filename, const char *topic)
279 {
280 int ret;
281
282 if (OPAL_SUCCESS != (ret = open_file(filename, topic))) {
283 return ret;
284 }
285
286 ret = find_topic(filename, topic);
287 if (OPAL_SUCCESS == ret) {
288 ret = read_topic(array);
289 }
290
291 fclose(opal_show_help_yyin);
292 opal_show_help_yylex_destroy ();
293
294 if (OPAL_SUCCESS != ret) {
295 opal_argv_free(*array);
296 }
297
298 return ret;
299 }
300
301 char *opal_show_help_vstring(const char *filename, const char *topic,
302 int want_error_header, va_list arglist)
303 {
304 int rc;
305 char *single_string, *output, **array = NULL;
306
307
308 if (OPAL_SUCCESS != (rc = load_array(&array, filename, topic))) {
309 return NULL;
310 }
311
312
313 rc = array2string(&single_string, want_error_header, array);
314
315 if (OPAL_SUCCESS == rc) {
316
317 opal_vasprintf(&output, single_string, arglist);
318 free(single_string);
319 }
320
321 opal_argv_free(array);
322 return (OPAL_SUCCESS == rc) ? output : NULL;
323 }
324
325 char *opal_show_help_string(const char *filename, const char *topic,
326 int want_error_handler, ...)
327 {
328 char *output;
329 va_list arglist;
330
331 va_start(arglist, want_error_handler);
332 output = opal_show_help_vstring(filename, topic, want_error_handler,
333 arglist);
334 va_end(arglist);
335
336 return output;
337 }
338
339 static int opal_show_vhelp_internal(const char *filename, const char *topic,
340 int want_error_header, va_list arglist)
341 {
342 char *output;
343
344
345 output = opal_show_help_vstring(filename, topic, want_error_header,
346 arglist);
347
348
349 if (NULL != output) {
350 opal_output(output_stream, "%s", output);
351 free(output);
352 }
353
354 return (NULL == output) ? OPAL_ERROR : OPAL_SUCCESS;
355 }
356
357 static int opal_show_help_internal(const char *filename, const char *topic,
358 int want_error_header, ...)
359 {
360 va_list arglist;
361 int rc;
362
363
364 va_start(arglist, want_error_header);
365 rc = opal_show_vhelp(filename, topic, want_error_header, arglist);
366 va_end(arglist);
367
368 return rc;
369 }
370
371 int opal_show_help_add_dir(const char *directory)
372 {
373 opal_argv_append_nosize(&search_dirs, directory);
374 return OPAL_SUCCESS;
375 }