source: PSPA/madxPSPA/src/mad_macro.c @ 430

Last change on this file since 430 was 430, checked in by touze, 11 years ago

import madx-5.01.00

File size: 8.1 KB
Line 
1#include "madx.h"
2
3static struct macro*
4clone_macro(struct macro* org)
5{
6  int i;
7  struct macro* clone
8    = new_macro(org->n_formal, org->body->curr, org->tokens->curr);
9  if (org->body->curr > 0) strcpy(clone->body->c, org->body->c);
10  clone->body->curr = org->body->curr;
11  for (i = 0; i < org->tokens->curr; i++)
12    clone->tokens->p[i] = org->tokens->p[i];
13  clone->tokens->curr = org->tokens->curr;
14  for (i = 0; i < org->n_formal; i++)
15    clone->formal->p[i] = org->formal->p[i];
16  clone->n_formal = org->n_formal;
17  return clone;
18}
19
20static struct macro*
21delete_macro(struct macro* macro)
22{
23  char rout_name[] = "delete_macro";
24  if (macro == NULL)  return NULL;
25  if (stamp_flag && macro->stamp != 123456)
26    fprintf(stamp_file, "d_m double delete --> %s\n", macro->name);
27  if (watch_flag) fprintf(debug_file, "deleting --> %s\n", macro->name);
28  if (macro->formal != NULL) delete_char_p_array(macro->formal, 0);
29  if (macro->tokens != NULL) delete_char_p_array(macro->tokens, 0);
30  if (macro->body != NULL) delete_char_array(macro->body);
31  myfree(rout_name, macro);
32  return NULL;
33}
34
35static void
36grow_macro_list(struct macro_list* p)
37{
38  char rout_name[] = "grow_macro_list";
39  struct macro** n_loc = p->macros;
40  int j, new = 2*p->max;
41  p->max = new;
42  p->macros = (struct macro**) mycalloc(rout_name,new, sizeof(struct macro*));
43  for (j = 0; j < p->curr; j++) p->macros[j] = n_loc[j];
44  myfree(rout_name, n_loc);
45}
46
47#if 0 // not used...
48static void
49dump_macro(struct macro* m)
50{
51  fprintf(prt_file, "name: %s\n", m->name);
52  if (m->formal != NULL) dump_char_p_array(m->formal);
53  dump_char_array(m->body);
54  if (m->tokens != NULL) dump_char_p_array(m->tokens);
55}
56#endif
57
58#if 0 // not used...
59static void
60dump_macro_list(struct macro_list* ml)
61{
62  int i;
63  puts("++++++ dump of macro list");
64  for (i = 0; i < ml->curr; i++)
65    dump_macro(ml->macros[i]);
66}
67#endif
68
69void
70disable_line( /* prevents line from further expansion by "use" */
71  char* name, struct macro_list* nll)
72{
73  int pos;
74  if ((pos = name_list_pos(name, nll->list)) > -1) nll->macros[pos]->dead = 1;
75}
76
77#if 0 // not used
78static void
79remove_from_macro_list( /* removes macro from alphabetic macro list */
80  struct macro* macro, struct macro_list* nll)
81{
82  int pos;
83  if ((pos = name_list_pos(macro->name, nll->list)) > -1)
84  {
85    remove_from_name_list(macro->name, nll->list);
86    delete_macro(nll->macros[pos]);
87    nll->macros[pos] = nll->macros[nll->curr--];
88  }
89}
90#endif
91
92// public interface
93
94struct macro*
95new_macro(int n_formal, int length, int p_length)
96{
97  char rout_name[] = "new_macro";
98  struct macro* m = mycalloc(rout_name,1, sizeof(struct macro));
99  strcpy(m->name, "macro");
100  m->stamp = 123456;
101  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", m->name);
102  if ((m->n_formal  = n_formal) > 0) m->formal = new_char_p_array(n_formal);
103  if (p_length > 0) m->tokens = new_char_p_array(p_length);
104  ++length;
105  m->body = new_char_array(length + 1);
106  return m;
107}
108
109struct macro_list*
110new_macro_list(int length)
111{
112  char rout_name[] = "new_macro_list";
113  struct macro_list* nll = mycalloc(rout_name,1, sizeof(struct macro_list));
114  strcpy(nll->name, "macro_list");
115  nll->stamp = 123456;
116  if (watch_flag) fprintf(debug_file, "creating ++> %s\n", nll->name);
117  nll->list = new_name_list(nll->name, length);
118  nll->macros
119    = (struct macro**) mycalloc(rout_name,length, sizeof(struct macro*));
120  nll->max = length;
121  return nll;
122}
123
124int
125make_macro(char* statement)
126  /* makes a new macro from input command, stores name in name list */
127{
128  struct macro* m;
129  char** toks = tmp_l_array->p;
130  int i, n, rs, re, start_2;
131  int len = strlen(statement);
132  while(len >= aux_buff->max) grow_char_array(aux_buff);
133  strcpy(aux_buff->c, statement);
134  get_bracket_range(aux_buff->c, '{', '}', &rs, &re);
135  start_2 = rs + 1;
136  aux_buff->c[rs] = '\0'; aux_buff->c[re] = '\0'; /* drop '{' and '}' */
137  pre_split(aux_buff->c, l_wrk, 0);
138  mysplit(l_wrk->c, tmp_l_array);
139  get_bracket_t_range(toks, '(', ')', 0, tmp_l_array->curr-1, &rs, &re);
140  if ((n = re - rs - 1) < 0) n = 0; /* number of formal arguments if any */
141  m = new_macro(n, strlen(&aux_buff->c[start_2]), 0);
142  strcpy(m->name, toks[0]); rs++;
143  for (i = 0; i < n; i++) m->formal->p[i] = permbuff(toks[rs+i]);
144  if (n > 0) m->formal->curr = n;
145  strcpy(m->body->c, &aux_buff->c[start_2]); m->body->curr = strlen(m->body->c);
146  add_to_macro_list(m, macro_list);
147  return 0;
148}
149
150void
151exec_macro(struct in_cmd* cmd, int pos)
152  /* executes a macro */
153{
154  int i, rs, re, sum = 0, any = 0, level = pro->curr;
155  int n = macro_list->macros[pos]->n_formal;
156  char** toks = cmd->tok_list->p;
157  if (level == pro->max) grow_in_buff_list(pro);
158  if (pro->buffers[level] == NULL)
159    pro->buffers[level] = new_in_buffer(IN_BUFF_SIZE);
160  pro->curr++;
161  strcpy(pro->buffers[level]->c_a->c, macro_list->macros[pos]->body->c);
162  if (n)
163  {
164    get_bracket_t_range(toks, '(', ')', cmd->decl_start+1,
165                        cmd->tok_list->curr-1, &rs, &re);
166    any = re - rs - 1; rs++;
167    if (any < 0) any = 0;
168    else if (any > n) any = n;
169    for (i = 0; i < any; i++) {
170      int len = strlen(toks[rs+i]);
171      sum += len;
172    }
173    {
174      int len = strlen(pro->buffers[level]->c_a->c);
175      while (l_wrk->max < len+sum)
176        grow_char_array(l_wrk);
177    }
178    for (i = 0; i < any; i++)
179    {
180      myrepl(macro_list->macros[pos]->formal->p[i], toks[rs+i],
181             pro->buffers[level]->c_a->c, l_wrk->c);
182      mystrcpy(pro->buffers[level]->c_a, l_wrk->c);
183    }
184  }
185  pro_input(pro->buffers[level]->c_a->c);
186  pro->curr--;
187}
188
189void
190add_to_macro_list( /* adds macro to alphabetic macro list */
191  struct macro* macro, struct macro_list* nll)
192{
193  int pos, j;
194  if ((pos = name_list_pos(macro->name, nll->list)) > -1)
195  {
196    warning("macro redefined:", macro->name);
197    delete_macro(nll->macros[pos]);
198    nll->macros[pos] = macro;
199  }
200  else
201  {
202    if (nll->curr == nll->max) grow_macro_list(nll);
203    j = add_to_name_list(permbuff(macro->name), 0, nll->list);
204    nll->macros[nll->curr++] = macro;
205  }
206  /* RDM new matching*/
207  if (match_is_on==2)
208  {
209
210    for(j=0; j < MAX_MATCH_MACRO;j++)
211    {
212      if (match2_macro_name[j]==NULL)
213      {
214        break;
215      }
216    }
217
218    if (>= MAX_MATCH_MACRO  )
219    {
220      printf("Max number of match macros reached. Augmenting.\n");
221      match2_augmentnmacros();
222      j = MAX_MATCH_MACRO - 1;
223    }
224
225    match2_macro_name[j]=macro->name;
226
227  }
228  /* RDM new matching*/
229}
230
231int
232remove_from_name_list(char* name, struct name_list* nl)
233{
234  int j, i, k = -1;
235  for (i = 0; i < nl->curr; i++)
236    if (strcmp(nl->names[nl->index[i]], name) == 0) break;
237 
238 
239  if (i < nl->curr)
240  {
241   
242    k = nl->index[i];
243    for (j = i+1; j < nl->curr; j++) nl->index[j-1] = nl->index[j];
244   
245    for (j = 0; j < nl->curr-1; j++)
246      if(nl->index[j] == nl->curr-1) break;
247     
248    nl->index[j] = k;
249    nl->inform[k] = nl->inform[nl->curr-1];
250    nl->names[k] = nl->names[--nl->curr];
251  }
252 
253  return k;
254}
255
256void
257replace_lines(struct macro* org, int replace, char** reps)
258  /* replaces lines in line by elements - recursive */
259{
260  int i, j, k, l, n, pos;
261  int mf = replace < org->n_formal ? replace : org->n_formal;
262  char* p;
263  struct macro* line;
264  if (org->tokens == NULL) fatal_error("line not split:", org->name);
265  line = clone_macro(org);
266  for (j = 0; j < mf; j++)
267  {
268    for (i = 0; i < line->tokens->curr; i++)
269    {
270      p = line->tokens->p[i];
271      if (isalpha(*p) && strcmp(line->formal->p[j], p) == 0)
272        line->tokens->p[i] = reps[j];
273    }
274  }
275  for (i = 0; i < line->tokens->curr; i++)
276  {
277    p = line->tokens->p[i];
278    if (isalpha(*p) && (pos = name_list_pos(p, line_list->list)) > -1)
279    {
280      if (*line->tokens->p[i+1] == '(') /* formal arguments */
281      {
282        for (k = i+2; k < line->tokens->curr; k++)
283          if (*line->tokens->p[k] == ')') break;
284        n = k - i - 2;
285        l = k;
286      }
287      else
288      {
289        n = 0; l = i;
290      }
291      replace_lines(line_list->macros[pos], n, &line->tokens->p[i+2]);
292      i = l;
293    }
294    else
295    {
296      if (line_buffer->curr == line_buffer->max)
297        grow_char_p_array(line_buffer);
298      line_buffer->p[line_buffer->curr++] = tmpbuff(p);
299    }
300  }
301  delete_macro(line);
302}
303
304
Note: See TracBrowser for help on using the repository browser.