// It can be used for simple syntax parsers, like lyxrc,
// texclass and others to come. [asierra30/03/96]
//
-// (C) 1996 Lyx Team.
-#ifndef _LYXLEX_H
-#define _LYXLEX_H
+// Copyright 1996 Lyx Team.
+#ifndef LYXLEX_H
+#define LYXLEX_H
#ifdef __GNUG__
#pragma interface
#endif
-#include <stdio.h>
+#include <iosfwd>
+
#include "LString.h"
///
struct keyword_item {
///
- char const* tag;
+ char const * tag;
///
short code;
};
class LyXLex {
public:
///
- LyXLex (keyword_item*, int);
+ LyXLex (keyword_item *, int);
///
- ~LyXLex() { if (file && owns_file) fclose(file); };
-
+ ~LyXLex();
+
/// Lex basic codes
enum {
///
};
/// file is open and end of file is not reached
- bool IsOK();
+ bool IsOK() const;
/// return true if able to open file, else false
bool setFile(string const & filename);
- /// if file is already read from, line numbers will be wrong.
- // should be removed
- void setFile(FILE *f);
///
- // should be removed
- FILE *getFile() { return file; }
+ void setStream(std::istream & i);
+ ///
+ std::istream & getStream();
/// Danger! Don't use it unless you know what you are doing.
- void setLineNo(int l) { lineno = l; }
+ void setLineNo(int l);
+
/// returns a lex code
int lex();
split a word if it contains a backslash.
*/
bool nextToken();
+ /// Push a token, that next token got from lyxlex.
+ void pushToken(string const &);
///
- int GetLineNo() { return lineno; }
+ int GetLineNo() const;
+
///
- int GetInteger();
+ int GetInteger() const;
///
- bool GetBool();
+ bool GetBool() const;
///
- float GetFloat();
+ float GetFloat() const;
///
string GetString() const;
- /// get a long string, ended by the tag `endtag'
- string getLongString(string const &endtoken);
+ /**
+ * Get a long string, ended by the tag `endtag'
+ * This string can span several lines. The first line
+ * serves as a template for how many spaces the lines
+ * are indented. This much white space is skipped from
+ * each following line. This mechanism does not work
+ * perfectly if you use tabs.
+ */
+ string getLongString(string const & endtag);
///
bool EatLine();
///
- int FindToken(char const* string[]);
+ int FindToken(char const * str[]);
///
- int CheckToken(char const* string[], int print_error);
+ int CheckToken(char const * str[], int print_error);
///
- char const *text() const { return &buff[0]; }
+ char const * text() const;
/** Pushes a token list on a stack and replaces it with a new one.
*/
- void pushTable(keyword_item*, int);
+ void pushTable(keyword_item *, int);
/** Pops a token list into void and replaces it with the one now
on top of the stack.
and file name. If message contains the substring `$$Token',
it is replaced with the value of GetString()
*/
- void printError(string const & message);
+ void printError(string const & message) const;
/**
- Prints the current token table on stderr.
+ Prints the current token table on the supplied ostream.
*/
- void printTable();
-protected:
- ///
- enum {
- ///
- LEX_MAX_BUFF = 2048
- };
-
- ///
- struct pushed_table {
- ///
- pushed_table(){
- next=0;
- table_elem=0;
- }
- ///
- pushed_table *next;
- ///
- keyword_item *table_elem;
- ///
- int table_siz;
- };
-
- ///
- FILE *file;
- ///
- bool owns_file;
- ///
- string name;
- ///
- int lineno;
- ///
- keyword_item *table;
- ///
- int no_items;
- ///
- char buff[LEX_MAX_BUFF];
- ///
- pushed_table *pushed;
- ///
- int search_kw(char const * const) const;
- ///
- short status;
+ void printTable(std::ostream &);
+private:
+ struct Pimpl;
+ Pimpl * pimpl_;
};
-inline
-bool LyXLex::IsOK()
-{
- return (file && !feof(file));
-}
+// This is needed to ensure that the pop is done upon exit from methods
+// with more than one exit point or that can return as a response to
+// exceptions. (Lgb)
+struct pushpophelper {
+ pushpophelper(LyXLex & lexrc, keyword_item * i, int s) : lex(lexrc) {
+ lex.pushTable(i, s);
+ }
+ ~pushpophelper() {
+ lex.popTable();
+ }
+ LyXLex & lex;
+};
+// To avoid wrong usage:
+// pushpophelper(...); // wrong
+// pushpophelper pph(...); // right
+// we add this macro:
+#define pushpophelper(x, y, z) unnamed_pushpophelper;
+// Tip gotten from Bobby Schmidt's column in C/C++ Users Journal
#endif