PostgreSQL Source Code: src/bin/psql/psqlscanslash.l Source File (original) (raw)
1%top{
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
20
21#include <ctype.h>
22
25
28
30}
31
32%{
34
35
36
37
38
40
41
42
43
44
49
50
51
52#define LEXRES_EOL 0
53#define LEXRES_OK 1
54
55
57
58#define ECHO psqlscan_emit(cur_state, yytext, yyleng)
59
60
61
static int backtick_start_offset
static int unquoted_option_chars
static char * option_quote
static enum slash_option_type option_type
static void evaluate_backtick(PsqlScanState state)
62%}
63
64
65%option reentrant
66%option bison-bridge
67%option 8bit
68%option never-interactive
69%option nodefault
70%option noinput
71%option nounput
72%option noyywrap
73%option warn
74%option prefix="slash_yy"
75
76
77
78
79
80%option extra-type="PsqlScanState"
81
82
83
84
85
86
87
88
89
90
91
92%x xslashcmd
93%x xslashargstart
94%x xslasharg
95%x xslashquote
96%x xslashbackquote
97%x xslashdquote
98%x xslashwholeline
99%x xslashend
100
101
102
103
104space [ \t\n\r\f\v]
105quote '
106xeoctesc [\\][0-7]{1,3}
107xehexesc [\\]x[0-9A-Fa-f]{1,2}
108xqdouble {quote}{quote}
109dquote \"
110variable_char [A-Za-z\200-\377_0-9]
111
112other .
113
115
116%{
117
118 PsqlScanState cur_state = yyextra;
119 PQExpBuffer output_buf = cur_state->output_buf;
120
121
122
123
124
125
126
127
128 BEGIN(cur_state->start_state);
129%}
130
131
132
133
134
135
136{other}|\n { ECHO; }
137
138
139
140
141
142{
143
144
145{space}|"\\" {
146 yyless(0);
147 cur_state->start_state = YY_START;
149 }
150
151{other} { ECHO; }
152
153}
154
155{
156
157
158
159
160
161
162{space}+ { }
163
164"|" {
166 {
167
169 BEGIN(xslashwholeline);
170 }
171 else
172 {
173
174 yyless(0);
175 BEGIN(xslasharg);
176 }
177 }
178
179{other} {
180 yyless(0);
181 BEGIN(xslasharg);
182 }
183
184}
185
186{
187
188
189
190
191
192
193
194
195{space}|"\\" {
196
197
198
199
200
201
202
203
204
205 yyless(0);
206 cur_state->start_state = YY_START;
208 }
209
210{quote} {
213 BEGIN(xslashquote);
214 }
215
216"`" {
220 BEGIN(xslashbackquote);
221 }
222
223{dquote} {
227 BEGIN(xslashdquote);
228 }
229
230:{variable_char}+ {
231
232 if (cur_state->callbacks->get_variable == NULL)
234 else
235 {
236 char *varname;
238
240 yytext + 1,
242 value = cur_state->callbacks->get_variable(varname,
244 cur_state->cb_passthrough);
245 free(varname);
246
247
248
249
250
251
252
253
255 {
258 }
259 else
261
263 }
265 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
char * psqlscan_extract_substring(PsqlScanState state, const char *txt, int len)
266
267:'{variable_char}+' {
272 }
void psqlscan_escape_variable(PsqlScanState state, const char *txt, int len, PsqlScanQuoteType quote)
273
274
275:\"{variable_char}+\" {
280 }
281
282:\{\?{variable_char}+\} {
284 }
void psqlscan_test_variable(PsqlScanState state, const char *txt, int len)
285
286:'{variable_char}* {
287
288 yyless(1);
291 }
292
293:\"{variable_char}* {
294
295 yyless(1);
298 }
299
300:\{\?{variable_char}* {
301
302 yyless(1);
305 }
306
307:\{ {
308
309 yyless(1);
312 }
313
314{other} {
317 }
318
319}
320
321{
322
323
324
325
326
327{quote} { BEGIN(xslasharg); }
328
void appendPQExpBufferChar(PQExpBuffer str, char ch)
330
336
337{xeoctesc} {
338
340 (char) strtol(yytext + 1, NULL, 8));
341 }
342
343{xehexesc} {
344
346 (char) strtol(yytext + 2, NULL, 16));
347 }
348
349"\\". { psqlscan_emit(cur_state, yytext + 1, 1); }
void psqlscan_emit(PsqlScanState state, const char *txt, int len)
350
351{other}|\n { ECHO; }
352
353}
354
355{
356
357
358
359
360
361"`" {
362
363 if (cur_state->cb_passthrough == NULL ||
366 BEGIN(xslasharg);
367 }
bool conditional_active(ConditionalStack cstack)
368
369:{variable_char}+ {
370
371 if (cur_state->callbacks->get_variable == NULL)
373 else
374 {
375 char *varname;
377
379 yytext + 1,
381 value = cur_state->callbacks->get_variable(varname,
383 cur_state->cb_passthrough);
384 free(varname);
385
387 {
390 }
391 else
393 }
394 }
395
396:'{variable_char}+' {
399 }
400
401:'{variable_char}* {
402
403 yyless(1);
405 }
406
407{other}|\n { ECHO; }
408
409}
410
411{
412
413
414{dquote} {
416 BEGIN(xslasharg);
417 }
418
419{other}|\n { ECHO; }
420
421}
422
423{
424
425
426
427{space}+ {
428 if (output_buf->len > 0)
430 }
431
432{other} { ECHO; }
433
434}
435
436{
437
438
439"\\\\" {
440 cur_state->start_state = YY_START;
442 }
443
444{other}|\n {
445 yyless(0);
446 cur_state->start_state = YY_START;
448 }
449
450}
451
452<> {
453 if (cur_state->buffer_stack == NULL)
454 {
455 cur_state->start_state = YY_START;
456 return LEXRES_EOL;
457 }
458
459
460
461
462
465 }
void psqlscan_select_top_buffer(PsqlScanState state)
void psqlscan_pop_buffer_stack(PsqlScanState state)
466
467%%
468
469
470
471
472
473
474
475
476
477
478
479char *
481{
483
484
486
487
489
490
491 state->output_buf = &mybuf;
492
493
494 if (state->buffer_stack != NULL)
495 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
496 else
497 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
498
499
500
501
502
503 state->start_state = xslashcmd;
504
505
507
508
509
510
511
512
513
515
516 return mybuf.data;
517}
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538char *
541 char *quote,
543{
546 int final_state;
547 char local_quote;
548
549
551
552 if (quote == NULL)
553 quote = &local_quote;
554 *quote = 0;
555
556
558
559
563
564
565 state->output_buf = &mybuf;
566
567
568 if (state->buffer_stack != NULL)
569 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
570 else
571 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
572
573
575 state->start_state = xslashwholeline;
576 else
577 state->start_state = xslashargstart;
578
579
580 lexresult = yylex(NULL, state->scanner);
581
582
583 final_state = state->start_state;
584
585
586
587
588
590
591
592
593
594
595
597
598 switch (final_state)
599 {
600 case xslashargstart:
601
602 break;
603 case xslasharg:
604
606 {
608 mybuf.len > 0 &&
609 mybuf.data[mybuf.len - 1] == ';')
610 {
611 mybuf.data[--mybuf.len] = '\0';
612 }
613 }
614
615
616
617
618
620 {
623 state->encoding);
624
625 mybuf.len = strlen(mybuf.data);
626 }
627 break;
628 case xslashquote:
629 case xslashbackquote:
630 case xslashdquote:
631
634 return NULL;
635 case xslashwholeline:
636
637
638
639
640
641
642
644 {
645 while (mybuf.len > 0 &&
646 (mybuf.data[mybuf.len - 1] == ';' ||
647 (isascii((unsigned char) mybuf.data[mybuf.len - 1]) &&
648 isspace((unsigned char) mybuf.data[mybuf.len - 1]))))
649 {
650 mybuf.data[--mybuf.len] = '\0';
651 }
652 }
653 break;
654 default:
655
656 fprintf(stderr, "invalid YY_START\n");
657 exit(1);
658 }
659
660
661
662
663
664 if (mybuf.len == 0 && *quote == 0)
665 {
667 return NULL;
668 }
669
670
671 return mybuf.data;
672}
673
674
675
676
677void
679{
680
682
683
684 state->output_buf = NULL;
685
686
687 if (state->buffer_stack != NULL)
688 yy_switch_to_buffer(state->buffer_stack->buf, state->scanner);
689 else
690 yy_switch_to_buffer(state->scanbufhandle, state->scanner);
691
692
693 state->start_state = xslashend;
694
695
697
698
699
700
701
702
703
705}
706
707
708
709
710int
712{
713 return state->paren_depth;
714}
715
716
717
718
719void
721{
723 state->paren_depth = depth;
724}
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742void
744{
745 bool inquotes = false;
746 char *cp = str;
747
748 while (*cp)
749 {
750 if (*cp == '"')
751 {
752 if (inquotes && cp[1] == '"')
753 {
754
755 cp++;
756 }
757 else
758 inquotes = !inquotes;
759
760 memmove(cp, cp + 1, strlen(cp));
761
762 }
763 else
764 {
765 if (downcase && !inquotes)
766 *cp = pg_tolower((unsigned char) *cp);
768 }
769 }
770}
771
772
773
774
775
776
777
778static void
780{
784 FILE *fd;
785 bool error = false;
786 int exit_code = 0;
787 char buf[512];
788 size_t result;
789
791
792 fflush(NULL);
793 fd = popen(cmd, "r");
794 if ()
795 {
798 exit_code = -1;
799 }
800
802 {
803 do
804 {
805 result = fread(buf, 1, sizeof(buf), fd);
806 if (ferror(fd))
807 {
810 break;
811 }
813 } while (!feof(fd));
814 }
815
816 if (fd)
817 {
818
819
820
821
822
823 exit_code = pclose(fd);
824 if (exit_code == -1)
825 {
828 }
829 }
830
832 {
835 }
836
837
839 output_buf->data[output_buf->len] = '\0';
840
841
843 {
844
845 if (cmd_output.len > 0 &&
846 cmd_output.data[cmd_output.len - 1] == '\n')
847 cmd_output.len--;
849 }
850
851
853
855}
void SetShellResultVariables(int wait_result)
#define PG_USED_FOR_ASSERTS_ONLY
#define fprintf(file, fmt, msg)
int PQmblenBounded(const char *s, int encoding)
Assert(PointerIsAligned(start, uint64))
#define pg_log_error(...)
unsigned char pg_tolower(unsigned char ch)
void initPQExpBuffer(PQExpBuffer str)
void appendBinaryPQExpBuffer(PQExpBuffer str, const char *data, size_t datalen)
void termPQExpBuffer(PQExpBuffer str)
#define PQExpBufferDataBroken(buf)
static int fd(const char *x, int i)
void psql_scan_reselect_sql_lexer(PsqlScanState state)
void psql_scan_slash_command_end(PsqlScanState state)
void psql_scan_set_paren_depth(PsqlScanState state, int depth)
void dequote_downcase_identifier(char *str, bool downcase, int encoding)
int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner)
char * psql_scan_slash_option(PsqlScanState state, enum slash_option_type type, char *quote, bool semicolon)
int psql_scan_get_paren_depth(PsqlScanState state)
char * psql_scan_slash_command(PsqlScanState state)