]> saetta.ns0.it Git - reptool/libreptool/commitdiff
Added the parser for text's attribute "source".
authorAndrea Zagli <azagli@libero.it>
Tue, 1 May 2007 10:17:01 +0000 (10:17 +0000)
committerAndrea Zagli <azagli@libero.it>
Tue, 1 May 2007 10:17:01 +0000 (10:17 +0000)
Added special value @Pages for text's source.

git-svn-id: svn+ssh://saetta.homelinux.org/svn/libreptool/trunk@14 3191ed1d-3fce-41bb-ab4a-0cebc0943b59

ChangeLog
src/Makefile.am
src/lexycal.fl [new file with mode: 0644]
src/parser.y [new file with mode: 0644]
src/rptreport.c
tests/test_report_db.rpt

index 7b21192442044483bab31fc0415e3a16fdff692a..9ba911ba22267b87072de5eeabfa832c4b6a784b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-05-01 Andrea Zagli <azagli@inwind.it>
+
+       * src/lexycal.fl:
+       * src/parser.y:
+       * src/lexycal.yy.h:
+       * src/lexycal.yy.c:
+       * src/parser.tab.h:
+       * src/parser.tab.c:
+       * src/rptreport.c: added parser for text's attribute "source"
+       * src/rptreport.c: added spcial value @Pages for text's attribute "source"
+
 2007-04-22 Andrea Zagli <azagli@inwind.it>
 
        * src/rptcommon.h:
index 271533336f9dc927e2490cdd822ab971d0315827..cee72335b872d0bf4e89d0d397a06a260118ecd9 100644 (file)
@@ -1,4 +1,5 @@
-LIBS = $(REPTOOL_LIBS)
+LIBS = $(REPTOOL_LIBS) \
+       -lfl
 
 AM_CPPFLAGS = $(REPTOOL_CFLAGS)
 
@@ -16,7 +17,9 @@ libreptool_la_SOURCES = \
                         rptreport.c \
                         rptprint.c \
                         rptcommon.c \
-                        rptmarshal.c
+                        rptmarshal.c \
+                        parser.tab.c \
+                        lexycal.yy.c
 
 include_HEADERS = \
                   libreptool.h \
@@ -31,4 +34,7 @@ include_HEADERS = \
                   rptcommon.h
 
 noinst_HEADERS = \
