CUBRID Engine  latest
esql_grammar.y
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  * esql_grammar.y : esql grammar file
21  */
22 
23 
24 
25 %{/*%CODE_REQUIRES_START%*/
26 #include "esql_host_variable.h"
27 /*%CODE_END%*/%}
28 
29 %{/*%CODE_PROVIDES_START%*/
30 #include "esql_scanner_support.h"
31 
32 #if defined (SUPPRESS_STRLEN_WARNING)
33 #define strlen(s1) ((int) strlen(s1))
34 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
35 
36 #define START 0
37 #define ECHO_mode START
38 #define CSQL_mode 1
39 #define C_mode 2
40 #define EXPR_mode 3
41 #define VAR_mode 4
42 #define HV_mode 5
43 #define BUFFER_mode 6
44 #define COMMENT_mode 7
45 
46 static KEYWORD_REC c_keywords[] = {
47  {"auto", AUTO_, 0},
48  {"BIT", BIT_, 1},
49  {"bit", BIT_, 1},
50  {"break", GENERIC_TOKEN, 0},
51  {"case", GENERIC_TOKEN, 0},
52  {"char", CHAR_, 0},
53  {"const", CONST_, 0},
54  {"continue", GENERIC_TOKEN, 0},
55  {"default", GENERIC_TOKEN, 0},
56  {"do", GENERIC_TOKEN, 0},
57  {"double", DOUBLE_, 0},
58  {"else", GENERIC_TOKEN, 0},
59  {"enum", ENUM, 0},
60  {"extern", EXTERN_, 0},
61  {"float", FLOAT_, 0},
62  {"for", GENERIC_TOKEN, 0},
63  {"go", GENERIC_TOKEN, 0},
64  {"goto", GENERIC_TOKEN, 0},
65  {"if", GENERIC_TOKEN, 0},
66  {"int", INT_, 0},
67  {"long", LONG_, 0},
68  {"register", REGISTER_, 0},
69  {"return", GENERIC_TOKEN, 0},
70  {"short", SHORT_, 0},
71  {"signed", SIGNED_, 0},
72  {"sizeof", GENERIC_TOKEN, 0},
73  {"static", STATIC_, 0},
74  {"struct", STRUCT_, 0},
75  {"switch", GENERIC_TOKEN, 0},
76  {"typedef", TYPEDEF_, 0},
77  {"union", UNION_, 0},
78  {"unsigned", UNSIGNED_, 0},
79  {"VARCHAR", VARCHAR_, 1},
80  {"varchar", VARCHAR_, 1},
81  {"VARYING", VARYING, 0},
82  {"varying", VARYING, 0},
83  {"void", VOID_, 0},
84  {"volatile", VOLATILE_, 0},
85  {"while", GENERIC_TOKEN, 0},
86 };
87 
88 static KEYWORD_REC csql_keywords[] = {
89  /* Make sure that they are in alphabetical order */
90  {"ADD", ADD, 0},
91  {"ALL", ALL, 0},
92  {"ALTER", ALTER, 0},
93  {"AND", AND, 0},
94  {"AS", AS, 0},
95  {"ASC", ASC, 0},
96  {"ATTACH", ATTACH, 0},
97  {"ATTRIBUTE", ATTRIBUTE, 0},
98  {"AVG", AVG, 0},
99  {"BEGIN", BEGIN_, 1},
100  {"BETWEEN", BETWEEN, 0},
101  {"BY", BY, 0},
102  {"CALL", CALL_, 0},
103  {"CHANGE", CHANGE, 0},
104  {"CHAR", CHAR_, 0},
105  {"CHARACTER", CHARACTER, 0},
106  {"CHECK", CHECK_, 0},
107  {"CLASS", CLASS, 0},
108  {"CLOSE", CLOSE, 0},
109  {"COMMIT", COMMIT, 0},
110  {"CONNECT", CONNECT, 1},
111  {"CONTINUE", CONTINUE_, 1},
112  {"COUNT", COUNT, 0},
113  {"CREATE", CREATE, 0},
114  {"CURRENT", CURRENT, 1},
115  {"CURSOR", CURSOR_, 1},
116  {"DATE", DATE_, 0},
117  {"DEC", NUMERIC, 0},
118  {"DECIMAL", NUMERIC, 0},
119  {"DECLARE", DECLARE, 1},
120  {"DEFAULT", DEFAULT, 0},
121  {"DELETE", DELETE_, 0},
122  {"DESC", DESC, 0},
123  {"DESCRIBE", DESCRIBE, 1},
124  {"DESCRIPTOR", DESCRIPTOR, 1},
125  {"DIFFERENCE", DIFFERENCE_, 0},
126  {"DISCONNECT", DISCONNECT, 1},
127  {"DISTINCT", DISTINCT, 0},
128  {"DOUBLE", DOUBLE_, 0},
129  {"DROP", DROP, 0},
130  {"END", END, 1},
131  {"ESCAPE", ESCAPE, 0},
132  {"EVALUATE", EVALUATE, 0},
133  {"EXCEPT", EXCEPT, 0},
134  {"EXCLUDE", EXCLUDE, 0},
135  {"EXECUTE", EXECUTE, 1},
136  {"EXISTS", EXISTS, 0},
137  {"FETCH", FETCH, 1},
138  {"FILE", FILE_, 0},
139  {"FLOAT", FLOAT_, 0},
140  {"FOR", FOR, 0},
141  {"FOUND", FOUND, 0},
142  {"FROM", FROM, 0},
143  {"FUNCTION", FUNCTION_, 0},
144  {"GET", GET, 0},
145  {"GO", GO, 1},
146  {"GOTO", GOTO_, 1},
147  {"GRANT", GRANT, 0},
148  {"GROUP", GROUP_, 0},
149  {"HAVING", HAVING, 0},
150  {"IDENTIFIED", IDENTIFIED, 1},
151  {"IMMEDIATE", IMMEDIATE, 1},
152  {"IN", IN_, 0},
153  {"INCLUDE", INCLUDE, 1},
154  {"INDEX", INDEX, 0},
155  {"INDICATOR", INDICATOR, 1},
156  {"INHERIT", INHERIT, 0},
157  {"INSERT", INSERT, 0},
158  {"INT", INT_, 0},
159  {"INTEGER", INTEGER, 0},
160  {"INTERSECTION", INTERSECTION, 0},
161  {"INTO", INTO, 0},
162  {"IS", IS, 0},
163  {"LIKE", LIKE, 0},
164  {"MAX", MAX_, 0},
165  {"METHOD", METHOD, 0},
166  {"MIN", MIN_, 0},
167  {"MULTISET_OF", MULTISET_OF, 0},
168  {"NOT", NOT, 0},
169  {"NULL", NULL_, 0},
170  {"NUMBER", NUMERIC, 0},
171  {"NUMERIC", NUMERIC, 0},
172  {"OBJECT", OBJECT, 0},
173  {"OF", OF, 0},
174  {"OID", OID_, 0},
175  {"ON", ON_, 0},
176  {"ONLY", ONLY, 0},
177  {"OPEN", OPEN, 0},
178  {"OPTION", OPTION, 0},
179  {"OR", OR, 0},
180  {"ORDER", ORDER, 0},
181  {"PRECISION", PRECISION, 0},
182  {"PREPARE", PREPARE, 1},
183  {"PRIVILEGES", PRIVILEGES, 0},
184  {"PUBLIC", PUBLIC_, 0},
185  {"READ", READ, 0},
186  {"REAL", REAL, 0},
187  {"REGISTER", REGISTER_, 0},
188  {"RENAME", RENAME, 0},
189  {"REPEATED", REPEATED, 1},
190  {"REVOKE", REVOKE, 0},
191  {"ROLLBACK", ROLLBACK, 0},
192  {"SECTION", SECTION, 1},
193  {"SELECT", SELECT, 0},
194  {"SEQUENCE_OF", SEQUENCE_OF, 0},
195  {"SET", SET, 0},
196  {"SETEQ", SETEQ, 0},
197  {"SETNEQ", SETNEQ, 0},
198  {"SET_OF", SET_OF, 0},
199  {"SHARED", SHARED, 0},
200  {"SMALLINT", SMALLINT, 0},
201  {"SOME", SOME, 0},
202  {"SQLCA", SQLCA, 1},
203  {"SQLDA", SQLDA, 1},
204  {"SQLERROR", SQLERROR_, 1},
205  {"SQLM", SQLX, 1},
206  {"SQLWARNING", SQLWARNING_, 1},
207  {"STATISTICS", STATISTICS, 0},
208  {"STOP", STOP_, 1},
209  {"STRING", STRING, 0},
210  {"SUBCLASS", SUBCLASS, 0},
211  {"SUBSET", SUBSET, 0},
212  {"SUBSETEQ", SUBSETEQ, 0},
213  {"SUM", SUM, 0},
214  {"SUPERCLASS", SUPERCLASS, 0},
215  {"SUPERSET", SUPERSET, 0},
216  {"SUPERSETEQ", SUPERSETEQ, 0},
217  {"TABLE", TABLE, 0},
218  {"TIME", TIME, 0},
219  {"TIMESTAMP", TIMESTAMP, 0},
220  {"TO", TO, 0},
221  {"TRIGGER", TRIGGER, 0},
222  {"UNION", UNION_, 0},
223  {"UNIQUE", UNIQUE, 0},
224  {"UPDATE", UPDATE, 0},
225  {"USE", USE, 0},
226  {"USER", USER, 0},
227  {"USING", USING, 0},
228  {"UTIME", UTIME, 0},
229  {"VALUES", VALUES, 0},
230  {"VIEW", VIEW, 0},
231  {"WHENEVER", WHENEVER, 1},
232  {"WHERE", WHERE, 0},
233  {"WITH", WITH, 0},
234  {"WORK", WORK, 0},
235 };
236 
237 static KEYWORD_REC preprocessor_keywords[] = {
238  /* Make sure that they are in alphabetical order */
239  {"FROM", FROM, 0},
240  {"IDENTIFIED", IDENTIFIED, 0},
241  {"INDICATOR", INDICATOR, 1},
242  {"INTO", INTO, 0},
243  {"ON", ON_, 0},
244  {"SELECT", SELECT, 0},
245  {"TO", TO, 0},
246  {"VALUES", VALUES, 0},
247  {"WITH", WITH, 0},
248 };
249 
250 static KEYWORD_TABLE csql_table = { csql_keywords, DIM (csql_keywords) };
251 static KEYWORD_TABLE preprocessor_table = { preprocessor_keywords,
252  DIM (preprocessor_keywords) };
253 
254 extern char g_delay[];
255 extern bool g_indicator;
256 extern bool need_line_directive;
257 
258 enum scanner_mode esql_yy_mode (void);
259 char *mm_malloc (int size);
260 char *mm_strdup (char *str);
261 void mm_free (void);
262 /*%CODE_END%*/%}
263 
264 
265 %{
266 #ifndef ESQL_GRAMMAR
267 #define ESQL_GRAMMAR
268 
269 /* #define PARSER_DEBUG */
270 
271 #ifdef PARSER_DEBUG
272 
273 #define DBG_PRINT printf("rule: %d\n", __LINE__);
274 #define PARSER_NEW_NODE(a, b) __make_node(a, b, __LINE__)
275 #define PARSER_FREE_NODE(a, b) parser_free_node(a, b)
276 #define PRINT_(a) printf(a)
277 #define PRINT_1(a, b) printf(a, b)
278 
279 #else
280 
281 #define DBG_PRINT
282 #define PARSER_NEW_NODE(a, b) parser_new_node(a, b)
283 #define PARSER_FREE_NODE(a, b) parser_free_node(a, b)
284 #define PRINT_(a)
285 #define PRINT_1(a, b)
286 
287 #endif
288 
289 #if !defined(yytext_ptr)
290 extern char *esql_yytext;
291 extern int esql_yylineno;
292 #endif
293 
294 #include "config.h"
295 #include <ctype.h>
296 #include <stdlib.h>
297 #include <stdio.h>
298 #include <fcntl.h>
299 #include <errno.h>
300 
301 #include "cubrid_getopt.h"
302 #include "language_support.h"
303 #include "message_catalog.h"
304 #include "variable_string.h"
305 #include "parser.h"
306 #include "esql_translate.h"
307 #include "memory_alloc.h"
308 #include "misc_string.h"
309 #include "esql_misc.h"
310 #include "environment_variable.h"
311 #include "utility.h"
312 #include "esql_scanner_support.h"
313 #define ESQLMSG(x) pp_get_msg(EX_ESQLM_SET, (x))
314 
315 #define NO_CURSOR 0
316 #define CURSOR_DELETE 1
317 #define CURSOR_UPDATE 2
318 
319 static SYMBOL *g_identifier_symbol;
320 static STRUCTDEF *g_sdef2;
321 static int g_su;
322 static SYMBOL *g_psym;
323 static SYMBOL *g_struct_declaration_sym;
324 static SYMBOL *g_last;
325 static HOST_VAR *g_href;
326 static int g_cursor_type;
327 
328 static bool repeat_option;
329 static PTR_VEC id_list;
330 static bool already_translated;
331 static bool structs_allowed;
332 static bool hvs_allowed;
333 static int i;
334 static int n_refs;
335 
336 static void reset_globals (void);
337 static void ignore_repeat (void);
338 static char *ofile_name (char *fname);
339 #if defined (ENABLE_UNUSED_FUNCTION)
340 static int validate_input_file (void *fname, FILE * outfp);
341 #endif
342 void pt_print_errors (PARSER_CONTEXT * parser_in);
343 
344 extern PARSER_CONTEXT *parser;
345 
346 varstring *esql_yy_get_buf (void);
347 void esql_yy_set_buf (varstring * vstr);
348 int esql_yylex(void);
349 
350 
351 extern varstring *g_varstring;
352 extern varstring *g_subscript;
353 #endif
354 
355 %}
356 
357 %glr-parser
358 %define parse.error verbose
359 
360 %union {
361  SYMBOL *p_sym;
362  void *ptr;
363  int number;
364 }
365 
366 %token<ptr> ADD
367 %token<ptr> ALL
368 %token<ptr> ALTER
369 %token<ptr> AND
370 %token<ptr> AS
371 %token<ptr> ASC
372 %token<ptr> ATTRIBUTE
373 %token<ptr> ATTACH
374 %token<ptr> AUTO_
375 %token<ptr> AVG
376 %token<ptr> BAD_TOKEN
377 %token<ptr> BOGUS_ECHO
378 %token<ptr> BEGIN_
379 %token<ptr> BETWEEN
380 %token<ptr> BIT_
381 %token<ptr> BY
382 %token<ptr> CALL_
383 %token<ptr> CHANGE
384 %token<ptr> CHAR_
385 %token<ptr> CHARACTER
386 %token<ptr> CHECK_
387 %token<ptr> CLASS
388 %token<ptr> CLOSE
389 %token<ptr> COMMIT
390 %token<ptr> CONNECT
391 %token<ptr> CONST_
392 %token<ptr> CONTINUE_
393 %token<ptr> COUNT
394 %token<ptr> CREATE
395 %token<ptr> CURRENT
396 %token<ptr> CURSOR_
397 %token<ptr> DATE_
398 %token<ptr> DATE_LIT
399 %token<ptr> DECLARE
400 %token<ptr> DEFAULT
401 %token<ptr> DELETE_
402 %token<ptr> DESC
403 %token<ptr> DESCRIBE
404 %token<ptr> DESCRIPTOR
405 %token<ptr> DIFFERENCE_
406 %token<ptr> DISCONNECT
407 %token<ptr> DISTINCT
408 %token<ptr> DOUBLE_
409 %token<ptr> DROP
410 %token<ptr> ELLIPSIS
411 %token<ptr> END
412 %token<ptr> ENUM
413 %token<ptr> EQ
414 %token<ptr> ESCAPE
415 %token<ptr> EVALUATE
416 %token<ptr> EXCEPT
417 %token<ptr> EXCLUDE
418 %token<ptr> EXECUTE
419 %token<ptr> EXISTS
420 %token<ptr> EXTERN_
421 %token<ptr> FETCH
422 %token<ptr> FILE_
423 %token<ptr> FILE_PATH_LIT
424 %token<ptr> FLOAT_
425 %token<ptr> FOR
426 %token<ptr> FOUND
427 %token<ptr> FROM
428 %token<ptr> FUNCTION_
429 %token<ptr> GENERIC_TOKEN
430 %token<ptr> GEQ
431 %token<ptr> GET
432 %token<ptr> GO
433 %token<ptr> GOTO_
434 %token<ptr> GRANT
435 %token<ptr> GROUP_
436 %token<ptr> GT
437 %token<ptr> HAVING
438 %token<ptr> IDENTIFIED
439 %token<ptr> IMMEDIATE
440 %token<ptr> IN_
441 %token<ptr> INCLUDE
442 %token<ptr> INDEX
443 %token<ptr> INDICATOR
444 %token<ptr> INHERIT
445 %token<ptr> INSERT
446 %token<ptr> INTEGER
447 %token<ptr> INTERSECTION
448 %token<ptr> INTO
449 %token<ptr> INT_
450 %token<ptr> INT_LIT
451 %token<ptr> IS
452 %token<ptr> LDBVCLASS
453 %token<ptr> LEQ
454 %token<ptr> LIKE
455 %token<ptr> LONG_
456 %token<ptr> LT
457 %token<ptr> MAX_
458 %token<ptr> METHOD
459 %token<ptr> MIN_
460 %token<ptr> MINUS
461 %token<ptr> MONEY_LIT
462 %token<ptr> MULTISET_OF
463 %token<ptr> NEQ
464 %token<ptr> NOT
465 %token<ptr> NULL_
466 %token<ptr> NUMERIC
467 %token<ptr> OBJECT
468 %token<ptr> OF
469 %token<ptr> OID_
470 %token<ptr> ON_
471 %token<ptr> ONLY
472 %token<ptr> OPEN
473 %token<ptr> OPTION
474 %token<ptr> OR
475 %token<ptr> ORDER
476 %token<ptr> PLUS
477 %token<ptr> PRECISION
478 %token<ptr> PREPARE
479 %token<ptr> PRIVILEGES
480 %token<ptr> PTR_OP
481 %token<ptr> PUBLIC_
482 %token<ptr> READ
483 %token<ptr> READ_ONLY_
484 %token<ptr> REAL
485 %token<ptr> REAL_LIT
486 %token<ptr> REGISTER_
487 %token<ptr> RENAME
488 %token<ptr> REPEATED
489 %token<ptr> REVOKE
490 %token<ptr> ROLLBACK
491 %token<ptr> SECTION
492 %token<ptr> SELECT
493 %token<ptr> SEQUENCE_OF
494 %token<ptr> SET
495 %token<ptr> SETEQ
496 %token<ptr> SETNEQ
497 %token<ptr> SET_OF
498 %token<ptr> SHARED
499 %token<ptr> SHORT_
500 %token<ptr> SIGNED_
501 %token<ptr> SLASH
502 %token<ptr> SMALLINT
503 %token<ptr> SOME
504 %token<ptr> SQLCA
505 %token<ptr> SQLDA
506 %token<ptr> SQLERROR_
507 %token<ptr> SQLWARNING_
508 %token<ptr> STATIC_
509 %token<ptr> STATISTICS
510 %token<ptr> STOP_
511 %token<ptr> STRING
512 %token<ptr> STRUCT_
513 %token<ptr> SUBCLASS
514 %token<ptr> SUBSET
515 %token<ptr> SUBSETEQ
516 %token<ptr> SUM
517 %token<ptr> SUPERCLASS
518 %token<ptr> SUPERSET
519 %token<ptr> SUPERSETEQ
520 %token<ptr> TABLE
521 %token<ptr> TIME
522 %token<ptr> TIMESTAMP
523 %token<ptr> TIME_LIT
524 %token<ptr> TO
525 %token<ptr> TRIGGER
526 %token<ptr> TYPEDEF_
527 %token<ptr> UNION_
528 %token<ptr> UNIQUE
529 %token<ptr> UNSIGNED_
530 %token<ptr> UPDATE
531 %token<ptr> USE
532 %token<ptr> USER
533 %token<ptr> USING
534 %token<ptr> UTIME
535 %token<ptr> VALUES
536 %token<ptr> VARBIT_
537 %token<ptr> VARCHAR_
538 %token<ptr> VARYING
539 %token<ptr> VCLASS
540 %token<ptr> VIEW
541 %token<ptr> VOID_
542 %token<ptr> VOLATILE_
543 %token<ptr> WHENEVER
544 %token<ptr> WHERE
545 %token<ptr> WITH
546 %token<ptr> WORK
547 
548 %token<ptr> ENUMERATION_CONSTANT
549 %token<ptr> TYPEDEF_NAME
550 %token<ptr> STRING_LIT
551 %token<ptr> IDENTIFIER
552 
553 %token<ptr> EXEC
554 %token<ptr> SQLX
555 %token<ptr> UNION
556 %token<ptr> STRUCT
557 
558 %type<number> of_whenever_state
559 %type<number> opt_for_read_only
560 %type<number> csql_statement_head
561 %type<number> opt_varying
562 %type<number> of_struct_union
563 
564 %type<ptr> opt_id_by_quasi
565 %type<ptr> opt_with_quasi
566 %type<ptr> dynamic_statement
567 %type<ptr> quasi_string_const
568 %type<ptr> host_variable_wo_indicator
569 %type<ptr> id_list_
570 %type<ptr> opt_specifier_list
571 %type<ptr> specifier_list
572 %type<ptr> optional_declarators
573 %type<ptr> struct_specifier
574 %type<ptr> opt_struct_specifier_body
575 %type<ptr> struct_specifier_body
576 %type<ptr> specifier_qualifier_list
577 %type<ptr> optional_struct_declarator_list
578 %type<ptr> struct_declarator_list
579 %type<ptr> struct_declarator
580 %type<ptr> init_declarator_list
581 %type<ptr> init_declarator
582 %type<ptr> declarator_
583 %type<ptr> direct_declarator
584 %type<ptr> param_spec
585 %type<ptr> param_type_list
586 %type<ptr> parameter_list
587 %type<ptr> trailing_params
588 %type<ptr> param_decl_tail_list
589 %type<ptr> parameter_declaration
590 %type<ptr> opt_abstract_declarator
591 %type<ptr> abstract_declarator
592 %type<ptr> direct_abstract_declarator
593 %type<ptr> opt_param_type_list
594 %type<ptr> identifier
595 %type<ptr> c_subscript
596 %type<ptr> indicator_var
597 %type<ptr> host_var_w_opt_indicator
598 %type<ptr> hostvar
599 %type<ptr> host_ref
600 %type<ptr> opt_host_ref_tail
601 %type<ptr> host_ref_tail
602 %type<ptr> host_var_subscript
603 %type<ptr> host_var_subscript_body
604 %type<ptr> cursor_query_statement
605 %type<ptr> cursor
606 %type<ptr> descriptor_name
607 %type<ptr> struct_tag
608 %type<ptr> struct_declaration_list
609 %type<ptr> struct_declaration
610 %type<ptr> host_variable
611 
612 %%
613 
614 // start
615 translation_unit
616  :
617  opt_embedded_chunk_list
618  {{
619 
620  pp_finish ();
621  vs_free (&pt_statement_buf);
622  /* verify push/pop modes were matched. */
623  esql_yy_check_mode ();
624  mm_free();
625  DBG_PRINT}}
626  ;
627 
628 opt_embedded_chunk_list
629  : // empty
630  {DBG_PRINT}
631  | embedded_chunk_list
632  {DBG_PRINT}
633  ;
634 
635 embedded_chunk_list
636  : embedded_chunk_list embedded_chunk
637  {DBG_PRINT}
638  | embedded_chunk
639  {DBG_PRINT}
640  ;
641 
642 embedded_chunk
643  : chunk_header
644  {DBG_PRINT}
645  chunk_body
646  {DBG_PRINT}
647  | '{'
648  {{
649 
650  pp_push_name_scope ();
651 
652  DBG_PRINT}}
653  opt_embedded_chunk_list
654  {{
655 
656  pp_pop_name_scope ();
657 
658  DBG_PRINT}}
659  '}'
660  {DBG_PRINT}
661  ;
662 
663 chunk_header
664  : exec sql
665  {DBG_PRINT}
666  ;
667 
668 chunk_body
669  : declare_section ';'
670  {{
671 
672  esql_yy_enter (ECHO_mode);
673  pp_suppress_echo (false);
674 
675  DBG_PRINT}}
676  | esql_statement ';'
677  {{
678 
679  esql_yy_enter (ECHO_mode);
680  pp_suppress_echo (false);
681 
682  DBG_PRINT}}
683  ;
684 
685 exec
686  : EXEC
687  {{
688 
689  esql_yy_enter (CSQL_mode);
690  reset_globals ();
691 
692  DBG_PRINT}}
693  ;
694 
695 sql
696  : SQLX
697  {DBG_PRINT}
698  ;
699 
700 // sqlx mode
701 declare_section
702  : BEGIN_ DECLARE SECTION ';'
703  {{
704 
705  esql_yy_enter (C_mode);
706  pp_suppress_echo (false);
707 
708  DBG_PRINT}}
709  declare_section_body
710  {DBG_PRINT}
711  exec sql END DECLARE SECTION
712  {DBG_PRINT}
713  ;
714 
715 esql_statement
716  : opt_repeated embedded_statement
717  {{
718 
719  ignore_repeat ();
720  esql_yy_sync_lineno ();
721  esql_yy_set_buf (NULL);
722 
723  DBG_PRINT}}
724  | opt_repeated declare_cursor_statement
725  {{
726 
727  ignore_repeat ();
728 
729  DBG_PRINT}}
730  | opt_repeated
731  {{
732 
733  vs_clear (&pt_statement_buf);
734  esql_yy_set_buf (&pt_statement_buf);
735 
736  DBG_PRINT}}
737  csql_statement
738  {DBG_PRINT}
739  ;
740 
741 opt_repeated
742  : // empty
743  {{
744 
745  repeat_option = false;
746 
747  DBG_PRINT}}
748  | REPEATED
749  {{
750 
751  repeat_option = true;
752 
753  DBG_PRINT}}
754  ;
755 
756 embedded_statement
757  : whenever_statement
758  {DBG_PRINT}
759  | connect_statement
760  {DBG_PRINT}
761  | disconnect_statement
762  {DBG_PRINT}
763  | open_statement
764  {DBG_PRINT}
765  | close_statement
766  {DBG_PRINT}
767  | describe_statement
768  {DBG_PRINT}
769  | prepare_statement
770  {DBG_PRINT}
771  | execute_statement
772  {DBG_PRINT}
773  | fetch_statement
774  {DBG_PRINT}
775  | INCLUDE SQLCA
776  {DBG_PRINT}
777  | INCLUDE SQLDA
778  {DBG_PRINT}
779  | commit_statement
780  {DBG_PRINT}
781  | rollback_statement
782  {DBG_PRINT}
783  ;
784 
785 whenever_statement
786  : WHENEVER whenever_action
787  {DBG_PRINT}
788  ;
789 
790 of_whenever_state
791  : SQLWARNING_
792  {{
793 
794  $$ = SQLWARNING;
795 
796  DBG_PRINT}}
797  | SQLERROR_
798  {{
799 
800  $$ = SQLERROR;
801 
802  DBG_PRINT}}
803  | NOT FOUND
804  {{
805 
806  $$ = NOT_FOUND;
807 
808  DBG_PRINT}}
809  ;
810 
811 whenever_action
812  : of_whenever_state CONTINUE_
813  {{
814 
815  pp_add_whenever_to_scope ($1, CONTINUE, NULL);
816 
817  DBG_PRINT}}
818  | of_whenever_state STOP_
819  {{
820 
821  pp_add_whenever_to_scope ($1, STOP, NULL);
822 
823  DBG_PRINT}}
824  | of_whenever_state GOTO_ opt_COLON IDENTIFIER
825  {{
826 
827  pp_add_whenever_to_scope ($1, GOTO, $4);
828 
829  DBG_PRINT}}
830  | of_whenever_state GO TO opt_COLON IDENTIFIER
831  {{
832 
833  pp_add_whenever_to_scope ($1, GOTO, $5);
834 
835  DBG_PRINT}}
836  | of_whenever_state CALL_ IDENTIFIER
837  {{
838 
839  pp_add_whenever_to_scope ($1, CALL, $3);
840 
841  DBG_PRINT}}
842  ;
843 
844 opt_COLON
845  : // empty
846  {DBG_PRINT}
847  | ':'
848  {DBG_PRINT}
849  ;
850 
851 connect_statement
852  : CONNECT quasi_string_const opt_id_by_quasi
853  {{
854 
855  HOST_LOD *hvars;
856  HOST_REF *href = $2;
857 
858  if ($3)
859  href = $3;
860 
861  hvars = pp_input_refs ();
862  esql_Translate_table.tr_connect (CHECK_HOST_REF (hvars, 0),
863  CHECK_HOST_REF (hvars, 1),
864  CHECK_HOST_REF (hvars, 2));
865  already_translated = true;
866 
867  DBG_PRINT}}
868  ;
869 
870 opt_id_by_quasi
871  : // empty
872  {{
873 
874  $$ = NULL;
875 
876  DBG_PRINT}}
877  | IDENTIFIED BY quasi_string_const opt_with_quasi
878  {{
879 
880  if ($4)
881  {
882  $$ = $4;
883  }
884  else
885  {
886  $$ = $3;
887  }
888 
889  DBG_PRINT}}
890  ;
891 
892 opt_with_quasi
893  : // empty
894  {{
895 
896  $$ = NULL;
897 
898  DBG_PRINT}}
899  | WITH quasi_string_const
900  {{
901 
902 
903  $$ = $2;
904 
905  DBG_PRINT}}
906  ;
907 
908 disconnect_statement
909  : DISCONNECT
910  {{
911 
912  esql_Translate_table.tr_disconnect ();
913  already_translated = true;
914 
915  DBG_PRINT}}
916  ;
917 
918 declare_cursor_statement
919  : DECLARE IDENTIFIER CURSOR_ FOR cursor_query_statement
920  {{
921 
922  char **cp = $5;
923  char *c_nam = strdup($2);
924  pp_new_cursor (c_nam, cp[0], (int) (long) cp[1], NULL,
925  pp_detach_host_refs ());
926  free_and_init(c_nam);
927 
928  DBG_PRINT}}
929  | DECLARE IDENTIFIER CURSOR_ FOR dynamic_statement
930  {{
931 
932  char *c_nam = strdup($2);
933  pp_new_cursor (c_nam, NULL, 0, (STMT *) $5, pp_detach_host_refs ());
934  free_and_init(c_nam);
935  esql_yy_sync_lineno ();
936  esql_yy_set_buf (NULL);
937 
938  DBG_PRINT}}
939  ;
940 
941 
942 dynamic_statement
943  : IDENTIFIER
944  {{
945 
946  $$ = pp_new_stmt ($1);
947 
948  DBG_PRINT}}
949  ;
950 
951 
952 open_statement
953  : OPEN cursor opt_for_read_only using_part
954  {{
955 
956  CURSOR *cur = $2;
957  int rdonly = $3;
958  HOST_LOD *usg;
959 
960  if (cur->static_stmt)
961  {
962  if (pp_input_refs ())
963  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_USING_NOT_PERMITTED),
964  cur->name);
965  else
966  esql_Translate_table.tr_open_cs (cur->cid,
967  (const char *) cur->static_stmt,
968  cur->stmtLength,
969  -1,
970  rdonly,
971  HOST_N_REFS (cur->host_refs),
972  HOST_REFS (cur->host_refs),
973  (const char *) HOST_DESC (cur->
974  host_refs));
975  }
976  else if (cur->dynamic_stmt)
977  {
978  usg = pp_input_refs ();
979  esql_Translate_table.tr_open_cs (cur->cid,
980  NULL,
981  (int) 0,
982  cur->dynamic_stmt->sid,
983  rdonly,
984  HOST_N_REFS (usg), HOST_REFS (usg),
985  (const char *) HOST_DESC (usg));
986  }
987  else
988  {
989  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_CURSOR_UNDEFINED),
990  cur->name);
991  }
992 
993 
994  already_translated = true;
995 
996  DBG_PRINT}}
997  ;
998 
999 opt_for_read_only
1000  : // empty
1001  {{
1002 
1003  $$ = 0;
1004 
1005  DBG_PRINT}}
1006  | FOR READ ONLY
1007  {{
1008 
1009  $$ = 1;
1010 
1011  DBG_PRINT}}
1012  ;
1013 
1014 using_part
1015  : // empty
1016  {DBG_PRINT}
1017  | USING host_variable_lod
1018  {DBG_PRINT}
1019  ;
1020 
1021 descriptor_name
1022  : host_variable_wo_indicator
1023  {{
1024 
1025  HOST_REF *href = $1;
1026  char *nam = NULL;
1027  if (pp_check_type (href,
1028  NEWSET (C_TYPE_SQLDA),
1029  pp_get_msg (EX_ESQLM_SET, MSG_PTR_TO_DESCR)))
1030  nam = pp_switch_to_descriptor ();
1031 
1032  $$ = nam;
1033 
1034  DBG_PRINT}}
1035  ;
1036 
1037 close_statement
1038  : CLOSE cursor
1039  {{
1040 
1041  CURSOR *cur = $2;
1042  if (cur)
1043  esql_Translate_table.tr_close_cs (cur->cid);
1044  already_translated = true;
1045 
1046  DBG_PRINT}}
1047  ;
1048 
1049 cursor
1050  : IDENTIFIER
1051  {{
1052 
1053  CURSOR *cur = NULL;
1054  if ((cur = pp_lookup_cursor ($1)) == NULL)
1055  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_CURSOR_UNDEFINED), $1);
1056 
1057  $$ = cur;
1058 
1059  DBG_PRINT}}
1060  ;
1061 
1062 describe_statement
1063  : DESCRIBE dynamic_statement INTO descriptor_name
1064  {{
1065 
1066  STMT *d_statement = $2;
1067  char *nam = $4;
1068 
1069  if (d_statement && nam)
1070  esql_Translate_table.tr_describe (d_statement->sid, nam);
1071  already_translated = true;
1072 
1073  DBG_PRINT}}
1074  | DESCRIBE OBJECT host_variable_wo_indicator ON_ id_list_ INTO descriptor_name
1075  {{
1076 
1077  HOST_REF *href = $3;
1078  PTR_VEC *pvec = $5;
1079  char *nam = $7;
1080 
1081  pp_copy_host_refs ();
1082 
1083  if (href && pvec && nam &&
1084  pp_check_type (href,
1085  NEWSET (C_TYPE_OBJECTID),
1086  pp_get_msg (EX_ESQLM_SET, MSG_PTR_TO_DB_OBJECT)))
1087  {
1088  esql_Translate_table.tr_object_describe (href,
1089  pp_ptr_vec_n_elems (pvec),
1090  (const char **)
1091  pp_ptr_vec_elems (pvec), nam);
1092  }
1093 
1094  pp_free_ptr_vec (pvec);
1095  already_translated = true;
1096 
1097  DBG_PRINT}}
1098  ;
1099 
1100 prepare_statement
1101  : PREPARE dynamic_statement FROM quasi_string_const
1102  {{
1103 
1104  HOST_REF *href = $4;
1105  STMT *d_statement = $2;
1106 
1107  if (d_statement && href)
1108  esql_Translate_table.tr_prepare_esql (d_statement->sid, href);
1109 
1110  already_translated = true;
1111 
1112  DBG_PRINT}}
1113  ;
1114 
1115 into_result
1116  : of_into_to
1117  {{
1118 
1119  pp_gather_output_refs ();
1120  esql_yy_erase_last_token ();
1121  esql_yy_set_buf (NULL);
1122 
1123  DBG_PRINT}}
1124  host_variable_lod
1125  {{
1126 
1127  pp_gather_input_refs ();
1128 
1129  DBG_PRINT}}
1130  ;
1131 
1132 of_into_to
1133  : INTO
1134  | TO
1135  ;
1136 
1137 host_variable_lod
1138  : host_variable_list
1139  {DBG_PRINT}
1140  | DESCRIPTOR descriptor_name
1141  {DBG_PRINT}
1142  ;
1143 
1144 quasi_string_const
1145  : STRING_LIT
1146  {{
1147 
1148  $$ = pp_add_host_str ($1);
1149 
1150  DBG_PRINT}}
1151  | host_variable_wo_indicator
1152  {{
1153 
1154  HOST_REF *href = $1;
1155  $$ = pp_check_type (href,
1156  NEWSET (C_TYPE_CHAR_ARRAY) |
1157  NEWSET (C_TYPE_CHAR_POINTER) |
1158  NEWSET (C_TYPE_STRING_CONST) |
1159  NEWSET (C_TYPE_VARCHAR) |
1160  NEWSET (C_TYPE_NCHAR) |
1161  NEWSET (C_TYPE_VARNCHAR),
1162  pp_get_msg (EX_ESQLM_SET, MSG_CHAR_STRING));
1163 
1164  DBG_PRINT}}
1165  ;
1166 
1167 host_variable_list
1168  :
1169  {{
1170 
1171  esql_yy_erase_last_token ();
1172  structs_allowed = true;
1173 
1174  DBG_PRINT}}
1175  host_variable_list_tail
1176  {{
1177 
1178  pp_check_host_var_list ();
1179  ECHO;
1180 
1181  DBG_PRINT}}
1182  ;
1183 
1184 host_variable_wo_indicator
1185  :
1186  {{
1187 
1188  esql_yy_erase_last_token ();
1189 
1190  DBG_PRINT}}
1191  host_var_w_opt_indicator
1192  {{
1193 
1194  HOST_REF *href2;
1195 
1196  href2 = $2;
1197  if (href2 && href2->ind)
1198  {
1199  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_INDICATOR_NOT_ALLOWED),
1200  pp_get_expr (href2));
1201  pp_free_host_var (href2->ind);
1202  href2->ind = NULL;
1203  }
1204 
1205  $$ = href2;
1206 
1207  DBG_PRINT}}
1208  ;
1209 
1210 id_list_
1211  : id_list_ ',' IDENTIFIER
1212  {{
1213 
1214  PTR_VEC *pvec = NULL;
1215  pvec = pp_add_ptr (pvec, strdup ($3));
1216  $$ = pvec;
1217 
1218  DBG_PRINT}}
1219  | IDENTIFIER
1220  {{
1221 
1222  PTR_VEC *pvec;
1223  pvec = pp_new_ptr_vec (&id_list);
1224  pp_add_ptr (&id_list, strdup ($1));
1225 
1226  $$ = pvec;
1227 
1228  DBG_PRINT}}
1229  ;
1230 
1231 execute_statement
1232  : EXECUTE dynamic_statement using_part opt_into_result
1233  {{
1234 
1235  STMT *d_statement = $2;
1236  if (d_statement)
1237  {
1238  HOST_LOD *inputs, *outputs;
1239  inputs = pp_input_refs ();
1240  outputs = pp_output_refs ();
1241  esql_Translate_table.tr_execute (d_statement->sid,
1242  HOST_N_REFS (inputs),
1243  HOST_REFS (inputs),
1244  (const char *) HOST_DESC (inputs),
1245  HOST_N_REFS (outputs),
1246  HOST_REFS (outputs),
1247  (const char *) HOST_DESC (outputs));
1248  already_translated = true;
1249  }
1250 
1251  DBG_PRINT}}
1252  | EXECUTE IMMEDIATE quasi_string_const
1253  {{
1254 
1255  HOST_REF *href = $3;
1256 
1257  if (href)
1258  esql_Translate_table.tr_execute_immediate (href);
1259  already_translated = true;
1260 
1261  DBG_PRINT}}
1262  ;
1263 
1264 opt_into_result
1265  : // empty
1266  | into_result
1267  ;
1268 
1269 fetch_statement
1270  : FETCH cursor into_result
1271  {{
1272 
1273  CURSOR *cur = $2;
1274  if (cur)
1275  {
1276  HOST_LOD *hlod = pp_output_refs ();
1277  esql_Translate_table.tr_fetch_cs (cur->cid,
1278  HOST_N_REFS (hlod), HOST_REFS (hlod),
1279  (char *) HOST_DESC (hlod));
1280  }
1281 
1282  already_translated = true;
1283 
1284  DBG_PRINT}}
1285  | FETCH OBJECT host_variable_wo_indicator ON_ id_list_ into_result
1286  {{
1287 
1288  HOST_REF *href = $3;
1289  PTR_VEC *pvec = $5;
1290  HOST_LOD *hlod;
1291 
1292 
1293  if (href && pvec
1294  && (hlod = pp_output_refs ())
1295  && pp_check_type (href,
1296  NEWSET
1297  (C_TYPE_OBJECTID),
1298  pp_get_msg (EX_ESQLM_SET, MSG_PTR_TO_DB_OBJECT)))
1299  {
1300  esql_Translate_table.tr_object_fetch (href,
1301  pp_ptr_vec_n_elems (pvec),
1302  (const char **)
1303  pp_ptr_vec_elems (pvec),
1304  HOST_N_REFS (hlod),
1305  HOST_REFS (hlod),
1306  (const char *) HOST_DESC (hlod));
1307  }
1308 
1309  pp_free_ptr_vec (pvec);
1310  already_translated = true;
1311 
1312  DBG_PRINT}}
1313  ;
1314 
1315 commit_statement
1316  : COMMIT opt_work
1317  {{
1318 
1319  esql_Translate_table.tr_commit ();
1320  already_translated = true;
1321 
1322  DBG_PRINT}}
1323  ;
1324 
1325 opt_work
1326  : // empty
1327  | WORK
1328  ;
1329 
1330 rollback_statement
1331  : ROLLBACK opt_work
1332  {{
1333 
1334  esql_Translate_table.tr_rollback ();
1335  already_translated = true;
1336 
1337  DBG_PRINT}}
1338  ;
1339 
1340 csql_statement_head
1341  : ALTER
1342  {{
1343 
1344  ECHO_STR ($1, strlen ($1));
1345  $$ = NO_CURSOR;
1346 
1347  DBG_PRINT}}
1348  | ATTACH
1349  {{
1350 
1351  ECHO_STR ($1, strlen ($1));
1352  $$ = NO_CURSOR;
1353 
1354  DBG_PRINT}}
1355  | CALL_
1356  {{
1357 
1358  ECHO_STR ($1, strlen ($1));
1359  $$ = NO_CURSOR;
1360 
1361  DBG_PRINT}}
1362  | CREATE
1363  {{
1364 
1365  ECHO_STR ($1, strlen ($1));
1366  $$ = NO_CURSOR;
1367 
1368  DBG_PRINT}}
1369  | DROP
1370  {{
1371 
1372  ECHO_STR ($1, strlen ($1));
1373  $$ = NO_CURSOR;
1374 
1375  DBG_PRINT}}
1376  | END
1377  {{
1378 
1379  ECHO_STR ($1, strlen ($1));
1380  $$ = NO_CURSOR;
1381 
1382  DBG_PRINT}}
1383  | EVALUATE
1384  {{
1385 
1386  ECHO_STR ($1, strlen ($1));
1387  $$ = NO_CURSOR;
1388 
1389  DBG_PRINT}}
1390  | EXCLUDE
1391  {{
1392 
1393  ECHO_STR ($1, strlen ($1));
1394  $$ = NO_CURSOR;
1395 
1396  DBG_PRINT}}
1397  | FOR
1398  {{
1399 
1400  ECHO_STR ($1, strlen ($1));
1401  $$ = NO_CURSOR;
1402 
1403  DBG_PRINT}}
1404  | GET
1405  {{
1406 
1407  ECHO_STR ($1, strlen ($1));
1408  $$ = NO_CURSOR;
1409 
1410  DBG_PRINT}}
1411  | GRANT
1412  {{
1413 
1414  ECHO_STR ($1, strlen ($1));
1415  $$ = NO_CURSOR;
1416 
1417  DBG_PRINT}}
1418  | INSERT
1419  {{
1420 
1421  ECHO_STR ($1, strlen ($1));
1422  $$ = NO_CURSOR;
1423 
1424  DBG_PRINT}}
1425  | ON_
1426  {{
1427 
1428  ECHO_STR ($1, strlen ($1));
1429  $$ = NO_CURSOR;
1430 
1431  DBG_PRINT}}
1432  | REGISTER_
1433  {{
1434 
1435  ECHO_STR ($1, strlen ($1));
1436  $$ = NO_CURSOR;
1437 
1438  DBG_PRINT}}
1439  | RENAME
1440  {{
1441 
1442  ECHO_STR ($1, strlen ($1));
1443  $$ = NO_CURSOR;
1444 
1445  DBG_PRINT}}
1446  | REVOKE
1447  {{
1448 
1449  ECHO_STR ($1, strlen ($1));
1450  $$ = NO_CURSOR;
1451 
1452  DBG_PRINT}}
1453  | SELECT
1454  {{
1455 
1456  ECHO_STR ($1, strlen ($1));
1457  $$ = NO_CURSOR;
1458 
1459  DBG_PRINT}}
1460  | SET
1461  {{
1462 
1463  ECHO_STR ($1, strlen ($1));
1464  $$ = NO_CURSOR;
1465 
1466  DBG_PRINT}}
1467  | TRIGGER
1468  {{
1469 
1470  ECHO_STR ($1, strlen ($1));
1471  $$ = NO_CURSOR;
1472 
1473  DBG_PRINT}}
1474  | USE
1475  {{
1476 
1477  ECHO_STR ($1, strlen ($1));
1478  $$ = NO_CURSOR;
1479 
1480  DBG_PRINT}}
1481  | DELETE_
1482  {{
1483 
1484  ECHO_STR ($1, strlen ($1));
1485  $$ = CURSOR_DELETE;
1486 
1487  DBG_PRINT}}
1488  | UPDATE
1489  {{
1490 
1491  ECHO_STR ($1, strlen ($1));
1492  $$ = CURSOR_UPDATE;
1493 
1494  DBG_PRINT}}
1495  ;
1496 
1497 csql_statement
1498  :
1499  {{
1500 
1501  esql_yy_set_buf (&pt_statement_buf);
1502  esql_yy_push_mode (BUFFER_mode);
1503 
1504  DBG_PRINT}}
1505  csql_statement_head
1506  {{
1507 
1508  g_cursor_type = $2;
1509  //esql_yy_push_mode(BUFFER_mode);
1510 
1511  DBG_PRINT}}
1512  csql_statement_tail
1513  {DBG_PRINT}
1514  ;
1515 
1516 
1517 // c mode
1518 
1519 declare_section_body
1520  : opt_ext_decl_list
1521  {DBG_PRINT}
1522  ;
1523 
1524 opt_ext_decl_list
1525  : // empty
1526  {DBG_PRINT}
1527  | ext_decl_list
1528  {DBG_PRINT}
1529  ;
1530 
1531 
1532 ext_decl_list
1533  : ext_decl_list external_declaration
1534  {DBG_PRINT}
1535  | external_declaration
1536  {DBG_PRINT}
1537  ;
1538 
1539 external_declaration
1540  :
1541  {{
1542 
1543  pp_reset_current_type_spec ();
1544 
1545  DBG_PRINT}}
1546  opt_specifier_list optional_declarators
1547  {{
1548 
1549  LINK *plink = $2;
1550  SYMBOL *psym = $3;
1551 
1552  if (psym)
1553  {
1554  pp_add_spec_to_decl (plink, psym);
1555  /*
1556  * If we have a VARCHAR declaration that didn't
1557  * come from a typedef, it has been suppressed
1558  * (i.e., it hasn't yet been echoed to the output
1559  * stream because it needs to be rewritten). Now
1560  * is the time to echo the rewritten decl out.
1561  *
1562  * If the decl came from a typedef, it's already
1563  * been echoed. That's fine, because it doesn't
1564  * need to be rewritten in that case.
1565  */
1566  if (IS_PSEUDO_TYPE (plink) && !plink->from_tdef)
1567  {
1568  pp_print_decls (psym, true);
1569  esql_yy_sync_lineno ();
1570  }
1571  /*
1572  * Don't do this until after printing, because
1573  * it's going to jack with the 'next' links in
1574  * the symbols, which will cause the printer to
1575  * repeat declarations.
1576  */
1577  pp_add_symbols_to_table (psym);
1578  }
1579  else if (plink)
1580  {
1581  /* pp_print_specs(plink); */
1582  }
1583  if (plink && !plink->tdef)
1584  pp_discard_link_chain (plink);
1585 
1586  DBG_PRINT}}
1587  end_declarator_list
1588  ;
1589 
1590 opt_specifier_list
1591  : // empty
1592  {{
1593 
1594  $$ = pp_current_type_spec ();
1595 
1596  DBG_PRINT}}
1597  | specifier_list
1598  {{
1599 
1600  $$ = $1;
1601 
1602  DBG_PRINT}}
1603  ;
1604 
1605 optional_declarators
1606  : // empty
1607  {{
1608 
1609  $$ = NULL;
1610 
1611  DBG_PRINT}}
1612  | init_declarator_list
1613  {{
1614 
1615  $$ = $1;
1616 
1617  DBG_PRINT}}
1618  ;
1619 
1620 end_declarator_list
1621  : nS_td ';'
1622  {{
1623 
1624  /*
1625  * The specifier for this declarator list may have
1626  * been a VARCHAR (or maybe not); if it was, echoing
1627  * has been suppressed since we saw that keyword.
1628  * Either way, we want to turn echoing back on.
1629  */
1630  pp_suppress_echo (false);
1631 
1632  DBG_PRINT}}
1633  ;
1634 
1635 specifier_list
1636  : specifier_list specifier_
1637  {{
1638 
1639  $$ = pp_current_type_spec ();
1640 
1641  DBG_PRINT}}
1642  | specifier_
1643  {{
1644 
1645  $$ = pp_current_type_spec ();
1646 
1647  DBG_PRINT}}
1648  ;
1649 
1650 specifier_
1651  : storage_class_specifier
1652  {DBG_PRINT}
1653  | type_specifier
1654  {DBG_PRINT}
1655  | type_qualifier
1656  {DBG_PRINT}
1657  ;
1658 
1659 storage_class_specifier
1660  : TYPEDEF_
1661  {{
1662 
1663  pp_add_storage_class (TYPEDEF_);
1664 
1665  DBG_PRINT}}
1666  | EXTERN_
1667  {{
1668 
1669  pp_add_storage_class (EXTERN_);
1670 
1671  DBG_PRINT}}
1672  | STATIC_
1673  {{
1674 
1675  pp_add_storage_class (STATIC_);
1676 
1677  DBG_PRINT}}
1678  | AUTO_
1679  {{
1680 
1681  pp_add_storage_class (AUTO_);
1682 
1683  DBG_PRINT}}
1684  | REGISTER_
1685  {{
1686 
1687  pp_add_storage_class (REGISTER_);
1688 
1689  DBG_PRINT}}
1690  ;
1691 
1692 type_specifier
1693  : nS_ntd base_type_specifier
1694  {DBG_PRINT}
1695  | type_adjective
1696  {DBG_PRINT}
1697  | struct_specifier
1698  {{
1699 
1700  pp_add_struct_spec ($1);
1701 
1702  DBG_PRINT}}
1703  | enum_specifier
1704  {{
1705 
1706  pp_add_type_noun (INT_);
1707  pp_add_type_adj (INT_);
1708 
1709  DBG_PRINT}}
1710  ;
1711 
1712 base_type_specifier
1713  : VOID_
1714  {{
1715 
1716  pp_add_type_noun (VOID_);
1717 
1718  DBG_PRINT}}
1719  | CHAR_
1720  {{
1721 
1722  pp_add_type_noun (CHAR_);
1723 
1724  DBG_PRINT}}
1725  | INT_
1726  {{
1727 
1728  pp_add_type_noun (INT_);
1729 
1730  DBG_PRINT}}
1731  | FLOAT_
1732  {{
1733 
1734  pp_add_type_noun (FLOAT_);
1735 
1736  DBG_PRINT}}
1737  | DOUBLE_
1738  {{
1739 
1740  pp_add_type_noun (DOUBLE_);
1741 
1742  DBG_PRINT}}
1743  | TYPEDEF_NAME
1744  {{
1745 
1746  pp_add_typedefed_spec (g_identifier_symbol->type);
1747 
1748  DBG_PRINT}}
1749  | VARCHAR_
1750  {{
1751 
1752  /*
1753  * The VARCHAR_ token turns OFF echoing (the magic
1754  * happens in check_c_identifier()) because we're
1755  * going to have to rewrite the declaration. This is
1756  * slimy, but doing the right thing (parsing
1757  * everything and then regurgitating it) is too
1758  * expensive because we allow arbitrary initializers,
1759  * etc. Echoing will be re-enabled again when we see
1760  * the end of the declarator list following the
1761  * current specifier.
1762  */
1763  pp_add_type_noun (VARCHAR_);
1764 
1765  DBG_PRINT}}
1766  | BIT_ opt_varying
1767  {{
1768 
1769  pp_add_type_noun ($2);
1770 
1771  DBG_PRINT}}
1772  ;
1773 
1774 opt_varying
1775  : // empty
1776  {{
1777 
1778  $$ = BIT_;
1779 
1780  DBG_PRINT}}
1781  | VARYING
1782  {{
1783 
1784  $$ = VARBIT_;
1785 
1786  DBG_PRINT}}
1787  ;
1788 
1789 type_adjective
1790  : SHORT_
1791  {{
1792 
1793  pp_add_type_adj (SHORT_);
1794 
1795  DBG_PRINT}}
1796  | LONG_
1797  {{
1798 
1799  pp_add_type_adj (LONG_);
1800 
1801  DBG_PRINT}}
1802  | SIGNED_
1803  {{
1804 
1805  pp_add_type_adj (SIGNED_);
1806 
1807  DBG_PRINT}}
1808  | UNSIGNED_
1809  {{
1810 
1811  pp_add_type_adj (UNSIGNED_);
1812 
1813  DBG_PRINT}}
1814  ;
1815 
1816 type_qualifier
1817  : CONST_
1818  {{
1819 
1820  pp_add_type_adj (CONST_);
1821 
1822  DBG_PRINT}}
1823  | VOLATILE_
1824  {{
1825 
1826  pp_add_type_adj (VOLATILE_);
1827 
1828  DBG_PRINT}}
1829  ;
1830 
1831 struct_specifier
1832  : nS_ntd
1833  of_struct_union
1834  {{
1835 
1836  g_su = $2;
1837  g_sdef2 = NULL;
1838 
1839  DBG_PRINT}}
1840  struct_specifier_body
1841  {{
1842 
1843  STRUCTDEF *sdef = $4;
1844  $$ = sdef;
1845 
1846  DBG_PRINT}}
1847  | nS_ntd
1848  of_struct_union
1849  struct_tag
1850  {{
1851 
1852  g_su = $2;
1853  g_sdef2 = $3;
1854 
1855  DBG_PRINT}}
1856  opt_struct_specifier_body
1857  {{
1858 
1859  STRUCTDEF *sdef = $5;
1860  sdef = g_sdef2;
1861  sdef->by_name = true;
1862  $$ = sdef;
1863 
1864  DBG_PRINT}}
1865  ;
1866 
1867 of_struct_union
1868  : STRUCT_
1869  {{
1870 
1871  $$ = 1;
1872 
1873  DBG_PRINT}}
1874  | UNION_
1875  {{
1876 
1877  $$ = 0;
1878 
1879  DBG_PRINT}}
1880  ;
1881 
1882 opt_struct_specifier_body
1883  : // emtpy
1884  {{
1885 
1886  $$ = NULL;
1887 
1888  DBG_PRINT}}
1889  | struct_specifier_body
1890  {{
1891 
1892  $$ = $1;
1893 
1894  DBG_PRINT}}
1895  ;
1896 
1897 struct_specifier_body
1898  : nS_td
1899  '{'
1900  {{
1901 
1902  pp_push_spec_scope ();
1903 
1904  DBG_PRINT}}
1905  struct_declaration_list
1906  {{
1907 
1908  pp_pop_spec_scope ();
1909 
1910  DBG_PRINT}}
1911  '}'
1912  {{
1913 
1914  SYMBOL *psym = $4;
1915 
1916  if (g_sdef2 == NULL)
1917  {
1918  g_sdef2 = pp_new_structdef (NULL);
1919  pp_Struct_table->add_symbol (pp_Struct_table, g_sdef2);
1920  }
1921  if (psym == NULL)
1922  {
1923  pp_Struct_table->remove_symbol (pp_Struct_table, g_sdef2);
1924  pp_discard_structdef (g_sdef2);
1925  }
1926  else if (g_sdef2->fields)
1927  {
1928  varstring gack;
1929  vs_new (&gack);
1930  vs_sprintf (&gack, "%s %s", g_sdef2->type_string, g_sdef2->tag);
1931  esql_yyredef (vs_str (&gack));
1932  vs_free (&gack);
1933  pp_discard_symbol_chain (psym);
1934  }
1935  else
1936  {
1937  g_sdef2->type = g_su;
1938  g_sdef2->type_string = (unsigned char *) (g_su ? "struct" : "union");
1939  g_sdef2->fields = psym;
1940  }
1941 
1942  $$ = g_sdef2;
1943 
1944  DBG_PRINT}}
1945  ;
1946 
1947 struct_tag
1948  : IDENTIFIER
1949  {{
1950 
1951  STRUCTDEF *sdef;
1952  SYMBOL dummy;
1953  dummy.name = $1;
1954 
1955  if (!
1956  (sdef =
1957  (STRUCTDEF *) pp_Struct_table->find_symbol (pp_Struct_table, &dummy)))
1958  {
1959  sdef = pp_new_structdef (strdup($1));
1960  pp_Struct_table->add_symbol (pp_Struct_table, sdef);
1961  }
1962 
1963  $$ = sdef;
1964 
1965  DBG_PRINT}}
1966  ;
1967 
1968 struct_declaration_list
1969  : struct_declaration_list struct_declaration
1970  {{
1971 
1972  SYMBOL *last_field = $1;
1973  if (last_field)
1974  {
1975  SYMBOL *tmp = last_field->next;
1976  last_field->next = $2;
1977  last_field->next->next = tmp;
1978  }
1979 
1980  $$ = $1;
1981 
1982  DBG_PRINT}}
1983  | struct_declaration
1984  {{
1985 
1986  $$ = $1;
1987 
1988  DBG_PRINT}}
1989  ;
1990 
1991 struct_declaration
1992  : specifier_qualifier_list optional_struct_declarator_list
1993  {{
1994 
1995  LINK *plink = $1;
1996  SYMBOL *psym = $2;
1997  SYMBOL *sym = NULL;
1998 
1999  if (psym)
2000  {
2001  pp_add_spec_to_decl (plink, psym);
2002  /*
2003  * Same deal as with an upper-level decl: this
2004  * may have been a VARCHAR decl that needs to be
2005  * rewritten. If so, it has not yet been echoed;
2006  * do so now.
2007  */
2008  if (IS_PSEUDO_TYPE (plink) && !plink->from_tdef)
2009  {
2010  pp_print_decls (psym, true);
2011  esql_yy_sync_lineno ();
2012  }
2013  sym = psym;
2014  }
2015  else
2016  sym = NULL;
2017 
2018  if (!plink->tdef)
2019  pp_discard_link_chain (plink);
2020 
2021  g_struct_declaration_sym = sym;
2022 
2023  DBG_PRINT}}
2024  end_declarator_list
2025  {{
2026 
2027  $$ = g_struct_declaration_sym;
2028 
2029  DBG_PRINT}}
2030  ;
2031 
2032 specifier_qualifier_list
2033  :
2034  {{
2035 
2036  pp_reset_current_type_spec ();
2037  pp_disallow_storage_classes ();
2038 
2039  DBG_PRINT}}
2040  specifier_list
2041  {{
2042 
2043  $$ = $2;
2044 
2045  DBG_PRINT}}
2046  ;
2047 
2048 optional_struct_declarator_list
2049  : // empty
2050  {{
2051 
2052  $$ = NULL;
2053 
2054  DBG_PRINT}}
2055  | struct_declarator_list
2056  {{
2057 
2058  $$ = $1;
2059 
2060  DBG_PRINT}}
2061  ;
2062 
2063 struct_declarator_list
2064  : struct_declarator_list ',' struct_declarator
2065  {{
2066 
2067  SYMBOL *psym = $1;
2068  if (psym)
2069  {
2070  psym->next = $3;
2071  }
2072 
2073  $$ = psym;
2074 
2075  DBG_PRINT}}
2076  | struct_declarator
2077  {{
2078 
2079  $$ = $1;
2080 
2081  DBG_PRINT}}
2082  ;
2083 
2084 struct_declarator
2085  : ':'
2086  {{
2087 
2088  esql_yy_push_mode (EXPR_mode);
2089 
2090  DBG_PRINT}}
2091  c_expression
2092  {{
2093 
2094  SYMBOL *psym = NULL;
2095  $$ = psym;
2096 
2097  DBG_PRINT}}
2098  | declarator_
2099  ':'
2100  {{
2101 
2102  esql_yy_push_mode (EXPR_mode);
2103 
2104  DBG_PRINT}}
2105  c_expression
2106  {{
2107 
2108  $$ = $1;
2109 
2110  DBG_PRINT}}
2111  | declarator_
2112  {{
2113 
2114  $$ = $1;
2115 
2116  DBG_PRINT}}
2117  ;
2118 
2119 enum_specifier
2120  : ENUM '{' enumerator_list '}'
2121  | ENUM identifier optional_enumerator_list
2122  {{
2123 
2124  SYMBOL *dl = $2;
2125  if (dl->type)
2126  {
2127  esql_yyredef ((char *) dl->name);
2128  }
2129  else
2130  {
2131  pp_discard_symbol (dl);
2132  }
2133 
2134  DBG_PRINT}}
2135  ;
2136 
2137 optional_enumerator_list
2138  : // empty
2139  {DBG_PRINT}
2140  | '{' enumerator_list '}'
2141  {DBG_PRINT}
2142  ;
2143 
2144 enumerator_list
2145  : enumerator_list ',' enumerator
2146  {DBG_PRINT}
2147  | enumerator
2148  {DBG_PRINT}
2149  ;
2150 
2151 enumerator
2152  : identifier
2153  {{
2154 
2155  SYMBOL *dl = $1;
2156  pp_do_enum (dl);
2157 
2158  DBG_PRINT}}
2159  | identifier
2160  '='
2161  {{
2162 
2163  esql_yy_push_mode (EXPR_mode);
2164 
2165  DBG_PRINT}}
2166  c_expression
2167  {{
2168 
2169  SYMBOL *dl = $1;
2170  pp_do_enum (dl);
2171 
2172  DBG_PRINT}}
2173  ;
2174 
2175 init_declarator_list
2176  : init_declarator_list ',' init_declarator
2177  {{
2178 
2179  SYMBOL *psym = $1;
2180  SYMBOL *psym3 = $3;
2181  if (psym3)
2182  {
2183  psym3->next = psym;
2184  }
2185 
2186  $$ = psym3;
2187 
2188  DBG_PRINT}}
2189 
2190  | init_declarator
2191  {{
2192 
2193  SYMBOL *psym = $1;
2194  if (psym)
2195  psym->next = NULL;
2196  $$ = psym;
2197 
2198  DBG_PRINT}}
2199  ;
2200 
2201 init_declarator
2202  : declarator_
2203  {{
2204 
2205  $$ = $1;
2206 
2207  DBG_PRINT}}
2208  | declarator_
2209  nS_td
2210  '='
2211  {{
2212 
2213  esql_yy_push_mode (EXPR_mode);
2214 
2215  DBG_PRINT}}
2216  c_expression nS_ntd
2217  {{
2218 
2219  SYMBOL *psym = $1;
2220  pp_add_initializer (psym);
2221 
2222  $$ = $1;
2223 
2224  DBG_PRINT}}
2225  ;
2226 
2227 declarator_
2228  : direct_declarator
2229  {{
2230 
2231  $$ = $1;
2232 
2233  DBG_PRINT}}
2234  | pointer declarator_
2235  {{
2236 
2237  SYMBOL *psym = $2;
2238  if (psym)
2239  pp_add_declarator (psym, D_POINTER);
2240  $$ = psym;
2241 
2242  DBG_PRINT}}
2243  ;
2244 
2245 direct_declarator
2246  : IDENTIFIER
2247  {{
2248 
2249  SYMBOL *psym = pp_new_symbol ($1, pp_nesting_level);
2250  g_psym = psym;
2251 
2252  DBG_PRINT}}
2253  opt_param_spec_list
2254  {{
2255 
2256  $$ = g_psym;
2257 
2258  DBG_PRINT}}
2259  | '(' declarator_ ')'
2260  {{
2261 
2262  SYMBOL *psym = pp_new_symbol ($2, pp_nesting_level);
2263  g_psym = psym;
2264 
2265  DBG_PRINT}}
2266  opt_param_spec_list
2267  {{
2268 
2269  $$ = g_psym;
2270 
2271  DBG_PRINT}}
2272  ;
2273 
2274 opt_param_spec_list
2275  : // empty
2276  {DBG_PRINT}
2277  | param_spec_list
2278  {DBG_PRINT}
2279  ;
2280 
2281 param_spec_list
2282  : param_spec_list param_spec
2283  {{
2284 
2285  SYMBOL *args = $2;
2286  if (g_psym)
2287  {
2288  pp_add_declarator (g_psym, D_FUNCTION);
2289  g_psym->etype->decl.d.args = args;
2290  }
2291 
2292  DBG_PRINT}}
2293  | param_spec_list c_subscript
2294  {{
2295 
2296  const char *sub = $2;
2297  if (g_psym)
2298  {
2299  pp_add_declarator (g_psym, D_ARRAY);
2300  g_psym->etype->decl.d.num_ele = (char *) sub;
2301  }
2302 
2303  DBG_PRINT}}
2304  | param_spec
2305  {{
2306 
2307  SYMBOL *args = $1;
2308  if (g_psym)
2309  {
2310  pp_add_declarator (g_psym, D_FUNCTION);
2311  g_psym->etype->decl.d.args = args;
2312  }
2313 
2314  DBG_PRINT}}
2315  | c_subscript
2316  {{
2317 
2318  const char *sub = $1;
2319  if (g_psym)
2320  {
2321  pp_add_declarator (g_psym, D_ARRAY);
2322  g_psym->etype->decl.d.num_ele = (char *) sub;
2323  }
2324 
2325  DBG_PRINT}}
2326  ;
2327 
2328 pointer
2329  : '*' opt_type_qualifier_list
2330  {DBG_PRINT}
2331  ;
2332 
2333 opt_type_qualifier_list
2334  : // empty
2335  {DBG_PRINT}
2336  | type_qualifier_list
2337  {DBG_PRINT}
2338  ;
2339 
2340 type_qualifier_list
2341  : type_qualifier_list type_qualifier
2342  {DBG_PRINT}
2343  | type_qualifier
2344  {DBG_PRINT}
2345  ;
2346 
2347 param_spec
2348  : '(' ')'
2349  {{
2350 
2351  $$ = NULL;
2352 
2353  DBG_PRINT}}
2354  | '(' push_name_scope param_type_list pop_name_scope ')'
2355  {{
2356 
2357  $$ = $3;
2358 
2359  DBG_PRINT}}
2360  | '(' push_name_scope id_list_ pop_name_scope ')'
2361  {{
2362 
2363  $$ = $3;
2364 
2365  DBG_PRINT}}
2366  ;
2367 
2368 push_name_scope
2369  : // empty
2370  {{
2371 
2372  pp_push_name_scope ();
2373 
2374  DBG_PRINT}}
2375  ;
2376 
2377 pop_name_scope
2378  : // empty
2379  {{
2380 
2381  pp_pop_name_scope ();
2382 
2383  DBG_PRINT}}
2384  ;
2385 
2386 push_spec_scope
2387  : // empty
2388  {{
2389 
2390  pp_push_spec_scope ();
2391 
2392  DBG_PRINT}}
2393  ;
2394 
2395 pop_spec_scope
2396  : // empty
2397  {{
2398 
2399  pp_pop_spec_scope ();
2400 
2401  DBG_PRINT}}
2402  ;
2403 
2404 param_type_list
2405  : push_spec_scope parameter_list pop_spec_scope
2406  {{
2407 
2408  $$ = $2;
2409 
2410  DBG_PRINT}}
2411  ;
2412 
2413 parameter_list
2414  : parameter_declaration trailing_params
2415  {{
2416 
2417  SYMBOL *psym = $1;
2418  psym->next = $2;
2419  $$ = psym;
2420 
2421  DBG_PRINT}}
2422  | parameter_declaration
2423  {{
2424 
2425  $$ = $1;
2426 
2427  DBG_PRINT}}
2428  ;
2429 
2430 trailing_params
2431  : param_decl_tail_list
2432  {{
2433 
2434  $$ = $1;
2435 
2436  DBG_PRINT}}
2437  | ',' ELLIPSIS
2438  {{
2439 
2440  $$ = NULL; // ???
2441 
2442  DBG_PRINT}}
2443  ;
2444 
2445 param_decl_tail_list
2446  : param_decl_tail_list ',' parameter_declaration
2447  {{
2448 
2449  SYMBOL *psym = $1;
2450  SYMBOL *tmp = $3;
2451  g_last->next = tmp;
2452  g_last = tmp;
2453 
2454  $$ = psym;
2455 
2456  DBG_PRINT}}
2457  | ',' parameter_declaration
2458  {{
2459 
2460  $$ = g_last = $2;
2461 
2462  DBG_PRINT}}
2463  ;
2464 
2465 parameter_declaration
2466  :
2467  {{
2468 
2469  pp_reset_current_type_spec ();
2470 
2471  DBG_PRINT}}
2472  specifier_list
2473  opt_abstract_declarator
2474  nS_td
2475  {{
2476 
2477  SYMBOL *psym = $3;
2478  LINK *plink = $2;
2479 
2480  if (psym == NULL)
2481  psym = pp_new_symbol (NULL, pp_nesting_level);
2482 
2483  pp_add_spec_to_decl (plink, psym);
2484  if (plink && !plink->tdef)
2485  pp_discard_link_chain (plink);
2486 
2487  $$ = psym;
2488 
2489  DBG_PRINT}}
2490  ;
2491 
2492 opt_abstract_declarator
2493  : // empty
2494  {{
2495 
2496  $$ = NULL;
2497 
2498  DBG_PRINT}}
2499  | abstract_declarator
2500  {{
2501 
2502  $$ = $1;
2503 
2504  DBG_PRINT}}
2505  ;
2506 
2507 abstract_declarator
2508  : pointer opt_abstract_declarator
2509  {{
2510 
2511  SYMBOL *psym = $2;
2512 
2513  if (psym == NULL)
2514  psym = pp_new_symbol (NULL, pp_nesting_level);
2515  if (psym)
2516  pp_add_declarator (psym, D_POINTER);
2517 
2518  DBG_PRINT}}
2519  | direct_abstract_declarator
2520  {{
2521 
2522  $$ = $1;
2523 
2524  DBG_PRINT}}
2525  ;
2526 
2527 direct_abstract_declarator
2528  : '(' abstract_declarator ')'
2529  {{
2530 
2531  g_psym = $2;
2532 
2533  DBG_PRINT}}
2534  opt_direct_adecl_tail
2535  {{
2536 
2537  $$ = g_psym;
2538 
2539  DBG_PRINT}}
2540  | '(' opt_param_type_list ')'
2541  {{
2542 
2543  SYMBOL *args = $2;
2544  g_psym = pp_new_symbol (NULL, pp_nesting_level);
2545  pp_add_declarator (g_psym, D_FUNCTION);
2546  g_psym->etype->decl.d.args = args;
2547 
2548  DBG_PRINT}}
2549  opt_direct_adecl_tail
2550  {{
2551 
2552  $$ = g_psym;
2553 
2554  DBG_PRINT}}
2555  | IDENTIFIER
2556  {{
2557 
2558  g_psym = pp_new_symbol ($1, pp_nesting_level);
2559 
2560  DBG_PRINT}}
2561  opt_direct_adecl_tail
2562  {{
2563 
2564  $$ = g_psym;
2565 
2566  DBG_PRINT}}
2567  | c_subscript
2568  {{
2569 
2570  const char *sub = $1;
2571  g_psym = pp_new_symbol (NULL, pp_nesting_level);
2572  pp_add_declarator (g_psym, D_ARRAY);
2573  g_psym->etype->decl.d.num_ele = (char *) sub;
2574 
2575  DBG_PRINT}}
2576  opt_direct_adecl_tail
2577  {{
2578 
2579  $$ = g_psym;
2580 
2581  DBG_PRINT}}
2582  ;
2583 
2584 opt_direct_adecl_tail
2585  : //empty
2586  | direct_adecl_tail
2587  ;
2588 
2589 direct_adecl_tail
2590  : direct_adecl_tail c_subscript
2591  {{
2592 
2593  const char *sub = $2;
2594  pp_add_declarator (g_psym, D_ARRAY);
2595  g_psym->etype->decl.d.num_ele = (char *) sub;
2596 
2597  DBG_PRINT}}
2598  | direct_adecl_tail '(' opt_param_type_list ')'
2599  {{
2600 
2601  SYMBOL *args = $3;
2602  pp_add_declarator (g_psym, D_FUNCTION);
2603  g_psym->etype->decl.d.args = args;
2604 
2605  DBG_PRINT}}
2606  | c_subscript
2607  {{
2608 
2609  const char *sub = $1;
2610  pp_add_declarator (g_psym, D_ARRAY);
2611  g_psym->etype->decl.d.num_ele = (char *) sub;
2612 
2613  DBG_PRINT}}
2614  | '(' opt_param_type_list ')'
2615  {{
2616 
2617  SYMBOL *args = $2;
2618  pp_add_declarator (g_psym, D_FUNCTION);
2619  g_psym->etype->decl.d.args = args;
2620 
2621  DBG_PRINT}}
2622  ;
2623 
2624 opt_param_type_list
2625  : // empty
2626  {{
2627 
2628  $$ = NULL;
2629 
2630  DBG_PRINT}}
2631  | param_type_list
2632  {{
2633 
2634  $$ = $1;
2635 
2636  DBG_PRINT}}
2637  ;
2638 
2639 nS_ntd
2640  : // empty
2641  {{
2642 
2643  pp_make_typedef_names_visible (0);
2644 
2645  DBG_PRINT}}
2646  ;
2647 
2648 nS_td
2649  : // empty
2650  {{
2651 
2652  pp_make_typedef_names_visible (1);
2653 
2654  DBG_PRINT}}
2655  ;
2656 
2657 identifier
2658  : nS_ntd TYPEDEF_NAME nS_td
2659  {{
2660 
2661  SYMBOL *result = pp_new_symbol ($2, pp_nesting_level);
2662  $$ = result;
2663 
2664  DBG_PRINT}}
2665  | IDENTIFIER
2666  {{
2667 
2668  SYMBOL *result;
2669  if (!g_identifier_symbol || g_identifier_symbol->level != pp_nesting_level)
2670  result = pp_new_symbol ($1, pp_nesting_level);
2671  else
2672  result = g_identifier_symbol;
2673 
2674  $$ = result;
2675 
2676  DBG_PRINT}}
2677  | ENUMERATION_CONSTANT
2678  {{
2679 
2680  SYMBOL *result = pp_new_symbol ($1, pp_nesting_level);
2681  $$ = result;
2682 
2683  DBG_PRINT}}
2684  ;
2685 
2686 c_subscript
2687  : '['
2688  {{
2689 
2690  varstring *subscript_buf = malloc (sizeof (varstring));
2691 
2692  esql_yy_push_mode (EXPR_mode);
2693  if (IS_PSEUDO_TYPE (pp_current_type_spec ()))
2694  {
2695  /*
2696  * There is no need to store the old values of the
2697  * echo function and echo suppression here because
2698  * we're going to pop right ought of this mode and
2699  * clobber them anyway.
2700  */
2701  vs_new (subscript_buf);
2702  (void) esql_yy_set_buf (subscript_buf);
2703  (void) pp_set_echo (&echo_vstr);
2704  pp_suppress_echo (false);
2705  }
2706 
2707  g_subscript = subscript_buf;
2708 
2709  DBG_PRINT}}
2710  c_subscript_body
2711  ']'
2712  {{
2713 
2714  char *subscript = NULL;
2715  varstring *subscript_buf = g_subscript;
2716 
2717  if (IS_PSEUDO_TYPE (pp_current_type_spec ()))
2718  {
2719  /*
2720  * Have to clobber the RB here, since the lookahead
2721  * has already put it in our buffer. Fortunately,
2722  * we're in a mode where we can do that.
2723  */
2724  esql_yy_erase_last_token ();
2725  esql_yy_set_buf (NULL);
2726  subscript = pp_strdup (vs_str (subscript_buf));
2727  vs_free (subscript_buf);
2728  }
2729 
2730  esql_yy_pop_mode ();
2731 
2732  $$ = subscript;
2733 
2734  DBG_PRINT}}
2735  ;
2736 
2737 
2738 //#lexclass EXPR_mode
2739 
2740 
2741 c_subscript_body
2742  : // empty
2743  {DBG_PRINT}
2744  | c_expr
2745  {DBG_PRINT}
2746  ;
2747 
2748 c_expression
2749  : c_expr
2750  {{
2751 
2752  esql_yy_pop_mode ();
2753 
2754  DBG_PRINT}}
2755  ;
2756 
2757 c_expr
2758  : any_list
2759  {DBG_PRINT}
2760  ;
2761 
2762 any_list
2763  : any_list any
2764  {DBG_PRINT}
2765  | any
2766  {DBG_PRINT}
2767  ;
2768 
2769 any_expr
2770  : // empty
2771  {DBG_PRINT}
2772  | acs_list
2773  {DBG_PRINT}
2774  ;
2775 
2776 acs_list
2777  : acs_list of_any_comma_semi
2778  {DBG_PRINT}
2779  | of_any_comma_semi
2780  {DBG_PRINT}
2781  ;
2782 
2783 of_any_comma_semi
2784  : any
2785  {DBG_PRINT}
2786  | ','
2787  {DBG_PRINT}
2788  | ';'
2789  {DBG_PRINT}
2790  ;
2791 
2792 any
2793  : GENERIC_TOKEN
2794  {DBG_PRINT}
2795  | '(' any_expr ')'
2796  {DBG_PRINT}
2797  | '[' any_expr ']'
2798  {DBG_PRINT}
2799  | '{' any_expr '}'
2800  {DBG_PRINT}
2801  ;
2802 
2803 
2804 //#lexclass VAR_mode
2805 
2806 host_variable_list_tail
2807  : host_variable_list_tail ',' host_var_w_opt_indicator
2808  {{
2809 
2810  ECHO_STR (", ", strlen (", "));
2811 
2812  DBG_PRINT}}
2813  | host_var_w_opt_indicator
2814  {DBG_PRINT}
2815  ;
2816 
2817 indicator_var
2818  : // empty
2819  {{
2820 
2821  $$ = NULL;
2822  g_indicator = false;
2823 
2824  DBG_PRINT}}
2825  | '#' hostvar
2826  {{
2827 
2828  $$ = $2;
2829  g_indicator = false;
2830 
2831  DBG_PRINT}}
2832  | INDICATOR '#' hostvar
2833  {{
2834 
2835  $$ = $3;
2836  g_indicator = false;
2837 
2838  DBG_PRINT}}
2839  | INDICATOR hostvar
2840  {{
2841 
2842  $$ = $2;
2843  g_indicator = false;
2844 
2845  DBG_PRINT}}
2846  ;
2847 
2848 
2849 host_var_w_opt_indicator
2850  :
2851  {{
2852 
2853  HOST_REF *href = NULL;
2854  g_delay[0] = 0;
2855  g_varstring = esql_yy_get_buf ();
2856 
2857  esql_yy_push_mode (VAR_mode);
2858  esql_yy_set_buf (NULL);
2859  structs_allowed = true;
2860 
2861  DBG_PRINT}}
2862  host_variable indicator_var
2863  {{
2864 
2865  HOST_REF *href;
2866  HOST_VAR *hvar1, *hvar2;
2867  hvar1 = $2;
2868  hvar2 = $3;
2869 
2870  esql_yy_pop_mode ();
2871  esql_yy_set_buf (g_varstring);
2872 
2873  href = pp_add_host_ref (hvar1, hvar2, structs_allowed, &n_refs);
2874  ECHO_STR ("? ", strlen ("? "));
2875  for (i = 1; i < n_refs; i++)
2876  ECHO_STR (", ? ", strlen (", ? "));
2877 
2878  ECHO_STR (g_delay, strlen (g_delay));
2879 
2880  $$ = href;
2881 
2882  DBG_PRINT}}
2883  ;
2884 
2885 host_variable
2886  : ':'
2887  {{
2888 
2889  g_indicator = true;
2890 
2891  DBG_PRINT}}
2892  hostvar
2893  {{
2894 
2895  $$ = $3;
2896 
2897  DBG_PRINT}}
2898  ;
2899 
2900 hostvar
2901  : host_ref
2902  {{
2903 
2904  $$ = $1;
2905 
2906  DBG_PRINT}}
2907  | '*' CONST_ hostvar
2908  {{
2909 
2910  HOST_VAR *hvar = NULL;
2911  HOST_VAR *hvar2 = $3;
2912  if ((hvar = pp_ptr_deref (hvar2, 0)) == NULL)
2913  pp_free_host_var (hvar2);
2914  else
2915  vs_prepend (&hvar->expr, "*");
2916 
2917  $$ = hvar;
2918 
2919  DBG_PRINT}}
2920  | '*' VOLATILE_ hostvar
2921  {{
2922 
2923  HOST_VAR *hvar = NULL;
2924  HOST_VAR *hvar2 = $3;
2925  if ((hvar = pp_ptr_deref (hvar2, 0)) == NULL)
2926  pp_free_host_var (hvar2);
2927  else
2928  vs_prepend (&hvar->expr, "*");
2929 
2930  $$ = hvar;
2931 
2932  DBG_PRINT}}
2933  | '*' hostvar
2934  {{
2935 
2936  HOST_VAR *hvar = NULL;
2937  HOST_VAR *hvar2 = $2;
2938  if ((hvar = pp_ptr_deref (hvar2, 0)) == NULL)
2939  pp_free_host_var (hvar2);
2940  else
2941  vs_prepend (&hvar->expr, "*");
2942 
2943  $$ = hvar;
2944 
2945  DBG_PRINT}}
2946  | '&' host_ref
2947  {{
2948 
2949  HOST_VAR *hvar;
2950  HOST_VAR *href2 = $2;
2951 
2952  if ((hvar = pp_addr_of (href2)) == NULL)
2953  pp_free_host_var (href2);
2954  else
2955  vs_prepend (&hvar->expr, "&");
2956 
2957  $$ = hvar;
2958 
2959  DBG_PRINT}}
2960  ;
2961 
2962 host_ref
2963  : IDENTIFIER
2964  {{
2965 
2966  HOST_VAR *href = NULL;
2967  SYMBOL *sym = pp_findsym (pp_Symbol_table, $1);
2968  if (sym == NULL)
2969  {
2970  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_NOT_DECLARED), $1);
2971  href = NULL;
2972  }
2973  else
2974  href = pp_new_host_var (NULL, sym);
2975 
2976  g_href = href;
2977 
2978  DBG_PRINT}}
2979  opt_host_ref_tail
2980  {{
2981 
2982  HOST_VAR *href = $3;
2983  if (href == NULL)
2984  href = g_href;
2985  $$ = href;
2986 
2987  DBG_PRINT}}
2988  | '(' hostvar ')'
2989  {{
2990 
2991  HOST_VAR *href = $2;
2992  if (href)
2993  {
2994  vs_prepend (&href->expr, "(");
2995  vs_strcat (&href->expr, ")");
2996  }
2997  g_href = href;
2998 
2999  DBG_PRINT}}
3000  opt_host_ref_tail
3001  {{
3002 
3003  HOST_VAR *href = $5;
3004  if (href == NULL)
3005  href = g_href;
3006  $$ = href;
3007 
3008  DBG_PRINT}}
3009  ;
3010 
3011 opt_host_ref_tail
3012  : %dprec 1
3013  // empty
3014  {{
3015 
3016  $$ = NULL;
3017 
3018  DBG_PRINT}}
3019  | host_ref_tail %dprec 2
3020  {{
3021 
3022  $$ = $1;
3023 
3024  DBG_PRINT}}
3025  ;
3026 
3027 host_ref_tail
3028  : host_ref_tail host_var_subscript
3029  {{
3030 
3031  $$ = $2;
3032 
3033  DBG_PRINT}}
3034  | host_ref_tail '.' IDENTIFIER
3035  {{
3036 
3037  HOST_VAR *href;
3038  if ((href = pp_struct_deref (g_href, $3, 0)) == NULL)
3039  pp_free_host_var (g_href);
3040  else
3041  vs_sprintf (&href->expr, ".%s", $3);
3042 
3043  $$ = href;
3044 
3045  DBG_PRINT}}
3046  | host_ref_tail PTR_OP IDENTIFIER
3047  {{
3048 
3049  HOST_VAR *href;
3050  if ((href = pp_struct_deref (g_href, $3, 1)) == NULL)
3051  pp_free_host_var (g_href);
3052  else
3053  vs_sprintf (&href->expr, "->%s", $3);
3054 
3055  $$ = href;
3056 
3057  DBG_PRINT}}
3058  | host_var_subscript
3059  {{
3060 
3061  $$ = $1;
3062 
3063  DBG_PRINT}}
3064  | '.' IDENTIFIER
3065  {{
3066 
3067  HOST_VAR *href;
3068  if ((href = pp_struct_deref (g_href, $2, 0)) == NULL)
3069  pp_free_host_var (g_href);
3070  else
3071  vs_sprintf (&href->expr, ".%s", $2);
3072 
3073  $$ = href;
3074 
3075  DBG_PRINT}}
3076  | PTR_OP IDENTIFIER
3077  {{
3078 
3079  HOST_VAR *href;
3080  if ((href = pp_struct_deref (g_href, $2, 1)) == NULL)
3081  pp_free_host_var (g_href);
3082  else
3083  vs_sprintf (&href->expr, "->%s", $2);
3084 
3085  $$ = href;
3086 
3087  DBG_PRINT}}
3088  ;
3089 
3090 host_var_subscript
3091  : '['
3092  {{
3093 
3094  vs_clear (&pp_subscript_buf);
3095  esql_yy_push_mode (HV_mode);
3096 
3097  DBG_PRINT}}
3098  host_var_subscript_body
3099  {{
3100 
3101  $$ = $3;
3102 
3103  DBG_PRINT}}
3104  ;
3105 
3106 
3107 host_var_subscript_body
3108  : opt_hv_sub_list ']'
3109  {{
3110 
3111  HOST_VAR *href;
3112 
3113  esql_yy_pop_mode ();
3114  if ((href = pp_ptr_deref (g_href, 1)) == NULL)
3115  pp_free_host_var (g_href);
3116  else
3117  vs_sprintf (&href->expr, "[%s%s", vs_str (&pp_subscript_buf), "]");
3118 
3119  $$ = href;
3120 
3121  DBG_PRINT}}
3122  ;
3123 
3124 // HV_mode
3125 hv_sub
3126  : '('
3127  {{
3128 
3129  vs_strcat (&pp_subscript_buf, "(");
3130 
3131  DBG_PRINT}}
3132  opt_hv_sub_list
3133  ')'
3134  {{
3135 
3136  vs_strcat (&pp_subscript_buf, ")");
3137 
3138  DBG_PRINT}}
3139  | '['
3140  {{
3141 
3142  vs_strcat (&pp_subscript_buf, "[");
3143 
3144  DBG_PRINT}}
3145  opt_hv_sub_list
3146  ']'
3147  {{
3148 
3149  vs_strcat (&pp_subscript_buf, "]");
3150 
3151  DBG_PRINT}}
3152  | '{'
3153  {{
3154 
3155  vs_strcat (&pp_subscript_buf, "{");
3156 
3157  DBG_PRINT}}
3158  opt_hv_sub_list
3159  '}'
3160  {{
3161 
3162  vs_strcat (&pp_subscript_buf, "}");
3163 
3164  DBG_PRINT}}
3165  ;
3166 
3167 opt_hv_sub_list
3168  : // empty
3169  {DBG_PRINT}
3170  | hv_sub_list
3171  {DBG_PRINT}
3172  ;
3173 
3174 hv_sub_list
3175  : hv_sub_list hv_sub
3176  {DBG_PRINT}
3177  | hv_sub
3178  {DBG_PRINT}
3179  ;
3180 
3181 
3182 
3183 // BUFFER_mode
3184 
3185 
3186 csql_statement_tail
3187  : opt_buffer_sql_list
3188  {{
3189 
3190  PT_NODE **pt, *cursr;
3191  char *statement, *text;
3192  PT_HOST_VARS *result;
3193  long is_upd_obj;
3194  HOST_LOD *inputs, *outputs;
3195  int length;
3196  PARSER_VARCHAR *varPtr;
3197  esql_yy_pop_mode ();
3198  statement = vs_str (&pt_statement_buf);
3199  length = (int) vs_strlen (&pt_statement_buf);
3200 
3201  PRINT_1 ("statement: %s\n", statement);
3202  pt = parser_parse_string (parser, statement);
3203 
3204  if (!pt || !pt[0])
3205  {
3206  pt_print_errors (parser);
3207  }
3208  else
3209  {
3210 
3211  is_upd_obj = pt_is_update_object (pt[0]);
3212  result = pt_host_info (parser, pt[0]);
3213  inputs = pp_input_refs ();
3214  outputs = pp_output_refs ();
3215  text = statement;
3216  if (is_upd_obj)
3217  {
3218  if (HOST_N_REFS (inputs) > 0
3219  && pp_check_type (&(HOST_REFS (inputs))[0],
3220  NEWSET (C_TYPE_OBJECTID),
3221  pp_get_msg (EX_ESQLM_SET,
3222  MSG_PTR_TO_DB_OBJECT)))
3223  esql_Translate_table.tr_object_update (text,
3224  length,
3225  repeat_option,
3226  HOST_N_REFS (inputs),
3227  HOST_REFS (inputs));
3228  }
3229  else if ((cursr = pt_get_cursor (result)) != NULL)
3230  {
3231  CURSOR *cur;
3232  const char *c_nam;
3233  c_nam = pt_get_name (cursr);
3234  if ((cur = pp_lookup_cursor ((char *) c_nam)) == NULL)
3235  {
3236  esql_yyverror (pp_get_msg (EX_ESQLM_SET, MSG_CURSOR_UNDEFINED),
3237  c_nam);
3238  }
3239  else
3240  {
3241  switch (g_cursor_type)
3242  {
3243  case CURSOR_DELETE:
3244  esql_Translate_table.tr_delete_cs (cur->cid);
3245  break;
3246  case CURSOR_UPDATE:
3247  pt_set_update_object (parser, pt[0]);
3248  varPtr = pt_print_bytes (parser, pt[0]);
3249  esql_Translate_table.tr_update_cs (cur->cid,
3250  (char *)
3251  pt_get_varchar_bytes
3252  (varPtr),
3253  (int)
3254  pt_get_varchar_length
3255  (varPtr), repeat_option,
3256  HOST_N_REFS (inputs),
3257  HOST_REFS (inputs));
3258  break;
3259  default:
3260  break;
3261  }
3262  }
3263  }
3264  else
3265  {
3266  repeat_option = (pt[0]->node_type == PT_INSERT && !pt[0]->info.insert.do_replace && pt[0]->info.insert.odku_assignments == NULL
3267  && pt[0]->info.insert.value_clauses->info.node_list.list_type != PT_IS_SUBQUERY
3268  && pt[0]->info.insert.value_clauses->info.node_list.list->next == NULL);
3269  esql_Translate_table.tr_static (text,
3270  length,
3271  repeat_option,
3272  HOST_N_REFS (inputs),
3273  HOST_REFS (inputs),
3274  (const char *) HOST_DESC (inputs),
3275  HOST_N_REFS (outputs),
3276  HOST_REFS (outputs),
3277  (const char *) HOST_DESC (outputs));
3278  }
3279  pt_free_host_info (result);
3280  }
3281 
3282  esql_yy_sync_lineno ();
3283  esql_yy_set_buf (NULL);
3284 
3285  DBG_PRINT}}
3286  ;
3287 
3288 opt_buffer_sql_list
3289  : // empty
3290  {DBG_PRINT}
3291  | buffer_sql_list
3292  {DBG_PRINT}
3293  ;
3294 
3295 buffer_sql_list
3296  : buffer_sql_list buffer_sql
3297  {DBG_PRINT}
3298  | buffer_sql
3299  {DBG_PRINT}
3300  ;
3301 
3302 buffer_sql
3303  : host_var_w_opt_indicator
3304  {DBG_PRINT}
3305  | DESCRIPTOR host_variable_wo_indicator
3306  {{
3307 
3308  HOST_REF *href = $2;
3309  if (pp_check_type (href,
3310  NEWSET (C_TYPE_SQLDA),
3311  pp_get_msg (EX_ESQLM_SET, MSG_PTR_TO_DESCR)))
3312  pp_switch_to_descriptor ();
3313 
3314  DBG_PRINT}}
3315  | var_mode_follow_set
3316  {DBG_PRINT}
3317  ;
3318 
3319 var_mode_follow_set
3320  : '*'
3321  {DBG_PRINT}
3322  | ','
3323  {DBG_PRINT}
3324  | '('
3325  {DBG_PRINT}
3326  | ')'
3327  {DBG_PRINT}
3328  | '{'
3329  {DBG_PRINT}
3330  | '}'
3331  {DBG_PRINT}
3332  | GENERIC_TOKEN
3333  {DBG_PRINT}
3334  | IDENTIFIER
3335  {DBG_PRINT}
3336  | INTO
3337  {{
3338 
3339  pp_gather_output_refs ();
3340 
3341  DBG_PRINT}}
3342  | TO
3343  {{
3344 
3345  pp_gather_output_refs ();
3346 
3347  DBG_PRINT}}
3348  | FROM
3349  {{
3350 
3351  pp_gather_input_refs ();
3352 
3353  DBG_PRINT}}
3354  | SELECT
3355  {{
3356 
3357  pp_gather_input_refs ();
3358 
3359  DBG_PRINT}}
3360  | VALUES
3361  {{
3362 
3363  pp_gather_input_refs ();
3364 
3365  DBG_PRINT}}
3366  | ON_
3367  {DBG_PRINT}
3368  | WITH
3369  {DBG_PRINT}
3370  ;
3371 
3372 cursor_query_statement
3373  :
3374  {{
3375 
3376  vs_clear (&pt_statement_buf);
3377  esql_yy_set_buf (&pt_statement_buf);
3378  esql_yy_push_mode (BUFFER_mode);
3379 
3380  DBG_PRINT}}
3381  of_select_lp opt_buffer_sql_list
3382  {{
3383 
3384  char *statement;
3385  char *text = NULL;
3386  long length;
3387  PT_NODE **pt;
3388  char **cp = malloc (sizeof (char *) * 2);
3389 
3390  esql_yy_pop_mode ();
3391  statement = vs_str (&pt_statement_buf);
3392  length = vs_strlen (&pt_statement_buf);
3393 
3394  PRINT_1 ("statement: %s\n", statement);
3395  pt = parser_parse_string (parser, statement);
3396  if (!pt || !pt[0])
3397  {
3398  pt_print_errors (parser);
3399  }
3400  else
3401  text = statement;
3402 
3403  cp[0] = text;
3404  cp[1] = (char *) length;
3405 
3406  esql_yy_sync_lineno ();
3407  esql_yy_set_buf (NULL);
3408 
3409  $$ = cp;
3410 
3411  DBG_PRINT}}
3412  ;
3413 
3414 
3415 of_select_lp
3416  : SELECT
3417  {{
3418 
3419  ECHO_STR ($1, strlen ($1));
3420 
3421  DBG_PRINT}}
3422  | '('
3423  {{
3424 
3425  ECHO_STR ("(", strlen ("("));
3426 
3427  DBG_PRINT}}
3428  ;
3429 
3430 
3431 //#lexclass COMMENT_mode
3432 
3433 
3434 
3435 %%
3436 
3437 #define UCI_OPT_UNSAFE_NULL 0x0001
3438 #define makestring1(x) #x
3439 #define makestring(x) makestring1(x)
3440 #if !defined(PRODUCT_STRING)
3441 #define PRODUCT_STRING makestring(RELEASE_STRING)
3442 #endif
3443 
3444 #define ESQL_MSG_CATALOG "esql.cat"
3445 
3446 char exec_echo[10] = "";
3447 static char *outfile_name = NULL;
3448 bool need_line_directive;
3449 FILE *esql_yyin, *esql_yyout;
3450 char *esql_yyfilename;
3451 int esql_yyendcol = 0;
3452 int errors = 0;
3453 varstring *current_buf; /* remain PUBLIC for debugging ease */
3454 ECHO_FN echo_fn = &echo_stream;
3455 char g_delay[1024] = { 0, };
3456 bool g_indicator = false;
3457 varstring *g_varstring = NULL;
3458 varstring *g_subscript = NULL;
3459 
3460 typedef struct pt_host_refs
3461 {
3462  unsigned char *descr[2]; /* at most 2 descriptors: 1 in, 1 out */
3463  int descr_occupied; /* occupied slots in descr */
3464  HOST_REF **host_refs; /* array of pointers to HOST_REF */
3465  int occupied; /* occupied slots in host_refs */
3466  int allocated; /* allocated slots in host_refs */
3467  unsigned char *in_descriptor; /* NULL or input descriptor name */
3468  unsigned char *out_descriptor; /* NULL or output descriptor name */
3469  HOST_REF **in_refs; /* array of input HOST_REF addresses */
3470  int in_refs_occupied;
3471  int in_refs_allocated;
3472  HOST_REF **out_refs; /* array of output HOST_REF addresses */
3473  int out_refs_occupied;
3474  int out_refs_allocated;
3475 } PT_HOST_REFS;
3476 
3477 enum esqlmain_msg
3478 {
3479  MSG_REPEATED_IGNORED = 1,
3480  MSG_VERSION = 2
3481 };
3482 
3483 const char *VARCHAR_ARRAY_NAME = "array";
3484 const char *VARCHAR_LENGTH_NAME = "length";
3485 const char *pp_include_path;
3486 char *pp_include_file = NULL;
3487 const char *prog_name;
3488 
3489 unsigned int pp_uci_opt = 0;
3490 int pp_emit_line_directives = 1;
3491 int pp_dump_scope_info = 0;
3492 int pp_dump_malloc_info = 0;
3493 int pp_announce_version = 0;
3494 int pp_enable_uci_trace = 0;
3495 int pp_disable_varchar_length = 0;
3496 int pp_varchar2 = 0;
3497 int pp_unsafe_null = 0;
3498 int pp_internal_ind = 0;
3499 PARSER_CONTEXT *parser;
3500 char *pt_buffer;
3501 varstring pt_statement_buf;
3502 
3503 
3504 /*
3505  * check() -
3506  * return : void
3507  * cond(in) :
3508  */
3509 static void
3510 check (int cond)
3511 {
3512  if (!cond)
3513  {
3514  perror (prog_name);
3515  exit (1);
3516  }
3517 }
3518 
3519 /*
3520  * check_w_file() -
3521  * return : void
3522  * cond(in) :
3523  * filename(in) :
3524  */
3525 static void
3526 check_w_file (int cond, const char *filename)
3527 {
3528  if (!cond)
3529  {
3530  char buf[2 * PATH_MAX];
3531  sprintf (buf, "%s: %s", prog_name, filename);
3532  perror (buf);
3533  exit (1);
3534  }
3535 }
3536 
3537 /*
3538  * reset_globals() -
3539  * return : void
3540  */
3541 static void
3542 reset_globals (void)
3543 {
3544  input_refs = NULL;
3545  output_refs = NULL;
3546  repeat_option = false;
3547  already_translated = false;
3548  structs_allowed = false;
3549  hvs_allowed = true;
3550 
3551  esql_yy_set_buf (NULL);
3552  pp_clear_host_refs ();
3553  pp_gather_input_refs ();
3554 }
3555 
3556 /*
3557  * ignore_repeat() -
3558  * return : void
3559  */
3560 static void
3561 ignore_repeat (void)
3562 {
3563  if (repeat_option)
3564  {
3565  esql_yyvwarn (pp_get_msg (EX_ESQLMMAIN_SET, MSG_REPEATED_IGNORED));
3566  }
3567 }
3568 
3569 
3570 #if defined (ENABLE_UNUSED_FUNCTION)
3571 static int
3572 validate_input_file (void *fname, FILE * outfp)
3573 {
3574  return (fname == NULL) && isatty (fileno (stdin));
3575 }
3576 #endif /* ENABLE_UNUSED_FUNCTION */
3577 
3578 
3579 static char *
3580 ofile_name (char *fname)
3581 {
3582  static char buf[PATH_MAX + 1]; /* reserve buffer for '\0' */
3583  char *p;
3584 
3585  /* Get the last pathname component into buf. */
3586  p = strrchr (fname, '/');
3587  strncpy (buf, p ? (p + 1) : fname, sizeof(buf));
3588 
3589  /* Now add the .c suffix, copying over the .ec suffix if present. */
3590  p = strrchr (buf, '.');
3591  if (p && !STREQ (p, ".c"))
3592  {
3593  strcpy (p, ".c");
3594  }
3595  else
3596  {
3597  strncat (buf, ".c", PATH_MAX - strnlen(buf, sizeof(buf)));
3598  }
3599 
3600  return buf;
3601 }
3602 
3603 /*
3604  * copy() -
3605  * return : void
3606  * fp(in) :
3607  * fname(in) :
3608  */
3609 static void
3610 copy (FILE * fp, const char *fname)
3611 {
3612  int ifd, ofd;
3613  int rbytes, wbytes;
3614  char buf[BUFSIZ];
3615 
3616  rewind (fp);
3617 
3618  ifd = fileno (fp);
3619  ofd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
3620  check_w_file (ofd >= 0, fname);
3621 
3622  /* Now copy the contents; use read() and write() to try to cut down
3623  on excess buffering. */
3624  rbytes = 0;
3625  wbytes = 0;
3626  while ((rbytes = read (ifd, buf, sizeof (buf))) > 0)
3627  {
3628  wbytes = write (ofd, buf, rbytes);
3629  if (wbytes != rbytes)
3630  {
3631  break;
3632  }
3633  }
3634  check (rbytes >= 0 && wbytes >= 0);
3635 
3636  close (ofd);
3637 }
3638 
3639 
3640 static const char *
3641 pp_unsafe_get_msg (int msg_set, int msg_num)
3642 {
3643  static int complained = 0;
3644  static MSG_CATD msg_cat = NULL;
3645 
3646  const char *msg;
3647 
3648  if (msg_cat == NULL)
3649  {
3650  if (complained)
3651  {
3652  return NULL;
3653  }
3654 
3655  msg_cat = msgcat_open (ESQL_MSG_CATALOG);
3656  if (msg_cat == NULL)
3657  {
3658  complained = 1;
3659  fprintf (stderr, "%s: %s: %s\n",
3660  prog_name, ESQL_MSG_CATALOG, strerror (ENOENT));
3661  return NULL;
3662  }
3663  }
3664 
3665  msg = msgcat_gets (msg_cat, msg_set, msg_num, NULL);
3666 
3667  return (msg == NULL || msg[0] == '\0') ? NULL : msg;
3668 }
3669 
3670 /*
3671  * pp_get_msg() -
3672  * return :
3673  * msg_set(in) :
3674  * msg_num(in) :
3675  */
3676 const char *
3677 pp_get_msg (int msg_set, int msg_num)
3678 {
3679  static const char no_msg[] = "No message available.";
3680  const char *msg;
3681 
3682  msg = pp_unsafe_get_msg (msg_set, msg_num);
3683  return msg ? msg : no_msg;
3684 }
3685 
3686 
3687 static void
3688 usage (void)
3689 {
3690  fprintf (stderr,
3691  "usage: cubrid_esql [OPTION] input-file\n\n"
3692  "valid option:\n"
3693  " -l, --suppress-line-directive suppress #line directives in output file; default: off\n"
3694  " -o, --output-file output file name; default: stdout\n"
3695  " -h, --include-file include file containing uci_ prototypes; default: cubrid_esql.h\n"
3696  " -s, --dump-scope-info dump scope debugging information; default: off\n"
3697  " -m, --dump-malloc-info dump final malloc debugging information; default: off\n"
3698  " -t, --enable-uci-trace enable UCI function trace; default: off\n"
3699  " -d, --disable-varchar-length disable length initialization of VARCHAR host variable; default; off\n"
3700  " -2, --varchar2-style use different VARCHAR style; default: off\n"
3701  " -u, --unsafe-null ignore -462(null indicator needed) error: default; off\n"
3702  " -e, --internal-indicator use internal NULL indicator to prevent -462(null indicator needed) error, default off\n");
3703 }
3704 
3705 static int
3706 get_next ()
3707 {
3708  return fgetc (esql_yyin);
3709 }
3710 
3711 /*
3712  * main() -
3713  * return :
3714  * argc(in) :
3715  * argv(in) :
3716  */
3717 int
3718 main (int argc, char **argv)
3719 {
3720  struct option esql_option[] = {
3721  {"suppress-line-directive", 0, 0, 'l'},
3722  {"output-file", 1, 0, 'o'},
3723  {"include-file", 1, 0, 'h'},
3724  {"dump-scope-info", 0, 0, 's'},
3725  {"dump-malloc-info", 0, 0, 'm'},
3726  {"version", 0, 0, 'v'},
3727  {"enable-uci-trace", 0, 0, 't'},
3728  {"disable-varchar-length", 0, 0, 'd'},
3729  {"varchar2-style", 0, 0, '2'},
3730  {"unsafe-null", 0, 0, 'u'},
3731  {"internal-indicator", 0, 0, 'e'},
3732  {0, 0, 0, 0}
3733  };
3734 
3735  while (1)
3736  {
3737  int option_index = 0;
3738  int option_key;
3739 
3740  option_key = getopt_long (argc, argv, "lo:h:smvtd2ue",
3741  esql_option, &option_index);
3742  if (option_key == -1)
3743  {
3744  break;
3745  }
3746 
3747  switch (option_key)
3748  {
3749  case 'l':
3750  pp_emit_line_directives = true;
3751  break;
3752  case 'o':
3753  if (outfile_name != NULL)
3754  {
3755  free_and_init(outfile_name);
3756  }
3757  outfile_name = strdup (optarg);
3758  break;
3759  case 'h':
3760  if (pp_include_file != NULL)
3761  {
3762  free_and_init(pp_include_file);
3763  }
3764  pp_include_file = strdup (optarg);
3765  break;
3766  case 's':
3767  pp_dump_scope_info = true;
3768  break;
3769  case 'm':
3770  pp_dump_malloc_info = true;
3771  break;
3772  case 'v':
3773  pp_announce_version = true;
3774  break;
3775  case 't':
3776  pp_enable_uci_trace = true;
3777  break;
3778  case 'd':
3779  pp_disable_varchar_length = true;
3780  break;
3781  case '2':
3782  pp_varchar2 = true;
3783  break;
3784  case 'u':
3785  pp_unsafe_null = true;
3786  break;
3787  case 'e':
3788  pp_internal_ind = true;
3789  break;
3790  default:
3791  usage ();
3792  return errors;
3793  }
3794  }
3795 
3796  if (optind < argc)
3797  {
3798  esql_yyfilename = argv[optind];
3799  }
3800  else
3801  {
3802  usage ();
3803  return errors;
3804  }
3805 
3806  prog_name = argv[0];
3807  if (pp_announce_version)
3808  {
3809  printf (pp_get_msg (EX_ESQLMMAIN_SET, MSG_VERSION), argv[0], PRODUCT_STRING);
3810  }
3811 
3812  if (pp_varchar2)
3813  {
3814  VARCHAR_ARRAY_NAME = "arr";
3815  VARCHAR_LENGTH_NAME = "len";
3816  }
3817 
3818  if (pp_unsafe_null)
3819  {
3820  pp_uci_opt |= UCI_OPT_UNSAFE_NULL;
3821  }
3822 
3823  pp_include_path = envvar_root ();
3824  if (pp_include_path == NULL)
3825  {
3826  exit (1);
3827  }
3828 
3829  if (esql_yyfilename == NULL)
3830  {
3831  /* No input filename was supplied; use stdin for input and stdout
3832  for output. */
3833  esql_yyin = stdin;
3834  }
3835  else
3836  {
3837  esql_yyin = fopen (esql_yyfilename, "r");
3838  check_w_file (esql_yyin != NULL, esql_yyfilename);
3839  }
3840 
3841  if (esql_yyfilename && !outfile_name)
3842  {
3843  outfile_name = ofile_name (esql_yyfilename);
3844  }
3845 
3846  if (outfile_name)
3847  {
3848  esql_yyout = tmpfile ();
3849  check (esql_yyout != NULL);
3850  }
3851  else
3852  {
3853  esql_yyout = stdout;
3854  }
3855 
3856  esql_yyinit ();
3857  pp_startup ();
3858  vs_new (&pt_statement_buf);
3859  emit_line_directive ();
3860 
3861  if (utility_initialize () != NO_ERROR)
3862  {
3863  exit (1);
3864  }
3865 
3866  if (lang_init () != NO_ERROR)
3867  {
3868  exit (1);
3869  }
3870 
3871  lang_set_charset_lang ("en_US.iso88591");
3872 
3873  parser = parser_create_parser ();
3874  pt_buffer = pt_append_string (parser, NULL, NULL);
3875 
3876  esql_yyparse ();
3877 
3878  if (esql_yyout != stdout)
3879  {
3880  if (errors == 0)
3881  {
3882  /*
3883  * We want to keep the file, so rewind the temp file and copy
3884  * it to the named file. It really would be nice if we could
3885  * just associate the name with the file resources we've
3886  * already created, but there doesn't seem to be a way to do
3887  * that.
3888  */
3889  copy (esql_yyout, outfile_name);
3890  }
3891  }
3892 
3893  if (esql_yyin != NULL)
3894  {
3895  fclose (esql_yyin);
3896  }
3897 
3898  if (esql_yyout != NULL)
3899  {
3900  fclose (esql_yyout);
3901  }
3902 
3903  msgcat_final ();
3904  exit (errors);
3905 
3906  free_and_init (outfile_name);
3907  free_and_init (pp_include_file);
3908 
3909  return errors;
3910 }
3911 
3912 /*
3913  * pt_print_errors() - print to stderr all parsing error messages associated
3914  * with current statement
3915  * return : void
3916  * parser_in(in) : the parser context
3917  */
3918 void
3919 pt_print_errors (PARSER_CONTEXT * parser_in)
3920 {
3921  int statement_no, line_no, col_no;
3922  const char *msg = NULL;
3923  PT_NODE *err = NULL;
3924 
3925  err = pt_get_errors (parser);
3926  do
3927  {
3928  err = pt_get_next_error (err, &statement_no, &line_no, &col_no, &msg);
3929  if (msg)
3930  esql_yyverror (msg);
3931  }
3932  while (err);
3933 
3934  /* sleazy way to clear errors */
3935  parser = parser_create_parser ();
3936 }
3937 
3938 
3939 /*
3940  * pp_suppress_echo() -
3941  * return : void
3942  * suppress(in) :
3943  */
3944 void
3945 pp_suppress_echo (int suppress)
3946 {
3947  suppress_echo = suppress;
3948 }
3949 
3950 /*
3951  * echo_stream() -
3952  * return: void
3953  * str(in) :
3954  * length(in) :
3955  */
3956 void
3957 echo_stream (const char *str, int length)
3958 {
3959  if (!suppress_echo)
3960  {
3961  if (exec_echo[0])
3962  {
3963  fputs (exec_echo, esql_yyout);
3964  exec_echo[0] = 0;
3965  }
3966  fwrite ((char *) str, length, 1, esql_yyout);
3967  //YY_FLUSH_ON_DEBUG;
3968  }
3969 }
3970 
3971 /*
3972  * echo_vstr() -
3973  * return : void
3974  * str(in) :
3975  * length(in) :
3976  */
3977 void
3978 echo_vstr (const char *str, int length)
3979 {
3980 
3981  if (!suppress_echo)
3982  {
3983  if (current_buf)
3984  {
3985  vs_strcatn (current_buf, str, length);
3986  }
3987  }
3988 }
3989 
3990 #if defined (ENABLE_UNUSED_FUNCTION)
3991 /*
3992  * echo_devnull() -
3993  * return : void
3994  * str(in) :
3995  * length(in) :
3996  */
3997 void
3998 echo_devnull (const char *str, int length)
3999 {
4000  /* Do nothing */
4001 }
4002 #endif /* ENABLE_UNUSED_FUNCTION */
4003 
4004 /*
4005  * pp_set_echo() -
4006  * return :
4007  * new_echo(in) :
4008  */
4009 ECHO_FN
4010 pp_set_echo (ECHO_FN new_echo)
4011 {
4012  ECHO_FN old_echo;
4013 
4014  old_echo = echo_fn;
4015  echo_fn = new_echo;
4016 
4017  return old_echo;
4018 }
4019 
4020 
4021 /*
4022  * esql_yyvmsg() -
4023  * return : void
4024  * fmt(in) :
4025  * args(in) :
4026  */
4027 static void
4028 esql_yyvmsg (const char *fmt, va_list args)
4029 {
4030  /* Flush esql_yyout just in case stderr and esql_yyout are the same. */
4031  fflush (esql_yyout);
4032 
4033  if (esql_yyfilename)
4034  {
4035  fprintf (stderr, "%s:", esql_yyfilename);
4036  }
4037 
4038  fprintf (stderr, "%d: ", esql_yylineno);
4039  vfprintf (stderr, fmt, args);
4040  fputs ("\n", stderr);
4041  fflush (stderr);
4042 }
4043 
4044 /*
4045  * esql_yyerror() -
4046  * return : void
4047  * s(in) :
4048  */
4049 void
4050 esql_yyerror (const char *s)
4051 {
4052  esql_yyverror ("%s before \"%s\"", s, esql_yytext);
4053 }
4054 
4055 /*
4056  * esql_yyverror() -
4057  * return : void
4058  * fmt(in) :
4059  */
4060 void
4061 esql_yyverror (const char *fmt, ...)
4062 {
4063  va_list args;
4064 
4065  errors++;
4066 
4067  va_start (args, fmt);
4068  esql_yyvmsg (fmt, args);
4069  va_end (args);
4070 }
4071 
4072 /*
4073  * esql_yyvwarn() -
4074  * return : void
4075  * fmt(in) :
4076  */
4077 void
4078 esql_yyvwarn (const char *fmt, ...)
4079 {
4080  va_list args;
4081 
4082  va_start (args, fmt);
4083  esql_yyvmsg (fmt, args);
4084  va_end (args);
4085 }
4086 
4087 /*
4088  * esql_yyredef() -
4089  * return : void
4090  * name(in) :
4091  */
4092 void
4093 esql_yyredef (char *name)
4094 {
4095  /* Eventually we will probably want to turn this off, but it's
4096  interesting to find out about perceived redefinitions right now. */
4097  esql_yyverror ("redefinition of symbol \"%s\"", name);
4098 }
4099 
4100 
4101 
4102 
4103 /*
4104  * keyword_cmp() -
4105  * return :
4106  * a(in) :
4107  * b(in) :
4108  */
4109 static int
4110 keyword_cmp (const void *a, const void *b)
4111 {
4112  return strcmp (((const KEYWORD_REC *) a)->keyword,
4113  ((const KEYWORD_REC *) b)->keyword);
4114 }
4115 
4116 /*
4117  * keyword_case_cmp() -
4118  * return :
4119  * a(in) :
4120  * b(in) :
4121  */
4122 static int
4123 keyword_case_cmp (const void *a, const void *b)
4124 {
4125  return intl_mbs_casecmp (((const KEYWORD_REC *) a)->keyword,
4126  ((const KEYWORD_REC *) b)->keyword);
4127 }
4128 
4129 
4130 
4131 
4132 
4133 /*
4134  * check_c_identifier() -
4135  * return :
4136  */
4137 int
4138 check_c_identifier (char *name)
4139 {
4140  KEYWORD_REC *p;
4141  KEYWORD_REC dummy;
4142  SYMBOL *sym;
4143 
4144 #ifdef PARSER_DEBUG
4145  printf ("check c id: %s\n", name);
4146 #endif
4147 
4148  /*
4149  * Check first to see if we have a keyword.
4150  */
4151  dummy.keyword = name;
4152  p = (KEYWORD_REC *) bsearch (&dummy,
4153  c_keywords,
4154  sizeof (c_keywords) / sizeof (c_keywords[0]),
4155  sizeof (KEYWORD_REC), &keyword_cmp);
4156 
4157  if (p)
4158  {
4159  /*
4160  * Notic that this is "sticky", unlike in check_identifier().
4161  * Once we've seen a keyword that initiates suppression, we don't
4162  * want anything echoed until the upper level grammar productions
4163  * say so. In particular, we don't want echoing to be re-enabled
4164  * the very next time we see an ordinary C keyword.
4165  */
4166  suppress_echo = suppress_echo || p->suppress_echo;
4167  return p->value;
4168  }
4169 
4170  /*
4171  * If not, see if this is an already-encountered identifier.
4172  */
4173  g_identifier_symbol = sym =
4174  pp_findsym (pp_Symbol_table, (unsigned char *) name);
4175  if (sym)
4176  {
4177  /*
4178  * Something by this name lives in the symbol table.
4179  *
4180  * This needs to be made sensitive to whether typedef names are
4181  * being recognized or not.
4182  */
4183  return sym->type->tdef && pp_recognizing_typedef_names ? TYPEDEF_NAME :
4184  IS_INT_CONSTANT (sym->type) ? ENUMERATION_CONSTANT : IDENTIFIER;
4185  }
4186  else
4187  {
4188  /*
4189  * Symbol wasn't recognized in the symbol table, so this must be
4190  * a new identifier.
4191  */
4192  return IDENTIFIER;
4193  }
4194 }
4195 
4196 
4197 
4198 /*
4199  * check_identifier() -
4200  * return :
4201  * keywords(in) :
4202  */
4203 int
4204 check_identifier (KEYWORD_TABLE * keywords, char *name)
4205 {
4206  KEYWORD_REC *p;
4207  KEYWORD_REC dummy;
4208 
4209  /*
4210  * Check first to see if we have a keyword.
4211  */
4212  dummy.keyword = name;
4213  p = (KEYWORD_REC *) bsearch (&dummy,
4214  keywords->keyword_array,
4215  keywords->size,
4216  sizeof (KEYWORD_REC), &keyword_case_cmp);
4217 
4218  if (p)
4219  {
4220  suppress_echo = p->suppress_echo;
4221  return p->value;
4222  }
4223  else
4224  {
4225  suppress_echo = false;
4226  return IDENTIFIER;
4227  }
4228 }
4229 
4230 /*
4231  * esql_yy_push_mode() -
4232  * return : void
4233  * new_mode(in) :
4234  */
4235 void
4236 esql_yy_push_mode (enum scanner_mode new_mode)
4237 {
4238  SCANNER_MODE_RECORD *next = malloc (sizeof (SCANNER_MODE_RECORD));
4239  if (next == NULL)
4240  {
4241  esql_yyverror (pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY));
4242  exit(1);
4243  return;
4244  }
4245 
4246  next->previous_mode = mode;
4247  next->recognize_keywords = recognize_keywords;
4248  next->previous_record = mode_stack;
4249  next->suppress_echo = suppress_echo;
4250  mode_stack = next;
4251 
4252  /*
4253  * Set up so that the first id-like token that we see in VAR_MODE
4254  * will be reported as an IDENTIFIER, regardless of whether it
4255  * strcasecmps the same as some CSQL keyword.
4256  */
4257  recognize_keywords = (new_mode != VAR_MODE);
4258 
4259  esql_yy_enter (new_mode);
4260 }
4261 
4262 /*
4263  * esql_yy_check_mode() -
4264  * return : void
4265  */
4266 void
4267 esql_yy_check_mode (void)
4268 {
4269  if (mode_stack != NULL)
4270  {
4271  esql_yyverror
4272  ("(esql_yy_check_mode) internal error: mode stack still full");
4273  exit (1);
4274  }
4275 }
4276 
4277 /*
4278  * esql_yy_pop_mode() -
4279  * return : void
4280  */
4281 void
4282 esql_yy_pop_mode (void)
4283 {
4284  SCANNER_MODE_RECORD *prev;
4285  enum scanner_mode new_mode;
4286 
4287  if (mode_stack == NULL)
4288  {
4289  esql_yyverror (pp_get_msg (EX_ESQLMSCANSUPPORT_SET, MSG_EMPTY_STACK));
4290  exit (1);
4291  }
4292 
4293  prev = mode_stack->previous_record;
4294  new_mode = mode_stack->previous_mode;
4295  recognize_keywords = mode_stack->recognize_keywords;
4296  suppress_echo = mode_stack->suppress_echo;
4297 
4298  free_and_init (mode_stack);
4299  mode_stack = prev;
4300 
4301  esql_yy_enter (new_mode);
4302 }
4303 
4304 /*
4305  * esql_yy_mode() -
4306  * return :
4307  */
4308 enum scanner_mode
4309 esql_yy_mode (void)
4310 {
4311  return mode;
4312 }
4313 
4314 /*
4315  * esql_yy_enter() -
4316  * return : void
4317  * new_mode(in) :
4318  */
4319 void
4320 esql_yy_enter (enum scanner_mode new_mode)
4321 {
4322  static struct
4323  {
4324  const char *name;
4325  int mode;
4326  void (*echo_fn) (const char *, int);
4327  }
4328  mode_info[] =
4329  {
4330  {
4331  "echo", START, &echo_stream}, /* ECHO_MODE 0 */
4332  {
4333  "csql", CSQL_mode, &echo_vstr}, /* CSQL_MODE 1 */
4334  {
4335  "C", C_mode, &echo_stream}, /* C_MODE 2 */
4336  {
4337  "expr", EXPR_mode, &echo_stream}, /* EXPR_MODE 3 */
4338  {
4339  "var", VAR_mode, &echo_vstr}, /* VAR_MODE 4 */
4340  {
4341  "hostvar", HV_mode, &echo_vstr}, /* HV_MODE 5 */
4342  {
4343  "buffer", BUFFER_mode, &echo_vstr}, /* BUFFER_MODE */
4344  {
4345  "comment", COMMENT_mode, NULL} /* COMMENT */
4346  };
4347 
4348 
4349  PRINT_1 ("#set mode : %s\n", mode_info[new_mode].name);
4350  mode = new_mode;
4351  if (mode_info[new_mode].echo_fn)
4352  echo_fn = mode_info[new_mode].echo_fn;
4353 }
4354 
4355 /*
4356  * emit_line_directive() -
4357  * return : void
4358  */
4359 void
4360 emit_line_directive (void)
4361 {
4362  if (pp_emit_line_directives)
4363  {
4364  if (esql_yyfilename)
4365  fprintf (esql_yyout, "#line %d \"%s\"\n", esql_yylineno,
4366  esql_yyfilename);
4367  else
4368  fprintf (esql_yyout, "#line %d\n", esql_yylineno);
4369  }
4370 
4371  need_line_directive = false;
4372 }
4373 
4374 #if defined (ENABLE_UNUSED_FUNCTION)
4375 /*
4376  * ignore_token() -
4377  * return : void
4378  */
4379 static void
4380 ignore_token (void)
4381 {
4382  esql_yyverror (pp_get_msg (EX_ESQLMSCANSUPPORT_SET, MSG_NOT_PERMITTED),
4383  esql_yytext);
4384 }
4385 
4386 /*
4387  * count_embedded_newlines() -
4388  * return : void
4389  */
4390 static void
4391 count_embedded_newlines (void)
4392 {
4393  const char *p = esql_yytext;
4394  for (; *p; ++p)
4395  {
4396  if (*p == '\n')
4397  {
4398  ++esql_yylineno;
4399  esql_yyendcol = 0;
4400  }
4401  ++esql_yyendcol;
4402  }
4403 }
4404 
4405 
4406 
4407 /*
4408  * echo_string_constant() -
4409  * return : void
4410  * str(in) :
4411  * length(in) :
4412  *
4413  * TODO(M2) : This may be incorrect now!
4414  * according to ansi, there is no escape syntax for newlines!
4415  */
4416 static void
4417 echo_string_constant (const char *str, int length)
4418 {
4419  const char *p;
4420  char *q, *result;
4421  int charsLeft = length;
4422 
4423  p = memchr (str, '\n', length);
4424 
4425  if (p == NULL)
4426  {
4427  ECHO_STR (str, length);
4428  return;
4429  }
4430 
4431  /*
4432  * Bad luck; there's at least one embedded newline, so we have to do
4433  * something to get rid of it (if it's escaped). If it's unescaped
4434  * then this is a pretty weird string, but we have to let it go.
4435  *
4436  * Because we come in here with the opening quote mark still intact,
4437  * we're always guaranteed that there is a valid character in front
4438  * of the result of strchr().
4439  */
4440 
4441  result = q = malloc (length + 1);
4442  if (q == NULL)
4443  {
4444  esql_yyverror (pp_get_msg (EX_MISC_SET, MSG_OUT_OF_MEMORY));
4445  exit(1);
4446  return;
4447  }
4448 
4449  /*
4450  * Copy the spans between escaped newlines to the new buffer. If we
4451  * encounter an unescaped newline we just include it.
4452  */
4453  while (p)
4454  {
4455 
4456  if (*(p - 1) == '\\')
4457  {
4458  int span;
4459 
4460  span = p - str - 1; /* exclude size of escape char */
4461  memcpy (q, str, span);
4462  q += span;
4463  str = p + 1;
4464  length -= 2;
4465  /* Exclude size of skipped escape and newline chars from string */
4466  charsLeft -= (span + 2);
4467  }
4468 
4469  p = memchr (p + 1, '\n', charsLeft);
4470  }
4471 
4472  memcpy (q, str, charsLeft);
4473 
4474  ECHO_STR (result, length);
4475  free_and_init (result);
4476 }
4477 #endif /* ENABLE_UNUSED_FUNCTION */
4478 
4479 /*
4480  * esql_yy_sync_lineno() -
4481  * return : void
4482  */
4483 void
4484 esql_yy_sync_lineno (void)
4485 {
4486  need_line_directive = true;
4487 }
4488 
4489 /*
4490  * esql_yy_set_buf() -
4491  * return : void
4492  * vstr(in) :
4493  */
4494 void
4495 esql_yy_set_buf (varstring * vstr)
4496 {
4497  current_buf = vstr;
4498 }
4499 
4500 /*
4501  * esql_yy_get_buf() -
4502  * return : void
4503  */
4504 varstring *
4505 esql_yy_get_buf (void)
4506 {
4507  return current_buf;
4508 }
4509 
4510 /*
4511  * esql_yy_erase_last_token() -
4512  * return : void
4513  */
4514 void
4515 esql_yy_erase_last_token (void)
4516 {
4517  if (current_buf && esql_yytext)
4518  current_buf->end -= strlen (esql_yytext);
4519 }
4520 
4521 /*
4522  * esql_yyinit() -
4523  * return : void
4524  */
4525 void
4526 esql_yyinit (void)
4527 {
4528  /*
4529  * We've been burned too many times by people who can't alphabetize;
4530  * just sort the bloody thing once to protect ourselves from bozos.
4531  */
4532  qsort (c_keywords,
4533  sizeof (c_keywords) / sizeof (c_keywords[0]),
4534  sizeof (c_keywords[0]), &keyword_cmp);
4535  qsort (csql_keywords,
4536  sizeof (csql_keywords) / sizeof (csql_keywords[0]),
4537  sizeof (csql_keywords[0]), &keyword_case_cmp);
4538 
4539  mode_stack = NULL;
4540  recognize_keywords = true;
4541  esql_yy_enter (START);
4542 }
4543 
4544 
4545 char* mm_buff = NULL;
4546 int mm_idx = 0;
4547 int mm_size = 0;
4548 
4549 /*
4550  * mm_malloc() -
4551  * return : char*
4552  * size(in) :
4553  */
4554 char*
4555 mm_malloc (int size)
4556 {
4557  char* ret;
4558 
4559  if (mm_buff==NULL)
4560  {
4561  mm_size = 1024*1024;
4562  mm_buff = pp_malloc(mm_size);
4563  }
4564 
4565  if (mm_idx + size > mm_size)
4566  {
4567  mm_size *= 2;
4568  ret = pp_malloc(mm_size);
4569  free(mm_buff);
4570  mm_buff = ret;
4571  }
4572 
4573  ret = &mm_buff[mm_idx];
4574  mm_idx += size;
4575 
4576  return ret;
4577 }
4578 
4579 
4580 /*
4581  * mm_strdup() -
4582  * return : char*
4583  * str(in) :
4584  */
4585 char*
4586 mm_strdup (char* str)
4587 {
4588  const int max_len = 1024 * 1024 * 10;
4589  char* buff;
4590  int len = strnlen(str, max_len);
4591 
4592  if (len == max_len)
4593  {
4594  esql_yyverror("(mm_strdup) internal error: string size is too large");
4595  exit (1);
4596  }
4597 
4598  buff = mm_malloc(len + 1);
4599  strncpy(buff, str, len);
4600  buff[len] = '\0';
4601 
4602  return buff;
4603 }
4604 
4605 
4606 /*
4607  * mm_free() -
4608  * return : void
4609  */
4610 void
4611 mm_free(void)
4612 {
4613  if (mm_buff)
4614  {
4615  free(mm_buff);
4616  mm_buff = NULL;
4617  mm_size = 0;
4618  mm_idx = 0;
4619  }
4620 }
4621 
4622 
4623 
4624 
4625 
4626 
4627 
4628 
4629 
4630 
4631