LCOV - code coverage report
Current view: top level - src/backend/replication - syncrep_scanner.l (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 53.0 % 66 35
Test Date: 2026-07-03 19:57:34 Functions: 57.1 % 7 4
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 21.4 % 14 3

             Branch data     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                 :          78 : {identifier} {
     119                 :          78 :                 yylval->str = pstrdup(yytext);
     120                 :          78 :                 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                 :          74 : syncrep_scanner_init(const char *str, yyscan_t *yyscannerp)
     174                 :             : {
     175                 :             :     yyscan_t    yyscanner;
     176                 :          74 :     struct syncrep_yy_extra_type *yyext = palloc0_object(struct syncrep_yy_extra_type);
     177                 :             : 
     178         [ -  + ]:          74 :     if (yylex_init(yyscannerp) != 0)
     179         [ #  # ]:           0 :         elog(ERROR, "yylex_init() failed: %m");
     180                 :             : 
     181                 :          74 :     yyscanner = *yyscannerp;
     182                 :             : 
     183                 :          74 :     yyset_extra(yyext, yyscanner);
     184                 :             : 
     185                 :          74 :     yy_scan_string(str, yyscanner);
     186                 :          74 : }
     187                 :             : 
     188                 :             : void
     189                 :          74 : syncrep_scanner_finish(yyscan_t yyscanner)
     190                 :             : {
     191                 :          74 :     pfree(yyextra);
     192                 :          74 :     yylex_destroy(yyscanner);
     193                 :          74 : }
     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                 :         296 : yyalloc(yy_size_t size, yyscan_t yyscanner)
     202                 :             : {
     203                 :         296 :     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                 :         370 : yyfree(void *ptr, yyscan_t yyscanner)
     217                 :             : {
     218         [ +  + ]:         370 :     if (ptr)
     219                 :         296 :         pfree(ptr);
     220                 :         370 : }
        

Generated by: LCOV version 2.0-1