-                 rptmarshal.h
+                 rptreport_priv.h \
+                 rptmarshal.h \
+                 parser.tab.h \
+                 lexycal.yy.h
diff --git a/src/lexycal.fl b/src/lexycal.fl
new file mode 100644 (file)
index 0000000..0ef117d
--- /dev/null
@@ -0,0 +1,58 @@
+%{
+#define YYSTYPE char *
+
+#include <glib.h>
+
+#include "parser.tab.h"
+%}
+
+DIGIT  [0-9]
+
+%%
+
+{DIGIT}+       {
+                       /*printf("An integer: %d\n", atoi (yytext));*/
+                       yylval = g_strdup (yytext);
+                       return INTEGER;
+                       }
+
+{DIGIT}+"."{DIGIT}*    {
+                                       /*printf("A float: %f\n", atof (yytext));*/
+                                       yylval = g_strdup (yytext);
+                                       return FLOAT;
+                                       }
+
+"\""[^"]*"\""  {
+                       /*printf ("A string: %s\n", yytext);*/
+                       yylval = g_strdup (yytext);
+                       return STRING;
+                       }
+
+"[".+"]"       {
+                       /*printf ("A field: %s\n", yytext);*/
+                       yylval = g_strdup (yytext);
+                       return FIELD;
+                       }
+
+"@Page" |
+"@Pages" |
+"@Date" |
+"@Time"        {
+               /*printf ("A special value: %s\n", yytext);*/
+               yylval = g_strdup (yytext);
+               return SPECIAL;
+               }
+
+"+"|"-"|"*"|"/"|"&"|"("|")"    {
+                                       /*printf ("An operator: %s\n", yytext );*/
+                                       yylval = NULL;
+                                       return (int)yytext[0];
+                                       }
+
+[a-zA-Z][a-zA-Z0-9_]*" "*"("")"        {
+                                                               /*printf ("A function: %s\n", yytext);*/
+                                                               yylval = g_strdup (yytext);
+                                                               return FUNCTION;
+                                                               }
+
+.|" "|\n       /* eat up unmatched chars */
diff --git a/src/parser.y b/src/parser.y
new file mode 100644 (file)
index 0000000..15d2d8b
--- /dev/null
@@ -0,0 +1,58 @@
+%{
+#define YYSTYPE char *
+
+#include <string.h>
+
+#include <glib.h>
+
+#include "lexycal.yy.h"
+#include "rptreport_priv.h"
+
+void yyerror (RptReport *rpt_report, gint row, gchar **ret, char const *s);
+%}
+
+%token INTEGER
+%token FLOAT
+%token STRING
+%token FIELD
+%token SPECIAL
+%token FUNCTION
+
+%left '&'
+%left '+'
+%left '-'
+%left '*'
+%left '/'
+
+%parse-param {RptReport *rpt_report}
+%parse-param {gint row}
+%parse-param {gchar **ret}
+
+%% /* Grammar rules and actions */
+input:    /* empty */
+        | input string
+;
+
+string: exp      { *ret = g_strdup ($1); }
+;
+
+exp:      INTEGER           { $$ = $1; }
+        | FLOAT             { $$ = $1; }
+        | STRING            { $$ = g_strndup ($1 + 1, strlen ($1) - 2) }
+        | FIELD             { $$ = rpt_report_get_field (rpt_report, g_strndup ($1 + 1, strlen ($1) - 2), row); }
+        | SPECIAL           { $$ = rpt_report_get_special (rpt_report, $1, row); }
+               | exp '+' exp           { $$ = g_strdup_printf ("%f", strtod ($1, NULL) + strtod ($3, NULL)); }
+               | exp '-' exp           { $$ = g_strdup_printf ("%f", strtod ($1, NULL) - strtod ($3, NULL)); }
+               | exp '*' exp           { $$ = g_strdup_printf ("%f", strtod ($1, NULL) * strtod ($3, NULL)); }
+               | exp '/' exp           { $$ = g_strdup_printf ("%f", strtod ($1, NULL) / strtod ($3, NULL)); }
+               | exp '&' exp           { $$ = g_strconcat ($1, $3, NULL); }
+        | '(' exp ')'       { $$ = $2; }
+;
+%%
+
+/* Called by yyparse on error.  */
+void
+yyerror (RptReport *rpt_report, gint row, gchar **ret, char const *s)
+{
+       fprintf (stderr, "BISON ERROR: %s\n", s);
+}
index e68f0a098ac97f76f5ecef9335c1a8efc5a6d8ef..ae7f8f0c37cb49c2e2aebe1ce69d34e18ed005a0 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 
 #include "rptreport.h"
+#include "rptreport_priv.h"
 #include "rptcommon.h"
 #include "rptobjecttext.h"
 #include "rptobjectline.h"
@@ -36,6 +37,8 @@
 
 #include "rptmarshal.h"
 
+#include "parser.tab.h"
+
 typedef struct
 {
        gchar *provider_id;
@@ -131,6 +134,8 @@ static void rpt_report_rptprint_parse_text_source (RptReport *rpt_report,
                                                    xmlNode *xnode,
                                                    gint row);
 
+static void rpt_report_change_specials (RptReport *rpt_report, xmlDoc *xdoc);
+
 
 #define RPT_REPORT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TYPE_RPT_REPORT, RptReportPrivate))
 
@@ -878,6 +883,9 @@ xmlDoc
                                        cur_y = priv->page->size->height - priv->page->margin_top - priv->page->margin_bottom - priv->page_footer->height;
                                        rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER, row - 1);
                                }
