1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ 2 /* 3 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana 4 * University Research and Technology 5 * Corporation. All rights reserved. 6 * Copyright (c) 2004-2006 The University of Tennessee and The University 7 * of Tennessee Research Foundation. All rights 8 * reserved. 9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 10 * University of Stuttgart. All rights reserved. 11 * Copyright (c) 2004-2005 The Regents of the University of California. 12 * All rights reserved. 13 * Copyright (c) 2008-2018 Cisco Systems, Inc. All rights reserved. 14 * Copyright (c) 2018 Triad National Security, LLC. All rights 15 * reserved. 16 * $COPYRIGHT$ 17 * 18 * Additional copyrights may follow 19 * 20 * $HEADER$ 21 */ 22 /** 23 * @file 24 * 25 * The "show help" subsystem (SHS) in Open MPI is intended to help the 26 * developer convey meaningful information to the user (read longer 27 * than is convenient in a single printf), particularly when errors 28 * occur. The SHS allows the storage of arbitrary-length help 29 * messages in text files which can be parameterized by text filename, 30 * message name, POSIX locale, and printf()-style parameters (e.g., 31 * "%s", "%d", etc.). Note that the primary purpose of the SHS is to 32 * display help messages, but it can actually be used to display any 33 * arbitrary text messages. 34 * 35 * The function opal_show_help() is used to find a help message and 36 * display it. Its important parameters are a filename, message name, 37 * and printf()-style varargs parameters used to substitute into the 38 * message. 39 * 40 * It was originally intended that this system would support a very 41 * simple version of i18n-like support, but we got (strong) feedback 42 * that i18n support was not desired. So it never happened. 43 * 44 * As such, the file lookup is quite straightforward -- the caller 45 * passes in the filename to find the help message, and the SHS looks 46 * for that file in $pkgdatadir (typically $prefix/share/openmpi). 47 * 48 * Once the file is successfully opened, the SHS looks for the 49 * appropriate help message to display. It looks for the message name 50 * in the file, reads in the message, and displays it. printf()-like 51 * substitutions are performed (e.g., %d, %s, etc.) -- 52 * opal_show_help() takes a variable legnth argument list that are 53 * used for these substitutions. 54 * 55 * The format of the help file is simplistic: 56 * 57 * - Comments begin with #. Any characters after a # on a line are 58 * ignored. It is not possible to escape a #. 59 * - Message names are on a line by themselves and marked with []. 60 * Names can be any ASCII string within the [] (excluding the 61 * characters newline, linefeed, [, ], and #). 62 * - Messages are any characters between message names and/or the end 63 * of the file. 64 * 65 * Here's a sample helpfile: 66 * 67 * \verbatimbegin 68 * # This is a comment. 69 * [topic 1] 70 * Here's the first message. Let's substitute in an integer: %d. 71 * The quick brown fox jumped over the lazy %s. 72 * # This is another comment -- it's not displayed in the first message. 73 * [another:topic:foo:foo:foo] 74 * This is the second message. Let's just keep rolling along to get 75 * to the second line in the message for this example. 76 * \verbatimend 77 * 78 * It is expected that help messages will be grouped by filename; 79 * similar messages should be in a single file. For example, an MCA 80 * component may install its own helpfile in Open MPI's $pkgdatadir, 81 * and therefore the component can invoke opal_show_help() to display 82 * its own help messages. 83 * 84 * Message files in $pkgdatadir have a naming convention: they 85 * generally start with the prefix "help-" and are followed by a name 86 * descriptive of what kind of messages they contain. MCA components 87 * should generally abide by the MCA prefix rule, with the exception 88 * that they should start the filename with "help-", as mentioned 89 * previously. 90 */ 91 92 #ifndef OPAL_SHOW_HELP_H 93 #define OPAL_SHOW_HELP_H 94 95 #include "opal_config.h" 96 97 #include <stdarg.h> 98 99 BEGIN_C_DECLS 100 101 /** 102 * \internal 103 * 104 * Initialization of show_help subsystem 105 */ 106 OPAL_DECLSPEC int opal_show_help_init(void); 107 108 /** 109 * Look up a text message in a text file and display it to the 110 * stderr using printf()-like substitutions (%d, %s, etc.). 111 * 112 * @param filename File where the text messages are contained. 113 * @param topic String index of which message to display from the 114 * text file. 115 * @param want_error_header Display error-bar line header and 116 * footer with the message. 117 * @param varargs Any additional parameters are substituted, 118 * printf()-style into the help message that is displayed. 119 * 120 * This function looks for the filename in the $pkgdatadir 121 * (typically $prefix/share/openmpi), and looks up the message 122 * based on the topic, and displays it. If want_error_header is 123 * true, a header and footer of asterisks are also displayed. 124 * 125 * Note that the "want_error_header" argument is int instead of bool, 126 * because passing a parameter that undergoes default argument 127 * promotion to va_start() has undefined behavior (according to clang 128 * warnings on MacOS High Sierra). 129 */ 130 typedef int (*opal_show_help_fn_t)(const char *filename, const char *topic, 131 int want_error_header, ...); 132 OPAL_DECLSPEC extern opal_show_help_fn_t opal_show_help; 133 134 /** 135 * This function does the same thing as opal_show_help(), but accepts 136 * a va_list form of varargs. 137 */ 138 typedef int (*opal_show_vhelp_fn_t)(const char *filename, const char *topic, 139 int want_error_header, va_list ap); 140 OPAL_DECLSPEC extern opal_show_vhelp_fn_t opal_show_vhelp; 141 142 /** 143 * This function does the same thing as opal_show_help(), but returns 144 * its output in a string (that must be freed by the caller). 145 */ 146 OPAL_DECLSPEC char* opal_show_help_string(const char *filename, 147 const char *topic, 148 int want_error_header, ...); 149 150 /** 151 * This function does the same thing as opal_show_help_string(), but 152 * accepts a va_list form of varargs. 153 */ 154 OPAL_DECLSPEC char* opal_show_help_vstring(const char *filename, 155 const char *topic, 156 int want_error_header, va_list ap); 157 158 /** 159 * This function adds another search location for the files that 160 * back show_help messages. Locations will be searched starting 161 * with the prefix installation directory, then cycled through 162 * any additional directories in the order they were added 163 * 164 * This interface allows libraries that use OMPI to take advantage 165 * of the show_help functionality. OMPI defines the show_help directory 166 * based on where OMPI was installed. However, if the library wants to 167 * use show_help to provide error output specific to itself, then it 168 * nees to tell show_help how to find its own show_help files - without 169 * interfering with the linked ORTE libs when they need to do show_help. 170 */ 171 OPAL_DECLSPEC int opal_show_help_add_dir(const char *directory); 172 173 END_C_DECLS 174 175 #endif