1/* -*- c -*-
2 * File: proscope.c
3 * Author: Igor Vlasenko <vlasenko@imath.kiev.ua>
4 * Created: Thu May 26 15:25:57 2005
5 *
6 * $Id$
7 */
8
9#include <stdlib.h>
10#include "proscope.h"
11#include "tmpllog.h"
12
13#define START_NUMBER_OF_NESTED_LOOPS 64
14
15static
16void
17Scope_init(struct scope_stack* scopestack) {
18  scopestack->max=START_NUMBER_OF_NESTED_LOOPS;
19  scopestack->root=(struct ProScopeEntry*) malloc ((scopestack->max) * sizeof(struct ProScopeEntry));
20  if (NULL==scopestack->root) tmpl_log(TMPL_LOG_ERROR, "DIE:_Scope_init:internal error:not enough memory\n");
21  scopestack->level=-1;
22}
23
24static
25void
26Scope_free(struct scope_stack* scopestack) {
27  free(scopestack->root);
28  scopestack->max=-1;
29  scopestack->level=-1;
30}
31
32INLINE
33static
34int curScopeLevel(const struct scope_stack* scopestack) {
35  return scopestack->level;
36}
37
38INLINE
39static
40struct ProScopeEntry* getCurrentScope(const struct scope_stack* scopestack) {
41  return scopestack->root+scopestack->level;
42}
43
44INLINE
45static
46struct ProScopeEntry*
47getScope(const struct scope_stack* scopestack, int depth) {
48  return &(scopestack->root)[depth];
49}
50
51static
52void
53popScope(struct scope_stack* scopestack) {
54  if (scopestack->level>0) scopestack->level--;
55  else tmpl_log(TMPL_LOG_ERROR, "WARN:PopScope:internal error:scope is exhausted\n");
56}
57
58static
59void
60_pushScope(struct scope_stack* scopestack) {
61  if (scopestack->max<0) {
62    tmpl_log(TMPL_LOG_ERROR, "WARN:PushScope:internal warning:why scope is empty?\n");
63    Scope_init(scopestack);
64  }
65  ++scopestack->level;
66  if (scopestack->level>scopestack->max)
67    {
68      if (scopestack->max<START_NUMBER_OF_NESTED_LOOPS) scopestack->max=START_NUMBER_OF_NESTED_LOOPS;
69      scopestack->max*=2;
70      scopestack->root=(struct ProScopeEntry*) realloc (scopestack->root, (scopestack->max) * sizeof(struct ProScopeEntry));
71    }
72}
73
74static
75void
76pushScopeLoop(struct scope_stack* scopestack, int loop_count, void *loops_AV) {
77  struct ProScopeEntry* CurrentScope;
78  _pushScope(scopestack);
79  CurrentScope=scopestack->root+scopestack->level;
80  CurrentScope->loop=-1;
81  CurrentScope->loop_count = loop_count;
82  CurrentScope->flags=0;
83  CurrentScope->loops_AV=loops_AV;
84  CurrentScope->param_HV=NULL;
85}
86
87static
88void
89pushScopeMap(struct scope_stack* scopestack, void *param_HV, int flags) {
90  struct ProScopeEntry* CurrentScope;
91  _pushScope(scopestack);
92  CurrentScope=scopestack->root+scopestack->level;
93  CurrentScope->flags=flags;
94  CurrentScope->loops_AV=NULL;
95  CurrentScope->param_HV=param_HV;
96}
97
98static
99void
100Scope_reset(struct scope_stack* scopestack, int keep_count) {
101  int init_level=-1;
102  // TODO; find out scope level
103  if (scopestack->max<0) {
104    tmpl_log(TMPL_LOG_ERROR, "ERROR:Scope_reset:internal error:scope is empty.\n");
105    Scope_init(scopestack);
106    scopestack->level=init_level;
107  } else {
108    scopestack->level=keep_count+init_level;
109  }
110}
111