+
+                       /* change @Pages */
+                       rpt_report_change_specials (rpt_report, xdoc);
                }
        else
                {
@@ -1564,96 +1572,136 @@ rpt_report_rptprint_section (RptReport *rpt_report, xmlNode *xpage, gdouble *cur
 static void
 rpt_report_rptprint_parse_text_source (RptReport *rpt_report, RptObject *rptobj, xmlNode *xnode, gint row)
 {
-       /* TO DO */
        gchar *source;
+       gchar *ret;
 
        RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
 
        g_object_get (G_OBJECT (rptobj), "source", &source, NULL);
 
-       if (row > -1 && priv->db->gda_datamodel != NULL && source[0] == '[' && source[strlen (source) - 1] == ']')
+       yy_scan_string (source);
+       yyparse (rpt_report, row, &ret);
+
+       if (ret == NULL)
                {
-                       gint col;
-                       gchar *field;
+                       xmlNodeSetContent (xnode, "");
+               }
+       else
+               {
+                       xmlNodeSetContent (xnode, ret);
+               }
+}
 
-                       field = g_strstrip (g_strndup (source + 1, strlen (source) - 2));
-                       col = gda_data_model_get_column_position (priv->db->gda_datamodel, field);
+static void
+rpt_report_change_specials (RptReport *rpt_report, xmlDoc *xdoc)
+{
+       xmlXPathContextPtr xpcontext;
+       xmlXPathObjectPtr xpresult;
+       xmlNodeSetPtr xnodeset;
+       RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
 
-                       if (col > -1)
-                               {
-                                       source = gda_value_stringify ((GdaValue *)gda_data_model_get_value_at (priv->db->gda_datamodel, col, row));
-                               }
-                       else
-                               {
-                                       /* ask value */
-                                       gchar *ret;
-                                       RptReportClass *klass = RPT_REPORT_GET_CLASS (rpt_report);
+       xpcontext = xmlXPathNewContext (xdoc);
 
-                                       g_signal_emit (rpt_report, klass->field_request_signal_id,
-                                                      0, field, priv->db->gda_datamodel, row, &ret);
-                                       if (ret != NULL)
-                                               {
-                                                       source = g_strdup (ret);
-                                               }
-                                       else
+       xpcontext->node = xmlDocGetRootElement (xdoc);
+       xpresult = xmlXPathEvalExpression ((const xmlChar *)"//text[contains(node(), \"@Pages\")]", xpcontext);
+       if (!xmlXPathNodeSetIsEmpty (xpresult->nodesetval))
+               {
+                       gint i;
+                       xmlNode *cur;
+                       gchar *ref;
+                       gchar *cont;
+
+                       xnodeset = xpresult->nodesetval;
+
+                       for (i = 0; i < xnodeset->nodeNr; i++)
+                               {
+                                       cur = xnodeset->nodeTab[i];
+                                       cont = g_strdup (xmlNodeGetContent (cur));
+                                       while ((ref = strstr (cont, "@Pages")) != NULL)
                                                {
-                                                       source = g_strdup ("");
+                                                       cont = g_strconcat ("",
+                                                                           g_strndup (cont, strlen (cont) - strlen (ref)),
+                                                                           g_strdup_printf ("%d", priv->cur_page),
+                                                                           g_strndup (ref + 6, strlen (ref - 6)),
+                                                                           NULL);
                                                }
+                                       xmlNodeSetContent (cur, cont);
                                }
                }
-       else if (source[0] == '[' && source[strlen (source) - 1] == ']')
+}
+
+gchar
+*rpt_report_get_field (RptReport *rpt_report, const gchar *field_name, gint row)
+{
+       gint col;
+       gchar *ret = NULL;
+
+       RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
+
+       col = gda_data_model_get_column_position (priv->db->gda_datamodel, field_name);
+
+       if (col > -1)
                {
-                       /* ask value */
-                       gchar *ret;
-                       gchar *field;
-                       RptReportClass *klass = RPT_REPORT_GET_CLASS (rpt_report);
-
-                       field = g_strstrip (g_strndup (source + 1, strlen (source) - 2));
-                       g_signal_emit (rpt_report, klass->field_request_signal_id,
-                                      0, field, NULL, row, &ret);
-                       if (ret != NULL)
-                               {
-                                       source = g_strdup (ret);
-                               }
-                       else
-                               {
-                                       source = g_strdup ("");
-                               }
+                       ret = gda_value_stringify ((GdaValue *)gda_data_model_get_value_at (priv->db->gda_datamodel, col, row));
                }
-       else if (source[0] == '@')
+       else
                {
-                       /* TO DO */
-                       /* special values */
+                       ret = rpt_report_ask_field (rpt_report, field_name, row);
+               }
 
-                       if (strcmp (source + 1, "Page") == 0)
-                               {
-                                       source = g_strdup_printf ("%d", priv->cur_page);
-                               }
-                       else if (strcmp (source + 1, "Date") == 0)
-                               {
-                                       char date[11] = "\0";
-                                       time_t now = time (NULL);
-                                       struct tm *tm = localtime (&now);
-                                       strftime (date, 11, "%F", tm);
-                                       source = g_strdup_printf ("%s", &date);
-                               }
-                       else if (strcmp (source + 1, "Time") == 0)
-                               {
-                                       char date[6] = "";
-                                       time_t now = time (NULL);
-                                       struct tm *tm = localtime (&now);
-                                       strftime (date, 6, "%H:%M", tm);
-                                       source = g_strdup_printf ("%s", &date);
-                               }
+       return ret;
+}
+
+gchar
+*rpt_report_ask_field (RptReport *rpt_report, const gchar *field, gint row)
+{
+       gchar *ret = NULL;
+
+       RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
+
+       RptReportClass *klass = RPT_REPORT_GET_CLASS (rpt_report);
+
+       g_signal_emit (rpt_report, klass->field_request_signal_id,
+                                  0, field, priv->db->gda_datamodel, row, &ret);
+       if (ret != NULL)
+               {
+                       ret = g_strdup (ret);
                }
-       else if (source[0] = '"' && source[strlen (source) - 1] == '"')
+
+       return ret;
+}
+
+gchar
+*rpt_report_get_special (RptReport *rpt_report, const gchar *special, gint row)
+{
+       gchar *ret = NULL;
+
+       RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report);
+
+       if (strcmp (special, "@Page") == 0)
                {
-                       source = g_strndup (source + 1, strlen (source) - 2);
+                       ret = g_strdup_printf ("%d", priv->cur_page);
                }
-       else
+       else if (strcmp (special, "@Pages") == 0)
+               {
+                       ret = g_strdup ("@Pages");
+               }
+       else if (strcmp (special, "@Date") == 0)
+               {
+                       char date[11] = "\0";
+                       time_t now = time (NULL);
+                       struct tm *tm = localtime (&now);
+                       strftime (date, 11, "%F", tm);
+                       ret = g_strdup_printf ("%s", &date);
+               }
+       else if (strcmp (special, "@Time") == 0)
                {
-                       source = g_strdup ("");
+                       char date[6] = "";
+                       time_t now = time (NULL);
+                       struct tm *tm = localtime (&now);
+                       strftime (date, 6, "%H:%M", tm);
+                       ret = g_strdup_printf ("%s", &date);
                }
 
-       xmlNodeSetContent (xnode, source);
+       return ret;
 }
index bef2885aaccc2a69c9ce3f183edc61f18e733d7f..c4c7bc00495cc8f1f2694dae723a4fc7d4269f50 100644 (file)
@@ -14,7 +14,7 @@
                        <text name="rephead" x="10" y="10" width="300" height="70" font-name="Verdana" font-size="16" font-bold="y" font-underline="y" font-color="#0000FF" source="&quot;the report's header&quot;" />
                </report-header>
                <page-header height="80" first-page="y">
-                       <text name="title" x="10" y="10" width="300" height="50" font-name="Courier New" font-size="10" font-bold="y" source="&quot;the page's title&quot;" />
+                       <text name="title" x="10" y="10" width="300" height="50" font-name="Courier New" font-size="10" font-bold="y" source="&quot;the page's title&quot; &amp; &quot; - &quot; &amp; @Page" />
                        <line name="line1" x="10" y="65" width="500" height="0" />
                </page-header>
                <body height="200">
@@ -33,7 +33,7 @@
                        <line name="line2" x="10" y="10" width="500" height="0" />
                        <text name="footer" x="10" y="20" width="300" height="50" source="&quot;the page's footer&quot;" />
                        <ellipse name="ellipse1" x="400" y="50" width="20" height="10" stroke-color="#FF0000" fill-color="#00FF00" />
-                       <text name="page_n" x="500" y="20" width="30" height="50" source="@Page" />
+                       <text name="page_n" x="500" y="20" width="50" height="50" source="@Page &amp; &quot;/&quot; &amp; @Pages" />
                </page-footer>
        </report>
 </reptool>