w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

stack.c
Go to the documentation of this file.
1 /* stack.c - code that implements a stack to handle braces and recursive calls
2  created by environments, and open and closing-braces
3 
4 Copyright (C) 1994-2002 The Free Software Foundation
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10 
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.
15 
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
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 
20 This file is available from http://sourceforge.net/projects/latex2rtf/
21 
22 Authors:
23  1994-1997 Ralf Schlatterbeck
24  1998-2000 Georg Lehner
25  2001-2002 Scott Prahl
26 */
27 
28 #include <stdlib.h>
29 #include "main.h"
30 #include "stack.h"
31 
32 #define STACKSIZE 1000
33 
34 static int stack[STACKSIZE];
35 static int top = 0;
36 int BraceLevel = 0;
37 
38 int BasicPush(int lev, int brack);
39 int BasicPop(int *lev, int *brack);
40 int getStackRecursionLevel(void);
41 
42 void
44 {
45 int i, lev, brack;
46 
47  fprintf(stderr, "\nStack Status top=%d\n",top);
48  i=0;
49  while (2*i<top) {
50  lev = stack[2*i+1];
51  brack = stack[2*i+2];
52  i++;
53 
54  fprintf(stderr, " #%d lev=%d bracket=%d\n", i, lev, brack);
55  }
56 }
57 
58 void
60 /******************************************************************************
61  purpose: pushes 0,1 and 1,1 on the stack to start things out
62  ******************************************************************************/
63 {
64  BraceLevel=0;
65  RecursionLevel = 1;
66  PushLevels();
67  BraceLevel=1;
68 }
69 
70 int
71 BasicPush(int lev, int brack)
72 /******************************************************************************
73  purpose: pushes the parameters lev and brack on the stack
74  return: top of stack
75  ******************************************************************************/
76 {
77 /* diagnostics(5,"pushing rec=%d and bra=%d on stack",lev,brack);*/
78  ++top;
79  stack[top] = lev;
80  ++top;
81  stack[top] = brack;
82 
83  if (top >= STACKSIZE)
84  diagnostics(ERROR, "Nesting too deep. latex2rtf bug, if file TeXs properly");
85 
86  return top;
87 }
88 
89 int
90 BasicPop(int *lev, int *brack)
91 /******************************************************************************
92  purpose: pops the parameters lev and brack from the stack
93  return: top of stack
94  ******************************************************************************/
95 {
96  *brack = stack[top];
97  --top;
98  *lev = stack[top];
99  --top;
100 
101  if (top < 0)
102  diagnostics(ERROR, "Nesting problem. latex2rtf bug, if file TeXs properly");
103 
104 /* diagnostics(5,"popped rec=%d and bra=%d off stack",*lev,*brack); */
105  return top;
106 }
107 
108 void
110 /******************************************************************************
111  purpose: wrapper to hide BraceLevel from rest of program
112  ******************************************************************************/
113 {
114  diagnostics(5, "PushLevels");
115  CleanStack();
117  /*myprintStack();*/
118 }
119 
120 int
122 /******************************************************************************
123  purpose: wrapper to hide BraceLevel from rest of program
124  ******************************************************************************/
125 {
126  int level;
128  return level;
129 }
130 
131 int
133 /******************************************************************************
134  purpose: returns the recursion level for the current BraceLevel
135  ******************************************************************************/
136 {
137 int PopLevel, PopBrack, PPopLevel, PPopBrack, size;
138 
139  PPopLevel = RecursionLevel;
140  PPopBrack = BraceLevel;
141  size = BasicPop(&PopLevel, &PopBrack);
142  while ((size = BasicPop(&PopLevel, &PopBrack)) >= 0) {
143  if (PopBrack < BraceLevel) {
144  break;
145  }
146  PPopLevel = PopLevel;
147  PPopBrack = PopBrack;
148  } /* while */
149  (void) BasicPush(PopLevel, PopBrack); /* push back */
150  (void) BasicPush(PPopLevel, BraceLevel);
151  return PPopLevel;
152 }
153 
154 void
156 /******************************************************************************
157  purpose: removes multiple identical copies on top of stack
158  ******************************************************************************/
159 {
160 int PopLevel, PopBrack, PPopLevel, PPopBrack;
161  diagnostics(5, "Cleaning Stack");
162 
163  if (top<4) return;
164 
165  BasicPop(&PPopLevel, &PPopBrack);
166  BasicPop(&PopLevel, &PopBrack);
167 
168  while (PPopLevel == PopLevel && PPopBrack == PopBrack && top>0)
169  BasicPop(&PopLevel, &PopBrack);
170 
171  BasicPush(PopLevel, PopBrack);
172  if (PPopLevel != PopLevel || PPopBrack != PopBrack)
173  BasicPush(PPopLevel, PPopBrack);
174 
175  /* myprintStack(); */
176 }
177 
178 void
180 /******************************************************************************
181  purpose: sets up the stack so that a closing brace will cause all commands
182  enclosed by the braces to be completed
183  ******************************************************************************/
184 {
185 /* diagnostics(5,"Pushing Brace Level");*/
187  ++BraceLevel;
188 }
189 
190 int
191 PopBrace(void)
192 /******************************************************************************
193  purpose: to return the recursion level of the matching open brace
194  search down through the stack for the lowest recursionlevel
195  that matches the current bracelevel-1.
196  ******************************************************************************/
197 {
198 int PopLevel, PopBrack, PPopLevel;
199 
200  diagnostics(6,"Popping Brace Level");
201  BraceLevel--;
202  PPopLevel = RecursionLevel;
203 
204  BasicPop(&PopLevel, &PopBrack);
205  while (PopBrack >= BraceLevel) {
206  if (PopLevel < PPopLevel) PPopLevel = PopLevel;
207  BasicPop(&PopLevel, &PopBrack);
208  }
209 
210  BasicPush(PopLevel, PopBrack); /* push back */
211  BasicPush(PPopLevel, BraceLevel);
212 
213  return PPopLevel;
214 }
215 
216 /*
217 The stack keeps track of the RecursionLevel and BraceLevel for each command.
218 
219  RecursionLevel is the number of recursive calls to Convert()
220  BraceLevel is the number of open braces '{'
221 
222 The top of stack has the current values of RecursionLevel and BraceLevel.
223 
224 The initial value of RecusionLevel is 1
225 The initial value of BraceLevel is 0
226 
227 Before each command and before each opening brace the current values
228 of RecursionLevel and BraceLevel are pushed on the stack.
229 
230 Each closing brace triggers a search of the stack to find
231 the RecursionLevel for the matching open brace.
232 
233 It is the lowest
234 RecursionLevel with the same BraceLevel as now (after subtract of the 1
235 closing brace found). The initial values for the RecursionLevel and
236 BraceLevel (1,0) always remain on the stack.
237 
238 The begin document command Pushes 1,1
239 
240 For example:
241 
242 { Text {\em Text} Text }
243 1 2 3 4 5
244 
245 1 Push 12
246 2 Push 13
247 3 Push 23
248 4 Bracket 3->2 Pop 23 Pop 13 Pop 12 Pop 11 -found- Push back 11
249  return to level 1
250 5 Bracket 2->1
251  return to level 1 = current -> no return
252 
253 \mbox{\em Text}
254 1 2 3 4
255 1 Push 11 RecursionLevel+1
256 2 Push 22
257 3 Push 32
258 4 Bracket 2->1 Pop 32 Pop 22 Pop 11 -found-
259  return to level 1 from level 3 -> double return from convert
260 
261 The necessary Push before every command increases the stack size. If the
262 commands don't include a recursive call the stack is not cleaned up.
263 After every TranslateCommand-function the stack is cleaned
264 
265 For example:
266 
267 \ldots \LaTeX \today \TeX
268  1 2 3 4
269 1 Push 11
270 2 Push 11
271 3 Push 11
272 4 Push 11
273 The clean-up loop pops till the values are not identical and pushes back the last
274 Therefore 11 will only occur once on the stack.
275 */
int level
Definition: afm2pl.c:1694
static void
Definition: fpif.c:118
small capitals from c petite p scientific i
Definition: afcover.h:80
#define ERROR(string)
Definition: error.h:36
void diagnostics(int level, char *format,...)
Definition: main.c:469
int RecursionLevel
Definition: main.c:120
#define fprintf
Definition: mendex.h:64
static int size
Definition: ppmlabel.c:24
Definition: spc_misc.c:56
#define STACKSIZE
Definition: stack.c:32
int PopBrace(void)
Definition: stack.c:191
void PushBrace(void)
Definition: stack.c:179
int BasicPop(int *lev, int *brack)
Definition: stack.c:90
void myprintStack(void)
Definition: stack.c:43
int PopLevels(void)
Definition: stack.c:121
int getStackRecursionLevel(void)
Definition: stack.c:132
int BasicPush(int lev, int brack)
Definition: stack.c:71
void InitializeStack(void)
Definition: stack.c:59
void CleanStack(void)
Definition: stack.c:155
int BraceLevel
Definition: stack.c:36
static int top
Definition: stack.c:35
void PushLevels(void)
Definition: stack.c:109