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

Generated by: LCOV version 1.14