CUBRID Engine  latest
esql_host_variable.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_host_variable.c - Routines for preparing statements
22  * with the esql parser.
23  */
24 
25 #ident "$Id$"
26 
27 #include "config.h"
28 
29 #include <assert.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 
33 #include "esql_grammar.h"
34 #include "esql_scanner_support.h"
35 #include "util_func.h"
36 #include "misc_string.h"
37 #include "esql_misc.h"
38 #include "memory_alloc.h"
39 
40 #define BAD_C_TYPE ((C_TYPE) -1)
41 #define UNINIT_C_TYPE ((C_TYPE) -2)
42 #define C_TYPE_STRUCT ((C_TYPE) -3)
43 #define UNINITIALIZED(p) ((p) == UNINIT_C_TYPE)
44 
45 
48 {
49  const char *name;
52  /* True if the an object of this type must be reached through a pointer */
53  bool mode;
54 };
55 
57  /* These are esql-specific types that the preprocessor needs to know about to do its job. */
58  {
59  "CUBRIDDA", NULL, C_TYPE_SQLDA, true},
60  /* These are CSQL types that programmers need to use, and so the preprocessor also needs to know about them. */
61  {
62  "DB_VALUE", NULL, C_TYPE_DB_VALUE, false},
63  {
64  "DB_OBJECT", NULL, C_TYPE_OBJECTID, true},
65  {
66  "DB_DATE", NULL, C_TYPE_DATE, false},
67  {
68  "DB_TIME", NULL, C_TYPE_TIME, false},
69  {
70  "DB_UTIME", NULL, C_TYPE_TIMESTAMP, false},
71  {
72  "DB_TIMESTAMP", NULL, C_TYPE_TIMESTAMP, false},
73  {
74  "DB_MONETARY", NULL, C_TYPE_MONETARY, false},
75  {
76  "DB_SET", NULL, C_TYPE_BASICSET, true},
77  {
78  "DB_MULTISET", NULL, C_TYPE_MULTISET, true},
79  {
80  "DB_SEQ", NULL, C_TYPE_SEQUENCE, true},
81  {
82  "DB_COLLECTION", NULL, C_TYPE_COLLECTION, true}
83 };
84 
85 /*
86  * This keeps track of whether we're gathering input or output host vars
87  * by pointing at either input_refs or output_refs. This is convenient
88  * when it's necessary to update pp_host_refs, since it allows us to
89  * easily update whichever of input_refs or output_refs is supposed to be
90  * in sync with pp_host_refs.
91  */
93 
98 
99 static HOST_REF *pp_add_struct_field_refs (HOST_VAR * var, int *n_refs);
100 static C_TYPE pp_check (HOST_VAR * var, bool structs_allowed);
101 static C_TYPE pp_check_builtin_type (LINK * type, bool mode);
102 static char *pp_expr (HOST_VAR * var);
103 static char *pp_addr_expr (HOST_VAR * var);
104 static SYMBOL *pp_find_field (STRUCTDEF * sdef, const char *field);
105 static void pp_add_dummy_structdef (SYMBOL ** symp, const char *name);
106 
107 /*
108  * pp_gather_input_refs() -
109  * return:
110  */
111 void
113 {
114  /* Don't do anything if we're already gathering input refs. */
115  if (pp_gathering == &output_refs)
116  {
118  pp_host_refs = input_refs;
119  pp_gathering = &input_refs;
120  }
121 }
122 
123 /*
124  * pp_gather_output_refs() -
125  * return:
126  */
127 void
129 {
130  /* Don't do anything if we're already gathering output refs. */
131  if (pp_gathering == &input_refs)
132  {
134  pp_host_refs = output_refs;
135  pp_gathering = &output_refs;
136  }
137 }
138 
139 /*
140  * pp_input_refs() -
141  * return:
142  */
143 HOST_LOD *
145 {
146  return input_refs;
147 }
148 
149 /*
150  * pp_output_refs() -
151  * return:
152  */
153 HOST_LOD *
155 {
156  return output_refs;
157 }
158 
159 
160 /*
161  * pp_clear_host_refs() - Clears all HOST_LOD structures that have been
162  * allocated since the last call to pp_clear_host_refs(), placing them
163  * on the host_lod_free_list.
164  * return : void
165  */
166 void
168 {
169  if (host_lod_chain != NULL)
170  {
171  HOST_LOD *chain, *next;
172 
173  /*
174  * Run down the chain of allocated HOST_LOD structures, clearing
175  * them as we go but leaving the 'next' fields intact. When we
176  * reach the end, just tack the chain on the the free list, point
177  * the free list to the head of the chain, and be off.
178  */
179  next = host_lod_chain;
180  do
181  {
182  chain = next;
183  pp_clear_host_lod (chain);
184  next = chain->next;
185  }
186  while (next);
187 
188  chain->next = host_lod_free_list;
189  host_lod_free_list = host_lod_chain;
190  host_lod_chain = NULL;
191  }
192 
193  input_refs = NULL;
194  output_refs = NULL;
195  pp_host_refs = NULL;
196  pp_gathering = &input_refs;
197 }
198 
199 /*
200  * pp_new_host_var() - Return a new host variable structure initialized
201  * with the given type. Allocate a new HOST_VAR if var is NULL.
202  * return : HOST_VAR *
203  * var(in): A pointer to a host_var to be initialized, or NULL.
204  * sym(in): The root symbol of the host variable reference.
205  */
206 HOST_VAR *
208 {
209  if (var == NULL)
210  {
211  var = (HOST_VAR *) malloc (sizeof (HOST_VAR));
212  if (var == NULL)
213  {
214  return NULL;
215  }
216  var->heap_allocated = 1;
217  }
218  else
219  {
220  var->heap_allocated = 0;
221  }
222 
223  var->type = pp_clone_type (sym->type, &var->etype);
224  vs_new (&var->expr);
225  vs_strcat (&var->expr, (char *) sym->name);
226  vs_new (&var->addr_expr);
227 
228  return var;
229 }
230 
231 /*
232  * pp_free_host_var() - Free the host var (if heap allocated) and all of its
233  * internal variables.
234  * return : void
235  * var(in): The host variable reference to be freed.
236  */
237 void
239 {
240  if (var == NULL)
241  {
242  return;
243  }
244 
245  if (var->type)
246  {
248  }
249  vs_free (&var->expr);
250  vs_free (&var->addr_expr);
251 
252  if (var->heap_allocated)
253  {
254  free_and_init (var);
255  }
256 
257 }
258 
259 /*
260  * pp_add_host_ref() - Add the var/indicator pair to the interface table for
261  * the translator.
262  * return : a pointer to the HOST_REF if everything is ok, NULL otherwise.
263  * var(in): The host variable proper.
264  * indicator(in): An optional indicator variable.
265  * structs_allowed(in): true if structures are permitted as host vars.
266  * n_refs(out): A pointer to an integer to be updated with the number
267  * of references actually added.
268  * note : If structures are allowed, they are expanded. that is, adding
269  * a ref to a structure is equivalent to adding refs to each of its
270  * components in the order in which they were declared.
271  */
272 HOST_REF *
273 pp_add_host_ref (HOST_VAR * var, HOST_VAR * indicator, bool structs_allowed, int *n_refs)
274 {
275  HOST_REF *ref;
276  C_TYPE uci_type;
277 
278  if (n_refs != NULL)
279  {
280  *n_refs = 0;
281  }
282 
283  if (var == NULL)
284  {
285  goto bad_news;
286  }
287 
288  if (indicator != NULL && (!(IS_INT (indicator->type) && !IS_LONG (indicator->type))))
289  {
291  goto bad_news;
292  }
293 
294  uci_type = pp_check (var, structs_allowed);
295  if (uci_type == BAD_C_TYPE)
296  {
297  goto bad_news;
298  }
299 
300  if (uci_type == C_TYPE_STRUCT)
301  {
302  if (indicator)
303  {
305  goto bad_news;
306  }
307 
308  return pp_add_struct_field_refs (var, n_refs);
309  }
310 
311  if (pp_host_refs == NULL)
312  {
313  pp_host_refs = pp_new_host_lod ();
314  if (pp_host_refs == NULL)
315  {
316  goto bad_news;
317  }
318 
319  *pp_gathering = pp_host_refs;
320  }
321 
322  if (pp_host_refs->n_refs >= pp_host_refs->max_refs)
323  {
324  HOST_REF *new_refs = (HOST_REF *) pp_malloc ((pp_host_refs->max_refs + 4) * sizeof (HOST_REF));
325  memset (new_refs, 0, (pp_host_refs->max_refs + 4) * sizeof (HOST_REF));
326  if (pp_host_refs->real_refs != NULL)
327  {
328  memcpy ((char *) new_refs, (char *) pp_host_refs->real_refs,
329  (size_t) sizeof (HOST_REF) * (size_t) pp_host_refs->max_refs);
330  free_and_init (pp_host_refs->real_refs);
331  }
332  pp_host_refs->max_refs += 4;
333  pp_host_refs->real_refs = new_refs;
334  }
335 
336  pp_host_refs->refs = pp_host_refs->real_refs;
337 
338  ref = &pp_host_refs->refs[pp_host_refs->n_refs++];
339  pp_host_refs->n_real_refs++;
340 
341  ref->var = var;
342  ref->ind = indicator;
343  ref->uci_type = uci_type;
344  ref->precision_buf = NULL;
345  ref->input_size_buf = NULL;
346  ref->output_size_buf = NULL;
347  ref->expr_buf = NULL;
348  ref->addr_expr_buf = NULL;
349  ref->ind_expr_buf = NULL;
350  ref->ind_addr_expr_buf = NULL;
351 
352  if (n_refs != NULL)
353  {
354  (*n_refs)++;
355  }
356 
357  return ref;
358 
359 bad_news:
360  if (var != NULL)
361  {
362  pp_free_host_var (var);
363  }
364  if (indicator != NULL)
365  {
366  pp_free_host_var (indicator);
367  }
368  return NULL;
369 }
370 
371 /*
372  * pp_add_struct_field_refs() - Add a host ref for each of the fields in
373  * the structure definition, using prefix as the root.
374  * Set *n_refs to 0 or the number of fields added.
375  * return : NULL if any of the fields causes a problem, a pointer to the last
376  * field otherwise
377  * var: A pointer to a HOST_VAR that is known to represent a struct.
378  * n_refs(out) : A pointer to an integer to be updated with the number of
379  * references actually added.
380  */
381 static HOST_REF *
382 pp_add_struct_field_refs (HOST_VAR * var, int *n_refs)
383 {
384  const char *prefix = vs_str (&var->expr);
385  SYMBOL *field = var->type->decl.s.val.v_struct->fields;
386  SYMBOL *next = field;
387  int errors = 0;
388  HOST_REF *result = NULL;
389 
390  if (field == NULL)
391  {
393  pp_free_host_var (var);
394  return NULL;
395  }
396 
397  for (; field; field = next)
398  {
399  HOST_VAR *var;
400 
401  /* Make a new host ref from this field, and then add it as a host variable. */
402  var = pp_new_host_var (NULL, field);
403  vs_prepend (&var->expr, ").");
404  vs_prepend (&var->expr, prefix);
405  vs_prepend (&var->expr, "(");
406  result = pp_add_host_ref (var, NULL, false, NULL);
407  if (result == NULL)
408  {
409  errors++;
410  }
411  if (n_refs != NULL)
412  {
413  (*n_refs)++;
414  }
415 
416  next = field->next;
417  }
418 
419  if (errors > 0)
420  {
421  if (n_refs)
422  {
423  *n_refs = 0;
424  }
425  result = NULL;
426  }
427 
428  /*
429  * We want to free the incoming host var regardless of whether there
430  * were errors or not. If there were errors, it is obviously
431  * unneeded. If there were no errors, it is still unneeded because
432  * only (host vars derived from) its components have been used.
433  */
434  pp_free_host_var (var);
435 
436  /*
437  * This choice of return value is kind of arbitrary: the important
438  * thing is to return some non-NULL pointer so that upper levels
439  * won't be deceived into believing that an error occurred.
440  */
441  return result;
442 }
443 
444 /*
445  * pp_free_host_ref() - This function doesn't actually free the storage
446  * occupied by *ref, since it assumes that the ref is actually in
447  * the pp_host_refs array.
448  * return : void
449  * ref(in): The host reference to be freed.
450  */
451 void
453 {
454  pp_free_host_var (ref->var);
455  pp_free_host_var (ref->ind);
456 
457  vs_free (ref->precision_buf);
458  vs_free (ref->input_size_buf);
459  vs_free (ref->output_size_buf);
460  vs_free (ref->expr_buf);
461  vs_free (ref->addr_expr_buf);
462  vs_free (ref->ind_expr_buf);
463  vs_free (ref->ind_addr_expr_buf);
464 }
465 
466 /*
467  * pp_copy_host_refs() - Return the current state of pp_host_refs to the
468  * caller. The recipient of the the returned HOST_LOD no longer needs
469  * to worry about freeing it. That will happen automatically the next
470  * time pp_clear_host_refs() is called.
471  * return : HOST_LOD *. Also clears pp_host_refs.
472  */
473 HOST_LOD *
475 {
476  HOST_LOD *lod = pp_host_refs;
477 
478  *pp_gathering = pp_host_refs = NULL;
479 
480  return lod;
481 }
482 
483 /*
484  * pp_detach_host_refs() - Copy the current host refs, and detach it from
485  * the chain of HOST_LODs that will be cleared at the end of compiling
486  * the current statement. This means that the recipient of the pointer
487  * assumes responsibility for freeing the structure.
488  * return : HOST_LOD *
489  *
490  * note : the recipient of the pointer assumes responsibility for freeing
491  * the structure.
492  */
493 HOST_LOD *
495 {
496  HOST_LOD *refs = pp_copy_host_refs ();
498 
499  while (*link)
500  {
501  if (*link == refs)
502  {
503  *link = refs->next;
504  refs->next = NULL;
505  return refs;
506  }
507  link = &((*link)->next);
508  }
509 
510  return NULL;
511 }
512 
513 /*
514  * pp_add_host_str() - Allocate a host variable, assign the string as its name,
515  * and give it the special C_TYPE of C_TYPE_STRING_CONST.
516  * return : pointer to the HOST_REF if everything is ok, NULL otherwise.
517  * str(in) : An CSQL string to be treated as a constant.
518  */
519 HOST_REF *
520 pp_add_host_str (char *str)
521 {
522  HOST_VAR *hv;
523  HOST_REF *hr;
524  varstring *vstr;
525 
526  hv = pp_new_host_var (NULL, string_dummy);
527  vstr = &hv->expr;
528  vs_clear (vstr);
529 
530  pp_translate_string (vstr, str, false);
531 
532  hr = pp_add_host_ref (hv, NULL, false, NULL);
533  if (hr != NULL)
534  {
536  }
537 
538  return hr;
539 }
540 
541 /*
542  * pp_check_type() - Check ref to make sure that its type is one of those
543  * encoded in typeset.
544  * return : If the ref's type is one of those encoded in typeset,
545  * return the ref. NULL otherwise.
546  * ref(in): A pointer to a host reference variable.
547  * typeset(in): A set of acceptable C_TYPE codes.
548  * msg(in): A message fragment to be used if the type is not acceptable.
549  *
550  * nore : This assumes that all types can be encoded in the number of bits
551  * provided by a BITSET.
552  */
553 HOST_REF *
554 pp_check_type (HOST_REF * ref, BITSET typeset, const char *msg)
555 {
556  C_TYPE type;
557 
558  if (ref == NULL)
559  {
560  return NULL;
561  }
562 
563  type = pp_get_type (ref);
564  if (MEMBER (typeset, type))
565  {
566  return ref;
567  }
568  else
569  {
570  /*
571  * Copy the silly message; it's probably also coming straight out
572  * of the message catalog stuff, and it will get clobbered by our
573  * intervening call to pp_get_msg().
574  */
575  char *msg_copy;
576  msg_copy = pp_strdup (msg);
578  free_and_init (msg_copy);
579  return NULL;
580  }
581 }
582 
583 /*
584  * pp_check_host_var_list() - Check that all members of pp_host_refs have types
585  * acceptable as db parameters.
586  * return : void
587  */
588 void
590 {
591  int i;
592 
593  if (pp_host_refs == NULL)
594  {
595  return;
596  }
597 
598  for (i = 0; i < pp_host_refs->n_refs; ++i)
599  {
600  if (pp_get_type (&pp_host_refs->refs[i]) >= NUM_C_VARIABLE_TYPES)
601  {
603  pp_type_str (pp_host_refs->refs[i].var->type), pp_get_expr (&pp_host_refs->refs[i]));
604  }
605  }
606 }
607 
608 /*
609  * pp_get_type() - Return the CUBRID C_TYPE described by ref's type LINK.
610  * return : C_TYPE
611  * ref(in) : A pointer to a host variable reference.
612  */
613 C_TYPE
615 {
616  assert (ref != NULL);
617 
618  if (UNINITIALIZED (ref->uci_type))
619  {
620  ref->uci_type = pp_check (ref->var, 1 /* structs allowed */ );
621  }
622 
623  return ref->uci_type;
624 
625 }
626 
627 /*
628  * pp_get_precision() - Return a C expression that will (when evaluated) yield
629  * the nominal precision (in type appropriate units) of the variable
630  * described by the reference.
631  * return : size_t
632  * ref(in): A pointer to a host variable reference.
633  */
634 char *
636 {
637  assert (ref != NULL);
638  assert (ref->var != NULL);
639 
640  if (ref->precision_buf == NULL)
641  {
642  ref->precision_buf = vs_new (NULL);
643 
644  switch (ref->uci_type)
645  {
646  case C_TYPE_SHORT:
647  case C_TYPE_INTEGER:
648  case C_TYPE_LONG:
649  case C_TYPE_FLOAT:
650  case C_TYPE_DOUBLE:
651  case C_TYPE_TIME:
652  case C_TYPE_TIMESTAMP:
653  case C_TYPE_DATE:
654  case C_TYPE_MONETARY:
655  case C_TYPE_DB_VALUE:
656  case C_TYPE_BASICSET:
657  case C_TYPE_MULTISET:
658  case C_TYPE_SEQUENCE:
659  case C_TYPE_COLLECTION:
660  case C_TYPE_OBJECTID:
661  /* Precision is meaningless */
662  vs_strcpy (ref->precision_buf, "0");
663  break;
664 
665  case C_TYPE_CHAR_POINTER:
666  /*
667  * In this case, this means that we will determine the precision
668  * at runtime by calling strlen(). We could probably emit the
669  * strlen() code here, but it's less expensive in terms of code
670  * space to interpret it at runtime.
671  */
672  vs_strcpy (ref->precision_buf, "0");
673  break;
674 
675  case C_TYPE_CHAR_ARRAY:
676  vs_sprintf (ref->precision_buf, "sizeof(%s)-1", pp_get_expr (ref));
677  break;
678 
679  case C_TYPE_VARCHAR:
680  vs_sprintf (ref->precision_buf, "sizeof((%s).%s)-1", pp_get_expr (ref), VARCHAR_ARRAY_NAME);
681  break;
682 
683  case C_TYPE_VARBIT:
684  case C_TYPE_BIT:
685  vs_sprintf (ref->precision_buf, "(%s).%s", pp_get_expr (ref), VARCHAR_LENGTH_NAME);
686  break;
687 
688  case C_TYPE_STRING_CONST:
689  vs_sprintf (ref->precision_buf, "sizeof(%s)-1", pp_get_expr (ref));
690  break;
691 
692  default:
693  {
695  vs_strcpy (ref->precision_buf, "0");
696  }
697  break;
698  }
699  }
700 
701  return vs_str (ref->precision_buf);
702 }
703 
704 /*
705  * pp_get_input_size() - Return a C expression that will (when evaluated)
706  * yield the nominal size (in size_t units) of the variable described by
707  * the reference (when that variable is used as an input variable).
708  * return : input size of variable.
709  * ref(in): A pointer to a host variable reference.
710  */
711 char *
713 {
714  const char *size_str = NULL;
715 
716  assert (ref != NULL);
717  assert (ref->var != NULL);
718 
719  if (ref->input_size_buf == NULL)
720  {
721  ref->input_size_buf = vs_new (NULL);
722 
723  switch (ref->uci_type)
724  {
725  case C_TYPE_SHORT:
726  size_str = "sizeof(short)";
727  break;
728  case C_TYPE_INTEGER:
729  size_str = "sizeof(int)";
730  break;
731  case C_TYPE_LONG:
732  size_str = "sizeof(long)";
733  break;
734  case C_TYPE_FLOAT:
735  size_str = "sizeof(float)";
736  break;
737  case C_TYPE_DOUBLE:
738  size_str = "sizeof(double)";
739  break;
740  case C_TYPE_TIME:
741  size_str = "sizeof(DB_TIME)";
742  break;
743  case C_TYPE_TIMESTAMP:
744  size_str = "sizeof(DB_TIMESTAMP)";
745  break;
746  case C_TYPE_DATE:
747  size_str = "sizeof(DB_DATE)";
748  break;
749  case C_TYPE_MONETARY:
750  size_str = "sizeof(DB_MONETARY)";
751  break;
752  case C_TYPE_DB_VALUE:
753  size_str = "sizeof(DB_VALUE)";
754  break;
755  case C_TYPE_BASICSET:
756  size_str = "sizeof(DB_SET *)";
757  break;
758  case C_TYPE_MULTISET:
759  size_str = "sizeof(DB_MULTISET *)";
760  break;
761  case C_TYPE_SEQUENCE:
762  size_str = "sizeof(DB_SEQ *)";
763  break;
764  case C_TYPE_COLLECTION:
765  size_str = "sizeof(DB_COLLECTION *)";
766  break;
767  case C_TYPE_OBJECTID:
768  size_str = "sizeof(DB_OBJECT *)";
769  break;
770 
771  case C_TYPE_CHAR_ARRAY:
772  case C_TYPE_STRING_CONST:
773  vs_sprintf (ref->input_size_buf, "sizeof(%s)", pp_get_expr (ref));
774  break;
775 
776  case C_TYPE_VARCHAR:
777  case C_TYPE_VARBIT:
778  case C_TYPE_BIT:
779  vs_sprintf (ref->input_size_buf, "(%s).%s", pp_get_expr (ref), VARCHAR_LENGTH_NAME);
780  break;
781 
782  case C_TYPE_CHAR_POINTER:
783  vs_sprintf (ref->input_size_buf, "strlen(%s)", pp_get_expr (ref));
784  break;
785 
786  default:
787  {
789  size_str = "0";
790  }
791  break;
792  }
793 
794  if (size_str != NULL)
795  {
796  vs_strcpy (ref->input_size_buf, size_str);
797  }
798  }
799 
800  return vs_str (ref->input_size_buf);
801 }
802 
803 /*
804  * pp_get_output_size() - Return a C expression that will (when evaluated)
805  * yield the nominal size (in size_t units) of the variable described by
806  * the reference (when that variable is used as an output variable).
807  * return : output size of variable
808  * ref(in): A pointer to a host variable reference.
809  */
810 char *
812 {
813  char *size_str = NULL;
814 
815  assert (ref != NULL);
816  assert (ref->var != NULL);
817 
818  if (ref->uci_type == C_TYPE_CHAR_POINTER)
819  {
820  if (ref->output_size_buf == NULL)
821  {
822  ref->output_size_buf = vs_new (NULL);
823  vs_sprintf (ref->output_size_buf, "strlen(%s)+1", pp_get_expr (ref));
824  }
825  size_str = vs_str (ref->output_size_buf);
826  }
827  else if (ref->uci_type == C_TYPE_VARCHAR || ref->uci_type == C_TYPE_VARBIT || ref->uci_type == C_TYPE_BIT)
828  {
829  if (ref->output_size_buf == NULL)
830  {
831  ref->output_size_buf = vs_new (NULL);
832  vs_sprintf (ref->output_size_buf, "sizeof(%s.%s)", pp_get_expr (ref), VARCHAR_ARRAY_NAME);
833  }
834  size_str = vs_str (ref->output_size_buf);
835  }
836  else
837  {
838  size_str = pp_get_input_size (ref);
839  }
840 
841  return size_str;
842 }
843 
844 
845 /*
846  * pp_get_expr() - Return a string of C text that can be used in an rvalue
847  * context in emitted codes.
848  * return : rvalue string of variable.
849  * ref: The given host reference.
850  */
851 char *
853 {
854  if (ref == NULL)
855  {
856  return NULL;
857  }
858 
859  if (ref->expr_buf == NULL)
860  {
861  ref->expr_buf = vs_new (NULL);
862  vs_strcpy (ref->expr_buf, pp_expr (ref->var));
863  }
864 
865  return vs_str (ref->expr_buf);
866 }
867 
868 /*
869  * pp_get_addr_expr() - Return an rvalue expression for the location identified
870  * by the given host variable. For most variables this is simply
871  * &var, i.e., the address of the storage of the variable. For string
872  * variables, however, this is the address of the string bytes themselves,
873  * i.e., the *value* of the variable.
874  * return : rvalue expression.
875  * ref(in): The given host reference.
876  */
877 char *
879 {
880  if (ref == NULL)
881  {
882  return NULL;
883  }
884 
885  if (ref->addr_expr_buf == NULL)
886  {
887  ref->addr_expr_buf = vs_new (NULL);
888  vs_strcpy (ref->addr_expr_buf, pp_addr_expr (ref->var));
889  }
890 
891  return vs_str (ref->addr_expr_buf);
892 }
893 
894 /*
895  * pp_get_ind_expr() - Return a C expression for the indicator variable
896  * associated with the given host variable, or NULL if there is none.
897  * returns/side-effects: C expression.
898  * ref(in): The given host variable reference.
899  */
900 char *
902 {
903  if (ref == NULL || ref->ind == NULL)
904  {
905  return NULL;
906  }
907 
908  if (ref->ind_expr_buf == NULL)
909  {
910  ref->ind_expr_buf = vs_new (NULL);
911  vs_strcpy (ref->ind_expr_buf, pp_expr (ref->ind));
912  }
913 
914  return vs_str (ref->ind_expr_buf);
915 }
916 
917 /*
918  * pp_get_ind_addr_expr() - Return a C expression giving the address of the
919  * indicator variable associated with the give host variable, or NULL if
920  * there is none.
921  * return : C expression
922  * ref(in): The given host variable reference.
923  */
924 char *
926 {
927  if (ref == NULL)
928  {
929  return NULL;
930  }
931 
932  if (ref->ind == NULL)
933  {
934  if (pp_internal_ind)
935  {
936  return (char *) "&uci_null_ind";
937  }
938  else
939  {
940  return (char *) "NULL";
941  }
942  }
943 
944  if (ref->ind_addr_expr_buf == NULL)
945  {
946  ref->ind_addr_expr_buf = vs_new (NULL);
948  }
949 
950  return vs_str (ref->ind_addr_expr_buf);
951 
952 }
953 
954 /*
955  * pp_print_host_ref() -
956  * return : void
957  * ref(in): The host reference to be printed.
958  * fp(in): The stream to print it on.
959  */
960 void
961 pp_print_host_ref (HOST_REF * ref, FILE * fp)
962 {
963  char *p;
964 
965  if (ref->var)
966  {
967  fputs (pp_get_expr (ref), fp);
968  p = pp_get_ind_expr (ref);
969  if (p != NULL)
970  {
971  fputs (":", fp);
972  fputs (p, fp);
973  }
974  fprintf (fp, " (%s)", pp_get_input_size (ref));
975  }
976 }
977 
978 /*
979  * pp_check() - Make sure that 'var' has an acceptable type for a host
980  * variable.
981  * return : The esql type code for the type, or -1 if the type is not
982  * permitted.
983  * var(in): A variable whose type should be checked.
984  * structs_allowed(in): true if structures are permitted.
985  */
986 static C_TYPE
987 pp_check (HOST_VAR * var, bool structs_allowed)
988 {
989  LINK *type;
990  C_TYPE c_type;
991 
992  if (var == NULL)
993  {
994  return BAD_C_TYPE;
995  }
996 
997  type = var->type;
998 
999  if (IS_SPECIFIER (type))
1000  {
1001  switch (type->decl.s.noun)
1002  {
1003  case N_CHR:
1004  break;
1005 
1006  case N_INT:
1007  if (type->decl.s.is_unsigned)
1008  {
1009  break;
1010  }
1011  else
1012  {
1013  return type->decl.s.is_long ? C_TYPE_LONG : type->decl.s.is_short ? C_TYPE_SHORT : C_TYPE_INTEGER;
1014  }
1015 
1016  case N_FLOAT:
1017  return type->decl.s.is_long ? C_TYPE_DOUBLE : C_TYPE_FLOAT;
1018 
1019  case N_STRUCTURE:
1020  {
1021  if (!var->type->decl.s.val.v_struct->type) /* It's really a union */
1022  {
1023  break;
1024  }
1025  c_type = pp_check_builtin_type (var->type, false);
1026  if (c_type != BAD_C_TYPE)
1027  {
1028  return c_type;
1029  }
1030  else if (structs_allowed)
1031  {
1032  return C_TYPE_STRUCT;
1033  }
1034  }
1035  break;
1036 
1037  case N_VARCHAR:
1038  return C_TYPE_VARCHAR;
1039  break;
1040 
1041  case N_BIT:
1042  return C_TYPE_BIT;
1043 
1044  case N_VARBIT:
1045  return C_TYPE_VARBIT;
1046 
1047  default:
1048  break;
1049  }
1050  }
1051  else
1052  {
1053  /* IS_DECLARATOR(type) */
1054  if (IS_POINTER (type))
1055  {
1056  if (IS_CHAR (type->next))
1057  {
1058  return C_TYPE_CHAR_POINTER;
1059  }
1060  c_type = pp_check_builtin_type (type->next, true);
1061  if (c_type != BAD_C_TYPE)
1062  {
1063  return c_type;
1064  }
1065  }
1066  else if (IS_ARRAY (type))
1067  {
1068  if (IS_CHAR (type->next))
1069  {
1070  return C_TYPE_CHAR_ARRAY;
1071  }
1072  }
1073  }
1074 
1076  return BAD_C_TYPE;
1077 }
1078 
1079 /*
1080  * pp_check_builtin_type() - Check the type to see whether it corresponds
1081  * to some builtin type.
1082  * return : The C_TYPE corresponding to type or BAD_C_TYPE.
1083  * type(in): A pointer to a host var known to be a struct of some sort.
1084  * mode(in): True if the structure has been reached through a pointer.
1085  */
1086 static C_TYPE
1088 {
1089  unsigned int i;
1090 
1091  for (i = 0; i < DIM (builtin_types); ++i)
1092  {
1093  if (pp_the_same_type (type, builtin_types[i].sym->type, 1) && mode == builtin_types[i].mode)
1094  {
1095  return builtin_types[i].c_type;
1096  }
1097  }
1098 
1099  return BAD_C_TYPE;
1100 }
1101 
1102 /*
1103  * pp_expr() - Return the text expression that denotes the host variable.
1104  * return : the text expression
1105  * var(in): A host variable.
1106  */
1107 static char *
1109 {
1110  return vs_str (&var->expr);
1111 }
1112 
1113 /*
1114  * pp_addr_expr() - Return a C expression for the location identified by the
1115  * given host variable. For most variables this is simply &var, i.e.,
1116  * the address of the storage of the variable. For string variables,
1117  * however, this is the address of the string bytes themselves.
1118  * return : C expression.
1119  * var(in): A host variable.
1120  */
1121 static char *
1123 {
1124  char *result;
1125 
1126  if (var == NULL)
1127  {
1129  result = (char *) "NULL";
1130  }
1131  else if (IS_PTR_TYPE (var->type) && IS_CHAR (var->type->next))
1132  {
1133  result = pp_expr (var);
1134  }
1135  else
1136  {
1137  vs_clear (&var->addr_expr);
1138  if (IS_PSEUDO_TYPE (var->type))
1139  {
1140  vs_sprintf (&var->addr_expr, "(%s).%s", pp_expr (var), VARCHAR_ARRAY_NAME);
1141  }
1142  else
1143  {
1144  vs_sprintf (&var->addr_expr, "&(%s)", pp_expr (var));
1145  }
1146  result = vs_str (&var->addr_expr);
1147  }
1148 
1149  return result;
1150 }
1151 
1152 /*
1153  * pp_ptr_deref() - Change the value of var->type to the new type obtained by
1154  * dereferencing the existing type.
1155  * return : The incoming host_var.
1156  * var(in): A host variable to be deref'ed.
1157  * style(in): 0 if through '*', 1 if through '[expr]'.
1158  */
1159 HOST_VAR *
1160 pp_ptr_deref (HOST_VAR * var, int style)
1161 {
1162  LINK *result_type;
1163 
1164  if (var == NULL)
1165  {
1166  return NULL;
1167  }
1168 
1169  if (!IS_PTR_TYPE (var->type))
1170  {
1171  esql_yyverror (pp_get_msg (EX_HOSTVAR_SET, MSG_DEREF_NOT_ALLOWED), vs_str (&var->expr), style ? "[]" : "*");
1172  return NULL;
1173  }
1174 
1175  result_type = var->type->next;
1176  pp_discard_link (var->type);
1177  var->type = result_type;
1178 
1179  return var;
1180 }
1181 
1182 /*
1183  * pp_struct_deref() - Perform a struct field dereference
1184  * on the incoming host var.
1185  * return : The incoming HOST_VAR.
1186  * var(in): A host variable to be deref'ed.
1187  * field(in): The name of the field to be extracted.
1188  * indirect(in): 0 if through '.', 1 if through '->'.
1189  */
1190 HOST_VAR *
1191 pp_struct_deref (HOST_VAR * var, char *field, int indirect)
1192 {
1193  SYMBOL *field_def;
1194 
1195  if (var == NULL)
1196  {
1197  return NULL;
1198  }
1199 
1200  if (indirect)
1201  {
1202  LINK *base_type;
1203  if (!IS_PTR_TYPE (var->type))
1204  {
1206  return NULL;
1207  }
1208  base_type = var->type->next;
1209  pp_discard_link (var->type);
1210  var->type = base_type;
1211  }
1212 
1213  if (!IS_STRUCT (var->type) && !IS_PSEUDO_TYPE (var->type))
1214  {
1216  vs_str (&var->expr));
1217  return NULL;
1218  }
1219 
1220  field_def = pp_find_field (var->type->decl.s.val.v_struct, field);
1221  if (field_def == NULL)
1222  {
1224  return NULL;
1225  }
1226 
1227  pp_discard_link_chain (var->type);
1228  var->type = pp_clone_type (field_def->type, &var->etype);
1229 
1230  return var;
1231 }
1232 
1233 /*
1234  * pp_addr_of() - Alter the type of var to be a pointer to the incoming type.
1235  * return : HOST_VAR *
1236  * var(in): The host variable whose address is to be taken.
1237  */
1238 HOST_VAR *
1240 {
1241  LINK *new_link;
1242 
1243  if (var == NULL)
1244  {
1245  return NULL;
1246  }
1247 
1248  new_link = pp_new_link ();
1249  if (new_link != NULL)
1250  {
1251  new_link->decl.d.dcl_type = D_POINTER;
1252  new_link->next = var->type;
1253  var->type = new_link;
1254  }
1255 
1256  return var;
1257 }
1258 
1259 /*
1260  * pp_find_field() - Return the type of the named field in the given struct
1261  * definition, or NULL if not present.
1262  * return : the type of named field
1263  * sdef(in): The struct to searched.
1264  * field(in): The field to be searched for.
1265  */
1266 static SYMBOL *
1267 pp_find_field (STRUCTDEF * sdef, const char *field)
1268 {
1269  SYMBOL *sym;
1270  for (sym = sdef->fields; sym; sym = sym->next)
1271  {
1272  if (STREQ (field, (char *) sym->name))
1273  {
1274  return sym;
1275  }
1276  }
1277 
1278  return NULL;
1279 }
1280 
1281 /*
1282  * pp_add_dummy_structdef() - Add entries to the struct and symbol tables
1283  * that would arise if we had encountered
1284  * typedef struct <name> <name>;
1285  * This adds an empty structdef for name, which is all we really
1286  * care about, and allows esql programmers to declare DB_VALUE
1287  * and CUBRIDDA types without any special effort.
1288  * return : void
1289  * symp(out): Address of a SYMBOL pointer to be initialized with the dummy
1290  * symbol that we create.
1291  * name(in): The name to be entered in the struct and symbol tables.
1292  */
1293 static void
1294 pp_add_dummy_structdef (SYMBOL ** symp, const char *name)
1295 {
1296  STRUCTDEF *dummy_struct;
1297  SYMBOL *dummy_symbol;
1298 
1299  dummy_symbol = pp_new_symbol (name, 0);
1300  dummy_struct = pp_new_structdef (name);
1302  pp_add_storage_class (TYPEDEF_);
1303  pp_add_struct_spec (dummy_struct);
1304  pp_add_spec_to_decl (pp_current_type_spec (), dummy_symbol);
1306  pp_Struct_table->add_symbol (pp_Struct_table, dummy_struct);
1307  pp_Symbol_table->add_symbol (pp_Symbol_table, dummy_symbol);
1308 
1309  *symp = dummy_symbol;
1310 }
1311 
1312 /*
1313  * pp_hv_init() - Initialize various static module data.
1314  *
1315  * arguments:
1316  *
1317  * returns/side-effects: nothing
1318  *
1319  * note : Make sure that all symbol table stuff is initialized before calling
1320  * this, because it is going to try to deposit a typedef in the outermost
1321  * level of the symbol table.
1322  */
1323 void
1325 {
1326  unsigned int i;
1327  SYMBOL *db_indicator;
1328  SYMBOL *db_int32;
1329 
1330  host_lod_chain = NULL;
1331  host_lod_free_list = NULL;
1332  input_refs = NULL;
1333  output_refs = NULL;
1334  pp_host_refs = NULL;
1335  pp_gathering = &input_refs;
1336  pp_clear_host_refs ();
1337 
1338  string_dummy = pp_new_symbol (NULL, 0);
1340  pp_add_type_noun (CHAR_);
1341  pp_add_declarator (string_dummy, D_ARRAY);
1342  pp_add_spec_to_decl (pp_current_type_spec (), string_dummy);
1344 
1345  /* This assumes that DB_INDICATOR is tyepdef'ed to short. Change this code when that assumption becomes invalid. */
1346  db_indicator = pp_new_symbol ("DB_INDICATOR", 0);
1348  pp_add_storage_class (TYPEDEF_);
1349  pp_add_type_noun (INT_);
1350  pp_add_type_adj (SHORT_);
1351  pp_add_spec_to_decl (pp_current_type_spec (), db_indicator);
1353  pp_add_symbols_to_table (db_indicator);
1354 
1355  /* Make sure that this one corresponds to the typedef in dbport.h. */
1356  db_int32 = pp_new_symbol ("int", 0);
1358  pp_add_storage_class (TYPEDEF_);
1359  pp_add_type_noun (INT_);
1360  if (sizeof (int) < 4)
1361  {
1362  pp_add_type_adj (LONG_);
1363  }
1366  pp_add_symbols_to_table (db_int32);
1367 
1368  for (i = 0; i < DIM (builtin_types); ++i)
1369  {
1370  pp_add_dummy_structdef (&builtin_types[i].sym, builtin_types[i].name);
1371  }
1372 }
1373 
1374 /*
1375  * pp_hv_finish() - Tear down various static module data.
1376  * return : void
1377  *
1378  * note : The builtin struct definitions will be removed automatically when
1379  * the symbol and struct tables are torn down.
1380  */
1381 void
1383 {
1384  while (host_lod_chain)
1385  {
1386  HOST_LOD *next = host_lod_chain->next;
1387  pp_free_host_lod (host_lod_chain);
1388  host_lod_chain = next;
1389  }
1390  while (host_lod_free_list)
1391  {
1392  HOST_LOD *next = host_lod_free_list->next;
1393  pp_free_host_lod (host_lod_free_list);
1394  host_lod_free_list = next;
1395  }
1396 
1397  pp_discard_symbol (string_dummy);
1398 }
1399 
1400 /*
1401  * pp_new_host_lod() - Allocate and initialize a new HOST_LOD. Keeps all
1402  * allocated lods in a chain for easier cleanup later.
1403  * return : HOST_LOD *
1404  */
1405 HOST_LOD *
1407 {
1409 
1410  if (lod == NULL)
1411  {
1412  lod = (HOST_LOD *) malloc (sizeof (HOST_LOD));
1413  if (lod == NULL)
1414  {
1416  exit (1);
1417  return NULL;
1418  }
1419  lod->real_refs = NULL;
1420  }
1421  else
1422  {
1423  host_lod_free_list = lod->next;
1424  }
1425 
1426  lod->desc = NULL;
1427  lod->n_refs = 0;
1428  lod->refs = NULL;
1429  lod->max_refs = 0;
1430  lod->n_real_refs = 0;
1431  lod->next = host_lod_chain;
1432 
1433  host_lod_chain = lod;
1434 
1435  return lod;
1436 }
1437 
1438 /*
1439  * pp_free_host_lod() - Free the indicated HOST_LOD and all HOST_VARs
1440  * it references.
1441  * return : nothing
1442  * lod : A pointer to a HOST_LOD to be deallocated.
1443  */
1444 void
1446 {
1447  if (lod == NULL)
1448  {
1449  return;
1450  }
1451 
1452  pp_clear_host_lod (lod);
1453  if (lod->real_refs != NULL)
1454  {
1455  free_and_init (lod->real_refs);
1456  }
1457 
1458  free_and_init (lod);
1459 }
1460 
1461 /*
1462  * pp_clear_host_lod() - Clear pp_buf and pp_host_refs in preparation for
1463  * a new statement.
1464  * return : void
1465  */
1466 void
1468 {
1469  int i;
1470 
1471  if (lod == NULL)
1472  {
1473  return;
1474  }
1475 
1476  /*
1477  * *DON'T* free the character string pointed to by desc. It is
1478  * assumed to point to the same string that some host_ref in
1479  * real_refs points to.
1480  */
1481  for (i = 0; i < lod->n_real_refs; ++i)
1482  {
1483  pp_free_host_ref (&lod->real_refs[i]);
1484  }
1485 
1486  lod->desc = NULL;
1487  lod->n_refs = 0;
1488  lod->refs = NULL;
1489  lod->n_real_refs = 0;
1490 
1491 }
1492 
1493 /*
1494  * pp_switch_to_descriptor() - Switch pp_host_ref's mode into descriptor mode.
1495  * return : NULL if there is a problem, the name of the descriptor otherwise.
1496  */
1497 char *
1499 {
1500  assert (pp_host_refs != NULL);
1501  assert (pp_host_refs->n_refs == 1);
1502  assert (pp_host_refs->refs != NULL);
1503 
1504  if (pp_host_refs == NULL || pp_host_refs->n_refs != 1 || pp_host_refs->refs == NULL)
1505  {
1506  return NULL;
1507  }
1508 
1509  pp_host_refs->desc = (unsigned char *) pp_get_expr (&pp_host_refs->refs[0]);
1510  pp_host_refs->n_refs = 0;
1511  pp_host_refs->refs = NULL;
1512 
1513  return (char *) pp_host_refs->desc;
1514 }
1515 
1516 /*
1517  * pp_translate_string() - Translate the string into another that will,
1518  * when processed by a C compiler, yield the original string. This
1519  * means being careful about things like single and double quotes and
1520  * backslashes. If the string is being embedded within another C string
1521  * (e.g., the string is a literal within some CSQL command that is being
1522  * prepared into a C string) we need to do some things a little differently
1523  * (e.g., make sure we escape the enclosing double quotes of
1524  * a C-style string).
1525  * return : void
1526  * vstr(out) : A varstring to receive the translated string.
1527  * str(in) : An input string, following either C or CSQL punctuation rules.
1528  * in_string(in) : true iff the translated string is being embedded within a C
1529  * string. false otherwise.
1530  */
1531 void
1532 pp_translate_string (varstring * vstr, const char *str, int in_string)
1533 {
1534  unsigned const char *p = (unsigned const char *) str;
1535 
1536  if (vstr == NULL || p == NULL)
1537  {
1538  return;
1539  }
1540 
1541  if (*p == '"')
1542  {
1543  vs_strcat (vstr, in_string ? "\\\"" : "\"");
1544 
1545  for (++p; *p != '"'; ++p)
1546  {
1547  switch (*p)
1548  {
1549  case '\\':
1550  switch (*++p)
1551  {
1552  case '"':
1553  vs_strcat (vstr, "\\\\\\\"");
1554  break;
1555  case '\n':
1556  break;
1557  default:
1558  vs_strcat (vstr, "\\\\");
1559  vs_putc (vstr, *p);
1560  break;
1561  }
1562  break;
1563 
1564  default:
1565  vs_putc (vstr, *p);
1566  break;
1567  }
1568  }
1569 
1570  vs_strcat (vstr, in_string ? "\\\"" : "\"");
1571  }
1572  else
1573  {
1574  vs_putc (vstr, in_string ? '\'' : '"');
1575 
1576  for (++p; *p; ++p)
1577  {
1578  switch (*p)
1579  {
1580  case '\\':
1581  if (*(p + 1) == '\n')
1582  {
1583  ++p;
1584  }
1585  else
1586  {
1587  vs_strcat (vstr, "\\\\");
1588  }
1589  break;
1590 
1591  case '\'':
1592  if (*(p + 1) == '\'')
1593  {
1594  ++p;
1595  if (in_string)
1596  {
1597  vs_putc (vstr, '\'');
1598  }
1599  vs_putc (vstr, '\'');
1600  }
1601  break;
1602 
1603  case '"':
1604  vs_strcat (vstr, "\\\"");
1605  break;
1606 
1607  default:
1608  vs_putc (vstr, *p);
1609  break;
1610  }
1611  }
1612 
1613  vs_putc (vstr, in_string ? '\'' : '"');
1614  }
1615 }
#define IS_ARRAY(p)
Definition: esql_misc.h:52
void pp_hv_init(void)
#define IS_PTR_TYPE(p)
Definition: esql_misc.h:85
static HOST_LOD * host_lod_chain
static char * pp_expr(HOST_VAR *var)
void *(* add_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:37
void pp_print_host_ref(HOST_REF *ref, FILE *fp)
#define MEMBER(set, val)
Definition: esql_misc.h:42
unsigned char is_unsigned
char * pp_strdup(const char *str)
Definition: esql_misc.c:372
varstring * vs_new(varstring *vstr)
STRUCTDEF * v_struct
SYMBOL * pp_new_symbol(const char *name, int scope)
SPECIFIER_NOUN noun
varstring * ind_addr_expr_buf
HOST_LOD * pp_copy_host_refs(void)
HOST_LOD * pp_detach_host_refs(void)
SYMTAB * pp_Struct_table
LINK * pp_clone_type(LINK *tchain, LINK **endp)
HOST_LOD * pp_new_host_lod(void)
LINK * pp_current_type_spec(void)
Definition: esql_declare.c:663
HOST_VAR * pp_struct_deref(HOST_VAR *var, char *field, int indirect)
static SYMBOL * string_dummy
static HOST_LOD * host_lod_free_list
void esql_yyverror(const char *,...)
HOST_VAR * pp_new_host_var(HOST_VAR *var, SYMBOL *sym)
void pp_add_type_adj(int adj)
Definition: esql_declare.c:857
int vs_prepend(varstring *vstr, const char *prefix)
char * pp_get_ind_addr_expr(HOST_REF *ref)
const char * pp_get_msg(int msg_set, int msg_num)
unsigned char is_long
varstring * ind_expr_buf
int vs_strcpy(varstring *vstr, const char *str)
HOST_REF * pp_add_host_str(char *str)
int vs_sprintf(varstring *vstr, const char *fmt,...)
void pp_hv_finish(void)
const char * pp_type_str(LINK *link)
void pp_clear_host_refs(void)
#define IS_INT(p)
Definition: esql_misc.h:59
varstring * precision_buf
union specifier::@74 val
void * pp_malloc(int n)
Definition: esql_misc.c:353
unsigned char * desc
HOST_REF * refs
char * vs_str(varstring *vstr)
char * pp_get_expr(HOST_REF *ref)
#define C_TYPE_STRUCT
#define BAD_C_TYPE
#define UNINITIALIZED(p)
#define IS_SPECIFIER(p)
Definition: esql_misc.h:49
void vs_free(varstring *vstr)
unsigned char type
HOST_LOD * pp_output_refs(void)
#define assert(x)
int errors
HOST_REF * pp_check_type(HOST_REF *ref, BITSET typeset, const char *msg)
#define IS_PSEUDO_TYPE(p)
Definition: esql_misc.h:76
varstring * expr_buf
unsigned int BITSET
Definition: esql_misc.h:94
varstring * output_size_buf
HOST_VAR * pp_addr_of(HOST_VAR *var)
void pp_free_host_var(HOST_VAR *var)
const char * VARCHAR_ARRAY_NAME
static HOST_LOD * input_refs
Definition: esql_misc.h:304
void pp_discard_link(LINK *p)
void pp_add_declarator(SYMBOL *sym, int type)
#define NULL
Definition: freelistheap.h:34
static SYMBOL * pp_find_field(STRUCTDEF *sdef, const char *field)
#define IS_STRUCT(p)
Definition: esql_misc.h:66
unsigned char is_short
varstring addr_expr
int vs_putc(varstring *vstr, int ch)
static HOST_LOD * pp_host_refs
varstring * addr_expr_buf
static C_TYPE pp_check(HOST_VAR *var, bool structs_allowed)
struct host_ref HOST_REF
varstring expr
void pp_reset_current_type_spec(void)
Definition: esql_declare.c:639
HOST_REF * real_refs
void vs_clear(varstring *vstr)
char * pp_get_output_size(HOST_REF *ref)
int pp_internal_ind
const char * name
void pp_discard_link_chain(LINK *p)
char * pp_get_ind_expr(HOST_REF *ref)
LINK * pp_new_link(void)
void pp_discard_symbol(SYMBOL *sym)
char * pp_get_input_size(HOST_REF *ref)
static HOST_LOD ** pp_gathering
HOST_REF * pp_add_host_ref(HOST_VAR *var, HOST_VAR *indicator, bool structs_allowed, int *n_refs)
void pp_add_spec_to_decl(LINK *p_spec, SYMBOL *decl_chain)
Definition: esql_declare.c:213
static HOST_REF * pp_add_struct_field_refs(HOST_VAR *var, int *n_refs)
static BUILTIN_TYPE builtin_types[]
void pp_add_struct_spec(STRUCTDEF *sdef)
Definition: esql_declare.c:707
const char * VARCHAR_LENGTH_NAME
int vs_strcat(varstring *vstr, const char *str)
HOST_VAR * var
#define free_and_init(ptr)
Definition: memory_alloc.h:147
static HOST_LOD * output_refs
Definition: esql_misc.h:304
void pp_gather_output_refs(void)
#define IS_POINTER(p)
Definition: esql_misc.h:54
void pp_free_host_lod(HOST_LOD *lod)
varstring * input_size_buf
C_TYPE pp_get_type(HOST_REF *ref)
void pp_add_type_noun(int type)
Definition: esql_declare.c:754
SYMBOL * next
HOST_LOD * pp_input_refs(void)
int i
Definition: dynamic_load.c:954
HOST_VAR * ind
#define IS_CHAR(p)
Definition: esql_misc.h:58
SYMTAB * pp_Symbol_table
void pp_add_storage_class(int sc)
Definition: esql_declare.c:677
STRUCTDEF * pp_new_structdef(const char *tag)
unsigned char * name
char * pp_get_addr_expr(HOST_REF *ref)
static char * pp_addr_expr(HOST_VAR *var)
enum c_pype C_TYPE
int pp_the_same_type(LINK *p1, LINK *p2, int relax)
void pp_check_host_var_list(void)
char * pp_get_precision(HOST_REF *ref)
void pp_free_host_ref(HOST_REF *ref)
HOST_LOD * next
void pp_add_symbols_to_table(SYMBOL *sym)
Definition: esql_declare.c:304
#define NUM_C_VARIABLE_TYPES
HOST_VAR * pp_ptr_deref(HOST_VAR *var, int style)
static void pp_add_dummy_structdef(SYMBOL **symp, const char *name)
#define IS_LONG(p)
Definition: esql_misc.h:61
const char ** p
Definition: dynamic_load.c:945
void pp_clear_host_lod(HOST_LOD *lod)
void pp_gather_input_refs(void)
static C_TYPE pp_check_builtin_type(LINK *type, bool mode)
const unsigned char * type_string
char * pp_switch_to_descriptor(void)
void pp_translate_string(varstring *vstr, const char *str, int in_string)