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 }