105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Muscle table manager for Bison. 205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 305436638acc7c010349a69c3395f1a57c642dc62Ying Wang Copyright (C) 2001-2012 Free Software Foundation, Inc. 405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 505436638acc7c010349a69c3395f1a57c642dc62Ying Wang This file is part of Bison, the GNU Compiler Compiler. 605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 705436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is free software: you can redistribute it and/or modify 805436638acc7c010349a69c3395f1a57c642dc62Ying Wang it under the terms of the GNU General Public License as published by 905436638acc7c010349a69c3395f1a57c642dc62Ying Wang the Free Software Foundation, either version 3 of the License, or 1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang (at your option) any later version. 1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang This program is distributed in the hope that it will be useful, 1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang but WITHOUT ANY WARRANTY; without even the implied warranty of 1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang GNU General Public License for more details. 1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang You should have received a copy of the GNU General Public License 1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang along with this program. If not, see <http://www.gnu.org/licenses/>. */ 1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <config.h> 2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "system.h" 2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include <hash.h> 2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "complain.h" 2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "files.h" 2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "getargs.h" 2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "muscle-tab.h" 2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#include "quote.h" 3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A key-value pair, along with storage that can be reclaimed when 3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang this pair is no longer needed. */ 3305436638acc7c010349a69c3395f1a57c642dc62Ying Wangtypedef struct 3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *key; 3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *value; 3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *storage; 3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} muscle_entry; 3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* An obstack used to create some entries. */ 4105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstruct obstack muscle_obstack; 4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Initial capacity of muscles hash table. */ 4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define HT_INITIAL_CAPACITY 257 4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic struct hash_table *muscle_table = NULL; 4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 4805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic bool 4905436638acc7c010349a69c3395f1a57c642dc62Ying Wanghash_compare_muscles (void const *x, void const *y) 5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry const *m1 = x; 5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry const *m2 = y; 5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang return strcmp (m1->key, m2->key) == 0; 5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 5605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic size_t 5705436638acc7c010349a69c3395f1a57c642dc62Ying Wanghash_muscle (const void *x, size_t tablesize) 5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry const *m = x; 6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return hash_string (m->key, tablesize); 6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*-----------------------------------------------------------------. 6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Create the MUSCLE_TABLE, and initialize it with default values. | 6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Also set up the MUSCLE_OBSTACK. | 6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang`-----------------------------------------------------------------*/ 6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 6805436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void 6905436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_entry_free (void *entry) 7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry *mentry = entry; 7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (mentry->storage); 7305436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (mentry); 7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 7605436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 7705436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_init (void) 7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Initialize the muscle obstack. */ 8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_init (&muscle_obstack); 8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_table = hash_initialize (HT_INITIAL_CAPACITY, NULL, hash_muscle, 8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang hash_compare_muscles, muscle_entry_free); 8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Version and input file. */ 8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang MUSCLE_INSERT_STRING ("version", VERSION); 8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 8905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------. 9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Free all the memory consumed by the muscle machinery only. | 9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------*/ 9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 9405436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 9505436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_free (void) 9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang hash_free (muscle_table); 9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, NULL); 9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------. 10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Insert (KEY, VALUE). If KEY already existed, overwrite the | 10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang| previous value. | 10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------*/ 10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 10805436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 10905436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_insert (char const *key, char const *value) 11005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 11105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry probe; 11205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry *entry; 11305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11405436638acc7c010349a69c3395f1a57c642dc62Ying Wang probe.key = key; 11505436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry = hash_lookup (muscle_table, &probe); 11605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 11705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!entry) 11805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 11905436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* First insertion in the hash. */ 12005436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry = xmalloc (sizeof *entry); 12105436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->key = key; 12205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!hash_insert (muscle_table, entry)) 12305436638acc7c010349a69c3395f1a57c642dc62Ying Wang xalloc_die (); 12405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 12505436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 12605436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (entry->storage); 12705436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->value = value; 12805436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->storage = NULL; 12905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 13005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*-------------------------------------------------------------------. 13305436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Append VALUE to the current value of KEY. If KEY did not already | 13405436638acc7c010349a69c3395f1a57c642dc62Ying Wang| exist, create it. Use MUSCLE_OBSTACK. De-allocate the previously | 13505436638acc7c010349a69c3395f1a57c642dc62Ying Wang| associated value. Copy VALUE and SEPARATOR. | 13605436638acc7c010349a69c3395f1a57c642dc62Ying Wang`-------------------------------------------------------------------*/ 13705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 13805436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 13905436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_grow (const char *key, const char *val, const char *separator) 14005436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 14105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry probe; 14205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry *entry = NULL; 14305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 14405436638acc7c010349a69c3395f1a57c642dc62Ying Wang probe.key = key; 14505436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry = hash_lookup (muscle_table, &probe); 14605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 14705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!entry) 14805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 14905436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* First insertion in the hash. */ 15005436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry = xmalloc (sizeof *entry); 15105436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->key = key; 15205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!hash_insert (muscle_table, entry)) 15305436638acc7c010349a69c3395f1a57c642dc62Ying Wang xalloc_die (); 15405436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->value = entry->storage = xstrdup (val); 15505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 15605436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 15705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 15805436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Grow the current value. */ 15905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *new_val; 16005436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, entry->value); 16105436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (entry->storage); 16205436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, separator); 16305436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, val); 16405436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, 0); 16505436638acc7c010349a69c3395f1a57c642dc62Ying Wang new_val = obstack_finish (&muscle_obstack); 16605436638acc7c010349a69c3395f1a57c642dc62Ying Wang entry->value = entry->storage = xstrdup (new_val); 16705436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, new_val); 16805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 16905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 17005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------------. 17205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Using muscle_grow, append a synchronization line for the location | 17305436638acc7c010349a69c3395f1a57c642dc62Ying Wang| LOC to the current value of KEY. | 17405436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------------*/ 17505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 17605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void 17705436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_syncline_grow (char const *key, location loc) 17805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 17905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *extension = NULL; 18005436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_printf (&muscle_obstack, "]b4_syncline(%d, ", loc.start.line); 18105436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_quote (&muscle_obstack, 18205436638acc7c010349a69c3395f1a57c642dc62Ying Wang quotearg_style (c_quoting_style, loc.start.file)); 18305436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, ")["); 18405436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, 0); 18505436638acc7c010349a69c3395f1a57c642dc62Ying Wang extension = obstack_finish (&muscle_obstack); 18605436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, extension, ""); 18705436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, extension); 18805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 18905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 19005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------------------------. 19105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Append VALUE to the current value of KEY, using muscle_grow. But | 19205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| in addition, issue a synchronization line for the location LOC | 19305436638acc7c010349a69c3395f1a57c642dc62Ying Wang| using muscle_syncline_grow. | 19405436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------------------------*/ 19505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 19605436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 19705436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_code_grow (const char *key, const char *val, location loc) 19805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 19905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_syncline_grow (key, loc); 20005436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, val, "\n"); 20105436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 20205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 20305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 20405436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid muscle_pair_list_grow (const char *muscle, 20505436638acc7c010349a69c3395f1a57c642dc62Ying Wang const char *a1, const char *a2) 20605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 20705436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *pair; 20805436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, "["); 20905436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_quote (&muscle_obstack, a1); 21005436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, ", "); 21105436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_quote (&muscle_obstack, a2); 21205436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, "]"); 21305436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, 0); 21405436638acc7c010349a69c3395f1a57c642dc62Ying Wang pair = obstack_finish (&muscle_obstack); 21505436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (muscle, pair, ",\n"); 21605436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, pair); 21705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 21805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 21905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 22005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*----------------------------------------------------------------------------. 22105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Find the value of muscle KEY. Unlike MUSCLE_FIND, this is always reliable | 22205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| to determine whether KEY has a value. | 22305436638acc7c010349a69c3395f1a57c642dc62Ying Wang`----------------------------------------------------------------------------*/ 22405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 22505436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const * 22605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_find_const (char const *key) 22705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 22805436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry probe; 22905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry *result = NULL; 23005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23105436638acc7c010349a69c3395f1a57c642dc62Ying Wang probe.key = key; 23205436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = hash_lookup (muscle_table, &probe); 23305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (result) 23405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result->value; 23505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return NULL; 23605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 23705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 23905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*----------------------------------------------------------------------------. 24005436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Find the value of muscle KEY. Abort if muscle_insert was invoked more | 24105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| recently than muscle_grow for KEY since muscle_find can't return a | 24205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| char const *. | 24305436638acc7c010349a69c3395f1a57c642dc62Ying Wang`----------------------------------------------------------------------------*/ 24405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 24505436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar * 24605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_find (char const *key) 24705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 24805436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry probe; 24905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_entry *result = NULL; 25005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 25105436638acc7c010349a69c3395f1a57c642dc62Ying Wang probe.key = key; 25205436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = hash_lookup (muscle_table, &probe); 25305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (result) 25405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 25505436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (result->value == result->storage); 25605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result->storage; 25705436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 25805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return NULL; 25905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 26005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 26105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 26205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In the format `file_name:line.column', append BOUND to MUSCLE. Use 26305436638acc7c010349a69c3395f1a57c642dc62Ying Wang digraphs for special characters in the file name. */ 26405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 26505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void 26605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_boundary_grow (char const *key, boundary bound) 26705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 26805436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *extension; 26905436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, "[["); 27005436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_escape (&muscle_obstack, bound.file); 27105436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, ':'); 27205436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_printf (&muscle_obstack, "%d", bound.line); 27305436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, '.'); 27405436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_printf (&muscle_obstack, "%d", bound.column); 27505436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, "]]"); 27605436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, '\0'); 27705436638acc7c010349a69c3395f1a57c642dc62Ying Wang extension = obstack_finish (&muscle_obstack); 27805436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, extension, ""); 27905436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, extension); 28005436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 28105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 28205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 28305436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* In the format `[[file_name:line.column]], [[file_name:line.column]]', 28405436638acc7c010349a69c3395f1a57c642dc62Ying Wang append LOC to MUSCLE. Use digraphs for special characters in each 28505436638acc7c010349a69c3395f1a57c642dc62Ying Wang file name. */ 28605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 28705436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic void 28805436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_location_grow (char const *key, location loc) 28905436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 29005436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_boundary_grow (key, loc.start); 29105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, "", ", "); 29205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_boundary_grow (key, loc.end); 29305436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 29405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 29505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#define COMMON_DECODE(Value) \ 29605436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '$': \ 29705436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++(Value) == ']'); \ 29805436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++(Value) == '['); \ 29905436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_sgrow (&muscle_obstack, "$"); \ 30005436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; \ 30105436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '@': \ 30205436638acc7c010349a69c3395f1a57c642dc62Ying Wang switch (*++(Value)) \ 30305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { \ 30405436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '@': obstack_sgrow (&muscle_obstack, "@" ); break; \ 30505436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '{': obstack_sgrow (&muscle_obstack, "[" ); break; \ 30605436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '}': obstack_sgrow (&muscle_obstack, "]" ); break; \ 30705436638acc7c010349a69c3395f1a57c642dc62Ying Wang default: aver (false); break; \ 30805436638acc7c010349a69c3395f1a57c642dc62Ying Wang } \ 30905436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; \ 31005436638acc7c010349a69c3395f1a57c642dc62Ying Wang default: \ 31105436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, *(Value)); \ 31205436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 31305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 31405436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Reverse of obstack_escape. */ 31505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic char * 31605436638acc7c010349a69c3395f1a57c642dc62Ying Wangstring_decode (char const *key) 31705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 31805436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *value; 31905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *value_decoded; 32005436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *result; 32105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 32205436638acc7c010349a69c3395f1a57c642dc62Ying Wang value = muscle_find_const (key); 32305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!value) 32405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return NULL; 32505436638acc7c010349a69c3395f1a57c642dc62Ying Wang do { 32605436638acc7c010349a69c3395f1a57c642dc62Ying Wang switch (*value) 32705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 32805436638acc7c010349a69c3395f1a57c642dc62Ying Wang COMMON_DECODE (value) 32905436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '[': 33005436638acc7c010349a69c3395f1a57c642dc62Ying Wang case ']': 33105436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (false); 33205436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 33305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 33405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } while (*value++); 33505436638acc7c010349a69c3395f1a57c642dc62Ying Wang value_decoded = obstack_finish (&muscle_obstack); 33605436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = xstrdup (value_decoded); 33705436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, value_decoded); 33805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result; 33905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 34005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 34105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Reverse of muscle_location_grow. */ 34205436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic location 34305436638acc7c010349a69c3395f1a57c642dc62Ying Wanglocation_decode (char const *key) 34405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 34505436638acc7c010349a69c3395f1a57c642dc62Ying Wang location loc; 34605436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *value = muscle_find_const (key); 34705436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (value); 34805436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*value == '['); 34905436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++value == '['); 35005436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (*++value) 35105436638acc7c010349a69c3395f1a57c642dc62Ying Wang switch (*value) 35205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 35305436638acc7c010349a69c3395f1a57c642dc62Ying Wang COMMON_DECODE (value) 35405436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '[': 35505436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (false); 35605436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 35705436638acc7c010349a69c3395f1a57c642dc62Ying Wang case ']': 35805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 35905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *boundary_str; 36005436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++value == ']'); 36105436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_1grow (&muscle_obstack, '\0'); 36205436638acc7c010349a69c3395f1a57c642dc62Ying Wang boundary_str = obstack_finish (&muscle_obstack); 36305436638acc7c010349a69c3395f1a57c642dc62Ying Wang switch (*++value) 36405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 36505436638acc7c010349a69c3395f1a57c642dc62Ying Wang case ',': 36605436638acc7c010349a69c3395f1a57c642dc62Ying Wang boundary_set_from_string (&loc.start, boundary_str); 36705436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, boundary_str); 36805436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++value == ' '); 36905436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++value == '['); 37005436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (*++value == '['); 37105436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 37205436638acc7c010349a69c3395f1a57c642dc62Ying Wang case '\0': 37305436638acc7c010349a69c3395f1a57c642dc62Ying Wang boundary_set_from_string (&loc.end, boundary_str); 37405436638acc7c010349a69c3395f1a57c642dc62Ying Wang obstack_free (&muscle_obstack, boundary_str); 37505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return loc; 37605436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 37705436638acc7c010349a69c3395f1a57c642dc62Ying Wang default: 37805436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (false); 37905436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 38005436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 38105436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 38205436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 38305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 38405436638acc7c010349a69c3395f1a57c642dc62Ying Wang aver (false); 38505436638acc7c010349a69c3395f1a57c642dc62Ying Wang return loc; 38605436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 38705436638acc7c010349a69c3395f1a57c642dc62Ying Wang 38805436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 38905436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_user_name_list_grow (char const *key, char const *user_name, 39005436638acc7c010349a69c3395f1a57c642dc62Ying Wang location loc) 39105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 39205436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, "[[[[", ","); 39305436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, user_name, ""); 39405436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, "]], ", ""); 39505436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_location_grow (key, loc); 39605436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_grow (key, "]]", ""); 39705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 39805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 39905436638acc7c010349a69c3395f1a57c642dc62Ying Wang/** If the \a variable name is obsolete, return the name to use, 40005436638acc7c010349a69c3395f1a57c642dc62Ying Wang * otherwise \a variable. */ 40105436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic 40205436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const * 40305436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_variable_update (char const *variable) 40405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 40505436638acc7c010349a69c3395f1a57c642dc62Ying Wang typedef struct 40605436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 40705436638acc7c010349a69c3395f1a57c642dc62Ying Wang const char *obsolete; 40805436638acc7c010349a69c3395f1a57c642dc62Ying Wang const char *updated; 40905436638acc7c010349a69c3395f1a57c642dc62Ying Wang } conversion_type; 41005436638acc7c010349a69c3395f1a57c642dc62Ying Wang const conversion_type conversion[] = 41105436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 41205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { "api.push_pull", "api.push-pull", }, 41305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { "location_type", "api.location.type", }, 41405436638acc7c010349a69c3395f1a57c642dc62Ying Wang { "lr.keep_unreachable_states", "lr.keep-unreachable-states", }, 41505436638acc7c010349a69c3395f1a57c642dc62Ying Wang }; 41605436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *res = variable; 41705436638acc7c010349a69c3395f1a57c642dc62Ying Wang int i; 41805436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (i = 0; i < ARRAY_CARDINALITY (conversion); ++i) 41905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (STREQ (conversion[i].obsolete, variable)) 42005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 42105436638acc7c010349a69c3395f1a57c642dc62Ying Wang res = conversion[i].updated; 42205436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 42305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 42405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return res; 42505436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 42605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 42705436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 42805436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_insert (char const *var, location variable_loc, 42905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *value, 43005436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_percent_define_how how) 43105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 43205436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Backward compatibility. */ 43305436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *variable = muscle_percent_variable_update (var); 43405436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); 43505436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); 43605436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *syncline_name = 43705436638acc7c010349a69c3395f1a57c642dc62Ying Wang UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); 43805436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")"); 43905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 44005436638acc7c010349a69c3395f1a57c642dc62Ying Wang /* Command-line options are processed before the grammar file. */ 44105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE 44205436638acc7c010349a69c3395f1a57c642dc62Ying Wang && muscle_find_const (name)) 44305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 44405436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned i = 0; 44505436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_percent_define_how how_old = 44605436638acc7c010349a69c3395f1a57c642dc62Ying Wang atoi (muscle_find_const (how_name)); 44705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (how_old == MUSCLE_PERCENT_DEFINE_F) 44805436638acc7c010349a69c3395f1a57c642dc62Ying Wang return; 44905436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain_at_indent (variable_loc, &i, 45005436638acc7c010349a69c3395f1a57c642dc62Ying Wang _("%%define variable %s redefined"), quote (variable)); 45105436638acc7c010349a69c3395f1a57c642dc62Ying Wang i += SUB_INDENT; 45205436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain_at_indent (muscle_percent_define_get_loc (variable), &i, 45305436638acc7c010349a69c3395f1a57c642dc62Ying Wang _("previous definition")); 45405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 45505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 45605436638acc7c010349a69c3395f1a57c642dc62Ying Wang MUSCLE_INSERT_STRING (name, value); 45705436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (loc_name, ""); 45805436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_location_grow (loc_name, variable_loc); 45905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (syncline_name, ""); 46005436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_syncline_grow (syncline_name, variable_loc); 46105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_user_name_list_grow ("percent_define_user_variables", variable, 46205436638acc7c010349a69c3395f1a57c642dc62Ying Wang variable_loc); 46305436638acc7c010349a69c3395f1a57c642dc62Ying Wang MUSCLE_INSERT_INT (how_name, how); 46405436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 46505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 46605436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar * 46705436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_get (char const *variable) 46805436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 46905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name; 47005436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *usage_name; 47105436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *value; 47205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 47305436638acc7c010349a69c3395f1a57c642dc62Ying Wang name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); 47405436638acc7c010349a69c3395f1a57c642dc62Ying Wang usage_name = UNIQSTR_CONCAT ("percent_define_bison_variables(", 47505436638acc7c010349a69c3395f1a57c642dc62Ying Wang variable, ")"); 47605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 47705436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (usage_name, ""); 47805436638acc7c010349a69c3395f1a57c642dc62Ying Wang value = string_decode (name); 47905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!value) 48005436638acc7c010349a69c3395f1a57c642dc62Ying Wang value = xstrdup (""); 48105436638acc7c010349a69c3395f1a57c642dc62Ying Wang return value; 48205436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 48305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 48405436638acc7c010349a69c3395f1a57c642dc62Ying Wanglocation 48505436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_get_loc (char const *variable) 48605436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 48705436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *loc_name; 48805436638acc7c010349a69c3395f1a57c642dc62Ying Wang loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); 48905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!muscle_find_const (loc_name)) 49005436638acc7c010349a69c3395f1a57c642dc62Ying Wang fatal(_("%s: undefined %%define variable %s"), 49105436638acc7c010349a69c3395f1a57c642dc62Ying Wang "muscle_percent_define_get_loc", quote (variable)); 49205436638acc7c010349a69c3395f1a57c642dc62Ying Wang return location_decode (loc_name); 49305436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 49405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 49505436638acc7c010349a69c3395f1a57c642dc62Ying Wangchar const * 49605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_get_syncline (char const *variable) 49705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 49805436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *syncline_name; 49905436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *syncline; 50005436638acc7c010349a69c3395f1a57c642dc62Ying Wang syncline_name = 50105436638acc7c010349a69c3395f1a57c642dc62Ying Wang UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); 50205436638acc7c010349a69c3395f1a57c642dc62Ying Wang syncline = muscle_find_const (syncline_name); 50305436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!syncline) 50405436638acc7c010349a69c3395f1a57c642dc62Ying Wang fatal(_("%s: undefined %%define variable %s"), 50505436638acc7c010349a69c3395f1a57c642dc62Ying Wang "muscle_percent_define_get_syncline", quote (variable)); 50605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return syncline; 50705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 50805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 50905436638acc7c010349a69c3395f1a57c642dc62Ying Wangbool 51005436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_ifdef (char const *variable) 51105436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 51205436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name; 51305436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *usage_name; 51405436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *value; 51505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 51605436638acc7c010349a69c3395f1a57c642dc62Ying Wang name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); 51705436638acc7c010349a69c3395f1a57c642dc62Ying Wang usage_name = 51805436638acc7c010349a69c3395f1a57c642dc62Ying Wang UNIQSTR_CONCAT ("percent_define_bison_variables(", variable, ")"); 51905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 52005436638acc7c010349a69c3395f1a57c642dc62Ying Wang value = muscle_find_const (name); 52105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (value) 52205436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 52305436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (usage_name, ""); 52405436638acc7c010349a69c3395f1a57c642dc62Ying Wang return true; 52505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 52605436638acc7c010349a69c3395f1a57c642dc62Ying Wang 52705436638acc7c010349a69c3395f1a57c642dc62Ying Wang return false; 52805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 52905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 53005436638acc7c010349a69c3395f1a57c642dc62Ying Wangbool 53105436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_flag_if (char const *variable) 53205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 53305436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *invalid_boolean_name; 53405436638acc7c010349a69c3395f1a57c642dc62Ying Wang bool result = false; 53505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 53605436638acc7c010349a69c3395f1a57c642dc62Ying Wang invalid_boolean_name = 53705436638acc7c010349a69c3395f1a57c642dc62Ying Wang UNIQSTR_CONCAT ("percent_define_invalid_boolean(", variable, ")"); 53805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 53905436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (muscle_percent_define_ifdef (variable)) 54005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 54105436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *value = muscle_percent_define_get (variable); 54205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (value[0] == '\0' || 0 == strcmp (value, "true")) 54305436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = true; 54405436638acc7c010349a69c3395f1a57c642dc62Ying Wang else if (0 == strcmp (value, "false")) 54505436638acc7c010349a69c3395f1a57c642dc62Ying Wang result = false; 54605436638acc7c010349a69c3395f1a57c642dc62Ying Wang else if (!muscle_find_const (invalid_boolean_name)) 54705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 54805436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (invalid_boolean_name, ""); 54905436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain_at(muscle_percent_define_get_loc (variable), 55005436638acc7c010349a69c3395f1a57c642dc62Ying Wang _("invalid value for %%define Boolean variable %s"), 55105436638acc7c010349a69c3395f1a57c642dc62Ying Wang quote (variable)); 55205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 55305436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (value); 55405436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 55505436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 55605436638acc7c010349a69c3395f1a57c642dc62Ying Wang fatal(_("%s: undefined %%define variable %s"), 55705436638acc7c010349a69c3395f1a57c642dc62Ying Wang "muscle_percent_define_flag", quote (variable)); 55805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 55905436638acc7c010349a69c3395f1a57c642dc62Ying Wang return result; 56005436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 56105436638acc7c010349a69c3395f1a57c642dc62Ying Wang 56205436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 56305436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_default (char const *variable, char const *value) 56405436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 56505436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name; 56605436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *loc_name; 56705436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *syncline_name; 56805436638acc7c010349a69c3395f1a57c642dc62Ying Wang name = UNIQSTR_CONCAT ("percent_define(", variable, ")"); 56905436638acc7c010349a69c3395f1a57c642dc62Ying Wang loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")"); 57005436638acc7c010349a69c3395f1a57c642dc62Ying Wang syncline_name = 57105436638acc7c010349a69c3395f1a57c642dc62Ying Wang UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")"); 57205436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!muscle_find_const (name)) 57305436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 57405436638acc7c010349a69c3395f1a57c642dc62Ying Wang location loc; 57505436638acc7c010349a69c3395f1a57c642dc62Ying Wang MUSCLE_INSERT_STRING (name, value); 57605436638acc7c010349a69c3395f1a57c642dc62Ying Wang loc.start.file = loc.end.file = "<default value>"; 57705436638acc7c010349a69c3395f1a57c642dc62Ying Wang loc.start.line = loc.end.line = -1; 57805436638acc7c010349a69c3395f1a57c642dc62Ying Wang loc.start.column = loc.end.column = -1; 57905436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (loc_name, ""); 58005436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_location_grow (loc_name, loc); 58105436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_insert (syncline_name, ""); 58205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 58305436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 58405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 58505436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 58605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_define_check_values (char const * const *values) 58705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 58805436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (; *values; ++values) 58905436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 59005436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const * const *variablep = values; 59105436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name; 59205436638acc7c010349a69c3395f1a57c642dc62Ying Wang char *value; 59305436638acc7c010349a69c3395f1a57c642dc62Ying Wang 59405436638acc7c010349a69c3395f1a57c642dc62Ying Wang name = UNIQSTR_CONCAT ("percent_define(", *variablep, ")"); 59505436638acc7c010349a69c3395f1a57c642dc62Ying Wang 59605436638acc7c010349a69c3395f1a57c642dc62Ying Wang value = string_decode (name); 59705436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (value) 59805436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 59905436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (++values; *values; ++values) 60005436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 60105436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (0 == strcmp (value, *values)) 60205436638acc7c010349a69c3395f1a57c642dc62Ying Wang break; 60305436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 60405436638acc7c010349a69c3395f1a57c642dc62Ying Wang if (!*values) 60505436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 60605436638acc7c010349a69c3395f1a57c642dc62Ying Wang unsigned i = 0; 60705436638acc7c010349a69c3395f1a57c642dc62Ying Wang location loc = muscle_percent_define_get_loc (*variablep); 60805436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain_at_indent (loc, &i, 60905436638acc7c010349a69c3395f1a57c642dc62Ying Wang _("invalid value for %%define variable %s: %s"), 61005436638acc7c010349a69c3395f1a57c642dc62Ying Wang quote (*variablep), quote_n (1, value)); 61105436638acc7c010349a69c3395f1a57c642dc62Ying Wang i += SUB_INDENT; 61205436638acc7c010349a69c3395f1a57c642dc62Ying Wang for (values = variablep + 1; *values; ++values) 61305436638acc7c010349a69c3395f1a57c642dc62Ying Wang complain_at_indent (loc, &i, _("accepted value: %s"), 61405436638acc7c010349a69c3395f1a57c642dc62Ying Wang quote (*values)); 61505436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 61605436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 61705436638acc7c010349a69c3395f1a57c642dc62Ying Wang { 61805436638acc7c010349a69c3395f1a57c642dc62Ying Wang while (*values) 61905436638acc7c010349a69c3395f1a57c642dc62Ying Wang ++values; 62005436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 62105436638acc7c010349a69c3395f1a57c642dc62Ying Wang free (value); 62205436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 62305436638acc7c010349a69c3395f1a57c642dc62Ying Wang else 62405436638acc7c010349a69c3395f1a57c642dc62Ying Wang fatal (_("%s: undefined %%define variable %s"), 62505436638acc7c010349a69c3395f1a57c642dc62Ying Wang "muscle_percent_define_check_values", quote (*variablep)); 62605436638acc7c010349a69c3395f1a57c642dc62Ying Wang } 62705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 62805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 62905436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 63005436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_percent_code_grow (char const *qualifier, location qualifier_loc, 63105436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *code, location code_loc) 63205436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 63305436638acc7c010349a69c3395f1a57c642dc62Ying Wang char const *name; 63405436638acc7c010349a69c3395f1a57c642dc62Ying Wang name = UNIQSTR_CONCAT ("percent_code(", qualifier, ")"); 63505436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_code_grow (name, code, code_loc); 63605436638acc7c010349a69c3395f1a57c642dc62Ying Wang muscle_user_name_list_grow ("percent_code_user_qualifiers", qualifier, 63705436638acc7c010349a69c3395f1a57c642dc62Ying Wang qualifier_loc); 63805436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 63905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 64005436638acc7c010349a69c3395f1a57c642dc62Ying Wang 64105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*------------------------------------------------. 64205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Output the definition of ENTRY as a m4_define. | 64305436638acc7c010349a69c3395f1a57c642dc62Ying Wang`------------------------------------------------*/ 64405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 64505436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic inline bool 64605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_m4_output (muscle_entry *entry, FILE *out) 64705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 64805436638acc7c010349a69c3395f1a57c642dc62Ying Wang fprintf (out, "m4_define([b4_%s],\n", entry->key); 64905436638acc7c010349a69c3395f1a57c642dc62Ying Wang fprintf (out, "[[%s]])\n\n\n", entry->value); 65005436638acc7c010349a69c3395f1a57c642dc62Ying Wang return true; 65105436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 65205436638acc7c010349a69c3395f1a57c642dc62Ying Wang 65305436638acc7c010349a69c3395f1a57c642dc62Ying Wangstatic bool 65405436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscle_m4_output_processor (void *entry, void *out) 65505436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 65605436638acc7c010349a69c3395f1a57c642dc62Ying Wang return muscle_m4_output (entry, out); 65705436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 65805436638acc7c010349a69c3395f1a57c642dc62Ying Wang 65905436638acc7c010349a69c3395f1a57c642dc62Ying Wang 66005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/*----------------------------------------------------------------. 66105436638acc7c010349a69c3395f1a57c642dc62Ying Wang| Output the definition of all the current muscles into a list of | 66205436638acc7c010349a69c3395f1a57c642dc62Ying Wang| m4_defines. | 66305436638acc7c010349a69c3395f1a57c642dc62Ying Wang`----------------------------------------------------------------*/ 66405436638acc7c010349a69c3395f1a57c642dc62Ying Wang 66505436638acc7c010349a69c3395f1a57c642dc62Ying Wangvoid 66605436638acc7c010349a69c3395f1a57c642dc62Ying Wangmuscles_m4_output (FILE *out) 66705436638acc7c010349a69c3395f1a57c642dc62Ying Wang{ 66805436638acc7c010349a69c3395f1a57c642dc62Ying Wang hash_do_for_each (muscle_table, muscle_m4_output_processor, out); 66905436638acc7c010349a69c3395f1a57c642dc62Ying Wang} 670