(root)/
texinfo-7.1/
tp/
Texinfo/
XS/
parsetexi/
errors.c
       1  /* Copyright 2010-2023 Free Software Foundation, Inc.
       2  
       3     This program is free software: you can redistribute it and/or modify
       4     it under the terms of the GNU General Public License as published by
       5     the Free Software Foundation, either version 3 of the License, or
       6     (at your option) any later version.
       7  
       8     This program is distributed in the hope that it will be useful,
       9     but WITHOUT ANY WARRANTY; without even the implied warranty of
      10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      11     GNU General Public License for more details.
      12  
      13     You should have received a copy of the GNU General Public License
      14     along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      15  
      16  #include <config.h>
      17  
      18  
      19  #ifdef ENABLE_NLS
      20  #include <libintl.h>
      21  #endif
      22  
      23  #include <stdlib.h>
      24  #include <stdarg.h>
      25  #include <stdio.h>
      26  
      27  #include "errors.h"
      28  #include "input.h"
      29  #include "text.h"
      30  #include "debug.h"
      31  
      32  /* wrappers for asprintf and vasprintf */
      33  int
      34  xvasprintf (char **ptr, const char *template, va_list ap)
      35  {
      36    int ret;
      37    ret = vasprintf (ptr, template, ap);
      38    if (ret < 0)
      39      abort (); /* out of memory */
      40    return ret;
      41  }
      42  
      43  int
      44  xasprintf (char **ptr, const char *template, ...)
      45  {
      46    va_list v;
      47    va_start (v, template);
      48    return xvasprintf (ptr, template, v);
      49  }
      50  
      51  
      52  void bug (char *message)
      53  {
      54    fprintf (stderr, "texi2any (XS parser): bug: %s\n", message);
      55  }
      56  
      57  void fatal (char *message)
      58  {
      59    bug (message);
      60    abort ();
      61  }
      62  
      63  /* these are not full line messages, but the part that are output along
      64     with debug messages, as is done in Texinfo::Register::line_warn/line_error
      65     called by the perl parser.  Here without using the gettext framework
      66     for the translation of 'warning'*/
      67  void
      68  debug_error_warning_message (ERROR_MESSAGE *error_message)
      69  {
      70    if (error_message->type == warning)
      71      fprintf (stderr, "warning: ");
      72  
      73    if (error_message->source_info.macro)
      74      fprintf (stderr, "%s (possibly involving @%s)\n",
      75               error_message->message, error_message->source_info.macro);
      76    else
      77      fprintf (stderr, "%s\n", error_message->message);
      78  }
      79  
      80  ERROR_MESSAGE *error_list = 0;
      81  size_t error_number = 0;
      82  static size_t error_space = 0;
      83  
      84  static void
      85  line_error_internal (enum error_type type, SOURCE_INFO *cmd_source_info,
      86                       char *format, va_list v)
      87  {
      88    char *message;
      89  #ifdef ENABLE_NLS
      90    xvasprintf (&message, gettext(format), v);
      91  #else
      92    xvasprintf (&message, format, v);
      93  #endif
      94    if (!message) fatal ("vasprintf failed");
      95  
      96    if (error_number == error_space)
      97      {
      98        error_list = realloc (error_list,
      99                              (error_space += 10) * sizeof (ERROR_MESSAGE));
     100      }
     101    error_list[error_number].message = message;
     102    error_list[error_number].type = type;
     103  
     104    if (cmd_source_info)
     105      {
     106        if (cmd_source_info->line_nr)
     107          error_list[error_number++].source_info = *cmd_source_info;
     108        else
     109          error_list[error_number++].source_info = current_source_info;
     110      }
     111    else
     112      error_list[error_number++].source_info = current_source_info;
     113  
     114    if (debug_output)
     115      debug_error_warning_message (&error_list[error_number -1]);
     116  }
     117  
     118  void
     119  line_error_ext (enum error_type type, SOURCE_INFO *cmd_source_info,
     120                  char *format, ...)
     121  {
     122    va_list v;
     123  
     124    va_start (v, format);
     125    line_error_internal (type, cmd_source_info, format, v);
     126  }
     127  
     128  void
     129  line_error (char *format, ...)
     130  {
     131    va_list v;
     132  
     133    va_start (v, format);
     134    line_error_internal (error, 0, format, v);
     135  }
     136  
     137  void
     138  line_warn (char *format, ...)
     139  {
     140    va_list v;
     141  
     142    va_start (v, format);
     143    line_error_internal (warning, 0, format, v);
     144  }
     145  
     146  void
     147  command_warn (ELEMENT *e, char *format, ...)
     148  {
     149    va_list v;
     150  
     151    va_start (v, format);
     152    line_error_internal (warning, &e->source_info, format, v);
     153  }
     154  
     155  void
     156  command_error (ELEMENT *e, char *format, ...)
     157  {
     158    va_list v;
     159  
     160    va_start (v, format);
     161    line_error_internal (error, &e->source_info, format, v);
     162  }
     163  
     164  void
     165  wipe_errors (void)
     166  {
     167    int i;
     168    for (i = 0; i < error_number; i++)
     169      free (error_list[i].message);
     170    error_number = 0;
     171  }
     172  
     173  static void
     174  bug_message_internal (char *format, va_list v)
     175  {
     176    fprintf (stderr, "You found a bug: ");
     177    vfprintf (stderr, format, v);
     178    fprintf (stderr, "\n");
     179    if (current_source_info.file_name)
     180      {
     181        fprintf (stderr,
     182                 "last location %s:%d", current_source_info.file_name,
     183                                           current_source_info.line_nr);
     184        if (current_source_info.macro)
     185          fprintf (stderr, " (possibly involving @%s)", current_source_info.macro);
     186        fprintf (stderr, "\n");
     187      }
     188    exit (1);
     189  }
     190  
     191  void
     192  bug_message (char *format, ...)
     193  {
     194    va_list v;
     195  
     196    va_start (v, format);
     197    bug_message_internal (format, v);
     198  }
     199