PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pgc.l File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <limits.h>
#include "common/string.h"
#include "preproc_extern.h"
#include "preproc.h"

Go to the source code of this file.

Data Structures

struct  _yy_buffer
 
struct  _if_value
 

Macros

#define startlit()   (literalbuf[0] = '\0', literallen = 0)
 
#define MAX_NESTED_IF   128
 

Functions

static void addlit (char *ytext, int yleng)
 
static void addlitchar (unsigned char ychar)
 
static int process_integer_literal (const char *token, YYSTYPE *lval, int base)
 
static void parse_include (void)
 
static bool ecpg_isspace (char ch)
 
static bool isdefine (void)
 
static bool isinformixdefine (void)
 
int yylex (void)
 
void lex_init (void)
 

Variables

YYSTYPE base_yylval
 
static int xcdepth = 0
 
static chardolqstart = NULL
 
static charliteralbuf = NULL
 
static int literallen
 
static int literalalloc
 
static int parenths_open
 
static bool include_next
 
chartoken_start
 
static int state_before_str_start
 
static int state_before_str_stop
 
static struct _yy_bufferyy_buffer = NULL
 
static short preproc_tos
 
static bool ifcond
 
static struct _if_value stacked_if_value [MAX_NESTED_IF]
 

Macro Definition Documentation

◆ MAX_NESTED_IF

#define MAX_NESTED_IF   128

Definition at line 102 of file pgc.l.

◆ startlit

#define startlit ( )    (literalbuf[0] = '\0', literallen = 0)

Definition at line 57 of file pgc.l.

Function Documentation

◆ addlit()

static void addlit ( char ytext,
int  yleng 
)
static

Definition at line 1650 of file pgc.l.

1651{
1652 /* enlarge buffer if needed */
1653 if ((literallen + yleng) >= literalalloc)
1654 {
1655 do
1656 literalalloc *= 2;
1657 while ((literallen + yleng) >= literalalloc);
1659 }
1660 /* append new data, add trailing null */
1662 literallen += yleng;
1663 literalbuf[literallen] = '\0';
static int literallen
Definition pgc.l:48
static char * literalbuf
Definition pgc.l:47
static int literalalloc
Definition pgc.l:49
static int fb(int x)
#define realloc(a, b)
1664}

References fb(), literalalloc, literalbuf, literallen, and realloc.

◆ addlitchar()

static void addlitchar ( unsigned char  ychar)
static

Definition at line 1667 of file pgc.l.

1668{
1669 /* enlarge buffer if needed */
1670 if ((literallen + 1) >= literalalloc)
1671 {
1672 literalalloc *= 2;
1674 }
1675 /* append new data, add trailing null */
1677 literallen += 1;
1678 literalbuf[literallen] = '\0';
1679}

References fb(), literalalloc, literalbuf, literallen, and realloc.

◆ ecpg_isspace()

static bool ecpg_isspace ( char  ch)
static

Definition at line 1814 of file pgc.l.

1815{
1816 if (ch == ' ' ||
1817 ch == '\t' ||
1818 ch == '\n' ||
1819 ch == '\r' ||
1820 ch == '\f' ||
1821 ch == '\v')
1822 return true;
1823 return false;
1824}

References fb().

Referenced by parse_include().

◆ isdefine()

static bool isdefine ( void  )
static

Definition at line 1831 of file pgc.l.

1832{
1833 struct _defines *ptr;
1834
1835 /* is it a define? */
1836 for (ptr = defines; ptr; ptr = ptr->next)
1837 {
1838 /* notice we do not match anything being actively expanded */
1839 if (strcmp(yytext, ptr->name) == 0 &&
1840 ptr->value != NULL &&
1841 ptr->used == NULL)
1842 {
1843 /* Save state associated with the current buffer */
1844 struct _yy_buffer *yb;
struct _defines * defines
Definition ecpg.c:31
struct _defines * next
Definition type.h:185
char * value
Definition type.h:182
char * name
Definition type.h:181
void * used
Definition type.h:184
1845
1846 yb = mm_alloc(sizeof(struct _yy_buffer));
void * mm_alloc(size_t size)
Definition util.c:85
1847
1848 yb->buffer = YY_CURRENT_BUFFER;
1849 yb->lineno = yylineno;
1850 yb->filename = mm_strdup(input_filename);
1851 yb->next = yy_buffer;
1852 yy_buffer = yb;
static struct _yy_buffer * yy_buffer
char * mm_strdup(const char *string)
Definition util.c:97
char * input_filename
1853
1854 /* Mark symbol as being actively expanded */
1855 ptr->used = yb;
1856
1857 /*
1858 * We use yy_scan_string which will copy the value, so there's no
1859 * need to worry about a possible undef happening while we are
1860 * still scanning it.
1861 */
1862 yy_scan_string(ptr->value);
1863 return true;
1864 }
1865 }
1866
1867 return false;
1868}

References defines, fb(), input_filename, mm_alloc(), mm_strdup(), _defines::name, _defines::next, _defines::used, _defines::value, and yy_buffer.

◆ isinformixdefine()

static bool isinformixdefine ( void  )
static

Definition at line 1875 of file pgc.l.

1876{
1877 const char *new = NULL;
1878
1879 if (strcmp(yytext, "dec_t") == 0)
1880 new = "decimal";
1881 else if (strcmp(yytext, "intrvl_t") == 0)
1882 new = "interval";
1883 else if (strcmp(yytext, "dtime_t") == 0)
1884 new = "timestamp";
1885
1886 if (new)
1887 {
1888 struct _yy_buffer *yb;
1889
1890 yb = mm_alloc(sizeof(struct _yy_buffer));
1891
1892 yb->buffer = YY_CURRENT_BUFFER;
1893 yb->lineno = yylineno;
1894 yb->filename = mm_strdup(input_filename);
1895 yb->next = yy_buffer;
1896 yy_buffer = yb;
1897
1898 yy_scan_string(new);
1899 return true;
1900 }
1901
1902 return false;
1903}

