textfile.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00044 #ifndef FILE_TEXTFILE_H
00045 #define FILE_TEXTFILE_H
00046
00047 #include "fastlib/base/base.h"
00048 #include "fastlib/col/col_string.h"
00049
00050 #include <cstdio>
00051 #include <ctype.h>
00052 #include <stdarg.h>
00053
00060 class TextLineReader {
00061 FORBID_ACCIDENTAL_COPIES(TextLineReader);
00062
00063 private:
00064 FILE *f_;
00065 String line_;
00066 int line_num_;
00067 bool has_line_;
00068
00069 public:
00071 TextLineReader() {
00072 f_ = NULL;
00073 }
00074
00078 ~TextLineReader() {
00079 if (f_) {
00080 ::fclose(f_);
00081 }
00082 }
00083
00089 success_t Open(const char *fname);
00090
00096 void Close() {
00097 (void)fclose(f_);
00098 f_ = NULL;
00099 }
00100
00104 bool MoreLines() {
00105 return has_line_;
00106 }
00107
00111 int line_num() const {
00112 return line_num_;
00113 }
00114
00118 String& Peek() {
00119 return line_;
00120 }
00121
00125 const String& Peek() const {
00126 return line_;
00127 }
00128
00134 bool Gobble();
00135
00139 COMPILER_PRINTF(2, 3)
00140 void Error(const char *msg, ...);
00141
00142 private:
00143 char *ReadLine_();
00144 };
00145
00169 class TextTokenizer {
00170 FORBID_ACCIDENTAL_COPIES(TextTokenizer);
00171 public:
00172 enum TokenType {
00173 INVALID = -1,
00174 END,
00175 PUNCT,
00176 IDENTIFIER,
00177 STRING,
00178 DOUBLE,
00179 INTEGER
00180 };
00181
00182 enum Features {
00183 WANT_NEWLINE = 0x01
00184 };
00185
00186 private:
00187 FILE *f_;
00188 String next_;
00189 TokenType next_type_;
00190 String cur_;
00191 TokenType cur_type_;
00192 const char *comment_start_;
00193 const char *ident_extra_;
00194 int features_;
00195 int line_;
00196
00197 public:
00198 TextTokenizer() {
00199 f_ = NULL;
00200 }
00201 ~TextTokenizer() {
00202 if (unlikely(f_ != NULL)) {
00203 (void) fclose(f_);
00204 }
00205 DEBUG_POISON_PTR(f_);
00206 }
00207
00208 success_t Open(const char *fname,
00209 const char *comment_chars = "", const char *ident_extra = "",
00210 int features = 0);
00211
00212
00213 const String& Peek() const {
00214 return next_;
00215 }
00216
00217 TokenType PeekType() const {
00218 return next_type_;
00219 }
00220
00221 const String& Current() const {
00222 return cur_;
00223 }
00224
00225 TokenType CurrentType() const {
00226 return cur_type_;
00227 }
00228
00229 void Gobble();
00230
00231 bool MoreTokens() const {
00232 return next_type_ != END;
00233 }
00234
00235 bool Match(const char *exact) {
00236 if (next_ == exact) {
00237 Gobble();
00238 return true;
00239 } else {
00240 return false;
00241 }
00242 }
00243
00244 bool MatchNoCase(const char *str) {
00245 if (next_.EqualsNoCase(str)) {
00246 Gobble();
00247 return true;
00248 } else {
00249 return false;
00250 }
00251 }
00252
00253 bool MatchInteger() {
00254 return MatchType(INTEGER);
00255 }
00256
00257 bool MatchDouble() {
00258 return MatchType(DOUBLE);
00259 }
00260
00261 bool MatchNumber() {
00262 return MatchInteger() || MatchDouble();
00263 }
00264
00265 bool MatchIdentifier() {
00266 return MatchType(IDENTIFIER);
00267 }
00268
00269 bool MatchQuasiIdentifier() {
00270 return MatchIdentifier() || MatchNumber();
00271 }
00272
00273 bool MatchString() {
00274 return MatchType(STRING);
00275 }
00276
00277 bool MatchPunct() {
00278 return MatchType(PUNCT);
00279 }
00280
00281 bool MatchType(TokenType type) {
00282 if (next_type_ == type) {
00283 Gobble();
00284 return true;
00285 } else {
00286 return false;
00287 }
00288 }
00289
00290 int line() const {
00291 return line_;
00292 }
00293
00294 COMPILER_PRINTF(2, 3)
00295 void Error(const char *msg, ...);
00296
00297 private:
00298 int GetChar_() {
00299 return ::getc(f_);
00300 }
00301
00302 void Unget_(int c) {
00303 ::ungetc(c, f_);
00304 }
00305
00306 bool IsEOF_() {
00307 return ::feof(f_);
00308 }
00309
00310 char Skip_(ArrayList<char> *token);
00311
00312 char NextChar_(ArrayList<char> *token);
00313
00314 char NextChar_();
00315
00316 void UndoNextChar_(ArrayList<char> *token);
00317
00318 void Error_(const char *msg, const ArrayList<char>& token);
00319
00320 bool isident_begin_(int c) const {
00321 return isalpha(c) || unlikely(c == '_');
00322 }
00323
00324 bool isident_rest_(int c) const {
00325 return isalnum(c) || unlikely(c == '_') || (c != 0 && strchr(ident_extra_, c));
00326 }
00327
00328 void ScanNumber_(char c, ArrayList<char> *token);
00329
00330 void ScanString_(char ending, ArrayList<char> *token);
00331
00332 void Scan_(ArrayList<char> *token);
00333 };
00334
00338 class TextWriter {
00339 FORBID_ACCIDENTAL_COPIES(TextWriter);
00340
00341 private:
00342 FILE *f_;
00343
00344 public:
00348 TextWriter() {
00349 f_ = NULL;
00350 }
00351
00359 ~TextWriter() {
00360 if (f_) {
00361 MUST_PASS(SUCCESS_FROM_C(::fclose(f_)));
00362 }
00363 DEBUG_POISON_PTR(f_);
00364 }
00365
00371 success_t Open(const char *fname) {
00372 f_ = ::fopen(fname, "w");
00373 return (unlikely(!f_)) ? SUCCESS_FAIL : SUCCESS_PASS;
00374 }
00375
00379 success_t Close() {
00380 int rv = fclose(f_);
00381 f_ = NULL;
00382 return unlikely(rv < 0) ? SUCCESS_FAIL : SUCCESS_PASS;
00383 }
00384
00385 success_t Printf(const char *format, ...);
00386
00387 success_t Write(const char *s) {
00388 return SUCCESS_FROM_C(fputs(s, f_));
00389 }
00390
00391 success_t Write(int i) {
00392 return SUCCESS_FROM_C(fprintf(f_, "%d", i));
00393 }
00394
00395 success_t Write(unsigned int i) {
00396 return SUCCESS_FROM_C(fprintf(f_, "%u", i));
00397 }
00398
00399 success_t Write(long i) {
00400 return SUCCESS_FROM_C(fprintf(f_, "%ld", i));
00401 }
00402
00403 success_t Write(unsigned long i) {
00404 return SUCCESS_FROM_C(fprintf(f_, "%lu", i));
00405 }
00406
00407 success_t Write(long long i) {
00408 return SUCCESS_FROM_C(fprintf(f_, "%lld", i));
00409 }
00410
00411 success_t Write(unsigned long long i) {
00412 return SUCCESS_FROM_C(fprintf(f_, "%llu", i));
00413 }
00414
00415 success_t Write(double d) {
00416 return SUCCESS_FROM_C(fprintf(f_, "%.15e", d));
00417 }
00418 };
00419
00420 #endif