LCOV - code coverage report
Current view: top level - src/backend/replication - syncrep_scanner.l (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 17 32 53.1 %
Date: 2025-02-21 16:15:14 Functions: 4 7 57.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : %top{
       2             : /*-------------------------------------------------------------------------
       3             :  *
       4             :  * syncrep_scanner.l
       5             :  *    a lexical scanner for synchronous_standby_names
       6             :  *
       7             :  * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/backend/replication/syncrep_scanner.l
      13             :  *
      14             :  *-------------------------------------------------------------------------
      15             :  */
      16             : #include "postgres.h"
      17             : 
      18             : #include "lib/stringinfo.h"
      19             : #include "nodes/pg_list.h"
      20             : 
      21             : /*
      22             :  * NB: include syncrep_gram.h only AFTER including syncrep.h, because syncrep.h
      23             :  * includes node definitions needed for YYSTYPE.
      24             :  */
      25             : #include "replication/syncrep.h"
      26             : #include "syncrep_gram.h"
      27             : }
      28             : 
      29             : %{
      30             : /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
      31             : #undef fprintf
      32             : #define fprintf(file, fmt, msg)  fprintf_to_ereport(fmt, msg)
      33             : 
      34             : static void
      35           0 : fprintf_to_ereport(const char *fmt, const char *msg)
      36             : {
      37           0 :     ereport(ERROR, (errmsg_internal("%s", msg)));
      38             : }
      39             : 
      40             : struct syncrep_yy_extra_type
      41             : {
      42             :     StringInfoData xdbuf;
      43             : };
      44             : 
      45             : /*
      46             :  * Better keep this definition here than put it in replication/syncrep.h and
      47             :  * save a bit of duplication.  Putting it in replication/syncrep.h would leak
      48             :  * the definition to other parts and possibly affect other scanners.
      49             : */
      50             : #define YY_DECL extern int  syncrep_yylex(union YYSTYPE *yylval_param, char **syncrep_parse_error_msg_p, yyscan_t yyscanner)
      51             : 
      52             : /* LCOV_EXCL_START */
      53             : 
      54             : %}
      55             : 
      56             : %option reentrant
      57             : %option bison-bridge
      58             : %option 8bit
      59             : %option never-interactive
      60             : %option nodefault
      61             : %option noinput
      62             : %option nounput
      63             : %option noyywrap
      64             : %option noyyalloc
      65             : %option noyyrealloc
      66             : %option noyyfree
      67             : %option warn
      68             : %option prefix="syncrep_yy"
      69             : %option extra-type="struct syncrep_yy_extra_type *"
      70             : 
      71             : /*
      72             :  * <xd> delimited identifiers (double-quoted identifiers)
      73             :  */
      74             : %x xd
      75             : 
      76             : space           [ \t\n\r\f\v]
      77             : 
      78             : digit           [0-9]
      79             : ident_start     [A-Za-z\200-\377_]
      80             : ident_cont      [A-Za-z\200-\377_0-9\$]
      81             : identifier      {ident_start}{ident_cont}*
      82             : 
      83             : dquote          \"
      84             : xdstart         {dquote}
      85             : xdstop          {dquote}
      86             : xddouble        {dquote}{dquote}
      87             : xdinside        [^"]+
      88             : 
      89             : %%
      90             : {space}+    { /* ignore */ }
      91             : 
      92             :     /* brute-force case insensitivity is safer than relying on flex -i */
      93             : 
      94             : [Aa][Nn][Yy]            { return ANY; }
      95             : [Ff][Ii][Rr][Ss][Tt]    { return FIRST; }
      96             : 
      97             : {xdstart}   {
      98             :                 initStringInfo(&yyextra->xdbuf);
      99             :                 BEGIN(xd);
     100             :         }
     101             : <xd>{xddouble} {
     102             :                 appendStringInfoChar(&yyextra->xdbuf, '"');
     103             :         }
     104             : <xd>{xdinside} {
     105             :                 appendStringInfoString(&yyextra->xdbuf, yytext);
     106             :         }
     107             : <xd>{xdstop} {
     108             :                 yylval->str = yyextra->xdbuf.data;
     109             :                 yyextra->xdbuf.data = NULL;
     110             :                 BEGIN(INITIAL);
     111             :                 return NAME;
     112             :         }
     113             : <xd><<EOF>> {
     114             :                 syncrep_yyerror(NULL, syncrep_parse_error_msg_p, yyscanner, "unterminated quoted identifier");
     115             :                 return JUNK;
     116             :         }
     117             : 
     118             : {identifier} {
     119             :                 yylval->str = pstrdup(yytext);
     120             :                 return NAME;
     121             :         }
     122             : 
     123             : {digit}+    {
     124             :                 yylval->str = pstrdup(yytext);
     125             :                 return NUM;
     126             :         }
     127             : 
     128             : "*"       {
     129             :                 yylval->str = "*";
     130             :                 return NAME;
     131             :         }
     132             : 
     133             : ","           { return ','; }
     134             : "("           { return '('; }
     135             : ")"           { return ')'; }
     136             : 
     137             : .           { return JUNK; }
     138             : %%
     139             : 
     140             : /* LCOV_EXCL_STOP */
     141             : 
     142             : /* see scan.l */
     143             : #undef yyextra
     144             : #define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
     145             : 
     146             : /*
     147             :  * This yyerror() function does not raise an error (elog or similar), it just
     148             :  * collects the error message in *syncrep_parse_error_msg_p and leaves it to
     149             :  * the ultimate caller of the syncrep parser to raise the error.  (The
     150             :  * ultimate caller will do that with special GUC error functions.)
     151             :  *
     152             :  * (The first argument is enforced by Bison to match the first argument of
     153             :  * yyparse(), but it is not used here.)
     154             :  */
     155             : void
     156           0 : syncrep_yyerror(SyncRepConfigData **syncrep_parse_result_p, char **syncrep_parse_error_msg_p, yyscan_t yyscanner, const char *message)
     157             : {
     158           0 :     struct yyguts_t *yyg = (struct yyguts_t *) yyscanner;   /* needed for yytext
     159             :                                                              * macro */
     160           0 :     char *syncrep_parse_error_msg = *syncrep_parse_error_msg_p;
     161             : 
     162             :     /* report only the first error in a parse operation */
     163           0 :     if (syncrep_parse_error_msg)
     164           0 :         return;
     165           0 :     if (yytext[0])
     166           0 :         syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
     167             :                                            message, yytext);
     168             :     else
     169           0 :         syncrep_parse_error_msg = psprintf("%s at end of input",
     170             :                                            message);
     171             : }
     172             : 
     173             : void
     174         130 : syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
     175             : {
     176             :     yyscan_t    yyscanner;
     177         130 :     struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type);
     178             : 
     179         130 :     if (yylex_init(yyscannerp) != 0)
     180           0 :         elog(ERROR, "yylex_init() failed: %m");
     181             : 
     182         130 :     yyscanner = *yyscannerp;
     183             : 
     184         130 :     yyset_extra(yyext, yyscanner);
     185             : 
     186         130 :     yy_scan_string(str, yyscanner);
     187         130 : }
     188             : 
     189             : void
     190         130 : syncrep_scanner_finish(yyscan_t yyscanner)
     191             : {
     192         130 :     pfree(yyextra);
     193         130 :     yylex_destroy(yyscanner);
     194         130 : }
     195             : 
     196             : /*
     197             :  * Interface functions to make flex use palloc() instead of malloc().
     198             :  * It'd be better to make these static, but flex insists otherwise.
     199             :  */
     200             : 
     201             : void *
     202         520 : yyalloc(yy_size_t size, yyscan_t yyscanner)
     203             : {
     204         520 :     return palloc(size);
     205             : }
     206             : 
     207             : void *
     208           0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
     209             : {
     210           0 :     if (ptr)
     211           0 :         return repalloc(ptr, size);
     212             :     else
     213           0 :         return palloc(size);
     214             : }
     215             : 
     216             : void
     217         650 : yyfree(void *ptr, yyscan_t yyscanner)
     218             : {
     219         650 :     if (ptr)
     220         520 :         pfree(ptr);
     221         650 : }

Generated by: LCOV version 1.14