References fb(), input_filename, mm_alloc(), mm_strdup(), and yy_buffer.

◆ lex_init()

void lex_init ( void  )

Definition at line 1624 of file pgc.l.

1625{
1626 braces_open = 0;
1627 parenths_open = 0;
static int parenths_open
Definition pgc.l:52
int braces_open
char * current_function
1629
1630 yylineno = 1;
1631
1632 /* initialize state for if/else/endif */
1633 preproc_tos = 0;
static short preproc_tos
Definition pgc.l:103
static struct _if_value stacked_if_value[MAX_NESTED_IF]
bool active
Definition pgc.l:107
bool else_branch
Definition pgc.l:109
bool saw_active
Definition pgc.l:108
1637
1638 /* initialize literal buffer to a reasonable but expansible size */
1639 if (literalbuf == NULL)
1640 {
1641 literalalloc = 1024;
1642 literalbuf = (char *) mm_alloc(literalalloc);
1643 }
1644 startlit();
#define startlit()
Definition pgc.l:57
1645
1646 BEGIN(C);
1647}

References _if_value::active, braces_open, current_function, _if_value::else_branch, fb(), literalalloc, literalbuf, mm_alloc(), parenths_open, preproc_tos, _if_value::saw_active, stacked_if_value, and startlit.

Referenced by main().

◆ parse_include()

static void parse_include ( void  )
static

Definition at line 1704 of file pgc.l.

