LCOV - code coverage report
Current view: top level - src/backend/replication - syncrep_scanner.l (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 17 31 54.8 %
Date: 2025-01-18 05:15:39 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             : /* LCOV_EXCL_START */
      46             : 
      47             : %}
      48             : 
      49             : %option reentrant
      50             : %option bison-bridge
      51             : %option 8bit
      52             : %option never-interactive
      53             : %option nodefault
      54             : %option noinput
      55             : %option nounput
      56             : %option noyywrap
      57             : %option noyyalloc
      58             : %option noyyrealloc
      59             : %option noyyfree
      60             : %option warn
      61             : %option prefix="syncrep_yy"
      62             : %option extra-type="struct syncrep_yy_extra_type *"
      63             : 
      64             : /*
      65             :  * <xd> delimited identifiers (double-quoted identifiers)
      66             :  */
      67             : %x xd
      68             : 
      69             : space           [ \t\n\r\f\v]
      70             : 
      71             : digit           [0-9]
      72             : ident_start     [A-Za-z\200-\377_]
      73             : ident_cont      [A-Za-z\200-\377_0-9\$]
      74             : identifier      {ident_start}{ident_cont}*
      75             : 
      76             : dquote          \"
      77             : xdstart         {dquote}
      78             : xdstop          {dquote}
      79             : xddouble        {dquote}{dquote}
      80             : xdinside        [^"]+
      81             : 
      82             : %%
      83             : {space}+    { /* ignore */ }
      84             : 
      85             :     /* brute-force case insensitivity is safer than relying on flex -i */
      86             : 
      87             : [Aa][Nn][Yy]            { return ANY; }
      88             : [Ff][Ii][Rr][Ss][Tt]    { return FIRST; }
      89             : 
      90             : {xdstart}   {
      91             :                 initStringInfo(&yyextra->xdbuf);
      92             :                 BEGIN(xd);
      93             :         }
      94             : <xd>{xddouble} {
      95             :                 appendStringInfoChar(&yyextra->xdbuf, '"');
      96             :         }
      97             : <xd>{xdinside} {
      98             :                 appendStringInfoString(&yyextra->xdbuf, yytext);
      99             :         }
     100             : <xd>{xdstop} {
     101             :                 yylval->str = yyextra->xdbuf.data;
     102             :                 yyextra->xdbuf.data = NULL;
     103             :                 BEGIN(INITIAL);
     104             :                 return NAME;
     105             :         }
     106             : <xd><<EOF>> {
     107             :                 syncrep_yyerror(yyscanner, "unterminated quoted identifier");
     108             :                 return JUNK;
     109             :         }
     110             : 
     111             : {identifier} {
     112             :                 yylval->str = pstrdup(yytext);
     113             :                 return NAME;
     114             :         }
     115             : 
     116             : {digit}+    {
     117             :                 yylval->str = pstrdup(yytext);
     118             :                 return NUM;
     119             :         }
     120             : 
     121             : "*"       {
     122             :                 yylval->str = "*";
     123             :                 return NAME;
     124             :         }
     125             : 
     126             : ","           { return ','; }
     127             : "("           { return '('; }
     128             : ")"           { return ')'; }
     129             : 
     130             : .           { return JUNK; }
     131             : %%
     132             : 
     133             : /* LCOV_EXCL_STOP */
     134             : 
     135             : /* see scan.l */
     136             : #undef yyextra
     137             : #define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
     138             : 
     139             : /* Needs to be here for access to yytext */
     140             : void
     141           0 : syncrep_yyerror(yyscan_t yyscanner, const char *message)
     142             : {
     143           0 :     struct yyguts_t *yyg = (struct yyguts_t *) yyscanner;   /* needed for yytext
     144             :                                                              * macro */
     145             : 
     146             :     /* report only the first error in a parse operation */
     147           0 :     if (syncrep_parse_error_msg)
     148           0 :         return;
     149           0 :     if (yytext[0])
     150           0 :         syncrep_parse_error_msg = psprintf("%s at or near \"%s\"",
     151             :                                            message, yytext);
     152             :     else
     153           0 :         syncrep_parse_error_msg = psprintf("%s at end of input",
     154             :                                            message);
     155             : }
     156             : 
     157             : void
     158         130 : syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
     159             : {
     160             :     yyscan_t    yyscanner;
     161         130 :     struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type);
     162             : 
     163         130 :     if (yylex_init(yyscannerp) != 0)
     164           0 :         elog(ERROR, "yylex_init() failed: %m");
     165             : 
     166         130 :     yyscanner = *yyscannerp;
     167             : 
     168         130 :     yyset_extra(yyext, yyscanner);
     169             : 
     170         130 :     yy_scan_string(str, yyscanner);
     171         130 : }
     172             : 
     173             : void
     174         130 : syncrep_scanner_finish(yyscan_t yyscanner)
     175             : {
     176         130 :     pfree(yyextra);
     177         130 :     yylex_destroy(yyscanner);
     178         130 : }
     179             : 
     180             : /*
     181             :  * Interface functions to make flex use palloc() instead of malloc().
     182             :  * It'd be better to make these static, but flex insists otherwise.
     183             :  */
     184             : 
     185             : void *
     186         520 : yyalloc(yy_size_t size, yyscan_t yyscanner)
     187             : {
     188         520 :     return palloc(size);
     189             : }
     190             : 
     191             : void *
     192           0 : yyrealloc(void *ptr, yy_size_t size, yyscan_t yyscanner)
     193             : {
     194           0 :     if (ptr)
     195           0 :         return repalloc(ptr, size);
     196             :     else
     197           0 :         return palloc(size);
     198             : }
     199             : 
     200             : void
     201         650 : yyfree(void *ptr, yyscan_t yyscanner)
     202             : {
     203         650 :     if (ptr)
     204         520 :         pfree(ptr);
     205         650 : }

Generated by: LCOV version 1.14