root/lib/common/output.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pcmk__output_free
  2. pcmk__output_new
  3. pcmk__register_format
  4. pcmk__register_formats
  5. pcmk__unregister_formats
  6. pcmk__call_message
  7. pcmk__register_message
  8. pcmk__register_messages
  9. pcmk__output_and_clear_error

   1 /*
   2  * Copyright 2019-2021 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <crm/common/util.h>
  13 #include <crm/common/xml.h>
  14 #include <libxml/tree.h>
  15 
  16 static GHashTable *formatters = NULL;
  17 
  18 void
  19 pcmk__output_free(pcmk__output_t *out) {
     /* [previous][next][first][last][top][bottom][index][help] */
  20     out->free_priv(out);
  21 
  22     if (out->messages != NULL) {
  23         g_hash_table_destroy(out->messages);
  24     }
  25 
  26     g_free(out->request);
  27     free(out);
  28 }
  29 
  30 int
  31 pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filename,
     /* [previous][next][first][last][top][bottom][index][help] */
  32                  char **argv) {
  33     pcmk__output_factory_t create = NULL;;
  34 
  35     if (formatters == NULL) {
  36         return EINVAL;
  37     }
  38 
  39     /* If no name was given, just try "text".  It's up to each tool to register
  40      * what it supports so this also may not be valid.
  41      */
  42     if (fmt_name == NULL) {
  43         create = g_hash_table_lookup(formatters, "text");
  44     } else {
  45         create = g_hash_table_lookup(formatters, fmt_name);
  46     }
  47 
  48     if (create == NULL) {
  49         return pcmk_rc_unknown_format;
  50     }
  51 
  52     *out = create(argv);
  53     if (*out == NULL) {
  54         return ENOMEM;
  55     }
  56 
  57     if (pcmk__str_eq(filename, "-", pcmk__str_null_matches)) {
  58         (*out)->dest = stdout;
  59     } else {
  60         (*out)->dest = fopen(filename, "w");
  61         if ((*out)->dest == NULL) {
  62             return errno;
  63         }
  64     }
  65 
  66     (*out)->quiet = false;
  67     (*out)->messages = pcmk__strkey_table(free, NULL);
  68 
  69     if ((*out)->init(*out) == false) {
  70         pcmk__output_free(*out);
  71         return ENOMEM;
  72     }
  73 
  74     setenv("OCF_OUTPUT_FORMAT", (*out)->fmt_name, 1);
  75 
  76     return pcmk_rc_ok;
  77 }
  78 
  79 int
  80 pcmk__register_format(GOptionGroup *group, const char *name,
     /* [previous][next][first][last][top][bottom][index][help] */
  81                       pcmk__output_factory_t create, GOptionEntry *options) {
  82     if (create == NULL) {
  83         return -EINVAL;
  84     }
  85 
  86     if (formatters == NULL) {
  87         formatters = pcmk__strkey_table(free, NULL);
  88     }
  89 
  90     if (options != NULL && group != NULL) {
  91         g_option_group_add_entries(group, options);
  92     }
  93 
  94     g_hash_table_insert(formatters, strdup(name), create);
  95     return 0;
  96 }
  97 
  98 void
  99 pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *formats) {
     /* [previous][next][first][last][top][bottom][index][help] */
 100     pcmk__supported_format_t *entry = NULL;
 101 
 102     if (formats == NULL) {
 103         return;
 104     }
 105 
 106     for (entry = formats; entry->name != NULL; entry++) {
 107         pcmk__register_format(group, entry->name, entry->create, entry->options);
 108     }
 109 }
 110 
 111 void
 112 pcmk__unregister_formats() {
     /* [previous][next][first][last][top][bottom][index][help] */
 113     if (formatters != NULL) {
 114         g_hash_table_destroy(formatters);
 115     }
 116 }
 117 
 118 int
 119 pcmk__call_message(pcmk__output_t *out, const char *message_id, ...) {
     /* [previous][next][first][last][top][bottom][index][help] */
 120     va_list args;
 121     int rc = pcmk_rc_ok;
 122     pcmk__message_fn_t fn;
 123 
 124     fn = g_hash_table_lookup(out->messages, message_id);
 125     if (fn == NULL) {
 126         crm_debug("Called unknown output message '%s' for format '%s'",
 127                   message_id, out->fmt_name);
 128         return EINVAL;
 129     }
 130 
 131     va_start(args, message_id);
 132     rc = fn(out, args);
 133     va_end(args);
 134 
 135     return rc;
 136 }
 137 
 138 void
 139 pcmk__register_message(pcmk__output_t *out, const char *message_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 140                        pcmk__message_fn_t fn) {
 141     g_hash_table_replace(out->messages, strdup(message_id), fn);
 142 }
 143 
 144 void
 145 pcmk__register_messages(pcmk__output_t *out, pcmk__message_entry_t *table) {
     /* [previous][next][first][last][top][bottom][index][help] */
 146     pcmk__message_entry_t *entry;
 147 
 148     for (entry = table; entry->message_id != NULL; entry++) {
 149         if (pcmk__strcase_any_of(entry->fmt_name, "default", out->fmt_name, NULL)) {
 150             pcmk__register_message(out, entry->message_id, entry->fn);
 151         }
 152     }
 153 }
 154 
 155 void
 156 pcmk__output_and_clear_error(GError *error, pcmk__output_t *out)
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {
 158     if (error == NULL) {
 159         return;
 160     }
 161 
 162     if (out != NULL) {
 163         out->err(out, "%s: %s", g_get_prgname(), error->message);
 164     } else {
 165         fprintf(stderr, "%s: %s\n", g_get_prgname(), error->message);
 166     }
 167 
 168     g_clear_error(&error);
 169 }

/* [previous][next][first][last][top][bottom][index][help] */