LCOV - code coverage report
Current view: top level - src/backend/replication - syncrep_scanner.l (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 53.0 % 66 35
Test Date: 2026-02-17 16:40:31 Functions: 57.1 % 7 4
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-2026, 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           10 : 
      92              :     /* brute-force case insensitivity is safer than relying on flex -i */
      93            4 : 
      94            4 : [Aa][Nn][Yy]            { return ANY; }
      95            2 : [Ff][Ii][Rr][Ss][Tt]    { return FIRST; }
      96            2 : 
      97            0 : {xdstart}   {
      98            0 :                 initStringInfo(&yyextra->xdbuf);
      99            0 :                 BEGIN(xd);
     100              :         }
     101            0 : <xd>{xddouble} {
     102            0 :                 appendStringInfoChar(&yyextra->xdbuf, '"');
     103              :         }
     104            0 : <xd>{xdinside} {
     105            0 :                 appendStringInfoString(&yyextra->xdbuf, yytext);
     106              :         }
     107            0 : <xd>{xdstop} {
     108            0 :                 yylval->str = yyextra->xdbuf.data;
     109            0 :                 yyextra->xdbuf.data = NULL;
     110            0 :                 BEGIN(INITIAL);
     111            0 :                 return NAME;
     112              :         }
     113              : <xd><<EOF>> {
     114            0 :                 syncrep_yyerror(NULL, syncrep_parse_error_msg_p, yyscanner, "unterminated quoted identifier");
     115            0 :                 return JUNK;
     116              :         }
     117              : 
     118           81 : {identifier} {
     119           81 :                 yylval->str = pstrdup(yytext);
     120           81 :                 return NAME;
     121              :         }
     122              : 
     123           18 : {digit}+    {
     124           18 :                 yylval->str = pstrdup(yytext);
     125           18 :                 return NUM;
     126              :         }
     127              : 
     128           26 : "*"       {
     129           26 :                 yylval->str = "*";
     130           26 :                 return NAME;
     131              :         }
     132              : 
     133           30 : ","           { return ','; }
     134           18 : "("           { return '('; }
     135           18 : ")"           { return ')'; }
     136           18 : 
     137            0 : .           { return JUNK; }
     138            0 : %%
     139            0 : 
     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              : 
     161              :     /* report only the first error in a parse operation */
     162            0 :     if (*syncrep_parse_error_msg_p)
     163            0 :         return;
     164            0 :     if (yytext[0])
     165            0 :         *syncrep_parse_error_msg_p = psprintf("%s at or near \"%s\"",
     166              :                                               message, yytext);
     167              :     else
     168            0 :         *syncrep_parse_error_msg_p = psprintf("%s at end of input",
     169              :                                               message);
     170              : }
     171              : 
     172              : void
     173           77 : syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
     174              : {
     175              :     yyscan_t    yyscanner;
     176           77 :     struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type);
     177              : 
     178           77 :     if (yylex_init(yyscannerp) != 0)
     179            0 :         elog(ERROR, "yylex_init() failed: %m");
     180              : 
     181           77 :     yyscanner = *yyscannerp;
     182              : 
     183           77 :     yyset_extra(yyext, yyscanner);
     184              : 
     185           77 :     yy_scan_string(str, yyscanner);
     186           77 : }
     187              : 
     188              : void
     189           77 : syncrep_scanner_finish(yyscan_t yyscanner)
     190              : {
     191           77 :     pfree(yyextra);
     192           77 :     yylex_destroy(yyscanner);
     193           77 : }
     194              : 
     195              : /*
     196              :  * Interface functions to make flex use palloc() instead of malloc().
     197              :  * It'd be better to make these static, but flex insists otherwise.
     198              :  */
     199              : 
     200              : void *
     201          308 : yyalloc(yy_size_t size, yyscan_t yyscanner)
     202              : {
     203          308 :     return palloc(size);
     204              : }
     205              : 
     206              : void *
     207            0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
     208              : {
     209            0 :     if (ptr)
     210            0 :         return repalloc(ptr, size);
     211              :     else
     212            0 :         return palloc(size);
     213              : }
     214              : 
     215              : void
     216          385 : yyfree(void *ptr, yyscan_t yyscanner)
     217              : {
     218          385 :     if (ptr)
     219          308 :         pfree(ptr);
     220          385 : }
        

Generated by: LCOV version 2.0-1