LCOV - code coverage report
Current view: top level - contrib/seg - segparse.y (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 45 46 97.8 %
Date: 2019-11-16 00:06:57 Functions: 1 1 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 <math.h>
       7             : 
       8             : #include "fmgr.h"
       9             : #include "utils/builtins.h"
      10             : 
      11             : #include "segdata.h"
      12             : 
      13             : /*
      14             :  * Bison doesn't allocate anything that needs to live across parser calls,
      15             :  * so we can easily have it use palloc instead of malloc.  This prevents
      16             :  * memory leaks if we error out during parsing.  Note this only works with
      17             :  * bison >= 2.0.  However, in bison 1.875 the default is to use alloca()
      18             :  * if possible, so there's not really much problem anyhow, at least if
      19             :  * you're building with gcc.
      20             :  */
      21             : #define YYMALLOC palloc
      22             : #define YYFREE   pfree
      23             : 
      24             : static float seg_atof(const char *value);
      25             : 
      26             : static char strbuf[25] = {
      27             :     '0', '0', '0', '0', '0',
      28             :     '0', '0', '0', '0', '0',
      29             :     '0', '0', '0', '0', '0',
      30             :     '0', '0', '0', '0', '0',
      31             :     '0', '0', '0', '0', '\0'
      32             : };
      33             : 
      34             : %}
      35             : 
      36             : /* BISON Declarations */
      37             : %parse-param {SEG *result}
      38             : %expect 0
      39             : %name-prefix="seg_yy"
      40             : 
      41             : %union {
      42             :     struct BND {
      43             :         float val;
      44             :         char  ext;
      45             :         char  sigd;
      46             :     } bnd;
      47             :     char * text;
      48             : }
      49             : %token <text> SEGFLOAT
      50             : %token <text> RANGE
      51             : %token <text> PLUMIN
      52             : %token <text> EXTENSION
      53             : %type  <bnd>  boundary
      54             : %type  <bnd>  deviation
      55             : %start range
      56             : 
      57             : /* Grammar follows */
      58             : %%
      59             : 
      60             : 
      61             : range: boundary PLUMIN deviation
      62             :     {
      63          10 :         result->lower = $1.val - $3.val;
      64          10 :         result->upper = $1.val + $3.val;
      65          10 :         sprintf(strbuf, "%g", result->lower);
      66          10 :         result->l_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
      67          10 :         sprintf(strbuf, "%g", result->upper);
      68          10 :         result->u_sigd = Max(Min(6, significant_digits(strbuf)), Max($1.sigd, $3.sigd));
      69          10 :         result->l_ext = '\0';
      70          10 :         result->u_ext = '\0';
      71             :     }
      72             : 
      73             :     | boundary RANGE boundary
      74             :     {
      75        4698 :         result->lower = $1.val;
      76        4698 :         result->upper = $3.val;
      77        4698 :         if ( result->lower > result->upper ) {
      78           0 :             ereport(ERROR,
      79             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
      80             :                      errmsg("swapped boundaries: %g is greater than %g",
      81             :                             result->lower, result->upper)));
      82             : 
      83             :             YYERROR;
      84             :         }
      85        4698 :         result->l_sigd = $1.sigd;
      86        4698 :         result->u_sigd = $3.sigd;
      87        4698 :         result->l_ext = ( $1.ext ? $1.ext : '\0' );
      88        4698 :         result->u_ext = ( $3.ext ? $3.ext : '\0' );
      89             :     }
      90             : 
      91             :     | boundary RANGE
      92             :     {
      93          92 :         result->lower = $1.val;
      94          92 :         result->upper = HUGE_VAL;
      95          92 :         result->l_sigd = $1.sigd;
      96          92 :         result->u_sigd = 0;
      97          92 :         result->l_ext = ( $1.ext ? $1.ext : '\0' );
      98          92 :         result->u_ext = '-';
      99             :     }
     100             : 
     101             :     | RANGE boundary
     102             :     {
     103          98 :         result->lower = -HUGE_VAL;
     104          98 :         result->upper = $2.val;
     105          98 :         result->l_sigd = 0;
     106          98 :         result->u_sigd = $2.sigd;
     107          98 :         result->l_ext = '-';
     108          98 :         result->u_ext = ( $2.ext ? $2.ext : '\0' );
     109             :     }
     110             : 
     111             :     | boundary
     112             :     {
     113         714 :         result->lower = result->upper = $1.val;
     114         714 :         result->l_sigd = result->u_sigd = $1.sigd;
     115         714 :         result->l_ext = result->u_ext = ( $1.ext ? $1.ext : '\0' );
     116             :     }
     117             :     ;
     118             : 
     119             : boundary: SEGFLOAT
     120             :     {
     121             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     122        7878 :         float val = seg_atof($1);
     123             : 
     124        7876 :         $$.ext = '\0';
     125        7876 :         $$.sigd = significant_digits($1);
     126        7876 :         $$.val = val;
     127             :     }
     128             :     | EXTENSION SEGFLOAT
     129             :     {
     130             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     131        2434 :         float val = seg_atof($2);
     132             : 
     133        2434 :         $$.ext = $1[0];
     134        2434 :         $$.sigd = significant_digits($2);
     135        2434 :         $$.val = val;
     136             :     }
     137             :     ;
     138             : 
     139             : deviation: SEGFLOAT
     140             :     {
     141             :         /* temp variable avoids a gcc 3.3.x bug on Sparc64 */
     142          10 :         float val = seg_atof($1);
     143             : 
     144          10 :         $$.ext = '\0';
     145          10 :         $$.sigd = significant_digits($1);
     146          10 :         $$.val = val;
     147             :     }
     148             :     ;
     149             : 
     150             : %%
     151             : 
     152             : 
     153             : static float
     154       10322 : seg_atof(const char *value)
     155             : {
     156             :     Datum datum;
     157             : 
     158       10322 :     datum = DirectFunctionCall1(float4in, CStringGetDatum(value));
     159       10320 :     return DatumGetFloat4(datum);
     160             : }
     161             : 
     162             : 
     163             : #include "segscan.c"

Generated by: LCOV version 1.13