1705{
1706 /* got the include file name */
1707 struct _yy_buffer *yb;
1708 struct _include_path *ip;
1709 char inc_file[MAXPGPATH];
1710 unsigned int i;
int i
Definition isn.c:77
#define MAXPGPATH
1711
1712 yb = mm_alloc(sizeof(struct _yy_buffer));
1713
1714 yb->buffer = YY_CURRENT_BUFFER;
1715 yb->lineno = yylineno;
1716 yb->filename = input_filename;
1717 yb->next = yy_buffer;
1718
1719 yy_buffer = yb;
1720
1721 /*
1722 * skip the ";" if there is one and trailing whitespace. Note that yytext
1723 * contains at least one non-space character plus the ";"
1724 */
1725 for (i = strlen(yytext) - 2;
1726 i > 0 && ecpg_isspace(yytext[i]);
1727 i--)
1728 ;
static bool ecpg_isspace(char ch)
Definition pgc.l:1814
1729
1730 if (yytext[i] == ';')
1731 i--;
1732
1733 yytext[i + 1] = '\0';
1734
1735 yyin = NULL;
1736
1737 /* If file name is enclosed in '"' remove these and look only in '.' */
1738
1739 /*
1740 * Informix does look into all include paths though, except filename
1741 * starts with '/'
1742 */
1743 if (yytext[0] == '"' && yytext[i] == '"' &&
1745 {
1746 yytext[i] = '\0';
enum COMPAT_MODE compat
Definition ecpg.c:26
@ ECPG_COMPAT_INFORMIX
@ ECPG_COMPAT_INFORMIX_SE
1748
1749 strlcpy(inc_file, yytext, sizeof(inc_file));
1750 yyin = fopen(inc_file, "r");
1751 if (!yyin)
1752 {
1753 if (strlen(inc_file) <= 2 || strcmp(inc_file + strlen(inc_file) - 2, ".h") != 0)
1754 {
1755 strcat(inc_file, ".h");
1756 yyin = fopen(inc_file, "r");
1757 }
1758 }
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
1759
1760 }
1761 else
1762 {
1763 if ((yytext[0] == '"' && yytext[i] == '"') || (yytext[0] == '<' && yytext[i] == '>'))
1764 {
1765 yytext[i] = '\0';
1767 }
1768
1769 for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
1770 {
1771 if (strlen(ip->path) + strlen(yytext) + 4 > MAXPGPATH)
1772 {
1773 fprintf(stderr, _("Error: include path \"%s/%s\" is too long on line %d, skipping\n"), ip->path, yytext, yylineno);
1774 continue;
1775 }
1776 snprintf(inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext);
1777 yyin = fopen(inc_file, "r");
1778 if (!yyin)
1779 {
1780 if (strcmp(inc_file + strlen(inc_file) - 2, ".h") != 0)
1781 {
1782 strcat(inc_file, ".h");
1783 yyin = fopen(inc_file, "r");
1784 }
1785 }
#define fprintf(file, fmt, msg)
Definition cubescan.l:21
struct _include_path * include_paths
Definition ecpg.c:28
#define _(x)
Definition elog.c:95
#define snprintf
Definition port.h:260
struct _include_path * next
Definition type.h:134
1786
1787 /*
1788 * if the command was "include_next" we have to disregard the
1789 * first hit
1790 */
1791 if (yyin && include_next)
1792 {
1793 fclose(yyin);
1794 yyin = NULL;
1795 include_next = false;
1796 }
1797 }
1798 }
1799 if (!yyin)
1800 mmfatal(NO_INCLUDE_FILE, "could not open include file \"%s\" on line %d", yytext, yylineno);
static bool include_next
Definition pgc.l:55
void pg_noreturn void mmfatal(int error_code, const char *error,...) pg_attribute_printf(2
#define NO_INCLUDE_FILE
1801
1804 yylineno = 1;
void output_line_number(void)
Definition output.c:10
1806
1807 BEGIN(C);
1808}

References _, compat, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ecpg_isspace(), fb(), fprintf, i, include_next, include_paths, input_filename, MAXPGPATH, mm_alloc(), mm_strdup(), mmfatal(), _include_path::next, NO_INCLUDE_FILE, output_line_number(), snprintf, strlcpy(), and yy_buffer.

◆ process_integer_literal()

static int process_integer_literal ( const char token,
YYSTYPE lval,
int  base 
)
static

Definition at line 1686 of file pgc.l.

1687{
1688 int val;
1689 char *endptr;
long val
Definition informix.c:689
1690
1691 errno = 0;
1692 val = strtoint(base == 10 ? token : token + 2, &endptr, base);
1693 if (*endptr != '\0' || errno == ERANGE)
1694 {
1695 /* integer too large (or contains decimal pt), treat it as a float */
1696 lval->str = loc_strdup(token);
1697 return FCONST;
1698 }
1699 lval->ival = val;
1700 return ICONST;
char * loc_strdup(const char *string)
Definition util.c:170
int strtoint(const char *pg_restrict str, char **pg_restrict endptr, int base)
Definition string.c:50
1701}

References fb(), loc_strdup(), strtoint(), and val.

◆ yylex()

int yylex ( void  )

Definition at line 465 of file pgc.l.

467 {
468 /* code to execute during start of each call of yylex() */
469 char *newdefsymbol = NULL;
470
char * token_start
Definition pgc.l:66
472%}
473
474<SQL>{
475{whitespace} {
476 /* ignore */
477 }
478} /* <SQL> */
479
480<C,SQL>{
481{xcstart} {
484 xcdepth = 0;
485 BEGIN(xc);
486 /* Put back any characters past slash-star; see above */
487 yyless(2);
488 fputs("/*", yyout);
489 }
static int state_before_str_start
Definition pgc.l:69
static int xcdepth
Definition pgc.l:38
490} /* <C,SQL> */
491
492<xc>{
493{xcstart} {
495 {
496 xcdepth++;
497 /* Put back any characters past slash-star; see above */
498 yyless(2);
499 fputs("/_*", yyout);
500 }
501 else if (state_before_str_start == C)
502 {
503 ECHO;
504 }
505 }
#define ECHO
506
507{xcstop} {
509 {
510 if (xcdepth <= 0)
511 {
512 ECHO;
513 BEGIN(SQL);
515 }
516 else
517 {
518 xcdepth--;
519 fputs("*_/", yyout);
520 }
521 }
522 else if (state_before_str_start == C)
523 {
524 ECHO;
525 BEGIN(C);
527 }
528 }
529
530{xcinside} {
531 ECHO;
532 }
533
534{op_chars} {
535 ECHO;
536 }
537
538\*+ {
539 ECHO;
540 }
541
542<<EOF>> {
543 mmfatal(PARSE_ERROR, "unterminated /* comment");
544 }
#define PARSE_ERROR
545} /* <xc> */
546
547<SQL>{
548{xbstart} {
551 BEGIN(xb);
552 startlit();
553 }
554} /* <SQL> */
555
556<xh>{xhinside} |
557<xb>{xbinside} {
559 }
static void addlit(char *ytext, int yleng)
Definition pgc.l:1650
#define yyleng
Definition scan.l:1108
560<xb><<EOF>> {
561 mmfatal(PARSE_ERROR, "unterminated bit string literal");
562 }
563
564<SQL>{xhstart} {
567 BEGIN(xh);
568 startlit();
569 }
570<xh><<EOF>> {
571 mmfatal(PARSE_ERROR, "unterminated hexadecimal string literal");
572 }
573
574<C>{xqstart} {
577 BEGIN(xqc);
578 startlit();
579 }
580
581<SQL>{
582{xnstart} {
583 /* National character. Transfer it as-is to the backend. */
586 BEGIN(xn);
587 startlit();
588 }
589
590{xqstart} {
593 BEGIN(xq);
594 startlit();
595 }
596{xestart} {
599 BEGIN(xe);
600 startlit();
601 }
602{xusstart} {
605 BEGIN(xus);
606 startlit();
607 }
608} /* <SQL> */
609
610<xb,xh,xq,xqc,xe,xn,xus>{quote} {
611 /*
612 * When we are scanning a quoted string and see an end
613 * quote, we must look ahead for a possible continuation.
614 * If we don't see one, we know the end quote was in fact
615 * the end of the string. To reduce the lexer table size,
616 * we use a single "xqs" state to do the lookahead for all
617 * types of strings.
618 */
620 BEGIN(xqs);
621 }
static int state_before_str_stop
Definition pgc.l:70
622<xqs>{quotecontinue} {
623 /*
624 * Found a quote continuation, so return to the in-quote
625 * state and continue scanning the literal. Nothing is
626 * added to the literal's contents.
627 */
629 }
630<xqs>{quotecontinuefail} |
631<xqs>{other} |
632<xqs><<EOF>> {
633 /*
634 * Failed to see a quote continuation. Throw back
635 * everything after the end quote, and handle the string
636 * according to the state we were in previously.
637 */
638 yyless(0);
640
641 switch (state_before_str_stop)
642 {
643 case xb:
644 if (literalbuf[strspn(literalbuf, "01")] != '\0')
645 mmerror(PARSE_ERROR, ET_ERROR, "invalid bit string literal");
646 base_yylval.str = make3_str("b'", literalbuf, "'");
647 return BCONST;
648 case xh:
649 if (literalbuf[strspn(literalbuf, "0123456789abcdefABCDEF")] != '\0')
650 mmerror(PARSE_ERROR, ET_ERROR, "invalid hexadecimal string literal");
651 base_yylval.str = make3_str("x'", literalbuf, "'");
652 return XCONST;
653 case xq:
654 /* fallthrough */
655 case xqc:
656 base_yylval.str = make3_str("'", literalbuf, "'");
657 return SCONST;
658 case xe:
659 base_yylval.str = make3_str("E'", literalbuf, "'");
660 return SCONST;
661 case xn:
662 base_yylval.str = make3_str("N'", literalbuf, "'");
663 return SCONST;
664 case xus:
665 base_yylval.str = make3_str("U&'", literalbuf, "'");
666 return USCONST;
667 default:
668 mmfatal(PARSE_ERROR, "unhandled previous state in xqs\n");
669 }
670 }
YYSTYPE base_yylval
void mmerror(int error_code, enum errortype type, const char *error,...) pg_attribute_printf(3
char * make3_str(const char *str1, const char *str2, const char *str3)
Definition util.c:256
@ ET_ERROR
Definition type.h:220
671
672<xq,xe,xn,xus>{xqdouble} {
674 }
675<xqc>{xqcquote} {
677 }
678<xq,xqc,xn,xus>{xqinside} {
680 }
681<xe>{xeinside} {
683 }
684<xe>{xeunicode} {
686 }
687<xe>{xeescape} {
689 }
690<xe>{xeoctesc} {
692 }
693<xe>{xehexesc} {
695 }
696<xe>. {
697 /* This is only needed for \ just before EOF */
698 addlitchar(yytext[0]);
699 }
static void addlitchar(unsigned char ychar)
Definition pgc.l:1667
700<xq,xqc,xe,xn,xus><<EOF>> {
701 mmfatal(PARSE_ERROR, "unterminated quoted string");
702 }
703
704<SQL>{
705{dolqdelim} {
707 if (dolqstart)
710 BEGIN(xdolq);
711 startlit();
713 }
static char * dolqstart
Definition pgc.l:39
#define free(a)
714{dolqfailed} {
715 /* throw back all but the initial "$" */
716 yyless(1);
717 /* and treat it as {other} */
718 return yytext[0];
719 }
720} /* <SQL> */
721
722<xdolq>{dolqdelim} {
723 if (strcmp(yytext, dolqstart) == 0)
724 {
727 dolqstart = NULL;
728 BEGIN(SQL);
730 return SCONST;
731 }
732 else
733 {
734 /*
735 * When we fail to match $...$ to dolqstart, transfer
736 * the $... part to the output, but put back the final
737 * $ for rescanning. Consider $delim$...$junk$delim$
738 */
739 addlit(yytext, yyleng - 1);
740 yyless(yyleng - 1);
741 }
742 }
743<xdolq>{dolqinside} {
745 }
746<xdolq>{dolqfailed} {
748 }
749<xdolq>. {
750 /* single quote or dollar sign */
751 addlitchar(yytext[0]);
752 }
753<xdolq><<EOF>> {
754 mmfatal(PARSE_ERROR, "unterminated dollar-quoted string");
755 }
756
757<SQL>{
758{xdstart} {
760 BEGIN(xd);
761 startlit();
762 }
763{xuistart} {
765 BEGIN(xui);
766 startlit();
767 }
768} /* <SQL> */
769
770<xd>{xdstop} {
772 if (literallen == 0)
773 mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
774
775 /*
776 * The server will truncate the identifier here. We do
777 * not, as (1) it does not change the result; (2) we don't
778 * know what NAMEDATALEN the server might use; (3) this
779 * code path is also taken for literal query strings in
780 * PREPARE and EXECUTE IMMEDIATE, which can certainly be
781 * longer than NAMEDATALEN.
782 */
784 return CSTRING;
785 }
786<xdc>{xdstop} {
789 return CSTRING;
790 }
791<xui>{dquote} {
793 if (literallen == 0)
794 mmerror(PARSE_ERROR, ET_ERROR, "zero-length delimited identifier");
795
796 /*
797 * The backend will truncate the identifier here. We do
798 * not as it does not change the result.
799 */
800 base_yylval.str = make3_str("U&\"", literalbuf, "\"");
801 return UIDENT;
802 }
803<xd,xui>{xddouble} {
805 }
806<xd,xui>{xdinside} {
808 }
809<xd,xui><<EOF>> {
810 mmfatal(PARSE_ERROR, "unterminated quoted identifier");
811 }
812<C>{xdstart} {
814 BEGIN(xdc);
815 startlit();
816 }
817<xdc>{xdcinside} {
819 }
820<xdc><<EOF>> {
821 mmfatal(PARSE_ERROR, "unterminated quoted string");
822 }
823
824<SQL>{
825{typecast} {
826 return TYPECAST;
827 }
828
829{dot_dot} {
830 return DOT_DOT;
831 }
832
833{colon_equals} {
834 return COLON_EQUALS;
835 }
836
837{equals_greater} {
838 return EQUALS_GREATER;
839 }
840
841{less_equals} {
842 return LESS_EQUALS;
843 }
844
845{greater_equals} {
846 return GREATER_EQUALS;
847 }
848
849{less_greater} {
850 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
851 return NOT_EQUALS;
852 }
853
854{not_equals} {
855 /* We accept both "<>" and "!=" as meaning NOT_EQUALS */
856 return NOT_EQUALS;
857 }
858
859{right_arrow} {
860 return RIGHT_ARROW;
861 }
862
863{informix_special} {
864 /* are we simulating Informix? */
865 if (INFORMIX_MODE)
866 {
867 unput(':');
868 }
869 else
870 return yytext[0];
871 }
#define INFORMIX_MODE(X)
872
873{self} {
874 /*
875 * We may find a ';' inside a structure definition in a
876 * TYPE or VAR statement. This is not an EOL marker.
877 */
878 if (yytext[0] == ';' && struct_level == 0)
879 BEGIN(C);
880 return yytext[0];
881 }
int struct_level
882
883{operator} {
884 /*
885 * Check for embedded slash-star or dash-dash; those
886 * are comment starts, so operator must stop there.
887 * Note that slash-star or dash-dash at the first
888 * character will match a prior rule, not this one.
889 */
890 int nchars = yyleng;
891 char *slashstar = strstr(yytext, "/*");
892 char *dashdash = strstr(yytext, "--");
893
894 if (slashstar && dashdash)
895 {
896 /* if both appear, take the first one */
897 if (slashstar > dashdash)
899 }
900 else if (!slashstar)
902 if (slashstar)
903 nchars = slashstar - yytext;
904
905 /*
906 * For SQL compatibility, '+' and '-' cannot be the
907 * last char of a multi-char operator unless the operator
908 * contains chars that are not in SQL operators.
909 * The idea is to lex '=-' as two operators, but not
910 * to forbid operator names like '?-' that could not be
911 * sequences of SQL operators.
912 */
913 if (nchars > 1 &&
914 (yytext[nchars - 1] == '+' ||
915 yytext[nchars - 1] == '-'))
916 {
917 int ic;
918
919 for (ic = nchars - 2; ic >= 0; ic--)
920 {
921 char c = yytext[ic];
char * c
922
923 if (c == '~' || c == '!' || c == '@' ||
924 c == '#' || c == '^' || c == '&' ||
925 c == '|' || c == '`' || c == '?' ||
926 c == '%')
927 break;
928 }
929 if (ic < 0)
930 {
931 /*
932 * didn't find a qualifying character, so remove
933 * all trailing [+-]
934 */
935 do
936 {
937 nchars--;
938 } while (nchars > 1 &&
939 (yytext[nchars - 1] == '+' ||
940 yytext[nchars - 1] == '-'));
941 }
942 }
943
944 if (nchars < yyleng)
945 {
946 /* Strip the unwanted chars from the token */
947 yyless(nchars);
948
949 /*
950 * If what we have left is only one char, and it's
951 * one of the characters matching "self", then
952 * return it as a character token the same way
953 * that the "self" rule would have.
954 */
955 if (nchars == 1 &&
956 strchr(",()[].;:|+-*/%^<>=", yytext[0]))
957 return yytext[0];
958
959 /*
960 * Likewise, if what we have left is two chars, and
961 * those match the tokens ">=", "<=", "=>", "<>" or
962 * "!=", then we must return the appropriate token
963 * rather than the generic Op.
964 */
965 if (nchars == 2)
966 {
967 if (yytext[0] == '=' && yytext[1] == '>')
968 return EQUALS_GREATER;
969 if (yytext[0] == '>' && yytext[1] == '=')
970 return GREATER_EQUALS;
971 if (yytext[0] == '<' && yytext[1] == '=')
972 return LESS_EQUALS;
973 if (yytext[0] == '<' && yytext[1] == '>')
974 return NOT_EQUALS;
975 if (yytext[0] == '!' && yytext[1] == '=')
976 return NOT_EQUALS;
977 if (yytext[0] == '-' && yytext[1] == '>')
978 return RIGHT_ARROW;
979 }
980 }
981
983 return Op;
984 }
985
986{param} {
987 int val;
988
989 errno = 0;
990 val = strtoint(yytext + 1, NULL, 10);
991 if (errno == ERANGE)
992 mmfatal(PARSE_ERROR, "parameter number too large");
993 base_yylval.ival = val;
994 return PARAM;
995 }
996{param_junk} {
997 mmfatal(PARSE_ERROR, "trailing junk after parameter");
998 }
999
1000{ip} {
1002 return IP;
1003 }
static uint8 IP[64]
Definition crypt-des.c:74
1004} /* <SQL> */
1005
1006<C,SQL>{
1007{decinteger} {
1009 }
static int process_integer_literal(const char *token, YYSTYPE *lval, int base)
Definition pgc.l:1686
1010{hexinteger} {
1012 }
1013{numeric} {
1015 return FCONST;
1016 }
1017{numericfail} {
1018 /* throw back the .., and treat as integer */
1019 yyless(yyleng - 2);
1021 }
1022{real} {
1024 return FCONST;
1025 }
1026{realfail} {
1027 /*
1028 * throw back the [Ee][+-], and figure out whether what
1029 * remains is an {decinteger} or {numeric}.
1030 */
1031 yyless(yyleng - 2);
1033 }
1034} /* <C,SQL> */
1035
1036<SQL>{
1037{octinteger} {
1039 }
1040{bininteger} {
1042 }
1043
1044 /*
1045 * Note that some trailing junk is valid in C (such as 100LL), so we
1046 * contain this to SQL mode.
1047 */
1048{integer_junk} {
1049 mmfatal(PARSE_ERROR, "trailing junk after numeric literal");
1050 }
1051{numeric_junk} {
1052 mmfatal(PARSE_ERROR, "trailing junk after numeric literal");
1053 }
1054{real_junk} {
1055 mmfatal(PARSE_ERROR, "trailing junk after numeric literal");
1056 }
1057
1058:{identifier}((("->"|\.){identifier})|(\[{array}\]))* {
1059 base_yylval.str = loc_strdup(yytext + 1);
1060 return CVARIABLE;
1061 }
1062
1063{identifier} {
1064 /* First check to see if it's a define symbol to expand */
1065 if (!isdefine())
1066 {
1067 int kwvalue;
static bool isdefine(void)
Definition pgc.l:1831
1068
1069 /*
1070 * User-defined typedefs override SQL keywords, but
1071 * not C keywords. Currently, a typedef name is just
1072 * reported as IDENT, but someday we might need to
1073 * return a distinct token type.
1074 */
1075 if (get_typedef(yytext, true) == NULL)
1076 {
1077 /* Is it an SQL/ECPG keyword? */
1079 if (kwvalue >= 0)
1080 return kwvalue;
1081 }
int ScanECPGKeywordLookup(const char *text)
struct typedefs * get_typedef(const char *name, bool noerror)
Definition variable.c:576
1082
1083 /* Is it a C keyword? */
1085 if (kwvalue >= 0)
1086 return kwvalue;
int ScanCKeywordLookup(const char *text)
Definition c_keywords.c:36
1087
1088 /*
1089 * None of the above. Return it as an identifier.
1090 *
1091 * The backend will attempt to truncate and case-fold
1092 * the identifier, but I see no good reason for ecpg
1093 * to do so; that's just another way that ecpg could
1094 * get out of step with the backend.
1095 */
1097 return IDENT;
1098 }
1099 }
1100
1101{other} {
1102 return yytext[0];
1103 }
1104} /* <SQL> */
1105
1106 /*
1107 * Begin ECPG-specific rules
1108 */
1109
1110<C>{exec_sql} {
1111 BEGIN(SQL);
1112 return SQL_START;
1113 }
1114<C>{informix_special} {
1115 /* are we simulating Informix? */
1116 if (INFORMIX_MODE)
1117 {
1118 BEGIN(SQL);
1119 return SQL_START;
1120 }
1121 else
1122 return S_ANYTHING;
1123 }
1124<C>{ccomment} {
1125 ECHO;
1126 }
1127<C>{cppinclude} {
1128 if (system_includes)
1129 {
1130 include_next = false;
1131 BEGIN(incl);
1132 }
1133 else
1134 {
1136 return CPP_LINE;
1137 }
1138 }
bool system_includes
Definition ecpg.c:17
1139<C>{cppinclude_next} {
1140 if (system_includes)
1141 {
1142 include_next = true;
1143 BEGIN(incl);
1144 }
1145 else
1146 {
1148 return CPP_LINE;
1149 }
1150 }
1151<C,SQL>{cppline} {
1153 return CPP_LINE;
1154 }
1155<C>{identifier} {
1156 /*
1157 * Try to detect a function name:
1158 * look for identifiers at the global scope
1159 * keep the last identifier before the first '(' and '{'
1160 */
1161 if (braces_open == 0 && parenths_open == 0)
1162 {
1163 if (current_function)
1166 }
1167 /* Informix uses SQL defines only in SQL space */
1168 /* however, some defines have to be taken care of for compatibility */
1169 if ((!INFORMIX_MODE || !isinformixdefine()) && !isdefine())
1170 {
1171 int kwvalue;
static bool isinformixdefine(void)
Definition pgc.l:1875
1172
1174 if (kwvalue >= 0)
1175 return kwvalue;
1176 else
1177 {
1179 return IDENT;
1180 }
1181 }
1182 }
1183<C>{xcstop} {
1184 mmerror(PARSE_ERROR, ET_ERROR, "nested /* ... */ comments");
1185 }
1186<C>":" { return ':'; }
1187<C>";" { return ';'; }
1188<C>"," { return ','; }
1189<C>"*" { return '*'; }
1190<C>"%" { return '%'; }
1191<C>"/" { return '/'; }
1192<C>"+" { return '+'; }
1193<C>"-" { return '-'; }
1194<C>"(" { parenths_open++; return '('; }
1195<C>")" { parenths_open--; return ')'; }
1196<C,xskip>{space} { ECHO; }
1197<C>\{ { return '{'; }
1198<C>\} { return '}'; }
1199<C>\[ { return '['; }
1200<C>\] { return ']'; }
1201<C>\= { return '='; }
1202<C>"->" { return S_MEMBER; }
1203<C>">>" { return S_RSHIFT; }
1204<C>"<<" { return S_LSHIFT; }
1205<C>"||" { return S_OR; }
1206<C>"&&" { return S_AND; }
1207<C>"++" { return S_INC; }
1208<C>"--" { return S_DEC; }
1209<C>"==" { return S_EQUAL; }
1210<C>"!=" { return S_NEQUAL; }
1211<C>"+=" { return S_ADD; }
1212<C>"-=" { return S_SUB; }
1213<C>"*=" { return S_MUL; }
1214<C>"/=" { return S_DIV; }
1215<C>"%=" { return S_MOD; }
1216<C>"->*" { return S_MEMPOINT; }
1217<C>".*" { return S_DOTPOINT; }
1218<C>{other} { return S_ANYTHING; }
1219<C>{exec_sql}{define}{space}* { BEGIN(def_ident); }
1220<C>{informix_special}{define}{space}* {
1221 /* are we simulating Informix? */
1222 if (INFORMIX_MODE)
1223 {
1225 }
1226 else
1227 {
1228 yyless(1);
1229 return S_ANYTHING;
1230 }
1231 }
1232<C>{exec_sql}{undef}{space}* {
1233 BEGIN(undef);
1234 }
1235<C>{informix_special}{undef}{space}* {
1236 /* are we simulating Informix? */
1237 if (INFORMIX_MODE)
1238 {
1239 BEGIN(undef);
1240 }
1241 else
1242 {
1243 yyless(1);
1244 return S_ANYTHING;
1245 }
1246 }
1247<undef>{identifier}{space}*";" {
1248 struct _defines *ptr,
1249 *ptr2 = NULL;
1250 int i;
1251
1252 /*
1253 * Skip the ";" and trailing whitespace. Note that yytext
1254 * contains at least one non-space character plus the ";"
1255 */
1256 for (i = strlen(yytext) - 2;
1257 i > 0 && ecpg_isspace(yytext[i]);
1258 i--)
1259 ;
1260 yytext[i + 1] = '\0';
1261
1262 /* Find and unset any matching define; should be only 1 */
1263 for (ptr = defines; ptr; ptr2 = ptr, ptr = ptr->next)
1264 {
1265 if (strcmp(yytext, ptr->name) == 0)
1266 {
1267 free(ptr->value);
1268 ptr->value = NULL;
1269 /* We cannot forget it if there's a cmdvalue */
1270 if (ptr->cmdvalue == NULL)
1271 {
1272 if (ptr2 == NULL)
1273 defines = ptr->next;
1274 else
1275 ptr2->next = ptr->next;
1276 free(ptr->name);
1277 free(ptr);
1278 }
1279 break;
1280 }
1281 }
1282
1283 BEGIN(C);
1284 }
1285<undef>{other}|\n {
1286 mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL UNDEF command");
1287 yyterminate();
1288 }
1289<C>{exec_sql}{include}{space}* {
1290 BEGIN(incl);
1291 }
1292<C>{informix_special}{include}{space}* {
1293 /* are we simulating Informix? */
1294 if (INFORMIX_MODE)
1295 {
1296 BEGIN(incl);
1297 }
1298 else
1299 {
1300 yyless(1);
1301 return S_ANYTHING;
1302 }
1303 }
1304<C,xskip>{exec_sql}{ifdef}{space}* {
1305 if (preproc_tos >= MAX_NESTED_IF - 1)
1306 mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
1307 preproc_tos++;
1311 ifcond = true;
1312 BEGIN(xcond);
1313 }
#define MAX_NESTED_IF
Definition pgc.l:102
static bool ifcond
Definition pgc.l:104
1314<C,xskip>{informix_special}{ifdef}{space}* {
1315 /* are we simulating Informix? */
1316 if (INFORMIX_MODE)
1317 {
1318 if (preproc_tos >= MAX_NESTED_IF - 1)
1319 mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
1320 preproc_tos++;
1324 ifcond = true;
1325 BEGIN(xcond);
1326 }
1327 else
1328 {
1329 yyless(1);
1330 return S_ANYTHING;
1331 }
1332 }
1333<C,xskip>{exec_sql}{ifndef}{space}* {
1334 if (preproc_tos >= MAX_NESTED_IF - 1)
1335 mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
1336 preproc_tos++;
1340 ifcond = false;
1341 BEGIN(xcond);
1342 }
1343<C,xskip>{informix_special}{ifndef}{space}* {
1344 /* are we simulating Informix? */
1345 if (INFORMIX_MODE)
1346 {
1347 if (preproc_tos >= MAX_NESTED_IF - 1)
1348 mmfatal(PARSE_ERROR, "too many nested EXEC SQL IFDEF conditions");
1349 preproc_tos++;
1353 ifcond = false;
1354 BEGIN(xcond);
1355 }
1356 else
1357 {
1358 yyless(1);
1359 return S_ANYTHING;
1360 }
1361 }
1362<C,xskip>{exec_sql}{elif}{space}* {
1363 if (preproc_tos == 0)
1364 mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
1365 if (stacked_if_value[preproc_tos].else_branch)
1366 mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
1367 ifcond = true;
1368 BEGIN(xcond);
1369 }
1370<C,xskip>{informix_special}{elif}{space}* {
1371 /* are we simulating Informix? */
1372 if (INFORMIX_MODE)
1373 {
1374 if (preproc_tos == 0)
1375 mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
1376 if (stacked_if_value[preproc_tos].else_branch)
1377 mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
1378 ifcond = true;
1379 BEGIN(xcond);
1380 }
1381 else
1382 {
1383 yyless(1);
1384 return S_ANYTHING;
1385 }
1386 }
1387
1388<C,xskip>{exec_sql}{else}{space}*";" {
1389 /* only exec sql endif pops the stack, so take care of duplicated 'else' */
1390 if (preproc_tos == 0)
1391 mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
1392 else if (stacked_if_value[preproc_tos].else_branch)
1393 mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
1394 else
1395 {
1401
1402 if (stacked_if_value[preproc_tos].active)
1403 BEGIN(C);
1404 else
1405 BEGIN(xskip);
1406 }
1407 }
1408<C,xskip>{informix_special}{else}{space}*";" {
1409 /* are we simulating Informix? */
1410 if (INFORMIX_MODE)
1411 {
1412 if (preproc_tos == 0)
1413 mmfatal(PARSE_ERROR, "missing matching \"EXEC SQL IFDEF\" / \"EXEC SQL IFNDEF\"");
1414 else if (stacked_if_value[preproc_tos].else_branch)
1415 mmfatal(PARSE_ERROR, "more than one EXEC SQL ELSE");
1416 else
1417 {
1423
1424 if (stacked_if_value[preproc_tos].active)
1425 BEGIN(C);
1426 else
1427 BEGIN(xskip);
1428 }
1429 }
1430 else
1431 {
1432 yyless(1);
1433 return S_ANYTHING;
1434 }
1435 }
1436<C,xskip>{exec_sql}{endif}{space}*";" {
1437 if (preproc_tos == 0)
1438 mmfatal(PARSE_ERROR, "unmatched EXEC SQL ENDIF");
1439 else
1440 preproc_tos--;
1441
1442 if (stacked_if_value[preproc_tos].active)
1443 BEGIN(C);
1444 else
1445 BEGIN(xskip);
1446 }
1447<C,xskip>{informix_special}{endif}{space}*";" {
1448 /* are we simulating Informix? */
1449 if (INFORMIX_MODE)
1450 {
1451 if (preproc_tos == 0)
1452 mmfatal(PARSE_ERROR, "unmatched EXEC SQL ENDIF");
1453 else
1454 preproc_tos--;
1455
1456 if (stacked_if_value[preproc_tos].active)
1457 BEGIN(C);
1458 else
1459 BEGIN(xskip);
1460 }
1461 else
1462 {
1463 yyless(1);
1464 return S_ANYTHING;
1465 }
1466 }
1467
1468<xskip>{other} { /* ignore */ }
1469
1470<xcond>{identifier}{space}*";" {
1471 {
1472 struct _defines *defptr;
1473 unsigned int i;
1474 bool this_active;
1475
1476 /*
1477 * Skip the ";" and trailing whitespace. Note that
1478 * yytext contains at least one non-space character
1479 * plus the ";"
1480 */
1481 for (i = strlen(yytext) - 2;
1482 i > 0 && ecpg_isspace(yytext[i]);
1483 i--)
1484 /* skip */ ;
1485 yytext[i + 1] = '\0';
1486
1487 /* Does a definition exist? */
1488 for (defptr = defines; defptr; defptr = defptr->next)
1489 {
1490 if (strcmp(yytext, defptr->name) == 0)
1491 {
1492 /* Found it, but is it currently undefined? */
1493 if (defptr->value == NULL)
1494 defptr = NULL; /* pretend it's not found */
1495 break;
1496 }
1497 }
1498
1503 this_active);
1505 }
1506
1507 if (stacked_if_value[preproc_tos].active)
1508 BEGIN(C);
1509 else
1510 BEGIN(xskip);
1511 }
1512
1513<xcond>{other}|\n {
1514 mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL IFDEF command");
1515 yyterminate();
1516 }
1517<def_ident>{identifier} {
1519 BEGIN(def);
1520 startlit();
1521 }
1522<def_ident>{other}|\n {
1523 mmfatal(PARSE_ERROR, "missing identifier in EXEC SQL DEFINE command");
1524 yyterminate();
1525 }
1526<def>{space}*";" {
1527 struct _defines *ptr;
1528
1529 /* Does it already exist? */
1530 for (ptr = defines; ptr != NULL; ptr = ptr->next)
1531 {
1532 if (strcmp(newdefsymbol, ptr->name) == 0)
1533 {
1534 free(ptr->value);
1535 ptr->value = mm_strdup(literalbuf);
1536 /* Don't leak newdefsymbol */
1538 break;
1539 }
1540 }
1541 if (ptr == NULL)
1542 {
1543 /* Not present, make a new entry */
1544 ptr = (struct _defines *) mm_alloc(sizeof(struct _defines));
1545
1546 ptr->name = newdefsymbol;
1547 ptr->value = mm_strdup(literalbuf);
1548 ptr->cmdvalue = NULL;
1549 ptr->used = NULL;
1550 ptr->next = defines;
1551 defines = ptr;
1552 }
const char * cmdvalue
Definition type.h:183
1553
1554 BEGIN(C);
1555 }
1556<def>[^;] { addlit(yytext, yyleng); }
1557<incl><[^>]+>{space}*";"? { parse_include(); }
1558<incl>{dquote}{xdinside}{dquote}{space}*";"? { parse_include(); }
1559<incl>[^;<>\"]+";" { parse_include(); }
1560<incl>{other}|\n {
1561 mmfatal(PARSE_ERROR, "syntax error in EXEC SQL INCLUDE command");
1562 yyterminate();
1563 }
1564
1565<<EOF>> {
1566 if (yy_buffer == NULL)
1567 {
1568 /* No more input */
1569 if (preproc_tos > 0)
1570 {
1571 preproc_tos = 0;
1572 mmfatal(PARSE_ERROR, "missing \"EXEC SQL ENDIF;\"");
1573 }
1574 yyterminate();
1575 }
1576 else
1577 {
1578 /* Revert to previous input source */
1579 struct _yy_buffer *yb = yy_buffer;
1580 int i;
1581 struct _defines *ptr;
1582
1583 /* Check to see if we are exiting a macro value */
1584 for (ptr = defines; ptr; ptr = ptr->next)
1585 {
1586 if (ptr->used == yy_buffer)
1587 {
1588 ptr->used = NULL;
1589 break; /* there can't be multiple matches */
1590 }
1591 }
1592
1593 if (yyin != NULL)
1594 fclose(yyin);
1595
YY_BUFFER_STATE buffer
Definition pgc.l:81
1598
long lineno
Definition pgc.l:82
1600
1601 /* We have to output the filename only if we change files here */
char * filename
Definition pgc.l:83
1603
1606
1608 free(yb);
struct _yy_buffer * next
Definition pgc.l:84
1609
1610 if (i != 0)
1612 }
1613 }
1614
1615<INITIAL>{other}|\n {
1616 mmfatal(PARSE_ERROR, "internal error: unreachable state; please report this to <%s>", PACKAGE_BUGREPORT);
1617 }
1618
1619%%

Referenced by expr_lex_one_word(), expr_yyerror_more(), ParseConfigFp(), psql_scan(), psql_scan_slash_command(), psql_scan_slash_command_end(), and psql_scan_slash_option().

Variable Documentation

◆ base_yylval

YYSTYPE base_yylval
extern

◆ dolqstart

char* dolqstart = NULL
static

Definition at line 39 of file pgc.l.

◆ ifcond

bool ifcond
static

Definition at line 104 of file pgc.l.

◆ include_next

bool include_next
static

Definition at line 55 of file pgc.l.

Referenced by parse_include().

◆ literalalloc

int literalalloc
static

Definition at line 49 of file pgc.l.

Referenced by addlit(), addlitchar(), and lex_init().

◆ literalbuf

char* literalbuf = NULL
static

Definition at line 47 of file pgc.l.

Referenced by addlit(), addlitchar(), and lex_init().

◆ literallen

int literallen
static

Definition at line 48 of file pgc.l.

Referenced by addlit(), and addlitchar().

◆ parenths_open

int parenths_open
static

Definition at line 52 of file pgc.l.

Referenced by lex_init().

◆ preproc_tos

short preproc_tos
static

Definition at line 103 of file pgc.l.

Referenced by lex_init().

◆ stacked_if_value

struct _if_value stacked_if_value[MAX_NESTED_IF]
static

Referenced by lex_init().

◆ state_before_str_start

int state_before_str_start
static

Definition at line 69 of file pgc.l.

◆ state_before_str_stop

int state_before_str_stop
static

Definition at line 70 of file pgc.l.

◆ token_start

char* token_start

Definition at line 66 of file pgc.l.

◆ xcdepth

int xcdepth = 0
static

Definition at line 38 of file pgc.l.

◆ yy_buffer

struct _yy_buffer * yy_buffer = NULL
static