diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2013-02-10 21:53:22 +0000 | 
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2013-02-10 21:53:22 +0000 | 
| commit | 1538ef47d1d4cc08e5f9c5894350bfa225866d40 (patch) | |
| tree | caacdbe75db8a134a14074229892af2dbebf1ad1 | |
| parent | 058caf24d2b48ab6b49ae8efe5e1eb1ed246eff1 (diff) | |
| download | libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.gz libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.bz2 libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.tar.xz libgats-1538ef47d1d4cc08e5f9c5894350bfa225866d40.zip  | |
Made the gats text parser much more robust.
| -rw-r--r-- | c++-libbu++/default.bld | 1 | ||||
| -rw-r--r-- | c++-libbu++/src/object.cpp | 27 | ||||
| -rw-r--r-- | c++-libbu++/src/object.h | 66 | 
3 files changed, 82 insertions, 12 deletions
diff --git a/c++-libbu++/default.bld b/c++-libbu++/default.bld index 5a09a55..e6d1380 100644 --- a/c++-libbu++/default.bld +++ b/c++-libbu++/default.bld  | |||
| @@ -52,6 +52,7 @@ target "gatsc" | |||
| 52 | { | 52 | { | 
| 53 | rule "exe"; | 53 | rule "exe"; | 
| 54 | input files("src/gatsc/*.cpp"); | 54 | input files("src/gatsc/*.cpp"); | 
| 55 | requires "libgats.a"; | ||
| 55 | CXXFLAGS += "-I. -Ilibbu++"; | 56 | CXXFLAGS += "-I. -Ilibbu++"; | 
| 56 | LDFLAGS += "-L. -lgats -lbu++"; | 57 | LDFLAGS += "-L. -lgats -lbu++"; | 
| 57 | } | 58 | } | 
diff --git a/c++-libbu++/src/object.cpp b/c++-libbu++/src/object.cpp index db7b80b..faeca16 100644 --- a/c++-libbu++/src/object.cpp +++ b/c++-libbu++/src/object.cpp  | |||
| @@ -80,12 +80,12 @@ Gats::Object *Gats::Object::read( Bu::Stream &rIn ) | |||
| 80 | return pObj; | 80 | return pObj; | 
| 81 | } | 81 | } | 
| 82 | 82 | ||
| 83 | void Gats::Object::skipWs( Bu::String::const_iterator &i ) | 83 | void Gats::Object::skipWs( Gats::Object::StrPos &i ) | 
| 84 | { | 84 | { | 
| 85 | for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { } | 85 | for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { } | 
| 86 | } | 86 | } | 
| 87 | 87 | ||
| 88 | Bu::String Gats::Object::token( Bu::String::const_iterator &i ) | 88 | Bu::String Gats::Object::token( Gats::Object::StrPos &i ) | 
| 89 | { | 89 | { | 
| 90 | Bu::String sRet; | 90 | Bu::String sRet; | 
| 91 | if( *i == '\"' ) | 91 | if( *i == '\"' ) | 
| @@ -111,7 +111,12 @@ Bu::String Gats::Object::token( Bu::String::const_iterator &i ) | |||
| 111 | return sRet; | 111 | return sRet; | 
| 112 | } | 112 | } | 
| 113 | 113 | ||
| 114 | Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | 114 | Bu::String::FormatProxy Gats::Object::posError( Gats::Object::StrPos &i, const Bu::String &msg ) | 
| 115 | { | ||
| 116 | return msg.format( new Thrower(i) ); | ||
| 117 | } | ||
| 118 | |||
| 119 | Gats::Object *Gats::Object::strToGats( Gats::Object::StrPos &i ) | ||
| 115 | { | 120 | { | 
| 116 | skipWs( i ); | 121 | skipWs( i ); | 
| 117 | 122 | ||
| @@ -145,7 +150,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | |||
| 145 | return pLst; | 150 | return pLst; | 
| 146 | 151 | ||
| 147 | default: | 152 | default: | 
| 148 | throw Bu::ExceptionBase("Invalid character found."); | 153 | posError(i, "Expected ',' or ']' but found '%1'."). | 
| 154 | arg( *i ); | ||
| 149 | } | 155 | } | 
| 150 | } | 156 | } | 
| 151 | } | 157 | } | 
| @@ -164,16 +170,18 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | |||
| 164 | return pDict; | 170 | return pDict; | 
| 165 | } | 171 | } | 
| 166 | if( *i != '\"' ) | 172 | if( *i != '\"' ) | 
| 167 | throw Bu::ExceptionBase("Keys must be quoted strings."); | 173 | posError(i, "Dictionary keys must be quoted strings."); | 
| 168 | Bu::String sKey = token( i ); | 174 | Bu::String sKey = token( i ); | 
| 169 | skipWs( i ); | 175 | skipWs( i ); | 
| 170 | if( *i != ':' ) | 176 | if( *i != ':' ) | 
| 171 | throw Bu::ExceptionBase("Keys and values must be " | 177 | posError(i, "Dictionary keys and values must be " | 
| 172 | "seperated with colons."); | 178 | "seperated with colons."); | 
| 179 | StrPos ih( i ); | ||
| 173 | i++; | 180 | i++; | 
| 181 | skipWs( i ); | ||
| 174 | Gats::Object *pObj = strToGats( i ); | 182 | Gats::Object *pObj = strToGats( i ); | 
| 175 | if( !pObj ) | 183 | if( !pObj ) | 
| 176 | throw Bu::ExceptionBase("No value object found."); | 184 | posError(ih, "Dictionary key has no value."); | 
| 177 | pDict->insert( sKey, pObj ); | 185 | pDict->insert( sKey, pObj ); | 
| 178 | skipWs( i ); | 186 | skipWs( i ); | 
| 179 | switch( *i ) | 187 | switch( *i ) | 
| @@ -187,7 +195,8 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | |||
| 187 | return pDict; | 195 | return pDict; | 
| 188 | 196 | ||
| 189 | default: | 197 | default: | 
| 190 | throw Bu::ExceptionBase("Invalid character found."); | 198 | posError(i, "Expected ',' or '}' but found '%1'.") | 
| 199 | .arg( *i ); | ||
| 191 | } | 200 | } | 
| 192 | } | 201 | } | 
| 193 | } | 202 | } | 
| @@ -277,7 +286,7 @@ Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i ) | |||
| 277 | 286 | ||
| 278 | Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) | 287 | Gats::Object *Gats::Object::strToGats( const Bu::String &sStr ) | 
| 279 | { | 288 | { | 
| 280 | Bu::String::const_iterator i = sStr.begin(); | 289 | StrPos i( sStr.begin() ); | 
| 281 | 290 | ||
| 282 | return strToGats( i ); | 291 | return strToGats( i ); | 
| 283 | } | 292 | } | 
diff --git a/c++-libbu++/src/object.h b/c++-libbu++/src/object.h index e4da8de..a876061 100644 --- a/c++-libbu++/src/object.h +++ b/c++-libbu++/src/object.h  | |||
| @@ -48,9 +48,69 @@ namespace Gats | |||
| 48 | static Object *strToGats( const Bu::String &sStr ); | 48 | static Object *strToGats( const Bu::String &sStr ); | 
| 49 | 49 | ||
| 50 | private: | 50 | private: | 
| 51 | static Object *strToGats( Bu::String::const_iterator &i ); | 51 | class StrPos | 
| 52 | static Bu::String token( Bu::String::const_iterator &i ); | 52 | { | 
| 53 | static void skipWs( Bu::String::const_iterator &i ); | 53 | public: | 
| 54 | StrPos( const Bu::String::const_iterator &i ) : | ||
| 55 | i( i ), iLine( 1 ), iChar( 1 ) | ||
| 56 | { } | ||
| 57 | Bu::String::const_iterator i; | ||
| 58 | int iLine; | ||
| 59 | int iChar; | ||
| 60 | |||
| 61 | char operator*() | ||
| 62 | { | ||
| 63 | return *i; | ||
| 64 | } | ||
| 65 | StrPos &operator++(int) | ||
| 66 | { | ||
| 67 | i++; | ||
| 68 | if( i ) | ||
| 69 | { | ||
| 70 | if( *i == '\n' ) | ||
| 71 | { | ||
| 72 | iLine++; | ||
| 73 | iChar = 0; | ||
| 74 | } | ||
| 75 | else | ||
| 76 | iChar++; | ||
| 77 | } | ||
| 78 | return *this; | ||
| 79 | } | ||
| 80 | operator bool() | ||
| 81 | { | ||
| 82 | return i; | ||
| 83 | } | ||
| 84 | }; | ||
| 85 | |||
| 86 | class Thrower : public Bu::String::FormatProxyEndAction | ||
| 87 | { | ||
| 88 | public: | ||
| 89 | Thrower( Gats::Object::StrPos &i ) : | ||
| 90 | i( i ) | ||
| 91 | { | ||
| 92 | } | ||
| 93 | |||
| 94 | virtual ~Thrower() | ||
| 95 | { | ||
| 96 | } | ||
| 97 | |||
| 98 | virtual void operator()( const Bu::String &sFinal ) | ||
| 99 | { | ||
| 100 | throw Bu::ExceptionBase( | ||
| 101 | (Bu::String("%1: %2: ").arg(i.iLine).arg(i.iChar).end() + sFinal) | ||
| 102 | .getStr() | ||
| 103 | ); | ||
| 104 | } | ||
| 105 | |||
| 106 | private: | ||
| 107 | Gats::Object::StrPos &i; | ||
| 108 | }; | ||
| 109 | |||
| 110 | static Bu::String::FormatProxy posError( Gats::Object::StrPos &i, const Bu::String &msg ); | ||
| 111 | static Object *strToGats( Gats::Object::StrPos &i ); | ||
| 112 | static Bu::String token( Gats::Object::StrPos &i ); | ||
| 113 | static void skipWs( Gats::Object::StrPos &i ); | ||
| 54 | }; | 114 | }; | 
| 55 | 115 | ||
| 56 | const char *typeToStr( Type t ); | 116 | const char *typeToStr( Type t ); | 
