* Drop ATmake / ATMatcher also in handling store expressions.
This commit is contained in:
		
							parent
							
								
									ed09821859
								
							
						
					
					
						commit
						a69534fc21
					
				
					 19 changed files with 118 additions and 258 deletions
				
			
		|  | @ -1,6 +1,8 @@ | ||||||
| SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \ | SUBDIRS = bin2c boost libutil libstore libmain nix-store nix-hash \ | ||||||
|  libexpr nix-instantiate nix-env log2xml |  libexpr nix-instantiate nix-env log2xml | ||||||
| 
 | 
 | ||||||
|  | EXTRA_DIST = aterm-helper.pl | ||||||
|  | 
 | ||||||
| SETUID_PROGS = nix-store nix-instantiate nix-env | SETUID_PROGS = nix-store nix-instantiate nix-env | ||||||
| install-exec-hook: | install-exec-hook: | ||||||
| if SETUID_HACK | if SETUID_HACK | ||||||
|  |  | ||||||
|  | @ -1,9 +1,41 @@ | ||||||
| #! /usr/bin/perl -w | #! /usr/bin/perl -w | ||||||
| 
 | 
 | ||||||
|  | # This program generates C/C++ code for efficiently manipulating | ||||||
|  | # ATerms.  It generates functions to build and match ATerms according | ||||||
|  | # to a set of constructor definitions defined in a file read from | ||||||
|  | # standard input.  A constructor is defined by a line with the | ||||||
|  | # following format: | ||||||
|  | # | ||||||
|  | #   SYM | ARGS | TYPE | FUN? | ||||||
|  | # | ||||||
|  | # where SYM is the name of the constructor, ARGS is a | ||||||
|  | # whitespace-separated list of argument types, TYPE is the type of the | ||||||
|  | # resulting ATerm (which should be `ATerm' or a type synonym for | ||||||
|  | # `ATerm'), and the optional FUN is used to construct the names of the | ||||||
|  | # build and match functions (it defaults to SYM; overriding it is | ||||||
|  | # useful if there are overloaded constructors, e.g., with different | ||||||
|  | # arities).  Note that SYM may be empty. | ||||||
|  | # | ||||||
|  | # A line of the form | ||||||
|  | # | ||||||
|  | #   VAR = EXPR | ||||||
|  | # | ||||||
|  | # causes a ATerm variable to be generated that is initialised to the | ||||||
|  | # value EXPR. | ||||||
|  | # | ||||||
|  | # Finally, a line of the form | ||||||
|  | # | ||||||
|  | #   init NAME | ||||||
|  | # | ||||||
|  | # causes the initialisation function to be called `NAME'.  This | ||||||
|  | # function must be called before any of the build/match functions or | ||||||
|  | # the generated variables are used. | ||||||
|  | 
 | ||||||
| die if scalar @ARGV != 2; | die if scalar @ARGV != 2; | ||||||
| 
 | 
 | ||||||
| my $syms = ""; | my $syms = ""; | ||||||
| my $init = ""; | my $init = ""; | ||||||
|  | my $initFun = "init"; | ||||||
| 
 | 
 | ||||||
