1 /* macro.c -- user-defined macros for Texinfo.
2 $Id: macro.c,v 1.6 2004/04/11 17:56:47 karl Exp $
4 Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #include "insertion.h"
27 /* If non-NULL, this is an output stream to write the full macro expansion
28 of the input text to. The result is another texinfo file, but
29 missing @include, @infoinclude, @macro, and macro invocations. Instead,
30 all of the text is placed within the file. */
31 FILE *macro_expansion_output_stream
= NULL
;
33 /* Output file for -E. */
34 char *macro_expansion_filename
;
36 /* Nonzero means a macro string is in execution, as opposed to a file. */
37 int me_executing_string
= 0;
39 /* Nonzero means we want only to expand macros and
40 leave everything else intact. */
41 int only_macro_expansion
= 0;
43 static ITEXT
**itext_info
= NULL
;
44 static int itext_size
= 0;
46 /* Return the arglist on the current line. This can behave in two different
47 ways, depending on the variable BRACES_REQUIRED_FOR_MACRO_ARGS. */
48 int braces_required_for_macro_args
= 0;
50 /* Array of macros and definitions. */
51 MACRO_DEF
**macro_list
= NULL
;
53 int macro_list_len
= 0; /* Number of elements. */
54 int macro_list_size
= 0; /* Number of slots in total. */
56 /* Return the length of the array in ARRAY. */
58 array_len (char **array
)
63 for (i
= 0; array
[i
]; i
++);
69 free_array (char **array
)
74 for (i
= 0; array
[i
]; i
++)
81 /* Return the macro definition of NAME or NULL if NAME is not defined. */
83 find_macro (char *name
)
89 for (i
= 0; macro_list
&& (def
= macro_list
[i
]); i
++)
91 if ((!def
->inhibited
) && (strcmp (def
->name
, name
) == 0))
97 /* Add the macro NAME with ARGLIST and BODY to the list of defined macros.
98 SOURCE_FILE is the name of the file where this definition can be found,
99 and SOURCE_LINENO is the line number within that file. If a macro already
100 exists with NAME, then a warning is produced, and that previous
101 definition is overwritten. */
103 add_macro (char *name
, char **arglist
, char *body
, char *source_file
,
104 int source_lineno
, int flags
)
108 def
= find_macro (name
);
112 if (macro_list_len
+ 2 >= macro_list_size
)
113 macro_list
= xrealloc
114 (macro_list
, ((macro_list_size
+= 10) * sizeof (MACRO_DEF
*)));
116 macro_list
[macro_list_len
] = xmalloc (sizeof (MACRO_DEF
));
117 macro_list
[macro_list_len
+ 1] = NULL
;
119 def
= macro_list
[macro_list_len
];
125 char *temp_filename
= input_filename
;
126 int temp_line
= line_number
;
128 warning (_("macro `%s' previously defined"), name
);
130 input_filename
= def
->source_file
;
131 line_number
= def
->source_lineno
;
132 warning (_("here is the previous definition of `%s'"), name
);
134 input_filename
= temp_filename
;
135 line_number
= temp_line
;
141 for (i
= 0; def
->arglist
[i
]; i
++)
142 free (def
->arglist
[i
]);
146 free (def
->source_file
);
150 def
->source_file
= xstrdup (source_file
);
151 def
->source_lineno
= source_lineno
;
153 def
->arglist
= arglist
;
160 get_brace_args (int quote_single
)
162 char **arglist
, *word
;
163 int arglist_index
, arglist_size
;
164 int character
, escape_seen
, start
;
167 /* There is an arglist in braces here, so gather the args inside of it. */
168 skip_whitespace_and_newlines ();
171 arglist_index
= arglist_size
= 0;
174 skip_whitespace_and_newlines ();
175 start
= input_text_offset
;
178 while ((character
= curchar ()))
180 if (character
== '\\')
182 input_text_offset
+= 2;
185 else if (character
== '{')
190 else if ((character
== ',' && !quote_single
) ||
191 ((character
== '}') && depth
== 1))
193 int len
= input_text_offset
- start
;
195 if (len
|| (character
!= '}'))
197 word
= xmalloc (1 + len
);
198 memcpy (word
, input_text
+ start
, len
);
201 /* Clean up escaped characters. */
205 for (i
= 0; word
[i
]; i
++)
207 memmove (word
+ i
, word
+ i
+ 1,
208 1 + strlen (word
+ i
+ 1));
211 if (arglist_index
+ 2 >= arglist_size
)
213 (arglist
, (arglist_size
+= 10) * sizeof (char *));
215 arglist
[arglist_index
++] = word
;
216 arglist
[arglist_index
] = NULL
;
220 if (character
== '}')
225 else if (character
== '}')
233 if (character
== '\n') line_number
++;
240 get_macro_args (MACRO_DEF
*def
)
245 /* Quickly check to see if this macro has been invoked with any arguments.
246 If not, then don't skip any of the following whitespace. */
247 for (i
= input_text_offset
; i
< input_text_length
; i
++)
248 if (!cr_or_whitespace (input_text
[i
]))
251 if (input_text
[i
] != '{')
253 if (braces_required_for_macro_args
)
259 /* Braces are not required to fill out the macro arguments. If
260 this macro takes one argument, it is considered to be the
261 remainder of the line, sans whitespace. */
262 if (def
->arglist
&& def
->arglist
[0] && !def
->arglist
[1])
266 get_rest_of_line (0, &word
);
267 if (input_text
[input_text_offset
- 1] == '\n')
272 /* canon_white (word); */
273 arglist
= xmalloc (2 * sizeof (char *));
280 /* The macro either took no arguments, or took more than
281 one argument. In that case, it must be invoked with
282 arguments surrounded by braces. */
287 return get_brace_args (def
->flags
& ME_QUOTE_ARG
);
290 /* Substitute actual parameters for named parameters in body.
291 The named parameters which appear in BODY must by surrounded
292 reverse slashes, as in \foo\. */
294 apply (char **named
, char **actuals
, char *body
)
297 int new_body_index
, new_body_size
;
298 char *new_body
, *text
;
299 int length_of_actuals
;
301 length_of_actuals
= array_len (actuals
);
302 new_body_size
= strlen (body
);
303 new_body
= xmalloc (1 + new_body_size
);
305 /* Copy chars from BODY into NEW_BODY. */
310 { /* Anything but a \ is easy. */
312 new_body
[new_body_index
++] = body
[i
++];
314 { /* Snarf parameter name, check against named parameters. */
316 int param_start
, len
;
319 while (body
[i
] && body
[i
] != '\\')
322 len
= i
- param_start
;
323 param
= xmalloc (1 + len
);
324 memcpy (param
, body
+ param_start
, len
);
327 if (body
[i
]) /* move past \ */
331 { /* \\ always means \, even if macro has no args. */
333 text
= xmalloc (1 + len
);
334 sprintf (text
, "\\%s", param
);
340 /* Check against named parameters. */
341 for (which
= 0; named
&& named
[which
]; which
++)
342 if (STREQ (named
[which
], param
))
345 if (named
&& named
[which
])
347 text
= which
< length_of_actuals
? actuals
[which
] : NULL
;
351 text
= xstrdup (text
); /* so we can free it */
354 { /* not a parameter, so it's an error. */
355 warning (_("\\ in macro expansion followed by `%s' instead of parameter name"),
358 text
= xmalloc (1 + len
);
359 sprintf (text
, "\\%s", param
);
363 if (strlen (param
) + 2 < len
)
365 new_body_size
+= len
+ 1;
366 new_body
= xrealloc (new_body
, new_body_size
);
371 strcpy (new_body
+ new_body_index
, text
);
372 new_body_index
+= len
;
378 new_body
[new_body_index
] = 0;
382 /* Expand macro passed in DEF, a pointer to a MACRO_DEF, and
383 return its expansion as a string. */
385 expand_macro (MACRO_DEF
*def
)
389 char *execution_string
= NULL
;
390 int start_line
= line_number
;
392 /* Find out how many arguments this macro definition takes. */
393 num_args
= array_len (def
->arglist
);
395 /* Gather the arguments present on the line if there are any. */
396 arglist
= get_macro_args (def
);
398 if (num_args
< array_len (arglist
))
400 free_array (arglist
);
401 line_error (_("Macro `%s' called on line %d with too many args"),
402 def
->name
, start_line
);
403 return execution_string
;
407 execution_string
= apply (def
->arglist
, arglist
, def
->body
);
409 free_array (arglist
);
410 return execution_string
;
413 /* Execute the macro passed in DEF, a pointer to a MACRO_DEF. */
415 execute_macro (MACRO_DEF
*def
)
417 char *execution_string
;
418 int start_line
= line_number
, end_line
;
420 if (macro_expansion_output_stream
&& !executing_string
&& !me_inhibit_expansion
)
421 me_append_before_this_command ();
423 execution_string
= expand_macro (def
);
424 if (!execution_string
)
429 /* Reset the line number to where the macro arguments began.
430 This makes line numbers reported in error messages correct in
431 case the macro arguments span several lines and the expanded
432 arguments invoke other commands. */
433 end_line
= line_number
;
434 line_number
= start_line
;
436 if (macro_expansion_output_stream
437 && !executing_string
&& !me_inhibit_expansion
)
439 remember_itext (input_text
, input_text_offset
);
440 me_execute_string (execution_string
);
443 execute_string ("%s", execution_string
);
445 free (execution_string
);
446 line_number
= end_line
;
451 /* Read and remember the definition of a macro. If RECURSIVE is set,
452 set the ME_RECURSE flag. MACTYPE is either "macro" or "rmacro", and
453 tells us what the matching @end should be. */
455 define_macro (char *mactype
, int recursive
)
459 char *last_end
= NULL
;
461 char **arglist
= NULL
;
462 int body_size
= 0, body_index
= 0;
465 int defining_line
= line_number
;
467 if (macro_expansion_output_stream
&& !executing_string
)
468 me_append_before_this_command ();
472 /* Get the name of the macro. This is the set of characters which are
473 not whitespace and are not `{' immediately following the @macro. */
474 start
= input_text_offset
;
478 for (i
= start
; i
< input_text_length
&& input_text
[i
] != '{'
479 && !cr_or_whitespace (input_text
[i
]);
483 name
= xmalloc (1 + len
);
484 memcpy (name
, input_text
+ start
, len
);
486 input_text_offset
= i
;
491 /* It is not required that the definition of a macro includes an arglist.
492 If not, don't try to get the named parameters, just use a null list. */
493 if (curchar () == '{')
496 int arglist_index
= 0, arglist_size
= 0;
497 int gathering_words
= 1;
500 /* Read the words inside of the braces which determine the arglist.
501 These words will be replaced within the body of the macro at
505 skip_whitespace_and_newlines ();
507 while (gathering_words
)
511 for (i
= input_text_offset
;
512 (character
= input_text
[i
]);
523 /* Found the end of the current arglist word. Save it. */
524 len
= i
- input_text_offset
;
525 word
= xmalloc (1 + len
);
526 memcpy (word
, input_text
+ input_text_offset
, len
);
528 input_text_offset
= i
;
530 /* Advance to the comma or close-brace that signified
531 the end of the argument. */
532 while ((character
= curchar ())
537 if (character
== '\n')
541 /* Add the word to our list of words. */
542 if (arglist_index
+ 2 >= arglist_size
)
545 arglist
= xrealloc (arglist
,
546 arglist_size
* sizeof (char *));
549 arglist
[arglist_index
++] = word
;
550 arglist
[arglist_index
] = NULL
;
554 if (character
== '}')
561 if (character
== ',')
564 skip_whitespace_and_newlines ();
565 i
= input_text_offset
- 1;
570 /* If we have exactly one argument, do @quote-arg implicitly. Not
571 only does this match TeX's behavior (which can't feasibly be
572 changed), but it's a good idea. */
573 if (arglist_index
== 1)
574 flags
|= ME_QUOTE_ARG
;
577 /* Read the text carefully until we find an "@end macro" which
578 matches this one. The text in between is the body of the macro. */
579 skip_whitespace_and_newlines ();
583 if ((input_text_offset
+ 9) > input_text_length
)
585 file_line_error (input_filename
, defining_line
,
586 _("%cend macro not found"), COMMAND_PREFIX
);
590 get_rest_of_line (0, &line
);
592 /* Handle commands only meaningful within a macro. */
593 if ((*line
== COMMAND_PREFIX
) && (depth
== 1) &&
594 (strncmp (line
+ 1, "allow-recursion", 15) == 0) &&
595 (line
[16] == 0 || whitespace (line
[16])))
597 for (i
= 16; whitespace (line
[i
]); i
++);
598 strcpy (line
, line
+ i
);
607 if ((*line
== COMMAND_PREFIX
) && (depth
== 1) &&
608 (strncmp (line
+ 1, "quote-arg", 9) == 0) &&
609 (line
[10] == 0 || whitespace (line
[10])))
611 for (i
= 10; whitespace (line
[i
]); i
++);
612 strcpy (line
, line
+ i
);
614 if (arglist
&& arglist
[0] && !arglist
[1])
616 flags
|= ME_QUOTE_ARG
;
624 line_error (_("@quote-arg only useful for single-argument macros"));
627 if (*line
== COMMAND_PREFIX
628 && (strncmp (line
+ 1, "macro ", 6) == 0
629 || strncmp (line
+ 1, "rmacro ", 7) == 0))
632 /* Incorrect implementation of nesting -- just check that the last
633 @end matches what we started with. Since nested macros don't
634 work in TeX anyway, this isn't worth the trouble to get right. */
635 if (*line
== COMMAND_PREFIX
&& strncmp (line
+ 1, "end macro", 9) == 0)
640 if (*line
== COMMAND_PREFIX
&& strncmp (line
+ 1, "end rmacro", 10) == 0)
648 if ((body_index
+ strlen (line
) + 3) >= body_size
)
649 body
= xrealloc (body
, body_size
+= 3 + strlen (line
));
650 strcpy (body
+ body_index
, line
);
651 body_index
+= strlen (line
);
652 body
[body_index
++] = '\n';
653 body
[body_index
] = 0;
658 /* Check that @end matched the macro command. */
659 if (!STREQ (last_end
, mactype
))
660 warning (_("mismatched @end %s with @%s"), last_end
, mactype
);
662 /* If it was an empty macro like
665 create an empty body. (Otherwise, the macro is not expanded.) */
668 body
= (char *)malloc(1);
672 /* We now have the name, the arglist, and the body. However, BODY
673 includes the final newline which preceded the `@end macro' text.
675 if (body
&& strlen (body
))
676 body
[strlen (body
) - 1] = 0;
681 add_macro (name
, arglist
, body
, input_filename
, defining_line
, flags
);
683 if (macro_expansion_output_stream
&& !executing_string
)
685 /* Remember text for future expansions. */
686 remember_itext (input_text
, input_text_offset
);
688 /* Bizarrely, output the @macro itself. This is so texinfo.tex
689 will have a chance to read it when texi2dvi calls makeinfo -E.
690 The problem is that we don't really expand macros in all
691 contexts; a @table's @item is one. And a fix is not obvious to
692 me, since it appears virtually identical to any other internal
693 expansion. Just setting a variable in cm_item caused other
694 strange expansion problems. */
695 write_region_to_macro_output ("@", 0, 1);
696 write_region_to_macro_output (mactype
, 0, strlen (mactype
));
697 write_region_to_macro_output (" ", 0, 1);
698 write_region_to_macro_output (input_text
, start
, input_text_offset
);
705 define_macro ("macro", 0);
711 define_macro ("rmacro", 1);
714 /* Delete the macro with name NAME. The macro is deleted from the list,
715 but it is also returned. If there was no macro defined, NULL is
719 delete_macro (char *name
)
726 for (i
= 0; macro_list
&& (def
= macro_list
[i
]); i
++)
727 if (strcmp (def
->name
, name
) == 0)
729 memmove (macro_list
+ i
, macro_list
+ i
+ 1,
730 ((macro_list_len
+ 1) - i
) * sizeof (MACRO_DEF
*));
744 if (macro_expansion_output_stream
&& !executing_string
)
745 me_append_before_this_command ();
747 get_rest_of_line (0, &line
);
749 for (i
= 0; line
[i
] && !whitespace (line
[i
]); i
++);
750 name
= xmalloc (i
+ 1);
751 memcpy (name
, line
, i
);
754 def
= delete_macro (name
);
758 free (def
->source_file
);
766 for (i
= 0; def
->arglist
[i
]; i
++)
767 free (def
->arglist
[i
]);
778 if (macro_expansion_output_stream
&& !executing_string
)
779 remember_itext (input_text
, input_text_offset
);
782 /* How to output sections of the input file verbatim. */
784 /* Set the value of POINTER's offset to OFFSET. */
786 remember_itext (char *pointer
, int offset
)
791 /* If we have no info, initialize a blank list. */
794 itext_info
= xmalloc ((itext_size
= 10) * sizeof (ITEXT
*));
795 for (i
= 0; i
< itext_size
; i
++)
796 itext_info
[i
] = NULL
;
799 /* If the pointer is already present in the list, then set the offset. */
800 for (i
= 0; i
< itext_size
; i
++)
801 if ((itext_info
[i
]) &&
802 (itext_info
[i
]->pointer
== pointer
))
804 itext
= itext_info
[i
];
805 itext_info
[i
]->offset
= offset
;
811 /* Find a blank slot (or create a new one), and remember the
812 pointer and offset. */
813 for (i
= 0; i
< itext_size
; i
++)
814 if (itext_info
[i
] == NULL
)
817 /* If not found, then add some slots. */
822 itext_info
= xrealloc
823 (itext_info
, (itext_size
+= 10) * sizeof (ITEXT
*));
825 for (j
= i
; j
< itext_size
; j
++)
826 itext_info
[j
] = NULL
;
829 /* Now add the pointer and the offset. */
830 itext_info
[i
] = xmalloc (sizeof (ITEXT
));
831 itext_info
[i
]->pointer
= pointer
;
832 itext_info
[i
]->offset
= offset
;
833 itext
= itext_info
[i
];
838 /* Forget the input text associated with POINTER. */
840 forget_itext (char *pointer
)
844 for (i
= 0; i
< itext_size
; i
++)
845 if (itext_info
[i
] && (itext_info
[i
]->pointer
== pointer
))
847 free (itext_info
[i
]);
848 itext_info
[i
] = NULL
;
853 /* Append the text which appeared in input_text from the last offset to
854 the character just before the command that we are currently executing. */
856 me_append_before_this_command (void)
860 for (i
= input_text_offset
; i
&& (input_text
[i
] != COMMAND_PREFIX
); i
--)
862 maybe_write_itext (input_text
, i
);
865 /* Similar to execute_string, but only takes a single string argument,
866 and remembers the input text location, etc. */
868 me_execute_string (char *execution_string
)
870 int saved_escape_html
= escape_html
;
871 int saved_in_paragraph
= in_paragraph
;
872 escape_html
= me_executing_string
== 0;
876 input_text_offset
= 0;
877 /* The following xstrdup is so we can relocate input_text at will. */
878 input_text
= xstrdup (execution_string
);
879 input_filename
= xstrdup (input_filename
);
880 input_text_length
= strlen (execution_string
);
882 remember_itext (input_text
, 0);
884 me_executing_string
++;
887 free (input_filename
);
889 me_executing_string
--;
891 in_paragraph
= saved_in_paragraph
;
892 escape_html
= saved_escape_html
;
895 /* A wrapper around me_execute_string which saves and restores
896 variables important for output generation. This is called
897 when we need to produce macro-expanded output for input which
898 leaves no traces in the Info output. */
900 me_execute_string_keep_state (char *execution_string
, char *append_string
)
902 int op_orig
, opcol_orig
, popen_orig
;
903 int fill_orig
, newline_orig
, indent_orig
, meta_pos_orig
;
905 remember_itext (input_text
, input_text_offset
);
906 op_orig
= output_paragraph_offset
;
907 meta_pos_orig
= meta_char_pos
;
908 opcol_orig
= output_column
;
909 popen_orig
= paragraph_is_open
;
910 fill_orig
= filling_enabled
;
911 newline_orig
= last_char_was_newline
;
913 indent_orig
= no_indent
;
915 me_execute_string (execution_string
);
917 write_region_to_macro_output (append_string
, 0, strlen (append_string
));
918 output_paragraph_offset
= op_orig
;
919 meta_char_pos
= meta_pos_orig
;
920 output_column
= opcol_orig
;
921 paragraph_is_open
= popen_orig
;
922 filling_enabled
= fill_orig
;
923 last_char_was_newline
= newline_orig
;
924 no_indent
= indent_orig
;
927 /* Append the text which appears in input_text from the last offset to
928 the current OFFSET. */
930 append_to_expansion_output (int offset
)
935 for (i
= 0; i
< itext_size
; i
++)
936 if (itext_info
[i
] && itext_info
[i
]->pointer
== input_text
)
938 itext
= itext_info
[i
];
945 if (offset
> itext
->offset
)
947 write_region_to_macro_output (input_text
, itext
->offset
, offset
);
948 remember_itext (input_text
, offset
);
952 /* Only write this input text iff it appears in our itext list. */
954 maybe_write_itext (char *pointer
, int offset
)
959 for (i
= 0; i
< itext_size
; i
++)
960 if (itext_info
[i
] && (itext_info
[i
]->pointer
== pointer
))
962 itext
= itext_info
[i
];
966 if (itext
&& (itext
->offset
< offset
))
968 write_region_to_macro_output (itext
->pointer
, itext
->offset
, offset
);
969 remember_itext (pointer
, offset
);
974 write_region_to_macro_output (char *string
, int start
, int end
)
976 if (macro_expansion_output_stream
)
977 fwrite (string
+ start
, 1, end
- start
, macro_expansion_output_stream
);
982 typedef struct alias_struct
986 struct alias_struct
*next
;
989 static alias_type
*aliases
;
991 /* @alias aname = cmdname */
996 alias_type
*a
= xmalloc (sizeof (alias_type
));
999 get_until_in_line (0, "=", &(a
->alias
));
1000 canon_white (a
->alias
);
1002 discard_until ("=");
1004 get_until_in_line (0, " ", &(a
->mapto
));
1010 /* Perform an alias expansion. Called from read_command. */
1012 alias_expand (char *tok
)
1014 alias_type
*findit
= aliases
;
1017 if (strcmp (findit
->alias
, tok
) == 0)
1020 return alias_expand (xstrdup (findit
->mapto
));
1023 findit
= findit
->next
;
1028 /* definfoenclose implementation. */
1030 /* This structure is used to track enclosure macros. When an enclosure
1031 macro is recognized, a pointer to the enclosure block corresponding
1032 to its name is saved in the brace element for its argument. */
1033 typedef struct enclose_struct
1038 struct enclose_struct
*next
;
1041 static enclosure_type
*enclosures
;
1043 typedef struct enclosure_stack_struct
1045 enclosure_type
*current
;
1046 struct enclosure_stack_struct
*next
;
1047 } enclosure_stack_type
;
1049 static enclosure_stack_type
*enclosure_stack
;
1051 /* @definfoenclose */
1053 cm_definfoenclose (void)
1055 enclosure_type
*e
= xmalloc (sizeof (enclosure_type
));
1058 get_until_in_line (1, ",", &(e
->enclose
));
1059 discard_until (",");
1060 get_until_in_line (0, ",", &(e
->before
));
1061 discard_until (",");
1062 get_until_in_line (0, "\n", &(e
->after
));
1064 e
->next
= enclosures
;
1068 /* If TOK is an enclosure command, push it on the enclosure stack and
1069 return 1. Else return 0. */
1072 enclosure_command (char *tok
)
1074 enclosure_type
*findit
= enclosures
;
1077 if (strcmp (findit
->enclose
, tok
) == 0)
1079 enclosure_stack_type
*new = xmalloc (sizeof (enclosure_stack_type
));
1080 new->current
= findit
;
1081 new->next
= enclosure_stack
;
1082 enclosure_stack
= new;
1087 findit
= findit
->next
;
1092 /* actually perform the enclosure expansion */
1094 enclosure_expand (int arg
, int start
, int end
)
1097 add_word (enclosure_stack
->current
->before
);
1100 enclosure_stack_type
*temp
;
1102 add_word (enclosure_stack
->current
->after
);
1104 temp
= enclosure_stack
;
1105 enclosure_stack
= enclosure_stack
->next
;