/* Copyright 2010-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "command_ids.h" #include "commands.h" #include "errors.h" #include "command_data.c" COMMAND *user_defined_command_data = 0; static size_t user_defined_number = 0; static size_t user_defined_space = 0; static int compare_command_fn (const void *a, const void *b) { const COMMAND *ca = (COMMAND *) a; const COMMAND *cb = (COMMAND *) b; return strcmp (ca->cmdname, cb->cmdname); } /* Return element number in command_data array. Return 0 if not found. */ enum command_id lookup_command (char *cmdname) { COMMAND *c; COMMAND target; int i; target.cmdname = cmdname; /* Check for user-defined commands: macros, indexes, etc. */ /* Do this before looking in the built-in commands, in case the user uses @definfoenclose or similar to override a command. If speed is a problem, then we could set a bit in the flags on the builtin command (maybe reusing CF_INFOENCLOSE) to say to look in the user commands instead. */ for (i = 0; i < user_defined_number; i++) { if (!strcmp (user_defined_command_data[i].cmdname, cmdname)) return ((enum command_id) i) | USER_COMMAND_BIT; } c = (COMMAND *) bsearch (&target, builtin_command_data + 1, /* number of elements */ sizeof (builtin_command_data) / sizeof (builtin_command_data[0]) - 1, sizeof (builtin_command_data[0]), compare_command_fn); if (c) return c - &builtin_command_data[0]; return 0; } /* Add a new user-defined Texinfo command, like an index or macro command. No reference to NAME is retained. */ enum command_id add_texinfo_command (char *name) { if (user_defined_number == user_defined_space) { user_defined_command_data = realloc (user_defined_command_data, (user_defined_space += 10) * sizeof (COMMAND)); if (!user_defined_command_data) fatal ("could not realloc"); } user_defined_command_data[user_defined_number].cmdname = strdup (name); user_defined_command_data[user_defined_number].flags = 0; user_defined_command_data[user_defined_number].data = 0; return ((enum command_id) user_defined_number++) | USER_COMMAND_BIT; } /* Remove CMD, for @unmacro. */ void remove_texinfo_command (enum command_id cmd) { cmd &= ~USER_COMMAND_BIT; free (user_defined_command_data[cmd].cmdname); user_defined_command_data[cmd].cmdname = strdup (""); } void wipe_user_commands (void) { int i; for (i = 0; i < user_defined_number; i++) free (user_defined_command_data[i].cmdname); user_defined_number = 0; } /* Commands that terminate a paragraph. */ /* We may replace this function with a macro, or represent this infomation in command_data. */ int close_paragraph_command (enum command_id cmd) { if (cmd == CM_verbatim) return 1; /* Block commands except 'raw' and 'conditional'. */ if (command_data(cmd).flags & CF_block) { if (command_data(cmd).data == BLOCK_conditional || command_data(cmd).data == BLOCK_raw) return 0; if (command_data(cmd).flags & CF_format_raw) return 0; return 1; } if (cmd == CM_titlefont || cmd == CM_insertcopying || cmd == CM_sp || cmd == CM_verbatiminclude || cmd == CM_page || cmd == CM_item || cmd == CM_itemx || cmd == CM_tab || cmd == CM_headitem || cmd == CM_printindex || cmd == CM_listoffloats || cmd == CM_center || cmd == CM_dircategory || cmd == CM_contents || cmd == CM_shortcontents || cmd == CM_summarycontents || cmd == CM_caption || cmd == CM_shortcaption || cmd == CM_setfilename || cmd == CM_exdent) return 1; if ((command_data(cmd).flags & CF_sectioning) && !(command_data(cmd).flags & CF_root)) return 1; if ((command_data(cmd).flags & CF_def)) return 1; return 0; } int close_preformatted_command (enum command_id cmd_id) { return cmd_id != CM_sp && close_paragraph_command (cmd_id); } int item_line_command (enum command_id cmd_id) { return cmd_id == CM_table || cmd_id == CM_ftable || cmd_id == CM_vtable; }