| open HEADER, ">$ARGV[0]"; | open HEADER, ">$ARGV[0]"; | ||||||
| open IMPL, ">$ARGV[1]"; | open IMPL, ">$ARGV[1]"; | ||||||
|  | @ -11,7 +43,7 @@ open IMPL, ">$ARGV[1]"; | ||||||
| while (<STDIN>) { | while (<STDIN>) { | ||||||
|     next if (/^\s*$/); |     next if (/^\s*$/); | ||||||
|      |      | ||||||
|     if (/^\s*(\w+)\s*\|([^\|]*)\|\s*(\w+)\s*\|\s*(\w+)?/) { |     if (/^\s*(\w*)\s*\|([^\|]*)\|\s*(\w+)\s*\|\s*(\w+)?/) { | ||||||
|         my $const = $1; |         my $const = $1; | ||||||
|         my @types = split ' ', $2; |         my @types = split ' ', $2; | ||||||
|         my $result = $3; |         my $result = $3; | ||||||
|  | @ -30,6 +62,8 @@ while (<STDIN>) { | ||||||
| #                $type = "const char *"; | #                $type = "const char *"; | ||||||
|                 $type = "ATerm"; |                 $type = "ATerm"; | ||||||
|                 $args .= "e$n"; |                 $args .= "e$n"; | ||||||
|  |                 # !!! in the matcher, we should check that the | ||||||
|  |                 # argument is a string (i.e., a nullary application). | ||||||
|             } elsif ($type eq "int") { |             } elsif ($type eq "int") { | ||||||
|                 $args .= "(ATerm) ATmakeInt(e$n)"; |                 $args .= "(ATerm) ATmakeInt(e$n)"; | ||||||
|             } elsif ($type eq "ATermList" || $type eq "ATermBlob") { |             } elsif ($type eq "ATermList" || $type eq "ATermBlob") { | ||||||
|  | @ -42,6 +76,7 @@ while (<STDIN>) { | ||||||
|             $formals2 .= ", "; |             $formals2 .= ", "; | ||||||
|             $formals2 .= "$type & e$n"; |             $formals2 .= "$type & e$n"; | ||||||
|             my $m = $n - 1; |             my $m = $n - 1; | ||||||
|  |             # !!! more checks here | ||||||
|             if ($type eq "int") { |             if ($type eq "int") { | ||||||
|                 $unpack .= "    e$n = ATgetInt((ATermInt) ATgetArgument(e, $m));\n"; |                 $unpack .= "    e$n = ATgetInt((ATermInt) ATgetArgument(e, $m));\n"; | ||||||
|             } elsif ($type eq "ATermList") { |             } elsif ($type eq "ATermList") { | ||||||
|  | @ -84,12 +119,16 @@ while (<STDIN>) { | ||||||
|         $init .= "    $name = $value;\n"; |         $init .= "    $name = $value;\n"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     elsif (/^\s*init\s+(\w+)\s*$/) { | ||||||
|  |         $initFun = $1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     else { |     else { | ||||||
|         die "bad line: `$_'"; |         die "bad line: `$_'"; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| print HEADER "void initSyms();\n\n"; | print HEADER "void $initFun();\n\n"; | ||||||
| 
 | 
 | ||||||
| print HEADER "static inline ATerm string2ATerm(const char * s) {\n"; | print HEADER "static inline ATerm string2ATerm(const char * s) {\n"; | ||||||
| print HEADER "    return (ATerm) ATmakeAppl0(ATmakeAFun((char *) s, 0, ATtrue));\n"; | print HEADER "    return (ATerm) ATmakeAppl0(ATmakeAFun((char *) s, 0, ATtrue));\n"; | ||||||
|  | @ -100,7 +139,7 @@ print HEADER "    return (const char *) ATgetName(ATgetAFun(t));\n"; | ||||||
| print HEADER "}\n\n"; | print HEADER "}\n\n"; | ||||||
| 
 | 
 | ||||||
| print IMPL "\n"; | print IMPL "\n"; | ||||||
| print IMPL "void initSyms() {\n"; | print IMPL "void $initFun() {\n"; | ||||||
| print IMPL "$init"; | print IMPL "$init"; | ||||||
| print IMPL "}\n"; | print IMPL "}\n"; | ||||||
| 
 | 
 | ||||||
|  | @ -3,10 +3,9 @@ noinst_LIBRARIES = libexpr.a | ||||||
| libexpr_a_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \ | libexpr_a_SOURCES = nixexpr.cc nixexpr.hh parser.cc parser.hh \ | ||||||
|  eval.cc eval.hh primops.cc \ |  eval.cc eval.hh primops.cc \ | ||||||
|  lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \ |  lexer-tab.c lexer-tab.h parser-tab.c parser-tab.h \ | ||||||
|  constructors.hh |  nixexpr-ast.hh | ||||||
| 
 | 
 | ||||||
| EXTRA_DIST = lexer.l parser.y constructors.def constructors.cc \ | EXTRA_DIST = lexer.l parser.y nixexpr-ast.def nixexpr-ast.cc | ||||||
|  aterm-helper.pl |  | ||||||
| 
 | 
 | ||||||
| AM_CXXFLAGS = \ | AM_CXXFLAGS = \ | ||||||
|  -I.. ${bdb_include} ${aterm_include} -I../libutil -I../libstore |  -I.. ${bdb_include} ${aterm_include} -I../libutil -I../libstore | ||||||
|  | @ -27,10 +26,10 @@ lexer-tab.c lexer-tab.h: lexer.l | ||||||
| 
 | 
 | ||||||
| # ATerm helper function generation. | # ATerm helper function generation. | ||||||
| 
 | 
 | ||||||
| constructors.cc constructors.hh: aterm-helper.pl constructors.def | nixexpr-ast.cc nixexpr-ast.hh: ../aterm-helper.pl nixexpr-ast.def | ||||||
| 	$(perl) aterm-helper.pl constructors.hh constructors.cc < constructors.def | 	$(perl) ../aterm-helper.pl nixexpr-ast.hh nixexpr-ast.cc < nixexpr-ast.def | ||||||
| 
 | 
 | ||||||
| nixexpr.hh: constructors.hh | nixexpr.hh: nixexpr-ast.hh | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| CLEANFILES = | CLEANFILES = | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| #include "eval.hh" | #include "eval.hh" | ||||||
| #include "parser.hh" | #include "parser.hh" | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| EvalState::EvalState() | EvalState::EvalState() | ||||||
|  | @ -10,7 +10,7 @@ EvalState::EvalState() | ||||||
|      |      | ||||||
|     nrEvaluated = nrCached = 0; |     nrEvaluated = nrCached = 0; | ||||||
| 
 | 
 | ||||||
|     initSyms(); |     initNixExprHelpers(); | ||||||
| 
 | 
 | ||||||
|     addPrimOps(); |     addPrimOps(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | init initNixExprHelpers | ||||||
|  | 
 | ||||||
| Pos | string int int | Pos | | Pos | string int int | Pos | | ||||||
| NoPos | | Pos | | NoPos | | Pos | | ||||||
| 
 | 
 | ||||||
|  | @ -2,8 +2,8 @@ | ||||||
| #include "storeexpr.hh" | #include "storeexpr.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| #include "constructors.cc" | #include "nixexpr-ast.cc" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ATermMap::ATermMap(unsigned int initialSize, unsigned int maxLoadPct) | ATermMap::ATermMap(unsigned int initialSize, unsigned int maxLoadPct) | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "aterm.hh" | #include "aterm.hh" | ||||||
| #include "parser.hh" | #include "parser.hh" | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| struct ParseData  | struct ParseData  | ||||||
|  |  | ||||||
|  | @ -18,7 +18,7 @@ | ||||||
| typedef ATerm Expr; | typedef ATerm Expr; | ||||||
| typedef ATerm Pos; | typedef ATerm Pos; | ||||||
|      |      | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| 
 | 
 | ||||||
| void setParseResult(void * data, ATerm t); | void setParseResult(void * data, ATerm t); | ||||||
| void parseError(void * data, char * error, int line, int column); | void parseError(void * data, char * error, int line, int column); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| #include "normalise.hh" | #include "normalise.hh" | ||||||
| #include "eval.hh" | #include "eval.hh" | ||||||
| #include "globals.hh" | #include "globals.hh" | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Load and evaluate an expression from path specified by the
 | /* Load and evaluate an expression from path specified by the
 | ||||||
|  |  | ||||||
|  | @ -55,6 +55,9 @@ void checkStoreNotSymlink(Path path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | void initStoreExprHelpers(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /* Initialize and reorder arguments, then call the actual argument
 | /* Initialize and reorder arguments, then call the actual argument
 | ||||||
|    processor. */ |    processor. */ | ||||||
| static void initAndRun(int argc, char * * argv) | static void initAndRun(int argc, char * * argv) | ||||||
|  | @ -101,6 +104,9 @@ static void initAndRun(int argc, char * * argv) | ||||||
|     string lt = getEnv("NIX_LOG_TYPE"); |     string lt = getEnv("NIX_LOG_TYPE"); | ||||||
|     if (lt != "") setLogType(lt); |     if (lt != "") setLogType(lt); | ||||||
| 
 | 
 | ||||||
|  |     /* ATerm stuff.  !!! find a better place to put this */ | ||||||
|  |     initStoreExprHelpers(); | ||||||
|  |      | ||||||
|     /* Put the arguments in a vector. */ |     /* Put the arguments in a vector. */ | ||||||
|     Strings args, remaining; |     Strings args, remaining; | ||||||
|     while (argc--) args.push_back(*argv++); |     while (argc--) args.push_back(*argv++); | ||||||
|  |  | ||||||
|  | @ -5,7 +5,14 @@ libstore_a_SOURCES = \ | ||||||
|  normalise.cc misc.cc normalise.hh \ |  normalise.cc misc.cc normalise.hh \ | ||||||
|  globals.cc globals.hh db.cc db.hh \ |  globals.cc globals.hh db.cc db.hh \ | ||||||
|  references.cc references.hh pathlocks.cc pathlocks.hh \ |  references.cc references.hh pathlocks.cc pathlocks.hh \ | ||||||
|  gc.cc gc.hh |  gc.cc gc.hh storeexpr-ast.hh | ||||||
|  | 
 | ||||||
|  | EXTRA_DIST = storeexpr-ast.def storeexpr-ast.cc | ||||||
| 
 | 
 | ||||||
| AM_CXXFLAGS = -Wall \ | AM_CXXFLAGS = -Wall \ | ||||||
|  -I.. ${bdb_include} ${aterm_include} -I../libutil |  -I.. ${bdb_include} ${aterm_include} -I../libutil | ||||||
|  | 
 | ||||||
|  | storeexpr-ast.cc storeexpr-ast.hh: ../aterm-helper.pl storeexpr-ast.def | ||||||
|  | 	$(perl) ../aterm-helper.pl storeexpr-ast.hh storeexpr-ast.cc < storeexpr-ast.def | ||||||
|  | 
 | ||||||
|  | storeexpr.cc: storeexpr-ast.hh | ||||||
							
								
								
									
										7
									
								
								src/libstore/storeexpr-ast.def
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/libstore/storeexpr-ast.def
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | ||||||
|  | init initStoreExprHelpers | ||||||
|  | 
 | ||||||
|  | Closure | ATermList ATermList | ATerm | | ||||||
|  | Derive | ATermList ATermList string string ATermList ATermList | ATerm | | ||||||
|  | 
 | ||||||
|  | | string string | ATerm | EnvBinding | | ||||||
|  | | string ATermList | ATerm | ClosureElem | | ||||||
|  | @ -2,6 +2,9 @@ | ||||||
| #include "globals.hh" | #include "globals.hh" | ||||||
| #include "store.hh" | #include "store.hh" | ||||||
| 
 | 
 | ||||||
|  | #include "storeexpr-ast.hh" | ||||||
|  | #include "storeexpr-ast.cc" | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| Hash hashTerm(ATerm t) | Hash hashTerm(ATerm t) | ||||||
| { | { | ||||||
|  | @ -29,10 +32,11 @@ Path writeTerm(ATerm t, const string & suffix) | ||||||
| 
 | 
 | ||||||
| static void parsePaths(ATermList paths, PathSet & out) | static void parsePaths(ATermList paths, PathSet & out) | ||||||
| { | { | ||||||
|     ATMatcher m; |  | ||||||
|     for (ATermIterator i(paths); i; ++i) { |     for (ATermIterator i(paths); i; ++i) { | ||||||
|         string s; |         if (ATgetType(*i) != AT_APPL) | ||||||
|         if (!(atMatch(m, *i) >> s)) |             throw badTerm("not a path", *i); | ||||||
|  |         string s = aterm2String(*i); | ||||||
|  |         if (s.size() == 0 || s[0] != '/') | ||||||
|             throw badTerm("not a path", *i); |             throw badTerm("not a path", *i); | ||||||
|         out.insert(s); |         out.insert(s); | ||||||
|     } |     } | ||||||
|  | @ -69,21 +73,20 @@ static void checkClosure(const Closure & closure) | ||||||
| static bool parseClosure(ATerm t, Closure & closure) | static bool parseClosure(ATerm t, Closure & closure) | ||||||
| { | { | ||||||
|     ATermList roots, elems; |     ATermList roots, elems; | ||||||
|     ATMatcher m; |  | ||||||
| 
 | 
 | ||||||
|     if (!(atMatch(m, t) >> "Closure" >> roots >> elems)) |     if (!matchClosure(t, roots, elems)) | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     parsePaths(roots, closure.roots); |     parsePaths(roots, closure.roots); | ||||||
| 
 | 
 | ||||||
|     for (ATermIterator i(elems); i; ++i) { |     for (ATermIterator i(elems); i; ++i) { | ||||||
|         string path; |         ATerm path; | ||||||
|         ATermList refs; |         ATermList refs; | ||||||
|         if (!(atMatch(m, *i) >> "" >> path >> refs)) |         if (!matchClosureElem(*i, path, refs)) | ||||||
|             throw badTerm("not a closure element", *i); |             throw badTerm("not a closure element", *i); | ||||||
|         ClosureElem elem; |         ClosureElem elem; | ||||||
|         parsePaths(refs, elem.refs); |         parsePaths(refs, elem.refs); | ||||||
|         closure.elems[path] = elem; |         closure.elems[aterm2String(path)] = elem; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     checkClosure(closure); |     checkClosure(closure); | ||||||
|  | @ -93,32 +96,29 @@ static bool parseClosure(ATerm t, Closure & closure) | ||||||
| 
 | 
 | ||||||
| static bool parseDerivation(ATerm t, Derivation & derivation) | static bool parseDerivation(ATerm t, Derivation & derivation) | ||||||
| { | { | ||||||
|     ATMatcher m; |  | ||||||
|     ATermList outs, ins, args, bnds; |     ATermList outs, ins, args, bnds; | ||||||
|     string builder, platform; |     ATerm builder, platform; | ||||||
| 
 | 
 | ||||||
|     if (!(atMatch(m, t) >> "Derive" >> outs >> ins >> platform |     if (!matchDerive(t, outs, ins, platform, builder, args, bnds)) | ||||||
|             >> builder >> args >> bnds)) |  | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     parsePaths(outs, derivation.outputs); |     parsePaths(outs, derivation.outputs); | ||||||
|     parsePaths(ins, derivation.inputs); |     parsePaths(ins, derivation.inputs); | ||||||
| 
 | 
 | ||||||
|     derivation.builder = builder; |     derivation.builder = aterm2String(builder); | ||||||
|     derivation.platform = platform; |     derivation.platform = aterm2String(platform); | ||||||
|      |      | ||||||
|     for (ATermIterator i(args); i; ++i) { |     for (ATermIterator i(args); i; ++i) { | ||||||
|         string s; |         if (ATgetType(*i) != AT_APPL) | ||||||
|         if (!(atMatch(m, *i) >> s)) |  | ||||||
|             throw badTerm("string expected", *i); |             throw badTerm("string expected", *i); | ||||||
|         derivation.args.push_back(s); |         derivation.args.push_back(aterm2String(*i)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (ATermIterator i(bnds); i; ++i) { |     for (ATermIterator i(bnds); i; ++i) { | ||||||
|         string s1, s2; |         ATerm s1, s2; | ||||||
|         if (!(atMatch(m, *i) >> "" >> s1 >> s2)) |         if (!matchEnvBinding(*i, s1, s2)) | ||||||
|             throw badTerm("tuple of strings expected", *i); |             throw badTerm("tuple of strings expected", *i); | ||||||
|         derivation.env[s1] = s2; |         derivation.env[aterm2String(s1)] = aterm2String(s2); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
|  | @ -142,7 +142,7 @@ static ATermList unparsePaths(const PathSet & paths) | ||||||
|     ATermList l = ATempty; |     ATermList l = ATempty; | ||||||
|     for (PathSet::const_iterator i = paths.begin(); |     for (PathSet::const_iterator i = paths.begin(); | ||||||
|          i != paths.end(); i++) |          i != paths.end(); i++) | ||||||
|         l = ATinsert(l, ATmake("<str>", i->c_str())); |         l = ATinsert(l, string2ATerm(i->c_str())); | ||||||
|     return ATreverse(l); |     return ATreverse(l); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -155,11 +155,11 @@ static ATerm unparseClosure(const Closure & closure) | ||||||
|     for (ClosureElems::const_iterator i = closure.elems.begin(); |     for (ClosureElems::const_iterator i = closure.elems.begin(); | ||||||
|          i != closure.elems.end(); i++) |          i != closure.elems.end(); i++) | ||||||
|         elems = ATinsert(elems, |         elems = ATinsert(elems, | ||||||
|             ATmake("(<str>, <term>)", |             makeClosureElem( | ||||||
|                 i->first.c_str(), |                 string2ATerm(i->first.c_str()), | ||||||
|                 unparsePaths(i->second.refs))); |                 unparsePaths(i->second.refs))); | ||||||
| 
 | 
 | ||||||
|     return ATmake("Closure(<term>, <term>)", roots, elems); |     return makeClosure(roots, elems); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -168,20 +168,21 @@ static ATerm unparseDerivation(const Derivation & derivation) | ||||||
|     ATermList args = ATempty; |     ATermList args = ATempty; | ||||||
|     for (Strings::const_iterator i = derivation.args.begin(); |     for (Strings::const_iterator i = derivation.args.begin(); | ||||||
|          i != derivation.args.end(); i++) |          i != derivation.args.end(); i++) | ||||||
|         args = ATinsert(args, ATmake("<str>", i->c_str())); |         args = ATinsert(args, string2ATerm(i->c_str())); | ||||||
| 
 | 
 | ||||||
|     ATermList env = ATempty; |     ATermList env = ATempty; | ||||||
|     for (StringPairs::const_iterator i = derivation.env.begin(); |     for (StringPairs::const_iterator i = derivation.env.begin(); | ||||||
|          i != derivation.env.end(); i++) |          i != derivation.env.end(); i++) | ||||||
|         env = ATinsert(env, |         env = ATinsert(env, | ||||||
|             ATmake("(<str>, <str>)",  |             makeEnvBinding( | ||||||
|                 i->first.c_str(), i->second.c_str())); |                 string2ATerm(i->first.c_str()), | ||||||
|  |                 string2ATerm(i->second.c_str()))); | ||||||
| 
 | 
 | ||||||
|     return ATmake("Derive(<term>, <term>, <str>, <str>, <term>, <term>)", |     return makeDerive( | ||||||
|         unparsePaths(derivation.outputs), |         unparsePaths(derivation.outputs), | ||||||
|         unparsePaths(derivation.inputs), |         unparsePaths(derivation.inputs), | ||||||
|         derivation.platform.c_str(), |         string2ATerm(derivation.platform.c_str()), | ||||||
|         derivation.builder.c_str(), |         string2ATerm(derivation.builder.c_str()), | ||||||
|         ATreverse(args), |         ATreverse(args), | ||||||
|         ATreverse(env)); |         ATreverse(env)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,10 +4,3 @@ libutil_a_SOURCES = util.cc util.hh hash.cc hash.hh \ | ||||||
|  archive.cc archive.hh md5.c md5.h aterm.cc aterm.hh |  archive.cc archive.hh md5.c md5.h aterm.cc aterm.hh | ||||||
| 
 | 
 | ||||||
| AM_CXXFLAGS = -Wall -I.. ${aterm_include} | AM_CXXFLAGS = -Wall -I.. ${aterm_include} | ||||||
| 
 |  | ||||||
| check_PROGRAMS = test-aterm |  | ||||||
| 
 |  | ||||||
| test_aterm_SOURCES = test-aterm.cc |  | ||||||
| test_aterm_LDADD = ./libutil.a ../boost/format/libformat.a \ |  | ||||||
|  ${aterm_lib} |  | ||||||
| 
 |  | ||||||
|  |  | ||||||
|  | @ -16,95 +16,6 @@ ostream & operator << (ostream & stream, ATerm e) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ATMatcher & atMatch(ATMatcher & pos, ATerm t) |  | ||||||
| { |  | ||||||
|     pos.t = t; |  | ||||||
|     pos.pos = ATMatcher::funPos; |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static inline bool failed(const ATMatcher & pos) |  | ||||||
| { |  | ||||||
|     return pos.pos == ATMatcher::failPos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| static inline ATMatcher & fail(ATMatcher & pos) |  | ||||||
| { |  | ||||||
|     pos.pos = ATMatcher::failPos; |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, ATerm & out) |  | ||||||
| { |  | ||||||
|     out = 0; |  | ||||||
|     if (failed(pos)) return pos; |  | ||||||
|     if (pos.pos == ATMatcher::funPos ||  |  | ||||||
|         ATgetType(pos.t) != AT_APPL || |  | ||||||
|         pos.pos >= (int) ATgetArity(ATgetAFun(pos.t))) |  | ||||||
|         return fail(pos); |  | ||||||
|     out = ATgetArgument(pos.t, pos.pos); |  | ||||||
|     pos.pos++; |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, string & out) |  | ||||||
| { |  | ||||||
|     out = ""; |  | ||||||
|     if (pos.pos == ATMatcher::funPos) { |  | ||||||
|         if (ATgetType(pos.t) != AT_APPL) return fail(pos); |  | ||||||
|         out = ATgetName(ATgetAFun(pos.t)); |  | ||||||
|         pos.pos = 0; |  | ||||||
|     } else { |  | ||||||
|         ATerm t; |  | ||||||
|         pos = pos >> t; |  | ||||||
|         if (failed(pos)) return pos; |  | ||||||
|         if (ATgetType(t) != AT_APPL || |  | ||||||
|             ATgetArity(ATgetAFun(t)) != 0) |  | ||||||
|             return fail(pos); |  | ||||||
|         out = ATgetName(ATgetAFun(t)); |  | ||||||
|     } |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, const string & s) |  | ||||||
| { |  | ||||||
|     string s2; |  | ||||||
|     pos = pos >> s2; |  | ||||||
|     if (failed(pos)) return pos; |  | ||||||
|     if (s != s2) return fail(pos); |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, int & n) |  | ||||||
| { |  | ||||||
|     n = 0; |  | ||||||
|     ATerm t; |  | ||||||
|     pos = pos >> t; |  | ||||||
|     if (failed(pos)) return pos; |  | ||||||
|     if (ATgetType(t) != AT_INT) return fail(pos); |  | ||||||
|     n = ATgetInt((ATermInt) t); |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, ATermList & out) |  | ||||||
| { |  | ||||||
|     out = 0; |  | ||||||
|     ATerm t; |  | ||||||
|     pos = pos >> t; |  | ||||||
|     if (failed(pos)) return pos; |  | ||||||
|     if (ATgetType(t) != AT_LIST) return fail(pos); |  | ||||||
|     out = (ATermList) t; |  | ||||||
|     return pos; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| Error badTerm(const format & f, ATerm t) | Error badTerm(const format & f, ATerm t) | ||||||
| { | { | ||||||
|     char * s = ATwriteToString(t); |     char * s = ATwriteToString(t); | ||||||
|  |  | ||||||
|  | @ -36,48 +36,6 @@ public: | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /* Type-safe matching. */ |  | ||||||
| 
 |  | ||||||
| struct ATMatcher  |  | ||||||
| { |  | ||||||
|     ATerm t; |  | ||||||
|     int pos; |  | ||||||
|     const static int failPos = -2; |  | ||||||
|     const static int funPos = -1; |  | ||||||
| 
 |  | ||||||
|     ATMatcher() : t(0), pos(failPos) |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     operator bool() const |  | ||||||
|     { |  | ||||||
|         return pos != failPos; |  | ||||||
|     } |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /* Initiate matching of a term. */ |  | ||||||
| ATMatcher & atMatch(ATMatcher & pos, ATerm t); |  | ||||||
| 
 |  | ||||||
| /* Get the next argument of an application. */ |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, ATerm & out); |  | ||||||
| 
 |  | ||||||
| /* Get the name of the function symbol of an application, or the next
 |  | ||||||
|    argument of an application as a string. */ |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, string & out); |  | ||||||
| 
 |  | ||||||
| /* Like the previous, but check that the string is equal to the given
 |  | ||||||
|    string. */ |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, const string & s); |  | ||||||
| 
 |  | ||||||
| /* Get the next argument of an application, and verify that it is a
 |  | ||||||
|    integer. */ |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, int & n); |  | ||||||
| 
 |  | ||||||
| /* Get the next argument of an application, and verify that it is a
 |  | ||||||
|    list. */ |  | ||||||
| ATMatcher & operator >> (ATMatcher & pos, ATermList & out); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /* Throw an exception with an error message containing the given
 | /* Throw an exception with an error message containing the given
 | ||||||
|    aterm. */ |    aterm. */ | ||||||
| Error badTerm(const format & f, ATerm t); | Error badTerm(const format & f, ATerm t); | ||||||
|  |  | ||||||
|  | @ -1,66 +0,0 @@ | ||||||
| #include "aterm.hh" |  | ||||||
| #include <iostream> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void runTests() |  | ||||||
| { |  | ||||||
|     verbosity = lvlDebug; |  | ||||||
| 
 |  | ||||||
|     ATMatcher pos; |  | ||||||
| 
 |  | ||||||
|     ATerm t = ATmake("Call(Foo, Bar, \"xyz\")"); |  | ||||||
|      |  | ||||||
|     debug(format("term: %1%") % t); |  | ||||||
| 
 |  | ||||||
|     string fun, arg3; |  | ||||||
|     ATerm lhs, rhs; |  | ||||||
| 
 |  | ||||||
|     if (!(atMatch(pos, t) >> "Call" >> lhs >> rhs >> arg3)) |  | ||||||
|         throw Error("should succeed"); |  | ||||||
|     if (arg3 != "xyz") throw Error("bad 1"); |  | ||||||
| 
 |  | ||||||
|     if (!(atMatch(pos, t) >> fun >> lhs >> rhs >> arg3)) |  | ||||||
|         throw Error("should succeed"); |  | ||||||
|     if (fun != "Call") throw Error("bad 2"); |  | ||||||
|     if (arg3 != "xyz") throw Error("bad 3"); |  | ||||||
| 
 |  | ||||||
|     if (!(atMatch(pos, t) >> fun >> lhs >> rhs >> "xyz")) |  | ||||||
|         throw Error("should succeed"); |  | ||||||
| 
 |  | ||||||
|     if (atMatch(pos, t) >> fun >> lhs >> rhs >> "abc") |  | ||||||
|         throw Error("should fail"); |  | ||||||
| 
 |  | ||||||
|     if (atMatch(pos, t) >> "Call" >> lhs >> rhs >> "abc") |  | ||||||
|         throw Error("should fail"); |  | ||||||
| 
 |  | ||||||
|     t = ATmake("X([A, B, C], \"abc\")"); |  | ||||||
| 
 |  | ||||||
|     ATerm t1, t2, t3; |  | ||||||
|     if (atMatch(pos, t) >> "X" >> t1 >> t2 >> t3) |  | ||||||
|         throw Error("should fail"); |  | ||||||
|     if (!(atMatch(pos, t) >> "X" >> t1 >> t2)) |  | ||||||
|         throw Error("should succeed"); |  | ||||||
|     ATermList ts; |  | ||||||
|     if (!(atMatch(pos, t) >> "X" >> ts >> t2)) |  | ||||||
|         throw Error("should succeed"); |  | ||||||
|     if (ATgetLength(ts) != 3) |  | ||||||
|         throw Error("bad"); |  | ||||||
|     if (atMatch(pos, t) >> "X" >> t1 >> ts) |  | ||||||
|         throw Error("should fail"); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| int main(int argc, char * * argv) |  | ||||||
| { |  | ||||||
|     ATerm bottomOfStack; |  | ||||||
|     ATinit(argc, argv, &bottomOfStack); |  | ||||||
| 
 |  | ||||||
|     try { |  | ||||||
|         runTests(); |  | ||||||
|     } catch (Error & e) { |  | ||||||
|         printMsg(lvlError, format("error: %1%") % e.msg()); |  | ||||||
|         return 1; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| #include "parser.hh" | #include "parser.hh" | ||||||
| #include "eval.hh" | #include "eval.hh" | ||||||
| #include "help.txt.hh" | #include "help.txt.hh" | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| 
 | 
 | ||||||
| #include <cerrno> | #include <cerrno> | ||||||
| #include <ctime> | #include <ctime> | ||||||
|  | @ -481,20 +481,22 @@ typedef list<Strings> Table; | ||||||
| 
 | 
 | ||||||
| void printTable(Table & table) | void printTable(Table & table) | ||||||
| { | { | ||||||
|     int nrColumns = table.size() > 0 ? table.front().size() : 0; |     unsigned int nrColumns = table.size() > 0 ? table.front().size() : 0; | ||||||
|      |      | ||||||
|     vector<int> widths; |     vector<unsigned int> widths; | ||||||
|     widths.resize(nrColumns); |     widths.resize(nrColumns); | ||||||
|      |      | ||||||
|     for (Table::iterator i = table.begin(); i != table.end(); ++i) { |     for (Table::iterator i = table.begin(); i != table.end(); ++i) { | ||||||
|         assert(i->size() == nrColumns); |         assert(i->size() == nrColumns); | ||||||
|         Strings::iterator j; int column; |         Strings::iterator j; | ||||||
|  |         unsigned int column; | ||||||
|         for (j = i->begin(), column = 0; j != i->end(); ++j, ++column) |         for (j = i->begin(), column = 0; j != i->end(); ++j, ++column) | ||||||
|             if (j->size() > widths[column]) widths[column] = j->size(); |             if (j->size() > widths[column]) widths[column] = j->size(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (Table::iterator i = table.begin(); i != table.end(); ++i) {  |     for (Table::iterator i = table.begin(); i != table.end(); ++i) {  | ||||||
|         Strings::iterator j; int column; |         Strings::iterator j; | ||||||
|  |         unsigned int column; | ||||||
|         for (j = i->begin(), column = 0; j != i->end(); ++j, ++column) |         for (j = i->begin(), column = 0; j != i->end(); ++j, ++column) | ||||||
|         { |         { | ||||||
|             cout << *j; |             cout << *j; | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| #include "shared.hh" | #include "shared.hh" | ||||||
| #include "eval.hh" | #include "eval.hh" | ||||||
| #include "parser.hh" | #include "parser.hh" | ||||||
| #include "constructors.hh" | #include "nixexpr-ast.hh" | ||||||
| #include "help.txt.hh" | #include "help.txt.hh" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -28,7 +28,6 @@ static Expr evalStdin(EvalState & state, bool parseOnly) | ||||||
| 
 | 
 | ||||||
| static void printDrvPaths(EvalState & state, Expr e) | static void printDrvPaths(EvalState & state, Expr e) | ||||||
| { | { | ||||||
|     ATMatcher m; |  | ||||||
|     ATermList es; |     ATermList es; | ||||||
| 
 | 
 | ||||||
|     /* !!! duplication w.r.t. parseDerivations in nix-env */ |     /* !!! duplication w.r.t. parseDerivations in nix-env */ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue