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     return pcmk_rc_ok;
  75 }
  76 
  77 int
  78 pcmk__register_format(GOptionGroup *group, const char *name,
     /* [previous][next][first][last][top][bottom][index][help] */
  79                       pcmk__output_factory_t create, GOptionEntry *options) {
  80     if (create == NULL) {
  81         return -EINVAL;
  82     }
  83 
  84     if (formatters == NULL) {
  85         formatters = pcmk__strkey_table(free, NULL);
  86     }
  87 
  88     if (options != NULL && group != NULL) {
  89         g_option_group_add_entries(group, options);
  90     }
  91 
  92     g_hash_table_insert(formatters, strdup(name), create);
  93     return 0;
  94 }
  95 
  96 void
  97 pcmk__register_formats(GOptionGroup *group, pcmk__supported_format_t *formats) {
     /* [previous][next][first][last][top][bottom][index][help] */
  98     pcmk__supported_format_t *entry = NULL;
  99 
 100     if (formats == NULL) {
 101         return;
 102     }
 103 
 104     for (entry = formats; entry->name != NULL; entry++) {
 105         pcmk__register_format(group, entry->name, entry->create, entry->options);
 106     }
 107 }
 108 
 109 void
 110 pcmk__unregister_formats() {
     /* [previous][next][first][last][top][bottom][index][help] */
 111     if (formatters != NULL) {
 112         g_hash_table_destroy(formatters);
 113     }
 114 }
 115 
 116 int
 117 pcmk__call_message(pcmk__output_t *out, const char *message_id, ...) {
     /* [previous][next][first][last][top][bottom][index][help] */
 118     va_list args;
 119     int rc = pcmk_rc_ok;
 120     pcmk__message_fn_t fn;
 121 
 122     fn = g_hash_table_lookup(out->messages, message_id);
 123     if (fn == NULL) {
 124         crm_debug("Called unknown output message '%s' for format '%s'",
 125                   message_id, out->fmt_name);
 126         return EINVAL;
 127     }
 128 
 129     va_start(args, message_id);
 130     rc = fn(out, args);
 131     va_end(args);
 132 
 133     return rc;
 134 }
 135 
 136 void
 137 pcmk__register_message(pcmk__output_t *out, const char *message_id,
     /* [previous][next][first][last][top][bottom][index][help] */
 138                        pcmk__message_fn_t fn) {
 139     g_hash_table_replace(out->messages, strdup(message_id), fn);
 140 }
 141 
 142 void
 143 pcmk__register_messages(pcmk__output_t *out, pcmk__message_entry_t *table) {
     /* [previous][next][first][last][top][bottom][index][help] */
 144     pcmk__message_entry_t *entry;
 145 
 146     for (entry = table; entry->message_id != NULL; entry++) {
 147         if (pcmk__strcase_any_of(entry->fmt_name, "default", out->fmt_name, NULL)) {
 148             pcmk__register_message(out, entry->message_id, entry->fn);
 149         }
 150     }
 151 }
 152 
 153 void
 154 pcmk__output_and_clear_error(GError *error, pcmk__output_t *out)
     /* [previous][next][first][last][top][bottom][index][help] */
 155 {
 156     if (error == NULL) {
 157         return;
 158     }
 159 
 160     if (out != NULL) {
 161         out->err(out, "%s: %s", g_get_prgname(), error->message);
 162     } else {
 163         fprintf(stderr, "%s: %s\n", g_get_prgname(), error->message);
 164     }
 165 
 166     g_clear_error(&error);
 167 }

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