mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-15 00:49:55 +00:00
.. added a new 'XDATA' element for the JsonRideFile and RideFile classes. .. this allows ride file readers to extract and load any time series data that doesn't neccessarily fit into the usual data points. .. this was added to support weather data from FIT files and also to support 3rd party merging data with the GC supported data. .. ** IMPORTANT ** the XDATA segment is added at the END of the JSON format. So older parsers will fail to read but will have loaded all data already (i.e. they will fail gracefully enough) This means files with XDATA can be read by earlier versions of GC, but the XDATA will be discarded.
179 lines
6.3 KiB
Plaintext
179 lines
6.3 KiB
Plaintext
%{
|
|
/*
|
|
* Copyright (c) 2010 Mark Liversedge (liversedge@gmail.com)
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "JsonRideFile.h"
|
|
|
|
// we use stdio for reading from FILE *JsonRideFilein
|
|
// because thats what lex likes to do, and since we're
|
|
// reading files that seems ok anyway
|
|
#include <stdio.h>
|
|
|
|
// The parser defines the token values for us
|
|
// so lets include them before declaring the
|
|
// token patterns
|
|
#include "JsonRideFile_yacc.h"/* generated by the scanner */
|
|
|
|
// the options below tell flex to no bother with
|
|
// yywrap since we only ever read a single file
|
|
// anyway. And yyunput() isn't needed for our
|
|
// parser, we read in one pass with no swanky
|
|
// interactions
|
|
#define YYSTYPE QString
|
|
|
|
// Un-Escape special characters (JSON compliance)
|
|
static QString unprotect(char *string)
|
|
{
|
|
// sending UTF-8 to FLEX demands symetric conversion back to QString
|
|
QString string2 = QString::fromUtf8(string);
|
|
|
|
// this is a lexer string so it will be enclosed
|
|
// in quotes. Lets strip those first
|
|
QString s = string2.mid(1,string2.length()-2);
|
|
|
|
// does it end with a space (to avoid token conflict) ?
|
|
if (s.endsWith(" ")) s = s.mid(0, s.length()-1);
|
|
|
|
// now un-escape the control characters
|
|
s.replace("\\t", "\t"); // tab
|
|
s.replace("\\n", "\n"); // newline
|
|
s.replace("\\r", "\r"); // carriage-return
|
|
s.replace("\\b", "\b"); // backspace
|
|
s.replace("\\f", "\f"); // formfeed
|
|
s.replace("\\/", "/"); // solidus
|
|
s.replace("\\\"", "\""); // quote
|
|
s.replace("\\\\", "\\"); // backslash
|
|
|
|
return s;
|
|
}
|
|
|
|
// we reimplement these to remove compiler warnings
|
|
// about unused parameter (scanner) in the default
|
|
// implementations, which may freak out developers
|
|
void *JsonRideFilealloc (yy_size_t size , yyscan_t /*scanner*/)
|
|
{
|
|
return (void *) malloc( size );
|
|
}
|
|
|
|
void *JsonRideFilerealloc (void * ptr, yy_size_t size , yyscan_t /*scanner*/)
|
|
{
|
|
/* The cast to (char *) in the following accommodates both
|
|
* implementations that use char* generic pointers, and those
|
|
* that use void* generic pointers. It works with the latter
|
|
* because both ANSI C and C++ allow castless assignment from
|
|
* any pointer type to void*, and deal with argument conversions
|
|
* as though doing an assignment.
|
|
*/
|
|
return (void *) realloc( (char *) ptr, size );
|
|
}
|
|
|
|
void JsonRideFilefree (void * ptr , yyscan_t /*scanner*/)
|
|
{
|
|
free( (char *) ptr ); /* see JsonRideFilerealloc() for (char *) cast */
|
|
}
|
|
|
|
// replace this too, as a) it exits (!!)
|
|
// cannot shutup compiler warning on yy_fatal_error function tho :(
|
|
#define YY_FATAL_ERROR(msg) qDebug()<<msg;
|
|
|
|
%}
|
|
%option prefix="JsonRideFile"
|
|
%option never-interactive
|
|
%option noyyalloc
|
|
%option noyyrealloc
|
|
%option noyyfree
|
|
%option noyywrap
|
|
%option nounput
|
|
%option noinput
|
|
%option reentrant
|
|
%option bison-bridge
|
|
|
|
%%
|
|
\"RIDE\" return RIDE;
|
|
\"STARTTIME\" return STARTTIME;
|
|
\"RECINTSECS\" return RECINTSECS;
|
|
\"DEVICETYPE\" return DEVICETYPE;
|
|
\"IDENTIFIER\" return IDENTIFIER;
|
|
\"OVERRIDES\" return OVERRIDES;
|
|
\"TAGS\" return TAGS;
|
|
\"INTERVALS\" return INTERVALS;
|
|
\"NAME\" return NAME;
|
|
\"START\" return START;
|
|
\"STOP\" return STOP;
|
|
\"CALIBRATIONS\" return CALIBRATIONS;
|
|
\"VALUE\" return VALUE;
|
|
\"VALUES\" return VALUES;
|
|
\"XDATA\" return XDATA;
|
|
\"REFERENCES\" return REFERENCES;
|
|
\"SAMPLES\" return SAMPLES;
|
|
\"SECS\" return SECS;
|
|
\"KM\" return KM;
|
|
\"WATTS\" return WATTS;
|
|
\"NM\" return NM;
|
|
\"CAD\" return CAD;
|
|
\"KPH\" return KPH;
|
|
\"HR\" return HR;
|
|
\"ALT\" return ALTITUDE; // ALT clashes with qtnamespace.h:46
|
|
\"LAT\" return LAT;
|
|
\"LON\" return LON;
|
|
\"HEADWIND\" return HEADWIND;
|
|
\"SLOPE\" return SLOPE;
|
|
\"TEMP\" return TEMP;
|
|
\"LRBALANCE\" return LRBALANCE;
|
|
\"LTE\" return LTE;
|
|
\"RTE\" return RTE;
|
|
\"LPS\" return LPS;
|
|
\"RPS\" return RPS;
|
|
\"LPCO\" return LPCO;
|
|
\"RPCO\" return RPCO;
|
|
\"LPPB\" return LPPB;
|
|
\"RPPB\" return RPPB;
|
|
\"LPPE\" return LPPE;
|
|
\"RPPE\" return RPPE;
|
|
\"LPPPB\" return LPPPB;
|
|
\"RPPPB\" return RPPPB;
|
|
\"LPPPE\" return LPPPE;
|
|
\"RPPPE\" return RPPPE;
|
|
\"SMO2\" return SMO2;
|
|
\"THB\" return THB;
|
|
\"RCON\" return RCON;
|
|
\"RVERT\" return RVERT;
|
|
\"RCAD\" return RCAD;
|
|
[-+]?[0-9]+ { *yylval = QString::fromUtf8(yytext); return JS_INTEGER; }
|
|
[-+]?[0-9]+e-[0-9]+ { *yylval = QString::fromUtf8(yytext); return JS_FLOAT; }
|
|
[-+]?[0-9]+\.[-+e0-9]* { *yylval = QString::fromUtf8(yytext); return JS_FLOAT; }
|
|
|
|
\"([^\"]|\\\")*\" { *yylval = unprotect(yytext); return JS_STRING; } /* contains non-quotes or escaped-quotes */
|
|
[ \n\t\r] ; /* we just ignore whitespace */
|
|
. return yytext[0]; /* any other character, typically :, { or } */
|
|
%%
|
|
|
|
// Older versions of flex (prior to 2.5.9) do not have the destroy function
|
|
// Or We're not using GNU flex then we also won't have a destroy function
|
|
#if !defined(FLEX_SCANNER) || (YY_FLEX_MINOR_VERSION < 6 && YY_FLEX_SUBMINOR_VERSION < 9)
|
|
int JsonRideFilelex_destroy(void*) { return 0; }
|
|
#endif
|
|
|
|
void JsonRideFile_setString(QString p, void *scanner)
|
|
{
|
|
// internally work with UTF-8 encoding
|
|
// this works for FLEX, since the multi-byte characters only appear WITHIN a "String",
|
|
// but not as part of the grammar - this is important since a char in UTF-8 can have up to 4 bytes
|
|
JsonRideFile_scan_string(p.toUtf8().data(), scanner);
|
|
}
|