CUBRID Engine  latest
esql_declare.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * esql_declare.c - Declaration-handling code for esql preprocessor.
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "esql_grammar.h"
33 #include "esql_misc.h"
34 #include "memory_alloc.h"
35 #include "esql_translate.h"
36 #include "variable_string.h"
37 
38 #define NFRAMES 8
39 #define MAX_LONGS_ALLOWED 1
40 
41 typedef struct spec_state SPEC_STATE;
42 typedef struct scope SCOPE;
43 
44 extern "C"
45 {
46  extern FILE *esql_yyout;
47 }
48 
49 struct spec_state
50 {
51  int noun_seen; /* 1 iff a type noun has been seen */
52  int longs_seen; /* # of longs seen */
53  int shorts_seen; /* # of shorts seen */
54  int signed_seen; /* 1 iff signed or unsigned " " */
55  int storage_class_seen; /* 1 iff a storage class " " */
56  int typedef_seen; /* 1 iff typedef is in progress */
57  int sc_allowed; /* 1 iff storage class specs are allowed */
58  int volatile_seen; /* 1 iff volatile keyword seen */
59  int const_seen; /* 1 iff const keyword seen */
60  LINK *spec; /* The specifier under construction */
61 };
62 
63 struct scope
64 {
70 };
71 
72 enum
73 {
83 };
84 
85 /* space and C token literal defs */
86 #define TOK_SPACE " "
87 #define TOK_COMMA ","
88 #define TOK_LB "{"
89 #define TOK_RB "}"
90 #define TOK_LP "("
91 #define TOK_RP ")"
92 #define TOK_SC ";"
93 #define TOK_STAR "*"
94 #define TOK_AUTO "auto"
95 #define TOK_CONST "const"
96 #define TOK_EXTERN "extern"
97 #define TOK_CHAR "char"
98 #define TOK_DOUBLE "double"
99 #define TOK_FLOAT "float"
100 #define TOK_INT "int"
101 #define TOK_LONG "long"
102 #define TOK_REGISTER "register"
103 #define TOK_SHORT "short"
104 #define TOK_STATIC "static"
105 #define TOK_TYPEDEF "typedef"
106 #define TOK_UNSIGNED "unsigned"
107 #define TOK_VOID "void"
108 #define TOK_VOLATILE "volatile"
109 #define TOK_INVALID "whoknows"
110 
111 
112 
115 
120 
121 static void pp_set_class_bit (int storage_class, LINK * p);
122 static LINK *pp_new_type_spec (void);
123 static void pp_remove_structdefs_from_table (STRUCTDEF * struct_chain);
124 static void pp_print_link (LINK * p, varstring * buf, int context, int preechoed);
125 static void pp_print_decl (SYMBOL * sym, varstring * buf, int preechoed);
126 
127 /*
128  * pp_set_class_bit() - Change the class of the specifier pointed to by p
129  * as indicated by storage_class.
130  * return : void
131  * storage_class(in): The new storage class for the specifier p.
132  * p(out): The specifier to be changed.
133  * note :The TYPEDEF class is used here only to remember that the input
134  * storage class was a typedef.
135  */
136 static void
138 {
139  switch (storage_class)
140  {
141  case 0:
142  {
143  p->decl.s.sclass = C_FIXED;
144  p->decl.s.is_static = 0;
145  p->decl.s.is_extern = 0;
146  p->decl.s.is_const = 0;
147  p->decl.s.is_volatile = 0;
148  }
149  break;
150 
151  case TYPEDEF_:
152  p->decl.s.sclass = C_TYPEDEF;
153  break;
154 
155  case REGISTER_:
156  p->decl.s.is_register = 1;
157  break;
158 
159  case AUTO_:
160  p->decl.s.is_auto = 1;
161  break;
162 
163  case EXTERN_:
164  p->decl.s.is_extern = 1;
165  break;
166 
167  case STATIC_:
168  p->decl.s.is_static = 1;
169  break;
170 
171  default:
172  {
174  exit (1);
175  }
176  break;
177  }
178 }
179 
180 /*
181  * pp_new_type_spec() - Return a new, initialized specifier structure.
182  * return : LINK *
183  */
184 static LINK *
186 {
187  LINK *p = pp_new_link ();
188 
189  if (p == NULL)
190  {
191  return NULL;
192  }
193 
194  p->class_ = SPECIFIER;
195  p->decl.s.noun = N_INT;
196  p->decl.s.sclass = C_AUTO;
197 
198  return p;
199 }
200 
201 /*
202  * pp_add_spec_to_decl() - Add the specifier to each of the declarators in
203  * decl_chain. This is accomplished by cloning p_spec and then tacking it
204  * onto the end of every declaration chain in decl_chain.
205  * return : void
206  * p_spec(in): A pointer to a specifier/declarator chain created by a previous
207  * typedef, or to a single specifier. It is cloned and then tacked onto
208  * the end of every declaration chain in the list pointed to by decl_chain.
209  * decl_chain(out): A chain of declarators, each of which is to receive the
210  * p_spec specifier.
211  */
212 void
213 pp_add_spec_to_decl (LINK * p_spec, SYMBOL * decl_chain)
214 {
215  LINK *clone_start, *clone_end;
216 
217  for (; decl_chain; decl_chain = decl_chain->next)
218  {
219  clone_start = pp_clone_type (p_spec, &clone_end);
220  if (clone_start == NULL)
221  {
223  exit (1);
224  }
225 
226  if (IS_PSEUDO_TYPE (clone_start) && clone_start->decl.s.val.v_struct == NULL)
227  {
228  LINK *old_etype;
229  char tmp[32];
230 
231  old_etype = decl_chain->etype;
232  if (old_etype == NULL || (IS_VAR_TYPE (clone_start) && IS_ARRAY (old_etype) == 0))
233  {
235  exit (1);
236  }
237 
238  clone_start->decl.s.val.v_struct = pp_new_pseudo_def (clone_start->decl.s.noun, old_etype->decl.d.num_ele);
239  if (clone_start->decl.s.noun == N_VARCHAR)
240  {
241  sprintf (tmp, " = { %s, \"\" }", old_etype->decl.d.num_ele);
242  }
243  else
244  {
245  sprintf (tmp, " = { ((%s)+7)/8, \"\" }", old_etype->decl.d.num_ele);
246  }
247  decl_chain->args = pp_new_symbol (tmp, decl_chain->level);
248  pp_discard_link (old_etype);
249 
250  if (decl_chain->type == old_etype)
251  {
252  decl_chain->type = NULL;
253  }
254  else
255  {
256  LINK *parent;
257  for (parent = decl_chain->type; parent->next != old_etype; parent = parent->next)
258  {
259  ;
260  }
261  parent->next = NULL;
262  decl_chain->etype = parent;
263  }
264  }
265 
266  if (decl_chain->type == NULL) /* No declarators */
267  {
268  decl_chain->type = clone_start;
269  }
270  else
271  {
272  decl_chain->etype->next = clone_start;
273  }
274 
275  decl_chain->etype = clone_end;
276 
277  /*
278  * If the declaration we're looking at is really a typedef,
279  * record the symbol itself within the specifier. This will
280  * make it easier to point back to the symbol from other
281  * declarations, which will make it easier to print out
282  * later declarations using the typedef name rather than its
283  * expansion.
284  */
285  if (IS_TYPEDEF (clone_end))
286  {
287  pp_set_class_bit (0, clone_end);
288  decl_chain->type->tdef = decl_chain;
289  decl_chain->type->from_tdef = decl_chain;
290  }
291  }
292 }
293 
294 
295 /*
296  * pp_add_symbols_to_table() - Add declarations to the symbol table. Removes
297  * duplicate declarations, complaining if they are not harmless. All
298  * declarations that are retained are accessible through
299  * current->scope->sym_chain.
300  * sym(in): A chain of symbols to be added to the symbol table.
301  * return : void
302  */
303 void
305 {
306  SYMBOL *exists, *pnew, *next = NULL;
307 
308  for (pnew = sym; pnew; pnew = next)
309  {
310  next = pnew->next;
311 
312  if (sym->name == NULL)
313  {
314  continue;
315  }
316 
317  exists = (SYMBOL *) pp_findsym (pp_Symbol_table, pnew->name);
318 
319  if (exists == NULL || exists->level != pnew->level)
320  {
322  pnew->next = pp_current_name_scope->sym_chain;
323  pp_current_name_scope->sym_chain = pnew;
324  }
325  else
326  {
327  int harmless = 0;
328 
329  if (pp_the_same_type (exists->type, pnew->type, 0))
330  {
331  if (exists->etype->decl.s.is_extern || pnew->etype->decl.s.is_extern)
332  {
333  harmless = 1;
334  if (pnew->etype->decl.s.is_extern == 0)
335  {
336  exists->etype->decl.s.sclass = pnew->etype->decl.s.sclass;
337  exists->etype->decl.s.is_static = pnew->etype->decl.s.is_static;
338  exists->etype->decl.s.is_extern = pnew->etype->decl.s.is_extern;
339  }
340  }
341  }
342 
343  if (harmless == 0)
344  {
345  esql_yyredef ((char *) pnew->name);
346  }
347 
348  pp_discard_symbol (pnew);
349  }
350  }
351 }
352 
353 /*
354  * pp_remove_symbols_from_table() - Remove all of the symbols on the chain
355  * from the table.
356  * return : void
357  * sym_chain(in): A pointer to a linked chain of symbols to be removed from
358  * the table.
359  */
360 void
362 {
363  SYMBOL *sym;
364 
365  for (sym = sym_chain; sym; sym = sym->next)
366  {
368  }
369 
370 }
371 
372 /*
373  * pp_remove_structdefs_from_table() - Remove all of the structs on the chain
374  * from the table.
375  * return : void
376  * struct_chain(in): A pointer to a linked chain of structdefs to be removed
377  * from the struct table.
378  */
379 static void
381 {
382  STRUCTDEF *sdef;
383 
384  for (sdef = struct_chain; sdef; sdef = sdef->next)
385  {
387  }
388 }
389 
390 /*
391  * pp_do_enum() - Enter the symbol as an enumerated constant with type int.
392  * We don't care about its actual value.
393  * return : void
394  * sym(in): A symbol being defined as an enumerated constant.
395  */
396 void
398 {
399  if (sym->type)
400  {
401  esql_yyredef ((char *) sym->name);
402  }
403  else
404  {
405  LINK *p = pp_new_type_spec ();
406  p->decl.s.sclass = C_CONSTANT;
407  p->decl.s.val.v_int = 0; /* We don't care about the value. */
408  sym->type = p;
410  }
411 }
412 
413 /*
414  * pp_push_name_scope() - Push a new symbol table scope.
415  * return : void
416  */
417 void
419 {
420  SCOPE *new_scope;
421 
422  new_scope = pp_current_name_scope ? (pp_current_name_scope + 1) : pp_name_scope_base;
423 
424  if (new_scope >= pp_name_scope_limit)
425  {
426  int nframes = (int) (pp_name_scope_limit - pp_name_scope_base);
427  SCOPE *const realloc_pp_name_scope_base
428  = (SCOPE *) realloc (pp_name_scope_base, sizeof (SCOPE) * (nframes + NFRAMES));
429  if (realloc_pp_name_scope_base == NULL)
430  {
432  exit (1);
433  return;
434  }
435  else
436  {
437  pp_name_scope_base = realloc_pp_name_scope_base;
438  }
439 
440  pp_name_scope_limit = pp_name_scope_base + nframes + NFRAMES;
441  if (pp_current_name_scope)
442  {
443  pp_current_name_scope = pp_name_scope_base + nframes - 1;
444  }
445  new_scope = pp_name_scope_base + nframes;
446  }
447 
448  new_scope->recognizing_typedef_names = 1;
449  new_scope->sym_chain = NULL;
450  new_scope->struct_chain = NULL;
451  new_scope->cursor_chain = NULL;
452  pp_init_whenever_scope (&new_scope->whenever, pp_current_name_scope ? &pp_current_name_scope->whenever : NULL);
453 
454  pp_current_name_scope = new_scope;
456 
458 }
459 
460 /*
461  * pp_pop_name_scope() - Pop the current symbol table scope.
462  * return : void
463  */
464 void
466 {
467  SCOPE *current, *next;
468 
469 #if !defined(NDEBUG)
470  if (pp_dump_scope_info)
471  {
472  fprintf (esql_yyout, "\n/*\n * Exiting scope level %d\n", pp_nesting_level);
475  fputs (" */\n", esql_yyout);
476  }
477 #endif
478 
479  current = pp_current_name_scope;
480  if (pp_current_name_scope == pp_name_scope_base)
481  {
482  next = NULL;
483  }
484  else
485  {
486  next = pp_current_name_scope - 1;
487  }
488 
491 
494 
497 
498  pp_finish_whenever_scope (&current->whenever, next ? &next->whenever : NULL);
499 
500  pp_current_name_scope = next;
501 
503 
504  pp_make_typedef_names_visible (pp_current_name_scope == NULL || pp_current_name_scope->recognizing_typedef_names);
505 }
506 
507 /*
508  * pp_make_typedef_names_visible() - Alter current scope so that typedef names
509  * are treated as such, rather than as ordinary identifiers, (if sense is 1)
510  * or vice versa (if sense is 0).
511  * return : void
512  * sense: 1 if names should be visible, 0 if not.
513  */
514 void
516 {
517  if (pp_current_name_scope)
518  {
519  pp_current_name_scope->recognizing_typedef_names = sense;
520  }
522 
523 }
524 
525 /*
526  * pp_decl_init() - Set up various initial conditions for the module.
527  * return : void
528  */
529 void
531 {
532  pp_nesting_level = -1; /* It will get bumped by push_name_scope(). */
533 
534  pp_name_scope_base = (SCOPE *) pp_malloc (NFRAMES * sizeof (SCOPE));
535  memset (pp_name_scope_base, 0, NFRAMES * sizeof (SCOPE));
536  pp_name_scope_limit = pp_name_scope_base + NFRAMES;
537  pp_current_name_scope = NULL;
539 
540  pp_spec_scope_base = (SPEC_STATE *) pp_malloc (NFRAMES * sizeof (SPEC_STATE));
541  memset (pp_spec_scope_base, 0, NFRAMES * sizeof (SPEC_STATE));
542  pp_spec_scope_limit = pp_spec_scope_base + NFRAMES;
543  pp_current_spec_scope = NULL;
545 
547 
548 }
549 
550 /*
551  * pp_decl_finish() - Tear down various module structures.
552  * return : void
553  */
554 void
556 {
557  while (pp_current_name_scope)
558  {
560  }
561 
562  while (pp_current_spec_scope)
563  {
565  }
566 
567  free_and_init (pp_name_scope_base);
568  free_and_init (pp_spec_scope_base);
569 }
570 
571 /*
572  * pp_push_spec_scope() - Start a new scope for type specifiers. This type of
573  * scoped behavior is necessary for processing struct definitions correctly.
574  * return : void
575  */
576 void
578 {
579  SPEC_STATE *p;
580 
581  p = pp_current_spec_scope ? (pp_current_spec_scope + 1) : pp_spec_scope_base;
582 
583  if (p >= pp_spec_scope_limit)
584  {
585  int nframes = (int) (pp_spec_scope_limit - pp_spec_scope_base);
586  SPEC_STATE *const realloc_pp_spec_scope_base
587  = (SPEC_STATE *) realloc (pp_spec_scope_base, sizeof (SPEC_STATE) * (nframes + NFRAMES));
588  if (realloc_pp_spec_scope_base == NULL)
589  {
591  exit (1);
592  return;
593  }
594  else
595  {
596  pp_spec_scope_base = realloc_pp_spec_scope_base;
597  }
598 
599  pp_spec_scope_limit = pp_spec_scope_base + nframes + NFRAMES;
600  if (pp_current_spec_scope)
601  {
602  pp_current_spec_scope = pp_spec_scope_base + nframes - 1;
603  }
604  p = pp_spec_scope_base + nframes;
605  }
606 
607  p->noun_seen = false;
608  p->longs_seen = 0;
609  p->shorts_seen = 0;
610  p->signed_seen = false;
611  p->storage_class_seen = false;
612  p->typedef_seen = false;
613  p->sc_allowed = true;
614  p->volatile_seen = false;
615  p->const_seen = false;
616  p->spec = NULL;
617  pp_current_spec_scope = p;
618 
619 }
620 
621 /*
622  * pp_pop_spec_scope() - Return to a previous scope for type specifiers.
623  * return : void
624  */
625 void
627 {
628  assert (pp_current_spec_scope != NULL);
629  pp_current_spec_scope = (pp_current_spec_scope == pp_spec_scope_base ? NULL : (pp_current_spec_scope - 1));
630 
631 }
632 
633 /*
634  * pp_reset_current_type_spec() - Reset the working variables for
635  * the current type spec.
636  * return : void
637  */
638 void
640 {
642 
643  p->noun_seen = false;
644  p->longs_seen = 0;
645  p->shorts_seen = 0;
646  p->signed_seen = false;
647  p->storage_class_seen = false;
648  p->typedef_seen = false;
649  p->sc_allowed = true;
650  p->volatile_seen = false;
651  p->const_seen = false;
652 
653  p->spec = pp_new_type_spec ();
654 
655 }
656 
657 /*
658  * pp_current_type_spec() - Return the type specifier currently
659  * under construction.
660  * return : LINK *
661  */
662 LINK *
664 {
665  return pp_current_spec_scope->spec;
666 
667 }
668 
669 /*
670  * pp_add_storage_class() -
671  * return : void
672  * sc(in): The storage class to be added to the current type specifier.
673  *
674  * note : Side effects pp_current_spec_scope.
675  */
676 void
678 {
680 
681  if (!p->sc_allowed)
682  {
684  return;
685  }
686 
687  if (p->storage_class_seen)
688  {
690  return;
691  }
692 
693  p->storage_class_seen = sc != TYPEDEF_;
694  p->typedef_seen = sc == TYPEDEF_;
695  pp_set_class_bit (sc, p->spec);
696 }
697 
698 /*
699  * pp_add_struct_spec() -
700  * return : void
701  * sdef(in): The struct definition that serves as the type noun of the
702  * current type spec.
703  *
704  * note : Side effects pp_current_spec_scope.
705  */
706 void
708 {
710 
711  if (sdef == NULL)
712  {
713  /*
714  * There was already some sort of error during parsing, and we've
715  * wound up here in a sort of no-op mode. Just ignore it.
716  */
717  return;
718  }
719 
720  if (p->noun_seen)
721  {
723  pp_discard_structdef (sdef);
724  return;
725  }
726 
727  if ((p->longs_seen > 0) || (p->shorts_seen > 0) || p->signed_seen)
728  {
730  pp_discard_structdef (sdef);
731  return;
732  }
733 
734  p->spec->decl.s.noun = N_STRUCTURE;
735  p->spec->decl.s.val.v_struct = sdef;
736  p->spec->decl.s.is_by_name = sdef->by_name;
737  p->noun_seen = true;
738  p->longs_seen = 1;
739  p->shorts_seen = 1;
740  p->signed_seen = true;
741 
742  sdef->by_name = false;
743 
744 }
745 
746 /*
747  * pp_add_type_noun() - Add the appropriate type to the current type specifier.
748  * return : void
749  * type(in): The type specifier to be added.
750  *
751  * note : Side effects pp_current_spec_scope.
752  */
753 void
755 {
757 
758  if (p->noun_seen)
759  {
761  return;
762  }
763 
764  switch (type)
765  {
766  case VOID_:
767  {
768  if ((p->longs_seen > 0) || (p->shorts_seen > 0) || p->signed_seen)
769  {
771  return;
772  }
773  p->longs_seen = 1;
774  p->shorts_seen = 1;
775  p->signed_seen = true;
776  p->spec->decl.s.noun = N_VOID;
777  }
778  break;
779 
780  case CHAR_:
781  {
782  if ((p->longs_seen > 0) || (p->shorts_seen > 0))
783  {
785  return;
786  }
787  p->longs_seen = 1;
788  p->spec->decl.s.noun = N_CHR;
789  }
790  break;
791 
792  case INT_:
793  {
794  p->spec->decl.s.noun = N_INT;
795  p->spec->decl.s.is_long = (p->longs_seen > 0);
796  p->spec->decl.s.is_short = (p->shorts_seen > 0);
797  }
798  break;
799 
800  case FLOAT_:
801  {
802  p->spec->decl.s.noun = N_FLOAT;
803  p->spec->decl.s.is_long = (p->longs_seen > 0) && p->spec->decl.s.is_long;
804  }
805  break;
806 
807  case DOUBLE_:
808  {
809  if ((p->longs_seen > 0) && !p->spec->decl.s.is_long)
810  {
812  return;
813  }
814  p->longs_seen = 1;
815  p->spec->decl.s.noun = N_FLOAT;
816  p->spec->decl.s.is_long = 1;
817  }
818  break;
819 
820  case VARCHAR_:
821  case BIT_:
822  case VARBIT_:
823  {
824  if ((p->longs_seen > 0) || (p->shorts_seen) || (p->signed_seen))
825  {
827  return;
828  }
829  p->spec->decl.s.noun = (type == VARCHAR_) ? N_VARCHAR : (type == BIT_) ? N_BIT : N_VARBIT;
830  p->spec->decl.s.val.v_struct = NULL;
831  }
832  break;
833 
834  default:
835  {
836  esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_TYPE_SPEC_UNEXPECTED_CASE), "pp_add_type_spec", type);
837  exit (1);
838  }
839  break;
840  }
841 
843  p->spec->decl.s.is_const = p->const_seen;
844 
845  p->noun_seen = true;
846 }
847 
848 /*
849  * pp_add_type_adj() - Add the indicated modifier to the current type
850  * specifier, if appropriate.
851  * return : void
852  * adj(in): The type modifier to be applied.
853  *
854  * note : Side effects pp_current_spec_scope.
855  */
856 void
858 {
860 
861  switch (adj)
862  {
863  /* Used for ENUM */
864  case INT_:
865  if (p->noun_seen && (p->spec->decl.s.noun == N_INT))
866  {
867  p->spec->decl.s.is_long = 0;
868  p->spec->decl.s.is_short = 0;
869  }
870  else
871  {
873  return;
874  }
875  case SHORT_:
876  {
877  if ((p->shorts_seen > 1) || (p->longs_seen > 0))
878  {
880  return;
881  }
882  if (p->noun_seen)
883  {
884  switch (p->spec->decl.s.noun)
885  {
886  case N_INT:
887  case N_FLOAT:
888  break;
889 
890  default:
892  return;
893  }
894  }
895  ++p->shorts_seen;
896  p->spec->decl.s.is_short = 1;
897  p->spec->decl.s.is_long = 0;
898  }
899  break;
900 
901  case LONG_:
902  {
903  if ((p->longs_seen > MAX_LONGS_ALLOWED) || p->shorts_seen > 0)
904  {
906  return;
907  }
908  if (p->noun_seen)
909  {
910  switch (p->spec->decl.s.noun)
911  {
912  case N_INT:
913  case N_FLOAT:
914  break;
915 
916  default:
918  return;
919  }
920  }
921  ++p->longs_seen;
922  p->spec->decl.s.is_long = 1;
923  p->spec->decl.s.is_short = 0;
924  }
925  break;
926 
927  case SIGNED_:
928  case UNSIGNED_:
929  {
930  if (p->signed_seen)
931  {
933  return;
934  }
935  if (p->noun_seen)
936  {
937  switch (p->spec->decl.s.noun)
938  {
939  case N_INT:
940  case N_CHR:
941  break;
942 
943  default:
945  return;
946  }
947  }
948  p->signed_seen = true;
949  p->spec->decl.s.is_unsigned = adj == UNSIGNED_;
950  }
951  break;
952 
953  case CONST_:
954  {
955  if (p->volatile_seen)
956  {
958  return;
959  }
960  p->const_seen = true;
961  }
962  break;
963 
964  case VOLATILE_:
965  {
966  if (p->volatile_seen)
967  {
969  return;
970  }
971  p->volatile_seen = true;
972  }
973  break;
974 
975  default:
976  {
978  exit (1);
979  }
980  break;
981  }
982 
983 }
984 
985 /*
986  * pp_add_typedefed_spec() - Set the type of the current definition
987  * (i.e., the specifier being built in pp_current_spec_scope) to a copy
988  * of the specifier/declarator chain associated with the given typedef.
989  * return : void
990  * spec(in): The type descriptor provided from a typedef definition.
991  *
992  * note : Side effects pp_current_spec_scope.
993  */
994 void
996 {
998  LINK *q;
999 
1000  if (p->noun_seen)
1001  {
1003  return;
1004  }
1005  if ((p->longs_seen > 0) || (p->shorts_seen > 0) || p->signed_seen)
1006  {
1008  return;
1009  }
1010 
1011  /*
1012  * Reset any class info in the new spec; this is ok since this spec
1013  * will be cloned onto every declarator that it modifies, and then
1014  * reset before every future use. The clones will keep any specific
1015  * changes that they need.
1016  */
1017  for (q = spec; q->next; q = q->next)
1018  {
1019  ;
1020  }
1021  if (p->spec->decl.s.sclass)
1022  {
1023  q->decl.s.sclass = p->spec->decl.s.sclass;
1024  }
1025  q->decl.s.is_static = p->spec->decl.s.is_static;
1026  q->decl.s.is_extern = p->spec->decl.s.is_extern;
1027  q->decl.s.is_const = p->spec->decl.s.is_const;
1028  q->decl.s.is_volatile = p->spec->decl.s.is_volatile;
1029 
1030  if (p->spec->tdef == NULL)
1031  {
1033  }
1034 
1035  p->spec = spec;
1036  p->noun_seen = true;
1037  p->longs_seen = 1;
1038  p->shorts_seen = 1;
1039  p->signed_seen = true;
1040 
1041 }
1042 
1043 /*
1044  * pp_add_initializer() - Record the fact that this symbol has an initializer.
1045  * At present, this is interesting only for array declarators. it lets us
1046  * know if sizeof(array) is meaningful or not. It works a little bit by
1047  * accident. at the point where it is called from the parser, sym doesn't
1048  * yet have a specifier (so sym->type might be NULL), but in that case we
1049  * don't care about recording the initializer anyway. If that ever changes
1050  * the initializer stuff probably ought to be put in the SYMBOL structure
1051  * itself.
1052  * return : void
1053  * sym(in): A pointer to a symbol.
1054  */
1055 void
1057 {
1058  if (sym == NULL)
1059  {
1060  return;
1061  }
1062 
1063  if (sym->type && IS_ARRAY (sym->type))
1064  {
1065  sym->type->decl.d.num_ele = NULL;
1066  }
1067 
1068 }
1069 
1070 /*
1071  * pp_disallow_storage_classes() - Disallow storage class specifiers in
1072  * specifier lists.
1073  * return : void
1074  */
1075 void
1077 {
1078  pp_current_spec_scope->sc_allowed = false;
1079 
1080 }
1081 
1082 /*
1083  * pp_add_cursor_to_scope() - Add the cursor to the current name scope.
1084  * The cursor will be deleted when the scope is exited.
1085  * return : void
1086  * cursor: A pointer to a cursor structure to be added to the current
1087  * name scope.
1088  */
1089 void
1091 {
1092  cursor->next = pp_current_name_scope->cursor_chain;
1093  pp_current_name_scope->cursor_chain = cursor;
1094 
1095 }
1096 
1097 /*
1098  * pp_add_whenever_to_scope() - Establish the action to be taken when the
1099  * specified condition is detected. This condition/action pair remains
1100  * in effect until overridden by another assignment or until the current
1101  * block is exited.
1102  * return : void
1103  * when(in): The condition to be monitored.
1104  * action(in): The action to be taken when the condition is detected.
1105  * name(in): An optional name to be used by the action.
1106  */
1107 void
1109 {
1110  WHENEVER_ACTION *p = &pp_current_name_scope->whenever.cond[when];
1111 
1112  p->action = action;
1113  p->name = name ? strdup (name) : NULL;
1114 
1115  esql_Translate_table.tr_whenever (when, action, p->name);
1116 
1117 }
1118 
1119 /*
1120  * pp_print_link() -
1121  * return:
1122  * p(in) :
1123  * buf(out) :
1124  * context(in) :
1125  * preechoed(in) :
1126  */
1127 static void
1128 pp_print_link (LINK * p, varstring * buf, int context, int preechoed)
1129 {
1130  if (p == NULL)
1131  {
1132  return;
1133  }
1134 
1135  if (p->from_tdef && p->tdef == NULL)
1136  {
1137  vs_prepend (buf, TOK_SPACE);
1138  vs_prepend (buf, (char *) p->from_tdef->name);
1139 
1140  /*
1141  * Now find the terminal specifier in the link chain and extract
1142  * any information about storage class specifiers.
1143  */
1144  while (p->next)
1145  {
1146  p = p->next;
1147  }
1148 
1149  if (preechoed == 0)
1150  {
1151  if (p->decl.s.is_extern)
1152  {
1154  }
1155  if (p->decl.s.is_static)
1156  {
1158  }
1159  if (p->decl.s.is_volatile)
1160  {
1162  }
1163  if (p->decl.s.is_const)
1164  {
1166  }
1167  if (p->decl.s.is_register)
1168  {
1170  }
1171  if (p->decl.s.is_auto)
1172  {
1173  vs_prepend (buf, TOK_AUTO TOK_SPACE);
1174  }
1175  }
1176  }
1177  else if (IS_SPECIFIER (p))
1178  {
1179  switch (p->decl.s.noun)
1180  {
1181  case N_INT:
1182  {
1183  if (p->decl.s.is_unsigned)
1184  {
1186  }
1187  if (p->decl.s.is_long)
1188  {
1189  vs_prepend (buf, TOK_LONG TOK_SPACE);
1190  }
1191  if (p->decl.s.is_short)
1192  {
1194  }
1195  vs_prepend (buf, TOK_INT TOK_SPACE);
1196  }
1197  break;
1198  case N_CHR:
1199  {
1200  if (p->decl.s.is_unsigned)
1201  {
1203  }
1204  vs_prepend (buf, TOK_CHAR TOK_SPACE);
1205  }
1206  break;
1207  case N_VOID:
1208  vs_prepend (buf, TOK_VOID TOK_SPACE);
1209  break;
1210  case N_FLOAT:
1211  vs_prepend (buf, p->decl.s.is_long ? TOK_DOUBLE TOK_SPACE : TOK_FLOAT TOK_SPACE);
1212  break;
1213  case N_VARCHAR:
1214  case N_BIT:
1215  case N_VARBIT:
1216  case N_STRUCTURE:
1217  {
1218  if (p->decl.s.val.v_struct->fields && !p->decl.s.is_by_name)
1219  {
1220  varstring fields, tmp;
1221  SYMBOL *field;
1222 
1223  vs_new (&fields);
1224  vs_new (&tmp);
1225  vs_strcpy (&fields, TOK_LB TOK_SPACE);
1226  for (field = p->decl.s.val.v_struct->fields; field; field = field->next)
1227  {
1228  pp_print_decl (field, &tmp, preechoed);
1229  vs_strcat (&fields, vs_str (&tmp));
1230  vs_strcat (&fields, TOK_SC TOK_SPACE);
1231  }
1232  vs_strcat (&fields, TOK_RB TOK_SPACE);
1233  vs_prepend (buf, vs_str (&fields));
1234  vs_free (&fields);
1235  vs_free (&tmp);
1236  }
1237  /*
1238  * Don't print the tags that we have invented for "anonymous"
1239  * structs. Probably ought to encapsulate this better.
1240  */
1241  if (p->decl.s.val.v_struct->tag && p->decl.s.val.v_struct->tag[0] != '$')
1242  {
1243  vs_prepend (buf, TOK_SPACE);
1244  vs_prepend (buf, (char *) p->decl.s.val.v_struct->tag);
1245  }
1246  vs_prepend (buf, TOK_SPACE);
1247  vs_prepend (buf, (char *) p->decl.s.val.v_struct->type_string);
1248  }
1249  break;
1250  case N_LABEL:
1251  default:
1252  vs_prepend (buf, TOK_INVALID TOK_SPACE);
1253  break;
1254  }
1255 
1256  if (preechoed == 0)
1257  {
1258  if (p->decl.s.is_extern)
1259  {
1261  }
1262  if (p->decl.s.is_static)
1263  {
1265  }
1266  if (p->decl.s.is_volatile)
1267  {
1269  }
1270  if (p->decl.s.is_const)
1271  {
1273  }
1274  if (p->decl.s.is_register)
1275  {
1277  }
1278  if (p->decl.s.is_auto)
1279  {
1280  vs_prepend (buf, TOK_AUTO TOK_SPACE);
1281  }
1282  }
1283  }
1284  else
1285  {
1286  switch (p->decl.d.dcl_type)
1287  {
1288  case D_POINTER:
1289  {
1290  vs_prepend (buf, TOK_STAR);
1291  pp_print_link (p->next, buf, D_POINTER, preechoed);
1292  }
1293  break;
1294  case D_ARRAY:
1295  {
1296  if (context == D_POINTER)
1297  {
1298  vs_prepend (buf, TOK_LP);
1299  vs_append (buf, TOK_RP);
1300  }
1301  vs_sprintf (buf, "[%s]", p->decl.d.num_ele ? p->decl.d.num_ele : "");
1302  pp_print_link (p->next, buf, D_ARRAY, preechoed);
1303  }
1304  break;
1305  case D_FUNCTION:
1306  {
1307  SYMBOL *arg;
1308  varstring tmp;
1309 
1310  /*
1311  * If this is a complex declaration like
1312  *
1313  * int (*f)(int);
1314  *
1315  * then we'll need parens around the inner declarators.
1316  * If not (i.e., the next link is a specifier) we won't
1317  * need anything.
1318  */
1319  if (context == D_POINTER)
1320  {
1321  vs_prepend (buf, TOK_LP);
1322  vs_append (buf, TOK_RP);
1323  }
1324 
1325  vs_append (buf, TOK_LP);
1326  vs_new (&tmp);
1327  for (arg = p->decl.d.args; arg; arg = arg->next)
1328  {
1329  vs_clear (&tmp);
1330  pp_print_decl (arg, &tmp, preechoed);
1331  vs_append (buf, vs_str (&tmp));
1332  if (arg->next)
1333  {
1334  vs_append (buf, TOK_COMMA TOK_SPACE);
1335  }
1336  }
1337  vs_free (&tmp);
1338  vs_append (buf, TOK_RP);
1339  pp_print_link (p->next, buf, D_FUNCTION, preechoed);
1340  }
1341  break;
1342 
1343  default:
1344  vs_prepend (buf, TOK_INVALID);
1345  break;
1346  }
1347  }
1348 }
1349 
1350 
1351 /*
1352  * pp_print_decl() -
1353  * return:
1354  * sym(in) :
1355  * buf(out) :
1356  * preechoed(in) :
1357  */
1358 static void
1359 pp_print_decl (SYMBOL * sym, varstring * buf, int preechoed)
1360 {
1361  vs_clear (buf);
1362  vs_strcpy (buf, (char *) sym->name);
1363  pp_print_link (sym->type, buf, D_ARRAY, preechoed);
1364  if (preechoed == 0)
1365  {
1366  if (sym->type->tdef)
1367  {
1369  }
1370  }
1371 }
1372 
1373 /*
1374  * pp_print_decls() - Print out C text for the declarations represented in
1375  * decl_chain.
1376  * return : void
1377  * decl_chain(in): a list of symbols to be printed.
1378  * preechoed(in): true if called from esql parser, false otherwise.
1379  *
1380  * note : Because we echo most declarations while parsing them, this
1381  * implementation currently concerns itself ONLY with VARCHAR declarations.
1382  * The esql parser sees and echoes storage class specifiers (auto,
1383  * register, static, extern) and type qualifiers (const, volatile) before
1384  * noting the VARCHAR token. therefore we don't want to reprint them and
1385  * preechoed will always be true. If pp_print_decls is called from anywhere
1386  * other than the esql parser (e.g. test programs), preechoed should be
1387  * specified as false.
1388  */
1389 void
1390 pp_print_decls (SYMBOL * decl_chain, int preechoed)
1391 {
1392  varstring buf;
1393 
1394  vs_new (&buf);
1395  for (; decl_chain; decl_chain = decl_chain->next)
1396  {
1397  pp_print_decl (decl_chain, &buf, preechoed);
1398  fputs (vs_str (&buf), esql_yyout);
1399  if (IS_PSEUDO_TYPE (decl_chain->type) && !pp_disable_varchar_length)
1400  {
1401  fputs ((char *) decl_chain->args->name, esql_yyout);
1402  }
1403  fputs (TOK_SC TOK_SPACE, esql_yyout);
1404  }
1405  vs_free (&buf);
1406 }
1407 
1408 /*
1409  * pp_print_specs() -
1410  * return:
1411  * link(in) :
1412  */
1413 void
1415 {
1416  varstring buf;
1417 
1418  vs_new (&buf);
1419  pp_print_link (link, &buf, D_ARRAY, true);
1420  fputs (vs_str (&buf), esql_yyout);
1421  vs_free (&buf);
1422 }
#define IS_ARRAY(p)
Definition: esql_misc.h:52
#define TOK_LB
Definition: esql_declare.c:88
STORAGE_CLASS sclass
#define TOK_INT
Definition: esql_declare.c:100
void *(* add_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:37
SYMBOL * pp_findsym(SYMTAB *symtab, unsigned char *name)
unsigned char is_volatile
int vs_append(varstring *vstr, const char *suffix)
unsigned char is_unsigned
int shorts_seen
Definition: esql_declare.c:53
varstring * vs_new(varstring *vstr)
#define TOK_EXTERN
Definition: esql_declare.c:96
STRUCTDEF * struct_chain
Definition: esql_declare.c:67
STRUCTDEF * v_struct
SYMBOL * pp_new_symbol(const char *name, int scope)
FILE * esql_yyout
#define TOK_RB
Definition: esql_declare.c:89
int longs_seen
Definition: esql_declare.c:52
ESQL_TRANSLATE_TABLE esql_Translate_table
static void pp_print_decl(SYMBOL *sym, varstring *buf, int preechoed)
struct cursor * next
Definition: esql_cli.c:326
SPECIFIER_NOUN noun
#define IS_TYPEDEF(p)
Definition: esql_misc.h:87
SYMTAB * pp_Struct_table
LINK * pp_clone_type(LINK *tchain, LINK **endp)
unsigned char * tag
unsigned char is_extern
#define TOK_STAR
Definition: esql_declare.c:93
STRUCTDEF * next
void pp_decl_init(void)
Definition: esql_declare.c:530
#define TOK_CHAR
Definition: esql_declare.c:97
LINK * pp_current_type_spec(void)
Definition: esql_declare.c:663
#define TOK_LONG
Definition: esql_declare.c:101
void pp_print_syms(FILE *fp)
SYMBOL * args
struct status_field fields[FIELD_LAST+1]
void pp_add_initializer(SYMBOL *sym)
void esql_yyverror(const char *,...)
void pp_add_type_adj(int adj)
Definition: esql_declare.c:857
int vs_prepend(varstring *vstr, const char *prefix)
#define TOK_CONST
Definition: esql_declare.c:95
void pp_do_enum(SYMBOL *sym)
Definition: esql_declare.c:397
const char * pp_get_msg(int msg_set, int msg_num)
unsigned char is_long
void pp_finish_whenever_scope(WHENEVER_SCOPE *scope, WHENEVER_SCOPE *new_scope)
Definition: esql_whenever.c:89
int vs_strcpy(varstring *vstr, const char *str)
int storage_class_seen
Definition: esql_declare.c:55
void pp_print_specs(LINK *link)
int vs_sprintf(varstring *vstr, const char *fmt,...)
const char * pp_type_str(LINK *link)
#define TOK_SC
Definition: esql_declare.c:92
#define TOK_SHORT
Definition: esql_declare.c:103
#define TOK_SPACE
Definition: esql_declare.c:86
static LINK * pp_new_type_spec(void)
Definition: esql_declare.c:185
void pp_print_decls(SYMBOL *decl_chain, int preechoed)
union specifier::@74 val
#define TOK_TYPEDEF
Definition: esql_declare.c:105
void * pp_malloc(int n)
Definition: esql_misc.c:353
#define TOK_LP
Definition: esql_declare.c:90
char * vs_str(varstring *vstr)
void pp_remove_cursors_from_table(CURSOR *chain)
Definition: esql_cursor.c:220
#define TOK_RP
Definition: esql_declare.c:91
int volatile_seen
Definition: esql_declare.c:58
#define IS_SPECIFIER(p)
Definition: esql_misc.h:49
unsigned char is_by_name
int recognizing_typedef_names
Definition: esql_declare.c:65
static SPEC_STATE * pp_current_spec_scope
Definition: esql_declare.c:117
static void pp_remove_structdefs_from_table(STRUCTDEF *struct_chain)
Definition: esql_declare.c:380
void vs_free(varstring *vstr)
#define assert(x)
enum when_action WHEN_ACTION
static SPEC_STATE * pp_spec_scope_base
Definition: esql_declare.c:119
void(* tr_whenever)(WHEN_CONDITION condition, WHEN_ACTION action, const char *name)
#define TOK_INVALID
Definition: esql_declare.c:109
#define IS_PSEUDO_TYPE(p)
Definition: esql_misc.h:76
int signed_seen
Definition: esql_declare.c:54
#define TOK_COMMA
Definition: esql_declare.c:87
static SCOPE * pp_name_scope_base
Definition: esql_declare.c:118
int pp_recognizing_typedef_names
Definition: esql_declare.c:113
int const_seen
Definition: esql_declare.c:59
unsigned char is_const
#define TOK_STATIC
Definition: esql_declare.c:104
void pp_disallow_storage_classes(void)
static SCOPE * pp_name_scope_limit
Definition: esql_declare.c:118
WHEN_ACTION action
Definition: esql_misc.h:101
void pp_decl_finish(void)
Definition: esql_declare.c:555
SYMBOL * sym_chain
Definition: esql_declare.c:66
void pp_make_typedef_names_visible(int sense)
Definition: esql_declare.c:515
#define TOK_VOID
Definition: esql_declare.c:107
#define TOK_AUTO
Definition: esql_declare.c:94
void pp_discard_link(LINK *p)
void(* remove_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:40
#define NULL
Definition: freelistheap.h:34
unsigned char is_short
void pp_push_spec_scope(void)
Definition: esql_declare.c:577
#define MAX_LONGS_ALLOWED
Definition: esql_declare.c:39
#define IS_VAR_TYPE(p)
Definition: esql_misc.h:80
void pp_reset_current_type_spec(void)
Definition: esql_declare.c:639
LINK * spec
Definition: esql_declare.c:60
void pp_add_whenever_to_scope(WHEN_CONDITION when, WHEN_ACTION action, char *name)
unsigned char is_register
storage_class
void vs_clear(varstring *vstr)
void pp_discard_cursor_chain(CURSOR *chain)
Definition: esql_cursor.c:239
void pp_discard_link_chain(LINK *p)
void pp_discard_structdef(STRUCTDEF *sdef)
enum when_condition WHEN_CONDITION
#define TOK_UNSIGNED
Definition: esql_declare.c:106
unsigned char is_auto
void pp_print_cursors(FILE *fp)
Definition: esql_cursor.c:199
LINK * pp_new_link(void)
static SCOPE * pp_current_name_scope
Definition: esql_declare.c:116
CURSOR * cursor_chain
Definition: esql_declare.c:68
#define TOK_REGISTER
Definition: esql_declare.c:102
void pp_discard_symbol(SYMBOL *sym)
static void pp_set_class_bit(int storage_class, LINK *p)
Definition: esql_declare.c:137
int typedef_seen
Definition: esql_declare.c:56
void pp_add_spec_to_decl(LINK *p_spec, SYMBOL *decl_chain)
Definition: esql_declare.c:213
void pp_add_typedefed_spec(LINK *spec)
Definition: esql_declare.c:995
unsigned char is_static
void pp_add_struct_spec(STRUCTDEF *sdef)
Definition: esql_declare.c:707
STRUCTDEF * pp_new_pseudo_def(SPECIFIER_NOUN type, const char *subscript)
int vs_strcat(varstring *vstr, const char *str)
#define TOK_FLOAT
Definition: esql_declare.c:99
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define TOK_VOLATILE
Definition: esql_declare.c:108
#define TOK_DOUBLE
Definition: esql_declare.c:98
void pp_add_cursor_to_scope(CURSOR *cursor)
#define NFRAMES
Definition: esql_declare.c:38
void pp_push_name_scope(void)
Definition: esql_declare.c:418
void pp_add_type_noun(int type)
Definition: esql_declare.c:754
void pp_pop_spec_scope(void)
Definition: esql_declare.c:626
SYMBOL * next
void pp_init_whenever_scope(WHENEVER_SCOPE *scope, WHENEVER_SCOPE *old_scope)
Definition: esql_whenever.c:67
SYMTAB * pp_Symbol_table
void pp_add_storage_class(int sc)
Definition: esql_declare.c:677
char * strdup(const char *str)
Definition: porting.c:901
unsigned char * name
void esql_yyredef(char *)
static void pp_print_link(LINK *p, varstring *buf, int context, int preechoed)
WHENEVER_ACTION cond[3]
Definition: esql_misc.h:107
int pp_the_same_type(LINK *p1, LINK *p2, int relax)
int pp_dump_scope_info
void pp_pop_name_scope(void)
Definition: esql_declare.c:465
int sc_allowed
Definition: esql_declare.c:57
static SPEC_STATE * pp_spec_scope_limit
Definition: esql_declare.c:119
void pp_add_symbols_to_table(SYMBOL *sym)
Definition: esql_declare.c:304
int pp_disable_varchar_length
int pp_nesting_level
Definition: esql_declare.c:114
void pp_discard_structdef_chain(STRUCTDEF *sdef)
WHENEVER_SCOPE whenever
Definition: esql_declare.c:69
void pp_discard_symbol_chain(SYMBOL *sym)
const char ** p
Definition: dynamic_load.c:945
void pp_remove_symbols_from_table(SYMBOL *sym_chain)
Definition: esql_declare.c:361
const unsigned char * type_string