CUBRID Engine  latest
esql_misc.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_misc.c - Generic helper functions for the esql preprocessor
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include "chartype.h"
31 #include "util_func.h"
32 #include "misc_string.h"
33 #include "memory_alloc.h"
34 #include "intl_support.h"
35 #include "esql_misc.h"
36 #include "esql_translate.h"
37 
38 extern "C"
39 {
40  extern FILE *esql_yyout;
41 }
42 /*
43  * This struct is used as a catchall struct for all of the various
44  * structures that are put in hash tables. We take care that each such
45  * structure is defined with its name field first, so that we can safely
46  * cast a pointer to such a struct as a pointer to a GENERIC struct.
47  * This allows all of the hash tables to use the same hash and comparison
48  * functions.
49  */
50 typedef struct generic GENERIC;
51 
52 struct generic
53 {
54  char *name;
55 };
56 
59 
60 static void tr_prelude (void);
61 static void grow_ptr_vec (PTR_VEC * vec);
62 
63 /*
64  * pp_generic_case_hash() - Assumes that p points to a GENERIC-compatible
65  * struct, and hashes on the lowercased name field of that struct.
66  * return : hash value
67  * p(in): A pointer to a generic structure to be hashed.
68  */
69 unsigned int
71 {
72  char *s, *d, nam[256];
73  int i;
74  GENERIC *gp;
75 
76  gp = (GENERIC *) p;
77  s = gp->name;
78  d = nam;
79  if (s)
80  {
81  for (i = 0; *s && i < 256; s++, d++, i++)
82  {
83  *d = char_tolower (*s);
84  }
85  }
86  *d = '\0';
87 
88  return hashpjw (nam);
89 }
90 
91 /*
92  * pp_generic_hash() - Assumes that p points to a GENERIC-compatible struct,
93  * and hashes on the name field of that struct.
94  * return : hash value
95  * p(in): A pointer to a generic structure to be hashed.
96  */
97 
98 unsigned int
100 {
101  GENERIC *gp = (GENERIC *) p;
102  return hashpjw (gp->name);
103 }
104 
105 /*
106  * pp_generic_case_cmp() - Assumes that both pointers point to
107  * GENERIC-compatible structs. returns -1, 0, or 1 according to
108  * the standard case-insensitive comparison of the name fields
109  * of those structs.
110  * return : int
111  * p1(in): A pointer to a structure to be compared.
112  * p2(in): Another pointer to a structure to be compared.
113  */
114 int
115 pp_generic_case_cmp (void *p1, void *p2)
116 {
117  GENERIC *gp1 = (GENERIC *) p1;
118  GENERIC *gp2 = (GENERIC *) p2;
119 
120  return intl_mbs_casecmp (gp1->name, gp2->name);
121 }
122 
123 /*
124  * pp_generic_cmp() - Assumes that both pointers point to GENERIC-compatible
125  * structs; returns -1, 0, or 1 according to the standard comparison of
126  * the name fields of those structs.
127  * return : int
128  * p1(in): A pointer to a structure to be compared.
129  * p2(in): Another pointer to a structure to be compared.
130  */
131 int
132 pp_generic_cmp (void *p1, void *p2)
133 {
134  GENERIC *gp1 = (GENERIC *) p1;
135  GENERIC *gp2 = (GENERIC *) p2;
136 
137  return strcmp (gp1->name, gp2->name);
138 }
139 
140 /*
141  * pp_startup() - Global initialization to be called before parsing a file.
142  * return : void
143  */
144 void
146 {
149  vs_new (&pp_subscript_buf);
150  vs_new (&pp_host_var_buf);
151  pp_symbol_init ();
152  pp_cursor_init ();
153  pp_decl_init ();
154  pp_hv_init ();
155  tr_prelude ();
156 }
157 
158 /*
159  * pp_finish() - Global teardown to be called after parsing a file.
160  * return : void
161  */
162 void
163 pp_finish (void)
164 {
165  vs_free (&pp_subscript_buf);
166  vs_free (&pp_host_var_buf);
167  pp_hv_finish ();
168  pp_decl_finish ();
169  pp_cursor_finish ();
170  pp_symbol_finish ();
172 }
173 
174 /*
175  * tr_prelude() - Emit the prelude jive (include files, etc.) required by the
176  * generated code.
177  * return : void
178  */
179 static void
181 {
182  const char *default_include_file = "cubrid_esql.h";
183 
184  if (pp_varchar2)
185  {
186  fprintf (esql_yyout, "#define _ESQLX_VARCHAR2_STYLE_\n");
187  }
188  fprintf (esql_yyout, "#include \"%s\"\n", pp_include_file ? pp_include_file : default_include_file);
189 }
190 
191 /*
192  * pp_new_ptr_vec() - Create a new counted vector, and initialize it as empty.
193  * return : PTR_VEC *
194  * vec(in): The address of a PTR_VEC structure to be initialized, or NULL.
195  */
196 PTR_VEC *
198 {
199  if (vec == NULL)
200  {
201  vec = (PTR_VEC *) malloc (sizeof (PTR_VEC));
202  if (vec == NULL)
203  {
205  exit (1);
206  return NULL;
207  }
208 
209  vec->heap_allocated = TRUE;
210  }
211  else
212  {
213  vec->heap_allocated = FALSE;
214  }
215 
216  vec->n_elems = 0;
217  vec->max_elems = DIM (vec->inline_elems);
218  vec->elems = vec->inline_elems;
220 
221  return vec;
222 }
223 
224 /*
225  * pp_free_ptr_vec() - Free the internal structures used by the PTR_VEC,
226  * and the PTR_VEC itself if it was heap-allocated.
227  * return : void
228  * vec(in): A pointer to a PTR_VEC, or NULL.
229  */
230 void
232 {
233  int i;
234 
235  if (vec == NULL)
236  {
237  return;
238  }
239 
240  for (i = 0; i < vec->n_elems; ++i)
241  {
242  if (vec->elems[i])
243  {
244  free_and_init (vec->elems[i]);
245  }
246  }
247 
248  if (vec->elems != vec->inline_elems)
249  {
250  free_and_init (vec->elems);
251  }
252 
253  if (vec->heap_allocated)
254  {
255  free_and_init (vec);
256  }
257 }
258 
259 static void
261 {
262  int new_max_elems;
263  void **new_elems;
264 
265  new_max_elems = (int) (vec->max_elems + vec->chunk_size);
266  if (vec->elems == vec->inline_elems)
267  {
268  new_elems = (void **) pp_malloc (sizeof (vec->elems[0]) * new_max_elems);
269  memcpy ((char *) new_elems, (char *) vec->elems, sizeof (vec->elems[0]) * vec->n_elems);
270  }
271  else
272  {
273  new_elems = (void **) realloc (vec->elems, sizeof (vec->elems[0]) * new_max_elems);
274  }
275 
276  if (new_elems == NULL)
277  {
279  exit (1);
280  }
281 
282  vec->elems = new_elems;
283  vec->max_elems = new_max_elems;
284 }
285 
286 /*
287  * pp_add_ptr() - Add another element to the end of the vector, reallocating
288  * and extending the internal array vector if necessary.
289  * return : PTR_VEC *
290  * vec(in): A pointer to a PTR_VEC that should receive a new element.
291  * new_elem(in): A pointer to be added to the vector.
292  */
293 PTR_VEC *
294 pp_add_ptr (PTR_VEC * vec, void *new_elem)
295 {
296  if (vec == NULL)
297  {
298  return NULL;
299  }
300  else if (vec->n_elems >= vec->max_elems)
301  {
302  grow_ptr_vec (vec);
303  }
304 
305  vec->elems[vec->n_elems++] = new_elem;
306  return vec;
307 }
308 
309 /*
310  * pp_ptr_vec_n_elems() - Return the number of elements currently stored
311  * in the vector.
312  * return : int
313  * vec(in): A pointer to some PTR_VEC, or NULL.
314  */
315 int
317 {
318  if (vec != NULL)
319  {
320  return vec->n_elems;
321  }
322  else
323  {
324  return 0;
325  }
326 }
327 
328 /*
329  * pp_ptr_vec_elems() - Return a pointer to the internal vector of void*
330  * pointers, or NULL.
331  * return : void **
332  * vec(in): A pointer to a PTR_VEC, or NULL.
333  */
334 void **
336 {
337  if (vec != NULL && vec->n_elems > 0)
338  {
339  return vec->elems;
340  }
341  else
342  {
343  return NULL;
344  }
345 }
346 
347 /*
348  * pp_malloc() - Safe malloc. prints a message and exits if no memory.
349  * return : void *
350  * int(in): number of bytes needed
351  */
352 void *
353 pp_malloc (int n)
354 {
355  char *tmp;
356 
357  tmp = (char *) malloc (n);
358  if (tmp == NULL)
359  {
360  fprintf (stderr, "%s: %s\n", prog_name, pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY));
361  exit (1);
362  }
363  return tmp;
364 }
365 
366 /*
367  * pp_strdup() - Safe strdup. prints a message and exits if no memory.
368  * return : char *
369  * str: string to be copied
370  */
371 char *
372 pp_strdup (const char *str)
373 {
374  long n;
375  char *tmp;
376 
377  if (str == NULL)
378  {
379  return NULL;
380  }
381  /* includes the null terminator of 'str' */
382  n = (int) strlen (str) + 1;
383  tmp = (char *) pp_malloc (n);
384  memcpy (tmp, str, n);
385  return tmp;
386 }
void pp_hv_init(void)
#define TRUE
Definition: broker_admin.c:49
unsigned int pp_generic_case_hash(void *p)
Definition: esql_misc.c:70
void pp_free_ptr_vec(PTR_VEC *vec)
Definition: esql_misc.c:231
char * pp_strdup(const char *str)
Definition: esql_misc.c:372
varstring * vs_new(varstring *vstr)
void pp_cursor_finish(void)
Definition: esql_cursor.c:143
const char * prog_name
int char_tolower(int c)
Definition: chartype.c:146
ESQL_TRANSLATE_TABLE esql_Translate_table
int pp_varchar2
int pp_generic_cmp(void *p1, void *p2)
Definition: esql_misc.c:132
void pp_symbol_init(void)
void pp_decl_init(void)
Definition: esql_declare.c:530
void esql_yyverror(const char *,...)
const char * pp_get_msg(int msg_set, int msg_num)
void pp_hv_finish(void)
static void tr_prelude(void)
Definition: esql_misc.c:180
void * pp_malloc(int n)
Definition: esql_misc.c:353
int pp_generic_case_cmp(void *p1, void *p2)
Definition: esql_misc.c:115
unsigned int hashpjw(const char *s)
Definition: util_func.c:83
#define PTR_VEC_CHUNK_SIZE
void pp_symbol_finish(void)
void vs_free(varstring *vstr)
void pp_symbol_stats(FILE *fp)
void pp_cursor_init(void)
Definition: esql_cursor.c:132
FILE * esql_yyout
void pp_finish(void)
Definition: esql_misc.c:163
void pp_decl_finish(void)
Definition: esql_declare.c:555
#define NULL
Definition: freelistheap.h:34
size_t chunk_size
char * name
Definition: esql_misc.c:54
unsigned int pp_generic_hash(void *p)
Definition: esql_misc.c:99
static void grow_ptr_vec(PTR_VEC *vec)
Definition: esql_misc.c:260
char * pp_include_file
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
int intl_mbs_casecmp(const char *mbs1, const char *mbs2)
Definition: intl_support.c:358
#define FALSE
Definition: broker_admin.c:50
int i
Definition: dynamic_load.c:954
varstring pp_host_var_buf
Definition: esql_misc.c:58
void * inline_elems[PTR_VEC_CHUNK_SIZE]
varstring pp_subscript_buf
Definition: esql_misc.c:57
void pp_startup(void)
Definition: esql_misc.c:145
PTR_VEC * pp_new_ptr_vec(PTR_VEC *vec)
Definition: esql_misc.c:197
void(* tr_set_out_stream)(FILE *out_stream)
const char ** p
Definition: dynamic_load.c:945
void(* tr_set_line_terminator)(const char *)
void ** pp_ptr_vec_elems(PTR_VEC *vec)
Definition: esql_misc.c:335
PTR_VEC * pp_add_ptr(PTR_VEC *vec, void *new_elem)
Definition: esql_misc.c:294
int pp_ptr_vec_n_elems(PTR_VEC *vec)
Definition: esql_misc.c:316