mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 22:16:16 +02:00
* Use SGparseString() instead of SGparseFile() because the latter is
buggy. It fails to clear an internal variable (SG_textIndex) between invocations, so it can be called only once during a program execution.
This commit is contained in:
parent
403cb9327f
commit
7db08cc924
1 changed files with 23 additions and 2 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -16,6 +17,11 @@ extern "C" {
|
||||||
#include "parse-table.h"
|
#include "parse-table.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Cleanup cleans up an imploded parse tree into an actual abstract
|
||||||
|
syntax tree that we can evaluate. It removes quotes around
|
||||||
|
strings, converts integer literals into actual integers, and
|
||||||
|
absolutises paths relative to the directory containing the input
|
||||||
|
file. */
|
||||||
struct Cleanup : TermFun
|
struct Cleanup : TermFun
|
||||||
{
|
{
|
||||||
string basePath;
|
string basePath;
|
||||||
|
@ -94,14 +100,28 @@ Expr parseExprFromFile(Path path)
|
||||||
initialised = true;
|
initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ATerm result = SGparseFile((char *) programId.c_str(), lang,
|
/* Read the input file. We can't use SGparseFile() because it's
|
||||||
"Expr", (char *) path.c_str());
|
broken, so we read the input ourselves and call
|
||||||
|
SGparseString(). */
|
||||||
|
AutoCloseFD fd = open(path.c_str(), O_RDONLY);
|
||||||
|
if (fd == -1) throw SysError(format("opening `%1%'") % path);
|
||||||
|
|
||||||
|
if (fstat(fd, &st) == -1)
|
||||||
|
throw SysError(format("statting `%1%'") % path);
|
||||||
|
|
||||||
|
char text[st.st_size + 1];
|
||||||
|
readFull(fd, (unsigned char *) text, st.st_size);
|
||||||
|
text[st.st_size] = 0;
|
||||||
|
|
||||||
|
/* Parse it. */
|
||||||
|
ATerm result = SGparseString(lang, "Expr", text);
|
||||||
if (!result)
|
if (!result)
|
||||||
throw SysError(format("parse failed in `%1%'") % path);
|
throw SysError(format("parse failed in `%1%'") % path);
|
||||||
if (SGisParseError(result))
|
if (SGisParseError(result))
|
||||||
throw Error(format("parse error in `%1%': %2%")
|
throw Error(format("parse error in `%1%': %2%")
|
||||||
% path % printTerm(result));
|
% path % printTerm(result));
|
||||||
|
|
||||||
|
/* Implode it. */
|
||||||
PT_ParseTree tree = PT_makeParseTreeFromTerm(result);
|
PT_ParseTree tree = PT_makeParseTreeFromTerm(result);
|
||||||
if (!tree)
|
if (!tree)
|
||||||
throw Error(format("cannot create parse tree"));
|
throw Error(format("cannot create parse tree"));
|
||||||
|
@ -121,6 +141,7 @@ Expr parseExprFromFile(Path path)
|
||||||
if (!imploded)
|
if (!imploded)
|
||||||
throw Error(format("cannot implode parse tree"));
|
throw Error(format("cannot implode parse tree"));
|
||||||
|
|
||||||
|
/* Finally, clean it up. */
|
||||||
Cleanup cleanup;
|
Cleanup cleanup;
|
||||||
cleanup.basePath = dirOf(path);
|
cleanup.basePath = dirOf(path);
|
||||||
return bottomupRewrite(cleanup, imploded);
|
return bottomupRewrite(cleanup, imploded);
|
||||||
|
|
Loading…
Reference in a new issue