+
+/*---------------------------------------------.
+| Prepare the muscles for symbol definitions. |
+`---------------------------------------------*/
+
+static void
+prepare_symbol_definitions (void)
+{
+ int i;
+ for (i = 0; i < nsyms; ++i)
+ {
+ symbol *sym = symbols[i];
+ const char *key;
+ const char *value;
+
+#define SET_KEY(Entry) \
+ obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry); \
+ obstack_1grow (&format_obstack, 0); \
+ key = obstack_finish (&format_obstack);
+
+ // Whether the symbol has an identifier.
+ value = symbol_id_get (sym);
+ SET_KEY("has_id");
+ MUSCLE_INSERT_INT (key, !!value);
+
+ // Its identifier.
+ SET_KEY("id");
+ MUSCLE_INSERT_STRING (key, value ? value : "");
+
+ // Its tag. Typically for documentation purpose.
+ SET_KEY("tag");
+ MUSCLE_INSERT_STRING (key, sym->tag);
+
+ SET_KEY("user_number");
+ MUSCLE_INSERT_INT (key, sym->user_token_number);
+
+ SET_KEY("is_token");
+ MUSCLE_INSERT_INT (key,
+ i < ntokens && sym != errtoken && sym != undeftoken);
+
+ SET_KEY("number");
+ MUSCLE_INSERT_INT (key, sym->number);
+
+ SET_KEY("has_type");
+ MUSCLE_INSERT_INT (key, !!sym->type_name);
+
+ SET_KEY("type");
+ MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
+
+#define CODE_PROP(PropName) \
+ do { \
+ code_props const *p = symbol_ ## PropName ## _get (sym); \
+ SET_KEY("has_" #PropName); \
+ MUSCLE_INSERT_INT (key, !!p->code); \
+ \
+ if (p->code) \
+ { \
+ SET_KEY(#PropName "_file"); \
+ MUSCLE_INSERT_STRING (key, p->location.start.file); \
+ \
+ SET_KEY(#PropName "_line"); \
+ MUSCLE_INSERT_INT (key, p->location.start.line); \
+ \
+ SET_KEY(#PropName); \
+ MUSCLE_INSERT_STRING_RAW (key, p->code); \
+ } \
+ } while (0)
+
+ CODE_PROP(destructor);
+ CODE_PROP(printer);
+#undef CODE_PROP
+#undef SET_KEY
+ }
+}
+
+