root/branches/mcstas-1.x/symtab.c

Revision 2699, 8.2 KB (checked in by pkwi, 2 years ago)

Added files from mcstas-1.12a

Line 
1/*******************************************************************************
2*
3* McStas, neutron ray-tracing package
4*         Copyright 1997-2002, All rights reserved
5*         Risoe National Laboratory, Roskilde, Denmark
6*         Institut Laue Langevin, Grenoble, France
7*
8* Kernel: symtab.c
9*
10* %Identification
11* Written by: K.N.
12* Date: Jul  1, 1997
13* Origin: Risoe
14* Release: McStas 1.6
15* Version: $Revision: 1.18 $
16*
17* Symbol tables.
18*
19*       $Id: symtab.c,v 1.18 2006-11-06 14:30:00 farhi Exp $
20*
21*       $Log: symtab.c,v $
22*       Revision 1.18  2006-11-06 14:30:00  farhi
23*       Improved COPY grammar, enabling to either redefine sections, or extend them (with e.g. INITIALIZE COPY parent EXTEND %{ %})
24*       over-definition of parameters for comp instances in the .instr works OK.
25*
26*       Revision 1.17  2006/04/19 13:06:26  farhi
27*       * Updated Release, Version and Origin fields in headers
28*       * Improved setversion to update all McStasx.y occurencies into current release
29*       * Added 'string' type for DEFINITION parameters to be handled as this type so that auto-quoting occurs in mcgui
30*       * Added possibility to save log of the session to a file (appended) in mcgui
31*       * Made Scilab use either TCL_EvalStr or TK_EvalStr
32*       
33*       Revision 1.16  2003/10/06 15:00:12  farhi
34*       Added symtab_previous function for PREVIOUS keyword
35*
36*       Revision 1.15  2003/02/11 12:28:45  farhi
37*       Variouxs bug fixes after tests in the lib directory
38*       mcstas_r  : disable output with --no-out.. flag. Fix 1D McStas output
39*       read_table:corrected MC_SYS_DIR -> MCSTAS define
40*       monitor_nd-lib: fix Log(signal) log(coord)
41*       HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample
42*       Progress_bar: precent -> percent parameter
43*       CS: ----------------------------------------------------------------------
44*
45*       Revision 1.4  1999/04/16 07:41:31  kn
46*       Make the value_free argument for the symtab_free function optional.
47*
48*       Revision 1.3  1998/10/02 08:39:25  kn
49*       Fixed header comment.
50*
51*       Revision 1.2  1997/09/07 17:58:45  kn
52*       Snapshot with (untested) code generation complete.
53*
54*       Revision 1.1  1997/08/13 09:16:14  kn
55*       Initial revision
56*
57*******************************************************************************/
58
59#include <string.h>
60
61#include "mcstas.h"
62
63
64/*******************************************************************************
65* A symbol table is an abstract data type that maps any name to a
66* corresponding symbol table entry (which can be anything).
67*
68* In this first version, we use a simple, but inefficient approach. Symbol
69* tables are implemented as fixed-size arrays of string and void pointer
70* pairs. Table lookups are performed with a linear search. But the interface
71* is designed to make a transition to a more efficient implementation easily
72* possible if and when it becomes necessary.
73*******************************************************************************/
74
75struct Symbol_table
76  {
77    int size;                   /* Number of entries currently in table. */
78    int maxsize;                /* Total size of table. */
79    struct Symtab_entry *entries; /* Array of pairs of names and values. */
80  };
81
82#define MAXSIZE 1000            /* Max. table size. */
83
84/* Position in a symbol table for doing traversals. */
85struct Symtab_position
86  {
87    struct Symbol_table *symtab; /* The symbol table we are traversing. */
88    int index;                   /* Next entry to return. */
89  };
90
91
92/*******************************************************************************
93* Allocate and initialize a new symbol table.
94*******************************************************************************/
95Symtab
96symtab_create(void)
97{
98  Symtab st;
99
100  palloc(st);                   /* Allocate new symbol table. */
101  st->maxsize = MAXSIZE;
102  nalloc(st->entries, st->maxsize); /* Allocate array for entries. */
103  st->size = 0;                 /* Empty table. */
104  return st;
105}
106
107
108/*******************************************************************************
109* Look up a name in a symbol table. Returns a void pointer to the table
110* entry, or NULL if not found.
111*******************************************************************************/
112struct Symtab_entry *
113symtab_lookup(Symtab st, char *name)
114{
115  int i;
116
117  for(i = 0; i < st->size; i++)
118  {
119    if(!strcmp(name, st->entries[i].name)) /* Found? */
120    {
121      return &(st->entries[i]);
122    }
123  }
124
125  /* Not found. */
126  return NULL;
127}
128
129
130/*******************************************************************************
131* Add a new name to an existing symbol table along with a table entry. The
132* table entry is a void pointer which could eg. point to a structure
133* containing information relevant to the name.
134*
135* The table entry must point to memory that remains valid for the duration of
136* the symbol table. The name, however, may be re-used freely as a new copy is
137* allocated in the symbol table.
138*******************************************************************************/
139struct Symtab_entry *
140symtab_add(Symtab st, char *name, void *value)
141{
142  int i;
143
144  /* First see if an entry for this name already exists (it shouldn't, but ...) */
145  for(i = 0; i < st->size; i++)
146  {
147    if(!strcmp(name, st->entries[i].name))
148    {
149      /* Hmm ... adding an already present name. */
150      debugn((DEBUG_MEDIUM, "add_to_symtab: name already exists: %s.\n", name));
151      return &(st->entries[i]);
152    }
153  }
154
155  /* Make sure the table is large enough. */
156  if(st->size >= st->maxsize)
157  {
158    /* No room in table. This causes the program to abort. */
159    fatal_error("symtab_add: symbol table too small.");
160  }
161
162  /* Add the name at the end of the table. */
163  i = st->size;
164  st->size++;
165  st->entries[i].name = str_dup(name);
166  st->entries[i].val = value;
167  return value;
168}
169
170
171/*******************************************************************************
172* Free up memory allocated to a symbol table. The caller can supply a
173* function value_free that will free the memory for each table entry.
174* Pass NULL for value_free if no freeing is necessary.
175*******************************************************************************/
176void
177symtab_free(Symtab st, void (*value_free)(void *))
178{
179  int i;
180
181  for(i = 0; i < st->size; i++)
182  {
183    str_free(st->entries[i].name);
184    if(value_free)
185      (*value_free)(st->entries[i].val);
186  }
187  memfree(st->entries);
188  memfree(st);
189}
190
191
192/*******************************************************************************
193* Prepare to start traversing a symbol table. Note that an improved
194* implementation is free to change the order in which a traversal returns the
195* elements (for example if using a hash table).
196*******************************************************************************/
197Symtab_handle
198symtab_iterate(Symtab s)
199{
200  Symtab_handle sh;
201
202  palloc(sh);
203  sh->symtab = s;
204  sh->index = 0;
205  return sh;
206}
207
208
209/*******************************************************************************
210* Get the next element during a traversal of a symbol table. Returns NULL
211* when no more elements exist.
212*******************************************************************************/
213struct Symtab_entry *
214symtab_next(Symtab_handle sh)
215{
216  int i = sh->index;
217
218  /* Check if there are any more entries. */
219  if(i >= sh->symtab->size)
220  {
221    return NULL;
222  }
223  else
224  {
225    sh->index++;
226    return &(sh->symtab->entries[i]);
227  }
228}
229
230/*******************************************************************************
231* Get the index-th previous element stored in the symbol table. Returns NULL
232* when error occurs.
233*******************************************************************************/
234struct Symtab_entry *
235symtab_previous(Symtab st, int index)
236{
237  if (index <= 0 || index > st->size) {
238    return NULL;
239  } else {
240    return &(st->entries[st->size - index]);
241  }
242}
243
244
245/*******************************************************************************
246* End a symbol table traversal, freeing the memory allocated to the handle.
247*******************************************************************************/
248void
249symtab_iterate_end(Symtab_handle sh)
250{
251  memfree(sh);
252}
253
254/*******************************************************************************
255* Catenate symtab2 to symtab1
256*******************************************************************************/
257Symtab symtab_cat(Symtab st1, Symtab st2)
258{
259  Symtab_handle siter;
260  struct Symtab_entry *sitem;
261  siter = symtab_iterate(st2);
262  while(sitem = symtab_next(siter))
263    symtab_add(st1, sitem->name, sitem->val);
264  symtab_iterate_end(siter);
265  return(st1);
266}
267
Note: See TracBrowser for help on using the browser.