LCOV - code coverage report
Current view: top level - contrib/seg - segparse.y (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 51 55 92.7 %
Date: 2024-11-21 08:14:44 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : %{
       2             : /* contrib/seg/segparse.y */
       3             : 
       4             : #include "postgres.h"
       5             : 
       6             : #include <float.h>
       7             : #include <math.h>
       8             : 
       9             : #include "fmgr.h"
      10             : #include "nodes/miscnodes.h"
      11             : #include "utils/builtins.h"
      12             : #include "utils/float.h"
      13             : 
      14             : #include "segdata.h"
      15             : #include "segparse.h"
      16             : 
      17             : /* silence -Wmissing-variable-declarations */
      18             : extern int seg_yychar;
      19             : extern int seg_yynerrs;
      20             : 
      21             : /*
      22             :  * Bison doesn't allocate anything that needs to live across parser calls,
      23             :  * so we can easily have it use palloc instead of malloc.  This prevents
      24             :  * memory leaks if we error out during parsing.
      25             :  */
      26             : #define YYMALLOC palloc
      27             : #define YYFREE   pfree
      28             : 
      29             : static bool seg_atof(char *value, float *result, struct Node *escontext);
      30             : 
      31             : static int sig_digits(const char *value);
      32             : 
      33             : %}
      34             : 
      35             : /* BISON Declarations */
      36             : %parse-param {SEG *result}
      37             : %parse-param {struct Node *escontext}
      38             : %expect 0
      39             : %name-prefix="seg_yy"
      40             : 
      41             : %union
      42             : {
      43             :     struct BND
      44             :     {
      45             :         float       val;
      46             :         char        ext;
      47             :         char        sigd;
      48             :     } bnd;
      49             :     char       *text;
      50             : }
      51             : %token <text> SEGFLOAT
      52             : %token <text> RANGE
      53             : %token <text> PLUMIN
      54             : %token <text> EXTENSION
      55             : %type  <bnd>  boundary
      56             : %type  <bnd>  deviation
      57             : %start range
      58             : 
      59             : /* Grammar follows */
      60             : %%
      61             : 
      62             : 
      63             : range: boundary PLUMIN deviation
      64             :     {
      65             :         char        strbuf[25];
      66             : 
      67          14 :         result->lower = $1.val - $3.val;
      68          14 :         result->upper = $1.val + $3.val;
      69          14 :         snprintf(strbuf, sizeof(strbuf), "%g", result->lower);
      70          14 :         result->l_sigd = Max(sig_digits(strbuf), Max($1.sigd, $3.sigd));
      71          14 :         snprintf(strbuf, sizeof(strbuf), "%g", result->upper);
      72          14 :         result->u_sigd = Max(sig_digits(strbuf), Max($1.sigd, $3.sigd));
      73          14 :         result->l_ext = '\0';
      74          14 :         result->u_ext = '\0';
      75             :     }
      76             : 
      77             :     | boundary RANGE boundary
      78             :     {
      79        4706 :         result->lower = $1.val;
      80        4706 :         result->upper = $3.val;
      81        4706 :         if ( result->lower > result->upper ) {
      82           0 :             errsave(escontext,
      83             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      84             :                      errmsg("swapped boundaries: %g is greater than %g",
      85             :                             result->lower, result->upper)));
      86             : 
      87           0 :             YYERROR;
      88             :         }
      89        4706 :         result->l_sigd = $1.sigd;
      90        4706 :         result->u_sigd = $3.sigd;
      91        4706 :         result->l_ext = ( $1.ext ? $1.ext : '\0' );
      92        4706 :         result->u_ext = ( $3.ext ? $3.ext : '\0' );
      93             :     }
      94             : 
      95             :     | boundary RANGE
      96             :     {
      97          92 :         result->lower = $1.val;
      98          92 :         result->upper = HUGE_VAL;
      99          92 :         result->l_sigd = $1.sigd;
     100          92 :         result->u_sigd = 0;
     101          92 :         result->l_ext = ( $1.ext ? $1.ext : '\0' );
     102          92 :         result->u_ext = '-';
     103             :     }
     104             : 
     105             :     | RANGE boundary
     106             :     {
     107          98 :         result->lower = -HUGE_VAL;
     108          98 :         result->upper = $2.val;
     109          98 :         result->l_sigd = 0;
     110          98 :         result->u_sigd = $2.sigd;
     111          98 :         result->l_ext = '-';
     112          98 :         result->u_ext = ( $2.ext ? $2.ext : '\0' );
     113             :     }
     114             : 
     115             :     | boundary
     116             :     {
     117         720 :         result->lower = result->upper = $1.val;
     118         720 :         result->l_sigd = result->u_sigd = $1.sigd;
     119         720 :         result->l_ext = result->u_ext = ( $1.ext ? $1.ext : '\0' );
     120             :     }
     121             :     ;
     122             : 
     123             : boundary: SEGFLOAT
     124             :     {
     125             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     126             :         float       val;
     127             : 
     128        7908 :         if (!seg_atof($1, &val, escontext))
     129           4 :             YYABORT;
     130             : 
     131        7902 :         $$.ext = '\0';
     132        7902 :         $$.sigd = sig_digits($1);
     133        7902 :         $$.val = val;
     134             :     }
     135             :     | EXTENSION SEGFLOAT
     136             :     {
     137             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     138             :         float       val;
     139             : 
     140        2434 :         if (!seg_atof($2, &val, escontext))
     141           0 :             YYABORT;
     142             : 
     143        2434 :         $$.ext = $1[0];
     144        2434 :         $$.sigd = sig_digits($2);
     145        2434 :         $$.val = val;
     146             :     }
     147             :     ;
     148             : 
     149             : deviation: SEGFLOAT
     150             :     {
     151             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     152             :         float       val;
     153             : 
     154          14 :         if (!seg_atof($1, &val, escontext))
     155           0 :             YYABORT;
     156             : 
     157          14 :         $$.ext = '\0';
     158          14 :         $$.sigd = sig_digits($1);
     159          14 :         $$.val = val;
     160             :     }
     161             :     ;
     162             : 
     163             : %%
     164             : 
     165             : 
     166             : static bool
     167       10356 : seg_atof(char *value, float *result, struct Node *escontext)
     168             : {
     169       10356 :     *result = float4in_internal(value, NULL, "seg", value, escontext);
     170       10354 :     if (SOFT_ERROR_OCCURRED(escontext))
     171           4 :         return false;
     172       10350 :     return true;
     173             : }
     174             : 
     175             : static int
     176       10382 : sig_digits(const char *value)
     177             : {
     178       10382 :     int         n = significant_digits(value);
     179             : 
     180             :     /* Clamp, to ensure value will fit in sigd fields */
     181       10382 :     return Min(n, FLT_DIG);
     182             : }

Generated by: LCOV version 1.14