summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/parser.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/parser.cc
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff)
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/parser.cc')
-rw-r--r--Build/source/utils/asymptote/parser.cc146
1 files changed, 146 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/parser.cc b/Build/source/utils/asymptote/parser.cc
new file mode 100644
index 00000000000..cbeb54fe230
--- /dev/null
+++ b/Build/source/utils/asymptote/parser.cc
@@ -0,0 +1,146 @@
+/*****
+ * parser.cc
+ * Tom Prince 2004/01/10
+ *
+ *****/
+
+#include <fstream>
+#include <sstream>
+
+#include "common.h"
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "interact.h"
+#include "locate.h"
+#include "errormsg.h"
+#include "parser.h"
+
+// The lexical analysis and parsing functions used by parseFile.
+void setlexer(size_t (*input) (char* bif, size_t max_size), string filename);
+extern bool yyparse(void);
+extern int yydebug;
+extern int yy_flex_debug;
+static const int YY_NULL = 0;
+extern bool lexerEOF();
+extern void reportEOF();
+
+namespace parser {
+
+namespace yy { // Lexers
+
+std::streambuf *sbuf = NULL;
+
+size_t stream_input(char *buf, size_t max_size)
+{
+ size_t count= sbuf ? sbuf->sgetn(buf,max_size) : 0;
+ return count ? count : YY_NULL;
+}
+
+} // namespace yy
+
+void debug(bool state)
+{
+ // For debugging the machine-generated lexer and parser.
+ yy_flex_debug = yydebug = state;
+}
+
+namespace {
+void error(const string& filename)
+{
+ em.sync();
+ em << "error: could not load module '" << filename << "'\n";
+ em.sync();
+ throw handled_error();
+}
+}
+
+absyntax::file *doParse(size_t (*input) (char* bif, size_t max_size),
+ const string& filename, bool extendable=false)
+{
+ setlexer(input,filename);
+ absyntax::file *root = yyparse() == 0 ? absyntax::root : 0;
+ absyntax::root = 0;
+ yy::sbuf = 0;
+
+ if (!root) {
+ if (lexerEOF()) {
+ if (extendable) {
+ return 0;
+ } else {
+ // Have the lexer report the error.
+ reportEOF();
+ }
+ }
+
+ em.error(nullPos);
+ if(!interact::interactive)
+ error(filename);
+ else
+ throw handled_error();
+ }
+
+ return root;
+}
+
+absyntax::file *parseStdin()
+{
+ debug(false);
+ yy::sbuf = cin.rdbuf();
+ return doParse(yy::stream_input,"-");
+}
+
+absyntax::file *parseFile(const string& filename,
+ const char *nameOfAction)
+{
+ if(filename == "-")
+ return parseStdin();
+
+ string file = settings::locateFile(filename);
+
+ if(file.empty())
+ error(filename);
+
+ if(nameOfAction && settings::verbose > 1)
+ cerr << nameOfAction << " " << filename << " from " << file << endl;
+
+ debug(false);
+
+ std::filebuf filebuf;
+ if(!filebuf.open(file.c_str(),std::ios::in))
+ error(filename);
+
+#ifdef HAVE_SYS_STAT_H
+ // Check that the file is not a directory.
+ static struct stat buf;
+ if(stat(file.c_str(),&buf) == 0) {
+ if(S_ISDIR(buf.st_mode))
+ error(filename);
+ }
+#endif
+
+ // Check that the file can actually be read.
+ try {
+ filebuf.sgetc();
+ } catch (...) {
+ error(filename);
+ }
+
+ yy::sbuf = &filebuf;
+ return doParse(yy::stream_input,file);
+}
+
+absyntax::file *parseString(const string& code,
+ const string& filename,
+ bool extendable)
+{
+ debug(false);
+ stringbuf buf(code);
+ yy::sbuf = &buf;
+ return doParse(yy::stream_input,filename,extendable);
+}
+
+} // namespace parser
+