From 576c43330c0f5f90c8d895699d809d680ef5778e Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 16 Nov 2013 00:55:41 +0100 Subject: [PATCH 001/101] First cut at PHP bindings; no tests yet. --- src/bindings/php/hammer.xml | 604 ++++++++++++++++++++++++++++++++++++ 1 file changed, 604 insertions(+) create mode 100644 src/bindings/php/hammer.xml diff --git a/src/bindings/php/hammer.xml b/src/bindings/php/hammer.xml new file mode 100644 index 0000000..2172292 --- /dev/null +++ b/src/bindings/php/hammer.xml @@ -0,0 +1,604 @@ + + + + A library for defining parsers (character- or binary-oriented) inline. + ... + + + + mlp + Meredith L. Patterson + mlp@upstandinghackers.com + lead + + + + LGPL + + + 0.1 + 2013-11-15 + alpha + First cut of extension. + + + + Hammer C library +
+
+
+ + + + + + + + + void free() + Deallocate a parse result + + Free the memory allocated to a parse result when the result is no longer needed. + + + + + + + + + void report() + Output benchmarking results in a human-readable format + + + + + + + + + + HParseResult parse(string input) + Parse an input + Top-level function to call a parser that has been built over some piece of input. + + + + + int compile(string backend, array params) + Generate parse tables for the given parsing backend + + Some of the parsing backends must transform a parser into a set of parse tables before they can be used. See the documentation for the parser backend in question for information about the [params] parameter, or pass in NULL for the defaults. + + Returns -1 if the grammar cannot be compiled with the specified options; 0 otherwise. + + + + + + object benchmark(array testcases) + Benchmark this parser using all the applicable parsing backends against a set of test cases you provide + + + + + + + + + HParseResult hammer_token(string token) + Parse a token (primitive) + + Given a string, returns a parser that parses that string value. + + Result token type: string + + + + + + + HParseResult hammer_ch(string ch) + Parse a character (primitive) + + Given a single character, returns a parser that parses that character. + + Result token type: string + + + + + + + HParseResult hammer_ch_range(string lower, string upper) + Parse a character within the given range (primitive) + + Given two single-character bounds, lower and upper, returns a parser that parses a single character within the range [lower, upper] (inclusive). + + Result token type: string + + + + + + + HParseResult hammer_int_range(HParser p, int lower, int upper) + Parse an integer within the given range (primitive) + + Given an integer parser, p, and two integer bounds, lower and upper, returns a parser that parses an integral value within the range [lower, upper] (inclusive). + + Result token type: int + + + + + + + HParseResult hammer_bits(int len, bool sign) + Parse a specified number of bits (primitive) + + Returns a parser that parses the specified number of bits. sign == true if signed, false if unsigned. + + Result token type: int + + + + + + + HParseResult hammer_int64() + Parse a 64-bit signed integer (primitive) + + Returns a parser that parses a signed 8-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_int32() + Parse a 32-bit signed integer (primitive) + + Returns a parser that parses a signed 4-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_int16() + Parse a 16-bit signed integer (primitive) + + Returns a parser that parses a signed 2-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_int8() + Parse an 8-bit signed integer (primitive) + + Returns a parser that parses a signed 1-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_uint64() + Parse a 64-bit unsigned integer (primitive) + + Returns a parser that parses an unsigned 8-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_uint32() + Parse a 32-bit unsigned integer (primitive) + + Returns a parser that parses an unsigned 4-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_uint16() + Parse a 16-bit unsigned integer (primitive) + + Returns a parser that parses an unsigned 2-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_uint8() + Parse an 8-bit unsigned integer (primitive) + + Returns a parser that parses an unsigned 1-byte integer value. + + Result token type: int + + + + + + + HParseResult hammer_whitespace(HParser p) + Parse something preceded by whitespace (higher-order) + + Given a parser, p, returns a parser that skips any whitespace and then applies p. + + Result token type: p's result type + + + + + + + HParseResult hammer_left(HParser p, HParser q) + Take the leftmost result of two parsers (higher-order) + + Given two parsers, p and q, returns a parser that parses them in sequence but only returns p's result. + + Result token type: p's result type + + + + + + + HParseResult hammer_right(HParser p, HParser q) + Take the rightmost result of two parsers (higher-order) + + Given two parsers, p and q, returns a parser that parses them in sequence but only returns q's result. + + Result token type: q's result type + + + + + + + HParseResult hammer_middle(HParser p, HParser x, HParser q) + Take the middle result of three parsers (higher-order) + + Given three parsers, p, x, and q, returns a parser that parses them in sequence but only returns x's result. + + Result token type: x's result type + + + + + + + HParseResult hammer_action(HParser p, callable f) + Attach a semantic action to a parser (higher-order) + + Given another parser, p, and a function, f, returns a parser that applies p, then applies f to everything in the AST of p's result. + + Result token type: any + + + + + + + HParseResult hammer_in(string charset) + Parse a character that appears in charset (primitive) + + Parse a single character in the given charset. + + Result token type: string + + + + + + + HParseResult hammer_not_in(string charset) + Parse a character that does not appear in charset (primitive) + + Parse a single character *not* in the given charset. + + Result token type: string + + + + + + + HParseResult hammer_end_p() + Recognize the end-of-input (primitive) + + A no-argument parser that succeeds if there is no more input to parse. + + Result token type: none. + + + + + + + HParseResult hammer_nothing_p() + This parser always fails (primitive) + + hammer_nothing_p is primarily useful when stubbing out a larger parser. If you define a rule as hammer_nothing_p(), the top-level parser will run, but if a rule containing hammer_nothing_p is invoked, the parse will fail. + + Result token type: there is no result token for this parser. + + + + + + + HParseResult hammer_sequence(array p_array) + Apply a list of parsers sequentially (higher-order) + + Given an array of parsers, p_array, apply each parser in order. The parse succeeds only if all parsers succeed. + + Result token type: array + + + + + + + HParseResult hammer_choice(array p_array) + Apply any one of a list of parsers (higher-order) + + Given an array of parsers, p_array, apply each parser in order. The first parser to succeed produces the result; if no parsers succeed, the parse fails. + + Result token type: the type of the first successful parser's result + + + + + + + HParseResult hammer_butnot(HParser p1, HParser p2) + Parse p1 but not p2 (higher-order) + + Given two parsers, p1 and p2, this parser succeeds in the following cases: + + * if p1 succeeds and p2 fails (starting from the same place in the input stream) + * if both succeed but p1's result is as long as or longer than p2's + + Result token type: p1's result type. + + + + + + + HParseResult hammer_difference(HParser p1, HParser p2) + Parse p1 but not p2 (higher-order) + + Given two parsers, p1 and p2, this parser succeeds in the following cases: + + * if p1 succeeds and p2 fails (starting from the same place in the input stream) + * if both succeed but p2's result is *strictly* shorter than p1's + + Result token type: p1's result type. + + + + + + + HParseResult hammer_xor(HParser p1, HParser p2) + Parse p1 or p2 but not both (higher-order) + + Given two parsers, p1 and p2, this parser suceeds if *either* p1 or p2 succeed, but not if they both do. + + Result token type: the result type of whichever parser succeeded + + + + + + + HParseResult hammer_many(HParser p) + Parse zero or more instances of p (higher-order) + + Given a parser, p, this parser succeeds for zero or more repetitions of p. + + Result token type: array + + + + + + + HParseResult hammer_many1(HParser p) + Parse one or more instances of p (higher-order) + + Given a parser, p, this parser succeeds for one or more repetitions of p. + + Result token type: array + + + + + + + HParseResult hammer_repeat_n(HParser p, int n) + Parse exactly n instances of p (higher-order) + + Given a parser, p, this parser succeeds for exactly N repetitions of p. + + Result token type: array + + + + + + + HParseResult hammer_optional(HParser p) + Mark a parser as optional, like ? in regular expressions (higher-order) + + Given a parser, p, this parser succeeds with the value p parsed or with an empty result. + + Result token type: If p succeeded, the type of its result; if not, nothing. + + + + + + + HParseResult hammer_ignore(HParser p) + Apply p but leave its result out of the final AST (higher-order) + + Given a parser, p, this parser succeeds if p succeeds, but doesn't include p's result in the final result. + + Result token type: none. + + + + + + + HParseResult hammer_sepBy(HParser p, HParser sep) + Parse a (possibly empty) sequence of values separated by a separator (higher-order) + + Given a parser, p, and a parser for a separator, sep, this parser matches a (possibly empty) list of things that p can parse, separated by sep. For example, if p is hammer_many1(hammer_ch_range('0', '9')) and sep is hammer_ch(','), hammer_sepBy(p, sep) will match a comma-separated list of integers. + + Result token type: array + + + + + + + HParseResult hammer_sepBy1(HParser p, HParser sep) + Parse a sequence of values separated by a separator (higher-order) + + Given a parser, p, and a parser for a separator, sep, this parser matches a list of things that p can parse, separated by sep. Unlike hammer_sepBy, this ensures that the result has at least one element. For example, if p is hammer_many(hammer_ch_range('0', '9')), hammer_sepBy1(p, sep) will match a comma-separated list of integers. + + Result token type: array + + + + + + + HParseResult hammer_epsilon_p() + Parse the empty string (primitive) + + This parser always returns a zero-length match, i.e., the empty string. + + Result token type: none + + + + + + + HParseResult hammer_length_value(HParser length, HParser value) + Parse (length) repetitions of (value) (higher-order) + + This parser applies its first argument to read an unsigned integer value, then applies its second argument that many times. length should produce an integer value; this is checked at runtime. Specifically, length's token type must be int. + + Result token type: array + + + + + + + HParseResult hammer_attr_bool(HParser p, callable pred) + Ensure that some property holds for the AST (higher-order) + + This parser attaches a predicate function, which returns true or false, to a parser. The function is evaluated over the parser's result. The parse only succeeds if pred returns true. + + hammer_attr_bool will check whether p's result exists and whether p's result AST exists; you do not need to check for this in your predicate function. + + Result token type: p's result type if pred succeeds, otherwise the parse fails. + + + + + + + HParseResult hammer_and(HParser p) + Verify that p succeeds, but don't actually apply it (higher-order) + + This parser asserts that a conditional syntax is satisfied, but doesn't consume that conditional syntax. This is useful for lookahead. As an example: + + Suppose you already have a parser, hex_p, that parses numbers in hexadecimal format (including the leading "0x"). Then + + hammer_sequence(hammer_and(hammer_token("0x")), hex_p) + + checks to see whether there is a leading "0x", does not consume the "0x", then applies hex_p to parse the hexadecimal number. + + This parser succeeds if p succeeds, and fails if p fails. + + Result token type: none + + + + + + + HParseResult hammer_not(HParser p) + Verify that p does not succeed, and don't consume any input (higher-order) + + This parser asserts that a conditional syntax is *not* satisfied, and doesn't consume the additional syntax. As a somewhat contrived example: + + Since hammer_choice applies its arguments in order, the following parser: + + hammer_sequence(hammer_ch('a'), hammer_choice(hammer_ch('+'), hammer_token('++')), hammer_ch('b')) + + will not parse "a++b", because once hammer_choice has succeeded, it will not backtrack and try other alternatives if a later parser in the sequence fails. Instead, you can force the use of the second alternative by turning the hammer_ch('+') alternative into a sequence with hammer_not: + + hammer_sequence(hammer_ch('a'), hammer_choice(hammer_sequence(hammer_ch('+'), hammer_not('+')), hammer_token('++')), hammer_ch('b')) + + If the input string is "a+b", the first alternative is applied; if the input string is "a++b", the second alternative is applied. + + Result token type: none + + + + + + + HParseResult hammer_indirect() + Forward-declare a parser to be used recursively (higher-order) + + Create a parser that calls out to another, as yet unknown, parser. Note that the inner parser must be bound later, using hammer_bind_indirect(). This can be used to create recursive parsers. + + Result token type: the type of whatever parser is bound to it with hammer_bind_indirect(). + + + + + + + void hammer_bind_indirect(HParser p) + Set the inner parser of an indirect parser. + + See hammer_indirect() for details. + + + + + + From fc4d4337e2266edafbe23ec8c467d145ab640563 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 16 Nov 2013 02:49:28 +0100 Subject: [PATCH 002/101] pecl-gen succeeds --- src/bindings/php/hammer.xml | 88 ++++++++++++++++++------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/bindings/php/hammer.xml b/src/bindings/php/hammer.xml index 2172292..9f72737 100644 --- a/src/bindings/php/hammer.xml +++ b/src/bindings/php/hammer.xml @@ -58,12 +58,12 @@ - HParseResult parse(string input) + object HParseResult parse(string str) Parse an input Top-level function to call a parser that has been built over some piece of input. - + --> int compile(string backend, array params) Generate parse tables for the given parsing backend @@ -76,7 +76,7 @@ - object benchmark(array testcases) + object HBenchmarkResults benchmark(array testcases) Benchmark this parser using all the applicable parsing backends against a set of test cases you provide @@ -86,7 +86,7 @@ - HParseResult hammer_token(string token) + object HParser hammer_token(string token) Parse a token (primitive) Given a string, returns a parser that parses that string value. @@ -98,7 +98,7 @@ - HParseResult hammer_ch(string ch) + object HParser hammer_ch(string ch) Parse a character (primitive) Given a single character, returns a parser that parses that character. @@ -110,7 +110,7 @@ - HParseResult hammer_ch_range(string lower, string upper) + object HParser hammer_ch_range(string lower, string upper) Parse a character within the given range (primitive) Given two single-character bounds, lower and upper, returns a parser that parses a single character within the range [lower, upper] (inclusive). @@ -122,7 +122,7 @@ - HParseResult hammer_int_range(HParser p, int lower, int upper) + object HParser hammer_int_range(object HParser p, int lower, int upper) Parse an integer within the given range (primitive) Given an integer parser, p, and two integer bounds, lower and upper, returns a parser that parses an integral value within the range [lower, upper] (inclusive). @@ -134,7 +134,7 @@ - HParseResult hammer_bits(int len, bool sign) + object HParser hammer_bits(int len, bool sign) Parse a specified number of bits (primitive) Returns a parser that parses the specified number of bits. sign == true if signed, false if unsigned. @@ -146,7 +146,7 @@ - HParseResult hammer_int64() + object HParser hammer_int64() Parse a 64-bit signed integer (primitive) Returns a parser that parses a signed 8-byte integer value. @@ -158,7 +158,7 @@ - HParseResult hammer_int32() + object HParser hammer_int32() Parse a 32-bit signed integer (primitive) Returns a parser that parses a signed 4-byte integer value. @@ -170,7 +170,7 @@ - HParseResult hammer_int16() + object HParser hammer_int16() Parse a 16-bit signed integer (primitive) Returns a parser that parses a signed 2-byte integer value. @@ -182,7 +182,7 @@ - HParseResult hammer_int8() + object HParser hammer_int8() Parse an 8-bit signed integer (primitive) Returns a parser that parses a signed 1-byte integer value. @@ -194,7 +194,7 @@ - HParseResult hammer_uint64() + object HParser hammer_uint64() Parse a 64-bit unsigned integer (primitive) Returns a parser that parses an unsigned 8-byte integer value. @@ -206,7 +206,7 @@ - HParseResult hammer_uint32() + object HParser hammer_uint32() Parse a 32-bit unsigned integer (primitive) Returns a parser that parses an unsigned 4-byte integer value. @@ -218,7 +218,7 @@ - HParseResult hammer_uint16() + object HParser hammer_uint16() Parse a 16-bit unsigned integer (primitive) Returns a parser that parses an unsigned 2-byte integer value. @@ -230,7 +230,7 @@ - HParseResult hammer_uint8() + object HParser hammer_uint8() Parse an 8-bit unsigned integer (primitive) Returns a parser that parses an unsigned 1-byte integer value. @@ -242,7 +242,7 @@ - HParseResult hammer_whitespace(HParser p) + object HParser hammer_whitespace(object HParser p) Parse something preceded by whitespace (higher-order) Given a parser, p, returns a parser that skips any whitespace and then applies p. @@ -254,7 +254,7 @@ - HParseResult hammer_left(HParser p, HParser q) + object HParser hammer_left(object HParser p, object HParser q) Take the leftmost result of two parsers (higher-order) Given two parsers, p and q, returns a parser that parses them in sequence but only returns p's result. @@ -266,7 +266,7 @@ - HParseResult hammer_right(HParser p, HParser q) + object HParser hammer_right(object HParser p, object HParser q) Take the rightmost result of two parsers (higher-order) Given two parsers, p and q, returns a parser that parses them in sequence but only returns q's result. @@ -278,7 +278,7 @@ - HParseResult hammer_middle(HParser p, HParser x, HParser q) + object HParser hammer_middle(object HParser p, object HParser x, object HParser q) Take the middle result of three parsers (higher-order) Given three parsers, p, x, and q, returns a parser that parses them in sequence but only returns x's result. @@ -290,7 +290,7 @@ - HParseResult hammer_action(HParser p, callable f) + object HParser hammer_action(object HParser p, callback f) Attach a semantic action to a parser (higher-order) Given another parser, p, and a function, f, returns a parser that applies p, then applies f to everything in the AST of p's result. @@ -302,7 +302,7 @@ - HParseResult hammer_in(string charset) + object HParser hammer_in(string charset) Parse a character that appears in charset (primitive) Parse a single character in the given charset. @@ -314,7 +314,7 @@ - HParseResult hammer_not_in(string charset) + object HParser hammer_not_in(string charset) Parse a character that does not appear in charset (primitive) Parse a single character *not* in the given charset. @@ -326,7 +326,7 @@ - HParseResult hammer_end_p() + object HParser hammer_end_p() Recognize the end-of-input (primitive) A no-argument parser that succeeds if there is no more input to parse. @@ -338,7 +338,7 @@ - HParseResult hammer_nothing_p() + object HParser hammer_nothing_p() This parser always fails (primitive) hammer_nothing_p is primarily useful when stubbing out a larger parser. If you define a rule as hammer_nothing_p(), the top-level parser will run, but if a rule containing hammer_nothing_p is invoked, the parse will fail. @@ -350,7 +350,7 @@ - HParseResult hammer_sequence(array p_array) + object HParser hammer_sequence(array p_array) Apply a list of parsers sequentially (higher-order) Given an array of parsers, p_array, apply each parser in order. The parse succeeds only if all parsers succeed. @@ -362,7 +362,7 @@ - HParseResult hammer_choice(array p_array) + object HParser hammer_choice(array p_array) Apply any one of a list of parsers (higher-order) Given an array of parsers, p_array, apply each parser in order. The first parser to succeed produces the result; if no parsers succeed, the parse fails. @@ -374,7 +374,7 @@ - HParseResult hammer_butnot(HParser p1, HParser p2) + object HParser hammer_butnot(object HParser p1, object HParser p2) Parse p1 but not p2 (higher-order) Given two parsers, p1 and p2, this parser succeeds in the following cases: @@ -389,7 +389,7 @@ - HParseResult hammer_difference(HParser p1, HParser p2) + object HParser hammer_difference(object HParser p1, object HParser p2) Parse p1 but not p2 (higher-order) Given two parsers, p1 and p2, this parser succeeds in the following cases: @@ -404,7 +404,7 @@ - HParseResult hammer_xor(HParser p1, HParser p2) + object HParser hammer_xor(object HParser p1, object HParser p2) Parse p1 or p2 but not both (higher-order) Given two parsers, p1 and p2, this parser suceeds if *either* p1 or p2 succeed, but not if they both do. @@ -416,7 +416,7 @@ - HParseResult hammer_many(HParser p) + object HParser hammer_many(object HParser p) Parse zero or more instances of p (higher-order) Given a parser, p, this parser succeeds for zero or more repetitions of p. @@ -428,7 +428,7 @@ - HParseResult hammer_many1(HParser p) + object HParser hammer_many1(object HParser p) Parse one or more instances of p (higher-order) Given a parser, p, this parser succeeds for one or more repetitions of p. @@ -440,7 +440,7 @@ - HParseResult hammer_repeat_n(HParser p, int n) + object HParser hammer_repeat_n(object HParser p, int n) Parse exactly n instances of p (higher-order) Given a parser, p, this parser succeeds for exactly N repetitions of p. @@ -452,7 +452,7 @@ - HParseResult hammer_optional(HParser p) + object HParser hammer_optional(object HParser p) Mark a parser as optional, like ? in regular expressions (higher-order) Given a parser, p, this parser succeeds with the value p parsed or with an empty result. @@ -464,7 +464,7 @@ - HParseResult hammer_ignore(HParser p) + object HParser hammer_ignore(object HParser p) Apply p but leave its result out of the final AST (higher-order) Given a parser, p, this parser succeeds if p succeeds, but doesn't include p's result in the final result. @@ -476,7 +476,7 @@ - HParseResult hammer_sepBy(HParser p, HParser sep) + object HParser hammer_sepBy(object HParser p, object HParser sep) Parse a (possibly empty) sequence of values separated by a separator (higher-order) Given a parser, p, and a parser for a separator, sep, this parser matches a (possibly empty) list of things that p can parse, separated by sep. For example, if p is hammer_many1(hammer_ch_range('0', '9')) and sep is hammer_ch(','), hammer_sepBy(p, sep) will match a comma-separated list of integers. @@ -488,7 +488,7 @@ - HParseResult hammer_sepBy1(HParser p, HParser sep) + object HParser hammer_sepBy1(object HParser p, object HParser sep) Parse a sequence of values separated by a separator (higher-order) Given a parser, p, and a parser for a separator, sep, this parser matches a list of things that p can parse, separated by sep. Unlike hammer_sepBy, this ensures that the result has at least one element. For example, if p is hammer_many(hammer_ch_range('0', '9')), hammer_sepBy1(p, sep) will match a comma-separated list of integers. @@ -500,7 +500,7 @@ - HParseResult hammer_epsilon_p() + object HParser hammer_epsilon_p() Parse the empty string (primitive) This parser always returns a zero-length match, i.e., the empty string. @@ -512,7 +512,7 @@ - HParseResult hammer_length_value(HParser length, HParser value) + object HParser hammer_length_value(object HParser length, object HParser value) Parse (length) repetitions of (value) (higher-order) This parser applies its first argument to read an unsigned integer value, then applies its second argument that many times. length should produce an integer value; this is checked at runtime. Specifically, length's token type must be int. @@ -524,7 +524,7 @@ - HParseResult hammer_attr_bool(HParser p, callable pred) + object HParser hammer_attr_bool(object HParser p, callback pred) Ensure that some property holds for the AST (higher-order) This parser attaches a predicate function, which returns true or false, to a parser. The function is evaluated over the parser's result. The parse only succeeds if pred returns true. @@ -538,7 +538,7 @@ - HParseResult hammer_and(HParser p) + object HParser hammer_and(object HParser p) Verify that p succeeds, but don't actually apply it (higher-order) This parser asserts that a conditional syntax is satisfied, but doesn't consume that conditional syntax. This is useful for lookahead. As an example: @@ -558,7 +558,7 @@ - HParseResult hammer_not(HParser p) + object HParser hammer_not(object HParser p) Verify that p does not succeed, and don't consume any input (higher-order) This parser asserts that a conditional syntax is *not* satisfied, and doesn't consume the additional syntax. As a somewhat contrived example: @@ -580,7 +580,7 @@ - HParseResult hammer_indirect() + object HParser hammer_indirect() Forward-declare a parser to be used recursively (higher-order) Create a parser that calls out to another, as yet unknown, parser. Note that the inner parser must be bound later, using hammer_bind_indirect(). This can be used to create recursive parsers. @@ -592,7 +592,7 @@ - void hammer_bind_indirect(HParser p) + void hammer_bind_indirect(object HParser p) Set the inner parser of an indirect parser. See hammer_indirect() for details. From 9c0b1c4bdb736ef6cc04e88cb4543a88188c2ab4 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 16 Nov 2013 03:54:00 +0100 Subject: [PATCH 003/101] ./configure succeeds, but make fails; I think CodeGen_PECL is too old or something --- src/bindings/php/hammer.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bindings/php/hammer.xml b/src/bindings/php/hammer.xml index 9f72737..484fcbd 100644 --- a/src/bindings/php/hammer.xml +++ b/src/bindings/php/hammer.xml @@ -24,9 +24,9 @@ Hammer C library -
-
-
+
+
+
From 6daa5367ca727a5c4a34e6a92d37461427c1a9cb Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 16 Nov 2013 05:50:21 +0100 Subject: [PATCH 004/101] removed elements in attempt to fix codegen_pecl output; didn't work --- src/bindings/php/hammer.xml | 90 ------------------------------------- 1 file changed, 90 deletions(-) diff --git a/src/bindings/php/hammer.xml b/src/bindings/php/hammer.xml index 484fcbd..4510e63 100644 --- a/src/bindings/php/hammer.xml +++ b/src/bindings/php/hammer.xml @@ -40,8 +40,6 @@ Free the memory allocated to a parse result when the result is no longer needed. - - @@ -51,8 +49,6 @@ Output benchmarking results in a human-readable format - - @@ -61,8 +57,6 @@ object HParseResult parse(string str) Parse an input Top-level function to call a parser that has been built over some piece of input. - - --> int compile(string backend, array params) @@ -72,16 +66,12 @@ Returns -1 if the grammar cannot be compiled with the specified options; 0 otherwise. - - object HBenchmarkResults benchmark(array testcases) Benchmark this parser using all the applicable parsing backends against a set of test cases you provide - - @@ -105,8 +95,6 @@ Result token type: string - - @@ -117,8 +105,6 @@ Result token type: string - - @@ -129,8 +115,6 @@ Result token type: int - - @@ -141,8 +125,6 @@ Result token type: int - - @@ -153,8 +135,6 @@ Result token type: int - - @@ -165,8 +145,6 @@ Result token type: int - - @@ -177,8 +155,6 @@ Result token type: int - - @@ -189,8 +165,6 @@ Result token type: int - - @@ -201,8 +175,6 @@ Result token type: int - - @@ -213,8 +185,6 @@ Result token type: int - - @@ -225,8 +195,6 @@ Result token type: int - - @@ -237,8 +205,6 @@ Result token type: int - - @@ -249,8 +215,6 @@ Result token type: p's result type - - @@ -261,8 +225,6 @@ Result token type: p's result type - - @@ -273,8 +235,6 @@ Result token type: q's result type - - @@ -285,8 +245,6 @@ Result token type: x's result type - - @@ -297,8 +255,6 @@ Result token type: any - - @@ -309,8 +265,6 @@ Result token type: string - - @@ -321,8 +275,6 @@ Result token type: string - - @@ -333,8 +285,6 @@ Result token type: none. - - @@ -345,8 +295,6 @@ Result token type: there is no result token for this parser. - - @@ -357,8 +305,6 @@ Result token type: array - - @@ -369,8 +315,6 @@ Result token type: the type of the first successful parser's result - - @@ -384,8 +328,6 @@ Result token type: p1's result type. - - @@ -399,8 +341,6 @@ Result token type: p1's result type. - - @@ -411,8 +351,6 @@ Result token type: the result type of whichever parser succeeded - - @@ -423,8 +361,6 @@ Result token type: array - - @@ -435,8 +371,6 @@ Result token type: array - - @@ -447,8 +381,6 @@ Result token type: array - - @@ -459,8 +391,6 @@ Result token type: If p succeeded, the type of its result; if not, nothing. - - @@ -471,8 +401,6 @@ Result token type: none. - - @@ -483,8 +411,6 @@ Result token type: array - - @@ -495,8 +421,6 @@ Result token type: array - - @@ -507,8 +431,6 @@ Result token type: none - - @@ -519,8 +441,6 @@ Result token type: array - - @@ -533,8 +453,6 @@ Result token type: p's result type if pred succeeds, otherwise the parse fails. - - @@ -553,8 +471,6 @@ Result token type: none - - @@ -575,8 +491,6 @@ Result token type: none - - @@ -587,8 +501,6 @@ Result token type: the type of whatever parser is bound to it with hammer_bind_indirect(). - - @@ -597,8 +509,6 @@ See hammer_indirect() for details. - - From 94d855c5160d021cafd480b098e3d1a527c23667 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 17:57:43 -0600 Subject: [PATCH 005/101] scons builds the SWIG PHP bindings that can create parsers but not parse any input yet --- src/bindings/php/SConscript | 12 ++++++++++++ src/bindings/swig/hammer.i | 3 +++ 2 files changed, 15 insertions(+) create mode 100644 src/bindings/php/SConscript diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript new file mode 100644 index 0000000..9962264 --- /dev/null +++ b/src/bindings/php/SConscript @@ -0,0 +1,12 @@ +# -*- python -*- +Import('env') + +phpenv = env.Clone() + +phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) +phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers']) +phpenv.Append(SWIGFLAGS = '-DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ -php') + +swig = ['../swig/hammer.i'] + +libhammer_php = phpenv.SharedLibrary('hammer', swig) \ No newline at end of file diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 13c30a4..971b37f 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -131,6 +131,7 @@ #warning no uint8_t* typemaps defined #endif +//%include "typemaps.i" // All the include paths are relative to the build, i.e., ../../. If you need to build these manually (i.e., not with scons), keep that in mind. %{ #include "allocator.h" @@ -344,3 +345,5 @@ def int64(): return _h_int64() %} #endif +//%apply const char* { const uint8_t* } + From 517cba9a769c719fcb066b37b3abc7e21805978d Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 19:49:38 -0600 Subject: [PATCH 006/101] scons now puts php binding support files in the correct place --- src/bindings/php/SConscript | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 9962264..6694602 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -5,8 +5,10 @@ phpenv = env.Clone() phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers']) -phpenv.Append(SWIGFLAGS = '-DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ -php') +phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php', '-outdir', 'build/$VARIANT/src/bindings/php/']) -swig = ['../swig/hammer.i'] +phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) + +swig = ['hammer.i'] libhammer_php = phpenv.SharedLibrary('hammer', swig) \ No newline at end of file From f3e42ea34e8e2c137f4d9777825cc5dd3d6507a1 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 19:58:01 -0600 Subject: [PATCH 007/101] ok, travis wants -Wno-sign-compare too --- src/bindings/php/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 6694602..1b9853c 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -4,7 +4,7 @@ Import('env') phpenv = env.Clone() phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) -phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers']) +phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers', '-Wno-sign-compare']) phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php', '-outdir', 'build/$VARIANT/src/bindings/php/']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) From 425c20dd3de0bd533f58a5b168fe40020e96abb3 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 20:09:13 -0600 Subject: [PATCH 008/101] that ought to make travis happy --- src/bindings/php/SConscript | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 1b9853c..0789332 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -4,11 +4,11 @@ Import('env') phpenv = env.Clone() phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) -phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers', '-Wno-sign-compare']) -phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php', '-outdir', 'build/$VARIANT/src/bindings/php/']) +phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) #'-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers', '-Wno-sign-compare']) +phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) swig = ['hammer.i'] -libhammer_php = phpenv.SharedLibrary('hammer', swig) \ No newline at end of file +libhammer_php = phpenv.SharedLibrary('hammer', swig) From a0f5b0892b41013c8cf4328a935c604b9b98d682 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 20:16:09 -0600 Subject: [PATCH 009/101] tidying things up a bit --- src/bindings/php/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 0789332..17f146e 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -4,7 +4,7 @@ Import('env') phpenv = env.Clone() phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) -phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) #'-Wno-unused-variable', '-Wno-unused-label', '-Wno-unused-function', '-Wno-missing-field-initializers', '-Wno-sign-compare']) +phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) From 632aa845a5c95b11a5bfd26f6c79b75b00014489 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 17 Nov 2013 20:54:13 -0600 Subject: [PATCH 010/101] link here, too --- src/bindings/php/SConscript | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 17f146e..f45b438 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,10 +1,12 @@ # -*- python -*- Import('env') -phpenv = env.Clone() +phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) -phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) +phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) +phpenv.Append(LIBS = ['hammer']) +phpenv.Append(LIBPATH = ['../../']) phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) From 689ee8441533872e2212e38a50465f4168a8e2c3 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Tue, 19 Nov 2013 22:59:14 -0600 Subject: [PATCH 011/101] stubbed PHP typemaps --- src/bindings/swig/hammer.i | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 971b37f..4dc9668 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -1,4 +1,5 @@ %module hammer +%nodefaultctor; %nodefaultctor; @@ -132,6 +133,31 @@ #endif //%include "typemaps.i" + +#if defined(SWIGPHP) +%ignore HCountedArray_; +%typemap(in) uint8_t* { + + } +%typemap(out) uint8_t* { + + } +%typemap(in) void*[] { + + } +%typemap(in) uint8_t { + + } +%typemap(out) HBytes* { + + } +%typemap(out) struct HCountedArray_* { + + } +#else + #warning no Hammer typemaps defined +#endif + // All the include paths are relative to the build, i.e., ../../. If you need to build these manually (i.e., not with scons), keep that in mind. %{ #include "allocator.h" @@ -347,3 +373,4 @@ def int64(): return _h_int64() #endif //%apply const char* { const uint8_t* } + From 0733700343dc29b3f431d6a12f4c581ef1c23b67 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Tue, 19 Nov 2013 23:59:58 -0600 Subject: [PATCH 012/101] gonna test these typemaps with the tests I'm gonna write next. --- src/bindings/swig/hammer.i | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 4dc9668..6c0d900 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -136,11 +136,12 @@ #if defined(SWIGPHP) %ignore HCountedArray_; -%typemap(in) uint8_t* { - +%typemap(in) (uint8_t* input, size_t len) { + $1 = (uint8_t*)$input->value.str.val; + $2 = $input->value.str.len; } -%typemap(out) uint8_t* { - +%typemap(out) (uint8_t* input, size_t len) { + RETVAL_STRINGL((char*)$1, $2, 1); } %typemap(in) void*[] { From c51b78461223834ef0c99231ccbc6d258e99c661 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 02:13:41 -0600 Subject: [PATCH 013/101] scons runs a minimal unit test, which errors. debugging typemaps commences. --- src/bindings/php/SConscript | 9 ++++++++- src/bindings/php/TestHammer.php | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 src/bindings/php/TestHammer.php diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index f45b438..b2194d6 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,5 +1,6 @@ # -*- python -*- -Import('env') +import os.path +Import('env libhammer_shared') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) @@ -14,3 +15,9 @@ phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) swig = ['hammer.i'] libhammer_php = phpenv.SharedLibrary('hammer', swig) + +phptestenv = phpenv.Clone() +phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) +phptestenv.Command(None, ['TestHammer.php', libhammer_php], "phpunit $SOURCE") + +Clean('.', ['hammer.php', 'TestHammer.php']) diff --git a/src/bindings/php/TestHammer.php b/src/bindings/php/TestHammer.php new file mode 100644 index 0000000..34fdde9 --- /dev/null +++ b/src/bindings/php/TestHammer.php @@ -0,0 +1,24 @@ +parser = hammer::h_token("95\xa2", 3); + } + public function testSuccess() + { + $result = hammer::h_parse($this->parser, "95\xa2", 3); + $this->assertEquals($result->ast->token_data->bytes, "95\xa2"); + } + public function testFailure() + { + $result = hammer::h_parse($this->parser, "95", 2); + $this->assertEquals($result, NULL); + } +} +?> \ No newline at end of file From 213f33835730a77f2d31e0bc18e0a7bcdca15df5 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 03:29:10 -0600 Subject: [PATCH 014/101] argument typemap for token works! next, make it work for parse as well. --- src/bindings/swig/hammer.i | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 6c0d900..767e85f 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -136,13 +136,14 @@ #if defined(SWIGPHP) %ignore HCountedArray_; -%typemap(in) (uint8_t* input, size_t len) { - $1 = (uint8_t*)$input->value.str.val; - $2 = $input->value.str.len; +%typemap(in) (const uint8_t* str, const size_t len) { + $1 = (uint8_t*)(*$input)->value.str.val; + $2 = (*$input)->value.str.len; } %typemap(out) (uint8_t* input, size_t len) { RETVAL_STRINGL((char*)$1, $2, 1); } +//%apply (uint8_t* input, size_t len) { (uint8_t* str, size_t len) } %typemap(in) void*[] { } From 8be21c3d2874c641175f270a9c64e216e7e8ede9 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 12:40:28 -0600 Subject: [PATCH 015/101] uint8_t* input typemap works for h_token and h_parse --- src/bindings/swig/hammer.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 767e85f..699019e 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -140,10 +140,10 @@ $1 = (uint8_t*)(*$input)->value.str.val; $2 = (*$input)->value.str.len; } -%typemap(out) (uint8_t* input, size_t len) { +%typemap(out) (uint8_t* input, size_t length) { RETVAL_STRINGL((char*)$1, $2, 1); } -//%apply (uint8_t* input, size_t len) { (uint8_t* str, size_t len) } +%apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } %typemap(in) void*[] { } From 12d93a315d36f68dcd3b1d6e2bca3f5e0acb05df Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 17:36:15 -0600 Subject: [PATCH 016/101] need to coerce HBytes to PHP string, but this seems to be looking for an object of HBytes class --- src/bindings/php/TestHammer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindings/php/TestHammer.php b/src/bindings/php/TestHammer.php index 34fdde9..8d0a6e3 100644 --- a/src/bindings/php/TestHammer.php +++ b/src/bindings/php/TestHammer.php @@ -13,7 +13,8 @@ class TestHammer extends PHPUnit_Framework_TestCase public function testSuccess() { $result = hammer::h_parse($this->parser, "95\xa2", 3); - $this->assertEquals($result->ast->token_data->bytes, "95\xa2"); + var_dump($result); + $this->assertEquals($result->__get("ast")->__get("token_data")->__get("bytes"), "95\xa2"); } public function testFailure() { From 0c0805591c606d9608969e7d3814a92704bd4144 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 18:45:02 -0600 Subject: [PATCH 017/101] minimal working PHP tests, for h_token. --- src/bindings/php/TestHammer.php | 16 +++++++++++----- src/bindings/swig/hammer.i | 8 ++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/bindings/php/TestHammer.php b/src/bindings/php/TestHammer.php index 8d0a6e3..b71eb9f 100644 --- a/src/bindings/php/TestHammer.php +++ b/src/bindings/php/TestHammer.php @@ -8,17 +8,23 @@ class TestHammer extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = hammer::h_token("95\xa2", 3); + $this->parser = h_token("95\xa2"); } public function testSuccess() { - $result = hammer::h_parse($this->parser, "95\xa2", 3); - var_dump($result); - $this->assertEquals($result->__get("ast")->__get("token_data")->__get("bytes"), "95\xa2"); + $result = h_parse($this->parser, "95\xa2"); + //var_dump($result); + $ast = hparseresult_ast_get($result); + //var_dump($ast); + $token_data = hparsedtoken_token_data_get($ast); + //var_dump($token_data); + $bytes = htokendata_bytes_get($token_data); + //var_dump($bytes); + $this->assertEquals($bytes, "95\xa2"); } public function testFailure() { - $result = hammer::h_parse($this->parser, "95", 2); + $result = h_parse($this->parser, "95"); $this->assertEquals($result, NULL); } } diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 699019e..ead3c3f 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -140,9 +140,9 @@ $1 = (uint8_t*)(*$input)->value.str.val; $2 = (*$input)->value.str.len; } -%typemap(out) (uint8_t* input, size_t length) { - RETVAL_STRINGL((char*)$1, $2, 1); - } +//%typemap(out) (const uint8_t* str, const size_t len) { +// RETVAL_STRINGL((char*)$1, $2, 1); +// } %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } %typemap(in) void*[] { @@ -151,7 +151,7 @@ } %typemap(out) HBytes* { - + RETVAL_STRINGL((char*)$1->token, $1->len, 1); } %typemap(out) struct HCountedArray_* { From 23cb4d0f7ce3f9a195af41c909cd8b145b10e854 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 20:24:21 -0600 Subject: [PATCH 018/101] test runner/test dir ready to go; scons builds/executes php tests in src/bindings/php/Tests --- src/bindings/php/SConscript | 7 ++++--- src/bindings/php/{TestHammer.php => Tests/TokenTest.php} | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) rename src/bindings/php/{TestHammer.php => Tests/TokenTest.php} (90%) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index b2194d6..16cfe15 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,5 +1,5 @@ # -*- python -*- -import os.path +import os, os.path Import('env libhammer_shared') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) @@ -18,6 +18,7 @@ libhammer_php = phpenv.SharedLibrary('hammer', swig) phptestenv = phpenv.Clone() phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -phptestenv.Command(None, ['TestHammer.php', libhammer_php], "phpunit $SOURCE") +tests = phptestenv.Dir('Tests/') +phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") -Clean('.', ['hammer.php', 'TestHammer.php']) +Clean('.', ['hammer.php']) diff --git a/src/bindings/php/TestHammer.php b/src/bindings/php/Tests/TokenTest.php similarity index 90% rename from src/bindings/php/TestHammer.php rename to src/bindings/php/Tests/TokenTest.php index b71eb9f..6a9cad5 100644 --- a/src/bindings/php/TestHammer.php +++ b/src/bindings/php/Tests/TokenTest.php @@ -1,8 +1,8 @@ Date: Wed, 20 Nov 2013 21:51:51 -0600 Subject: [PATCH 019/101] this won't fix the travis not finding Tests/ issue, but it should provide php.ini config --- src/bindings/php/hammer.ini | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 src/bindings/php/hammer.ini diff --git a/src/bindings/php/hammer.ini b/src/bindings/php/hammer.ini new file mode 100644 index 0000000..7311162 --- /dev/null +++ b/src/bindings/php/hammer.ini @@ -0,0 +1,2 @@ +enable_dl = On +extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/libhammer.so" \ No newline at end of file From 5cc6920b232201ec3afa17257cd763446f5073e6 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 22:43:15 -0600 Subject: [PATCH 020/101] attempt to push test responsibility off to travis: round 1 --- .travis.yml | 18 ++++++++++++++++++ src/bindings/php/SConscript | 8 ++++---- src/bindings/php/hammer.ini | 3 ++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index cb81ea8..68e2c5a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,12 +38,30 @@ matrix: language: perl perl: "5.10" env: BINDINGS=perl CC=clang + - compiler: gcc + language: php + php: "5.5" + env: BINDINGS=php + - compiler: clang + language: php + php: "5.5" + env: BINDINGS=php CC=clang + - compiler: gcc + language: php + php: "5.4" + env: BINDINGS=php + - compiler: clang + language: php + php: "5.4" + env: BINDINGS=php CC=clang before_install: - sudo apt-get update -qq - if [ "$BINDINGS" != "none" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; swig -version; fi - if [ "$BINDINGS" == "python" ]; then sudo apt-get install -qq python-dev; fi install: true +before_script: + - if [ "$BINDINGS" == "php" ]; then phpenv config-add hammer.ini; fi script: - scons bindings=$BINDINGS test notifications: diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 16cfe15..b165f20 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -16,9 +16,9 @@ swig = ['hammer.i'] libhammer_php = phpenv.SharedLibrary('hammer', swig) -phptestenv = phpenv.Clone() -phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -tests = phptestenv.Dir('Tests/') -phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") +#phptestenv = phpenv.Clone() +#phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) +#tests = phptestenv.Dir('Tests/') +#phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") Clean('.', ['hammer.php']) diff --git a/src/bindings/php/hammer.ini b/src/bindings/php/hammer.ini index 7311162..0556e28 100644 --- a/src/bindings/php/hammer.ini +++ b/src/bindings/php/hammer.ini @@ -1,2 +1,3 @@ enable_dl = On -extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/libhammer.so" \ No newline at end of file +extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/libhammer.so" +include_path = ".:/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings" \ No newline at end of file From 58fdc36178ced2c85dd82a49f2747ae2bb10830e Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 20 Nov 2013 22:55:22 -0600 Subject: [PATCH 021/101] path to hammer.ini --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 68e2c5a..d909225 100644 --- a/.travis.yml +++ b/.travis.yml @@ -61,7 +61,7 @@ before_install: install: true before_script: - - if [ "$BINDINGS" == "php" ]; then phpenv config-add hammer.ini; fi + - if [ "$BINDINGS" == "php" ]; then phpenv config-add src/bindings/php/hammer.ini; fi script: - scons bindings=$BINDINGS test notifications: From 75def00525d950d8e17e7c4d5c9fe97fbbdb4695 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 00:12:31 -0600 Subject: [PATCH 022/101] scons works with BINDINGS=none --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 872a974..fd62eda 100644 --- a/SConstruct +++ b/SConstruct @@ -7,7 +7,7 @@ import sys vars = Variables(None, ARGUMENTS) vars.Add(PathVariable('DESTDIR', "Root directory to install in (useful for packaging scripts)", None, PathVariable.PathIsDirCreate)) vars.Add(PathVariable('prefix', "Where to install in the FHS", "/usr/local", PathVariable.PathAccept)) -vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['python', 'perl'])) +vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['python', 'perl', 'php'])) env = Environment(ENV = {'PATH' : os.environ['PATH']}, variables = vars, tools=['default', 'scanreplace'], toolpath=['tools']) From 320f281ed38b7d563f0a306e3f67a65da48b56f0 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 00:58:49 -0600 Subject: [PATCH 023/101] doing swig steps manually, because the SharedLibrary builder was being weird. --- src/bindings/php/SConscript | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index b165f20..f779979 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -8,17 +8,17 @@ phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main' phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) phpenv.Append(LIBS = ['hammer']) phpenv.Append(LIBPATH = ['../../']) -phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) +#phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) +phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') -swig = ['hammer.i'] - -libhammer_php = phpenv.SharedLibrary('hammer', swig) +#swig = ['hammer.i'] +#libhammer_php = phpenv.SharedLibrary('hammer', swig) #phptestenv = phpenv.Clone() #phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) #tests = phptestenv.Dir('Tests/') #phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") -Clean('.', ['hammer.php']) +Clean('.', ['hammer.php', 'php_hammer.h']) From 4feec08273af38869510604f9dafa546238b679e Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 01:05:47 -0600 Subject: [PATCH 024/101] making a shared library works. --- src/bindings/php/SConscript | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index f779979..d516d79 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -8,13 +8,11 @@ phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main' phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) phpenv.Append(LIBS = ['hammer']) phpenv.Append(LIBPATH = ['../../']) -#phpenv.Append(SWIGFLAGS = ['-DHAMMER_INTERNAL__NO_STDARG_H', '-Isrc/', '-php']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') -#swig = ['hammer.i'] -#libhammer_php = phpenv.SharedLibrary('hammer', swig) +phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) #phptestenv = phpenv.Clone() #phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) From 57df8e2ad576c72e8f5855cdefb210aedfecc333 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 01:13:44 -0600 Subject: [PATCH 025/101] attempt to have travis build with new bindings option --- src/bindings/php/SConscript | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index d516d79..f6a33ca 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -12,11 +12,11 @@ phpenv.Append(LIBPATH = ['../../']) phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') -phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) +libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) + +phptestenv = phpenv.Clone() +phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) +tests = phptestenv.Dir('Tests/') +phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") -#phptestenv = phpenv.Clone() -#phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -#tests = phptestenv.Dir('Tests/') -#phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") -Clean('.', ['hammer.php', 'php_hammer.h']) From fb5c56b28ecbfb08a7a3dd3fdb40283fc9d1ea4d Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 01:17:14 -0600 Subject: [PATCH 026/101] helps if I get the include path right --- src/bindings/php/hammer.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/hammer.ini b/src/bindings/php/hammer.ini index 0556e28..d86063d 100644 --- a/src/bindings/php/hammer.ini +++ b/src/bindings/php/hammer.ini @@ -1,3 +1,3 @@ enable_dl = On -extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/libhammer.so" -include_path = ".:/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings" \ No newline at end of file +extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/php/libhammer.so" +include_path = ".:/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/php" \ No newline at end of file From 19290a75acb562984f7afdf657111a2da287a898 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 01:23:04 -0600 Subject: [PATCH 027/101] helps if I commit an up-to-date SConscript --- src/bindings/php/SConscript | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index f6a33ca..e9178cf 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -14,9 +14,9 @@ phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swi libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) -phptestenv = phpenv.Clone() -phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -tests = phptestenv.Dir('Tests/') -phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") +#phptestenv = phpenv.Clone() +#phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhamm#er_shared[0])) +#tests = phptestenv.Dir('Tests/') +#phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") From 0963a9d5504ea3b9f0da5923d2fb529edf493c02 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 02:26:47 -0600 Subject: [PATCH 028/101] that seems to be examples as its own target now --- examples/SConscript | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/SConscript b/examples/SConscript index 94f32ac..0932bda 100644 --- a/examples/SConscript +++ b/examples/SConscript @@ -3,7 +3,8 @@ Import('env') example = env.Clone() example.Append(LIBS="hammer", LIBPATH="../src") -example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c']) -example.Program('base64', 'base64.c') -example.Program('base64_sem1', 'base64_sem1.c') -example.Program('base64_sem2', 'base64_sem2.c') +dns = example.Program('dns', ['dns.c', 'rr.c', 'dns_common.c']) +base64 = example.Program('base64', 'base64.c') +base64_sem1 = example.Program('base64_sem1', 'base64_sem1.c') +base64_sem2 = example.Program('base64_sem2', 'base64_sem2.c') +env.Alias("examples", [dns, base64, base64_sem1, base64_sem2]) \ No newline at end of file From 43253c1664e474d9f500dcb0245675d40923ed35 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Thu, 21 Nov 2013 02:35:45 -0600 Subject: [PATCH 029/101] and now bindings=php works as a target too --- src/bindings/php/SConscript | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index e9178cf..32b696e 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -9,10 +9,10 @@ phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-erro phpenv.Append(LIBS = ['hammer']) phpenv.Append(LIBPATH = ['../../']) -phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) -phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') - +swig_src = phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) +bindings_src = phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) +Default(swig_src, bindings_src, libhammer_php) #phptestenv = phpenv.Clone() #phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhamm#er_shared[0])) From a578b2691c5ed0fc0310c88dbf91393808b7965b Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Fri, 22 Nov 2013 00:45:59 -0600 Subject: [PATCH 030/101] this works on my box; goooooo travis --- src/bindings/php/hammer.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bindings/php/hammer.ini b/src/bindings/php/hammer.ini index d86063d..5ceb898 100644 --- a/src/bindings/php/hammer.ini +++ b/src/bindings/php/hammer.ini @@ -1,3 +1,2 @@ enable_dl = On extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/php/libhammer.so" -include_path = ".:/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/php" \ No newline at end of file From 3d64c2973131df64610bc98a9ef0b910c96bed21 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Fri, 22 Nov 2013 02:46:56 -0600 Subject: [PATCH 031/101] copy built lib to extension dir --- src/bindings/php/hammer.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/hammer.ini b/src/bindings/php/hammer.ini index 5ceb898..5ac1942 100644 --- a/src/bindings/php/hammer.ini +++ b/src/bindings/php/hammer.ini @@ -1,2 +1,2 @@ enable_dl = On -extension = "/home/travis/build/abiggerhammer/hammer/build/opt/src/bindings/php/libhammer.so" +extension = "hammer.so" From cc3160072b6ef5d112887d3e8b0bf6e1f7166c07 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Fri, 22 Nov 2013 03:43:07 -0600 Subject: [PATCH 032/101] scons bindings=foo,bar test now runs C tests and tests for foo and bar. PHP tests need command-line fixed. --- src/bindings/php/SConscript | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 32b696e..7e5aae8 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,6 +1,6 @@ # -*- python -*- import os, os.path -Import('env libhammer_shared') +Import('env libhammer_shared testruns') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) @@ -14,9 +14,9 @@ bindings_src = phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], ' libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) Default(swig_src, bindings_src, libhammer_php) -#phptestenv = phpenv.Clone() -#phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhamm#er_shared[0])) -#tests = phptestenv.Dir('Tests/') -#phptestenv.Command(tests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET") - +phptestenv = phpenv.Clone() +phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) +phptests = phptestenv.Dir('Tests/') +testruns.append(phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET"))) + From 42e0707fb87ddb91fb87844528c3e347d1d28f0c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Fri, 22 Nov 2013 12:00:14 -0600 Subject: [PATCH 033/101] slightly more elegant way to pass around which tests to run --- SConstruct | 1 + src/bindings/php/SConscript | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index fd62eda..8a801f7 100644 --- a/SConstruct +++ b/SConstruct @@ -93,6 +93,7 @@ env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_")) #rootpath = env['ROOTPATH'] = os.path.abspath('.') #env.Append(CPPPATH=os.path.join('#', "hammer")) +env['testruns'] = [] testruns = [] targets = ["$libpath", diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 7e5aae8..7e86159 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,6 +1,6 @@ # -*- python -*- import os, os.path -Import('env libhammer_shared testruns') +Import('env libhammer_shared') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) @@ -16,7 +16,8 @@ Default(swig_src, bindings_src, libhammer_php) phptestenv = phpenv.Clone() phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -phptests = phptestenv.Dir('Tests/') -testruns.append(phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET"))) - +phptests = ['Tests'] +testphp = phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET")) +env['testruns'].append(testphp) +print "Testing: " + str([str(x[0]) for x in env['testruns']]) From 5917c3a599a947b91bf69fa986f5b107db71f804 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 12:45:21 -0600 Subject: [PATCH 034/101] phpunit is now running the tests, we just need to get them into build/opt/src. --- src/bindings/php/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 7e86159..a7fdb5d 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -17,7 +17,7 @@ Default(swig_src, bindings_src, libhammer_php) phptestenv = phpenv.Clone() phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) phptests = ['Tests'] -testphp = phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpunit -v --include-path "+os.getcwd()+" $TARGET")) +testphp = phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpenv exec phpunit -v --include-path "+os.getcwd()+" $TARGET")) env['testruns'].append(testphp) print "Testing: " + str([str(x[0]) for x in env['testruns']]) From 094d7ac7ff23a6b0700ef7a4936a36ab2eeb5f2d Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 13:06:48 -0600 Subject: [PATCH 035/101] get include paths from php-config --- src/bindings/php/SConscript | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index a7fdb5d..bed1226 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -4,7 +4,8 @@ Import('env libhammer_shared') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) -phpenv.Append(CPPPATH = ['../../', '/usr/include/php5', '/usr/include/php5/main', '/usr/include/php5/Zend', '/usr/include/php5/TSRM']) +php_include = os.popen("php-config --include-dir").read().rstrip() +phpenv.Append(CPPPATH = ['../../', php_include, os.path.join(php_include, 'main'), os.path.join(php_include, 'Zend'), os.path.join(php_include, 'TSRM')]) phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-error']) phpenv.Append(LIBS = ['hammer']) phpenv.Append(LIBPATH = ['../../']) From da33c86898de42be3fc78c9ed3649f9d551797b7 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 13:11:15 -0600 Subject: [PATCH 036/101] README about php configuration --- src/bindings/php/README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/bindings/php/README.md diff --git a/src/bindings/php/README.md b/src/bindings/php/README.md new file mode 100644 index 0000000..1c9f0fb --- /dev/null +++ b/src/bindings/php/README.md @@ -0,0 +1,12 @@ +Installing +========== +Requirements: +* SWIG 2.0 +* A properly configured [phpenv](https://github.com/CHH/phpenv) + +If you want to run the tests, you will also need to install PHPUnit. Do this with pyrus and save yourself some hell. + + pyrus channel-discover pear.phpunit.de + pyrus channel-discover pear.symfony.com + pyrus channel-discover pear.symfony-project.com + pyrus install --optionaldeps phpunit/PHPUnit From 4c58a0bcb22aea9eda8211b9a557311cdccbb442 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 16:07:19 -0600 Subject: [PATCH 037/101] php tests run on clean build --- SConstruct | 2 +- src/bindings/php/README.md | 10 ++++++++-- src/bindings/php/SConscript | 17 ++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/SConstruct b/SConstruct index 8a801f7..dac0107 100644 --- a/SConstruct +++ b/SConstruct @@ -93,9 +93,9 @@ env["ENV"].update(x for x in os.environ.items() if x[0].startswith("CCC_")) #rootpath = env['ROOTPATH'] = os.path.abspath('.') #env.Append(CPPPATH=os.path.join('#', "hammer")) -env['testruns'] = [] testruns = [] + targets = ["$libpath", "$incpath", "$parsersincpath", diff --git a/src/bindings/php/README.md b/src/bindings/php/README.md index 1c9f0fb..8e11cb9 100644 --- a/src/bindings/php/README.md +++ b/src/bindings/php/README.md @@ -1,12 +1,18 @@ -Installing -========== +Building +======== Requirements: * SWIG 2.0 * A properly configured [phpenv](https://github.com/CHH/phpenv) +SCons finds your PHP include path from `php-config`, so if you don't have that working, you're going to have a bad time. + If you want to run the tests, you will also need to install PHPUnit. Do this with pyrus and save yourself some hell. pyrus channel-discover pear.phpunit.de pyrus channel-discover pear.symfony.com pyrus channel-discover pear.symfony-project.com pyrus install --optionaldeps phpunit/PHPUnit + +Installing +========== +We're not building a proper package yet, but you can copy `build/$VARIANT/src/bindings/php/hammer.so` to your PHP extension directory (`scons test` will do this for you if you're using phpenv; for a system-wide php you'll probably have to use sudo) and add "extension=hammer.so" to your php.ini. There is a "hammer.ini" in src/bindings/php for your convenience; you can put it in the `conf.d` directory where PHP expects to find its configuration. `scons test` will do this for you too. \ No newline at end of file diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index bed1226..aa9a535 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -1,6 +1,6 @@ # -*- python -*- import os, os.path -Import('env libhammer_shared') +Import('env libhammer_shared testruns') phpenv = env.Clone(IMPLICIT_COMMAND_DEPENDENCIES = 0) @@ -17,8 +17,15 @@ Default(swig_src, bindings_src, libhammer_php) phptestenv = phpenv.Clone() phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) -phptests = ['Tests'] -testphp = phptestenv.Alias("testphp", phptestenv.Command(phptests, [libhammer_php], "phpenv exec phpunit -v --include-path "+os.getcwd()+" $TARGET")) -env['testruns'].append(testphp) -print "Testing: " + str([str(x[0]) for x in env['testruns']]) +phptests = ('Tests') +phpextprefix = os.popen("php-config --extension-dir").read().rstrip() +phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE")) +phpprefix = os.popen("php-config --prefix").read().rstrip() +phpincl = phptestenv.Command(os.path.join(phpprefix, "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) +phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") +print "phptestexec path: " + phptestexec[0].path +phptest = Alias("testphp", [phptestexec], phptestexec) +AlwaysBuild(phptest) +testruns.append(phptest) +print "Testing: " + str([str(x[0]) for x in testruns]) From 315c7a28c6303de69f3fa17e282e59df08c9f94c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 16:11:36 -0600 Subject: [PATCH 038/101] cleaned out some cruft; php tests run on successive builds w/o needing to clean. --- src/bindings/php/SConscript | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index aa9a535..30391c2 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -20,12 +20,12 @@ phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) phptests = ('Tests') phpextprefix = os.popen("php-config --extension-dir").read().rstrip() phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE")) +AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() phpincl = phptestenv.Command(os.path.join(phpprefix, "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") -print "phptestexec path: " + phptestexec[0].path phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) testruns.append(phptest) -print "Testing: " + str([str(x[0]) for x in testruns]) + From 0810bd33d2b2167b0a5159c6604e724bd3d49563 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 23 Nov 2013 16:14:07 -0600 Subject: [PATCH 039/101] updated build/install docs --- src/bindings/php/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/README.md b/src/bindings/php/README.md index 8e11cb9..5638c51 100644 --- a/src/bindings/php/README.md +++ b/src/bindings/php/README.md @@ -15,4 +15,4 @@ If you want to run the tests, you will also need to install PHPUnit. Do this wit Installing ========== -We're not building a proper package yet, but you can copy `build/$VARIANT/src/bindings/php/hammer.so` to your PHP extension directory (`scons test` will do this for you if you're using phpenv; for a system-wide php you'll probably have to use sudo) and add "extension=hammer.so" to your php.ini. There is a "hammer.ini" in src/bindings/php for your convenience; you can put it in the `conf.d` directory where PHP expects to find its configuration. `scons test` will do this for you too. \ No newline at end of file +We're not building a proper package yet, but you can copy `build/$VARIANT/src/bindings/php/hammer.so` to your PHP extension directory (`scons test` will do this for you if you're using phpenv; for a system-wide php you'll probably have to use sudo) and add "extension=hammer.so" to your php.ini. There is a "hammer.ini" in src/bindings/php for your convenience; you can put it in the `conf.d` directory where PHP expects to find its configuration. `scons test` will do this for you too. You'll also need to point your include_path to the location of hammer.php, which will be `build/$VARIANT/src/bindings/php/hammer.php` until you put it somewhere else. \ No newline at end of file From 49ca034b321a03882b79e4e71adfa0f8f8a40ba6 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 19:26:14 -0600 Subject: [PATCH 040/101] typemap for HParseResult is returning the appropriate zval, but why does PHP think it's null? --- src/bindings/php/SConscript | 2 +- src/bindings/php/Tests/TokenTest.php | 22 ++++----- src/bindings/swig/hammer.i | 72 ++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 30391c2..919677b 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -22,7 +22,7 @@ phpextprefix = os.popen("php-config --extension-dir").read().rstrip() phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_php, Copy("$TARGET", "$SOURCE")) AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() -phpincl = phptestenv.Command(os.path.join(phpprefix, "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) +phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php index 6a9cad5..720b74c 100644 --- a/src/bindings/php/Tests/TokenTest.php +++ b/src/bindings/php/Tests/TokenTest.php @@ -1,6 +1,6 @@ parser = h_token("95\xa2"); + $this->parser = hammer::h_token("95\xa2"); } - public function testSuccess() + public function testSuccess() { - $result = h_parse($this->parser, "95\xa2"); - //var_dump($result); - $ast = hparseresult_ast_get($result); - //var_dump($ast); - $token_data = hparsedtoken_token_data_get($ast); - //var_dump($token_data); - $bytes = htokendata_bytes_get($token_data); - //var_dump($bytes); - $this->assertEquals($bytes, "95\xa2"); - } + $result = hammer::h_parse($this->parser, "95\xa2"); + var_dump($result); + $this->assertEquals("95\xa2", $result); + } public function testFailure() { $result = h_parse($this->parser, "95"); - $this->assertEquals($result, NULL); + $this->assertEquals(NULL, $result); } } ?> \ No newline at end of file diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index ead3c3f..ccd5bf9 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -140,22 +140,52 @@ $1 = (uint8_t*)(*$input)->value.str.val; $2 = (*$input)->value.str.len; } + //%typemap(out) (const uint8_t* str, const size_t len) { // RETVAL_STRINGL((char*)$1, $2, 1); // } %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } + %typemap(in) void*[] { } + %typemap(in) uint8_t { } + %typemap(out) HBytes* { RETVAL_STRINGL((char*)$1->token, $1->len, 1); } + %typemap(out) struct HCountedArray_* { } +%typemap(out) struct HParseResult_* { + if ($1 == NULL) { + // TODO: raise parse failure + RETVAL_NULL(); + } else { + $result = hpt_to_php($1->ast); + printf("Being returned: %s\n", Z_STRVAL_P($result)); + } + } +%inline %{ + static int h_tt_php; + %} + +%init %{ + h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + %} + +%inline { + struct HParsedToken_; + struct HParseResult_; + static zval* hpt_to_php(const struct HParsedToken_ *token); + + //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); + } + #else #warning no Hammer typemaps defined #endif @@ -375,4 +405,46 @@ def int64(): return _h_int64() #endif //%apply const char* { const uint8_t* } +#if defined(SWIGPHP) +%inline { + static zval* hpt_to_php(const HParsedToken *token) { + zval *ret; + ALLOC_INIT_ZVAL(ret); + if (token == NULL) { + ZVAL_NULL(ret); + return ret; + } + switch (token->token_type) { + case TT_NONE: + ZVAL_NULL(ret); + return ret; + case TT_BYTES: + ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); + return ret; + case TT_SINT: + ZVAL_LONG(ret, token->token_data.sint); + return ret; + case TT_UINT: + ZVAL_LONG(ret, token->token_data.uint); + return ret; + case TT_SEQUENCE: + array_init(ret); + for (int i=0; i < token->token_data.seq->used; i++) { + add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); + } + return ret; + default: + /* if (token->token_type == h_tt_php) { */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ + /* return return_value; */ + /* } else { */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ + /* } */ + break; + } + } + } +#endif From ddbde603962370f78d3a968e30f2b06ae5032762 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:12:54 -0600 Subject: [PATCH 041/101] TT_BYTES is converting properly; TT_UINT is not. --- src/bindings/php/Tests/ChTest.php | 24 ++++++++ src/bindings/php/Tests/TokenTest.php | 5 +- src/bindings/swig/hammer.i | 82 ++++++++++++++++++++-------- 3 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 src/bindings/php/Tests/ChTest.php diff --git a/src/bindings/php/Tests/ChTest.php b/src/bindings/php/Tests/ChTest.php new file mode 100644 index 0000000..f18cdfb --- /dev/null +++ b/src/bindings/php/Tests/ChTest.php @@ -0,0 +1,24 @@ +parser = h_ch("\xa2"); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\xa2"); + $this->assertEquals("\xa2", $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "95"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php index 720b74c..492c17f 100644 --- a/src/bindings/php/Tests/TokenTest.php +++ b/src/bindings/php/Tests/TokenTest.php @@ -8,12 +8,11 @@ class TokenTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = hammer::h_token("95\xa2"); + $this->parser = h_token("95\xa2"); } public function testSuccess() { - $result = hammer::h_parse($this->parser, "95\xa2"); - var_dump($result); + $result = h_parse($this->parser, "95\xa2"); $this->assertEquals("95\xa2", $result); } public function testFailure() diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index ccd5bf9..000b0c4 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -136,6 +136,23 @@ #if defined(SWIGPHP) %ignore HCountedArray_; + +%inline %{ + static int h_tt_php; + %} + +%init %{ + h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + %} + +%inline { + struct HParsedToken_; + struct HParseResult_; + static zval* hpt_to_php(const struct HParsedToken_ *token); + + //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); + } + %typemap(in) (const uint8_t* str, const size_t len) { $1 = (uint8_t*)(*$input)->value.str.val; $2 = (*$input)->value.str.len; @@ -166,25 +183,42 @@ // TODO: raise parse failure RETVAL_NULL(); } else { - $result = hpt_to_php($1->ast); - printf("Being returned: %s\n", Z_STRVAL_P($result)); + if ($1->ast == NULL) { + RETVAL_NULL(); + } else { + switch($1->ast->token_type) { + case TT_NONE: + RETVAL_NULL(); + break; + case TT_BYTES: + RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1); + break; + case TT_SINT: + RETVAL_LONG($1->ast->token_data.sint); + break; + case TT_UINT: + RETVAL_LONG($1->ast->token_data.uint); + break; + case TT_SEQUENCE: + array_init($result); + for (int i=0; i < $1->ast->token_data.seq->used; i++) { + add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i])); + } + break; + default: + /* if (token->token_type == h_tt_php) { */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ + /* return return_value; */ + /* } else { */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ + /* } */ + break; + } + } } } -%inline %{ - static int h_tt_php; - %} - -%init %{ - h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); - %} - -%inline { - struct HParsedToken_; - struct HParseResult_; - static zval* hpt_to_php(const struct HParsedToken_ *token); - - //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); - } #else #warning no Hammer typemaps defined @@ -420,6 +454,7 @@ def int64(): return _h_int64() return ret; case TT_BYTES: ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); + printf("Being returned from hpt_to_php: %s\n", Z_STRVAL_P(ret)); return ret; case TT_SINT: ZVAL_LONG(ret, token->token_data.sint); @@ -430,21 +465,20 @@ def int64(): return _h_int64() case TT_SEQUENCE: array_init(ret); for (int i=0; i < token->token_data.seq->used; i++) { - add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); + add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); } return ret; default: /* if (token->token_type == h_tt_php) { */ - /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ - /* return return_value; */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh + /* return return_value; */ /* } else { */ - /* // I guess that's a python thing */ - /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ - /* // TODO: support registry */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ /* } */ break; } } } #endif - From 05cdf766abfc11b9158c600045fef8a5a50b5cb4 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:23:49 -0600 Subject: [PATCH 042/101] uint8_t typemap is happy now --- src/bindings/swig/hammer.i | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 000b0c4..60c7841 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -168,7 +168,13 @@ } %typemap(in) uint8_t { - + if (IS_LONG == Z_TYPE_PP($input)) { + $1 = Z_LVAL_PP($input); + } else if (IS_STRING != Z_TYPE_PP($input)) { + // FIXME raise some error + } else { + $1 = *(uint8_t*)Z_STRVAL_PP($input); + } } %typemap(out) HBytes* { From 282c42139db54d5760bce8017bed4337ddeaadbc Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:30:19 -0600 Subject: [PATCH 043/101] ChTest and ChRangeTest fail only because their result isn't being coerced to string. --- src/bindings/php/Tests/ChRangeTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/bindings/php/Tests/ChRangeTest.php diff --git a/src/bindings/php/Tests/ChRangeTest.php b/src/bindings/php/Tests/ChRangeTest.php new file mode 100644 index 0000000..b726a5d --- /dev/null +++ b/src/bindings/php/Tests/ChRangeTest.php @@ -0,0 +1,24 @@ +parser = h_ch_range("a", "c"); + } + public function testSuccess() + { + $result = h_parse($this->parser, "b"); + $this->assertEquals("b", $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "d"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From b13d5045e2867c127a2977de8f0a6d0cb917214f Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:40:48 -0600 Subject: [PATCH 044/101] there's all the signed-int parsers working --- src/bindings/php/Tests/Int16Test.php | 30 +++++++++++++++++++++++++++ src/bindings/php/Tests/Int32Test.php | 31 ++++++++++++++++++++++++++++ src/bindings/php/Tests/Int64Test.php | 24 +++++++++++++++++++++ src/bindings/php/Tests/Int8Test.php | 24 +++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 src/bindings/php/Tests/Int16Test.php create mode 100644 src/bindings/php/Tests/Int32Test.php create mode 100644 src/bindings/php/Tests/Int64Test.php create mode 100644 src/bindings/php/Tests/Int8Test.php diff --git a/src/bindings/php/Tests/Int16Test.php b/src/bindings/php/Tests/Int16Test.php new file mode 100644 index 0000000..4b170cc --- /dev/null +++ b/src/bindings/php/Tests/Int16Test.php @@ -0,0 +1,30 @@ +parser = h_int16(); + } + public function testNegative() + { + $result = h_parse($this->parser, "\xfe\x00"); + $this->assertEquals(-0x200, $result); + } + public function testPositive() { + $result = h_parse($this->parser, "\x02\x00"); + $this->assertEquals(0x200, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\xfe"); + $this->assertEquals(NULL, $result); + $result = h_parse($this->parser, "\x02"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Int32Test.php b/src/bindings/php/Tests/Int32Test.php new file mode 100644 index 0000000..c538aa2 --- /dev/null +++ b/src/bindings/php/Tests/Int32Test.php @@ -0,0 +1,31 @@ +parser = h_int32(); + } + public function testNegative() + { + $result = h_parse($this->parser, "\xff\xfe\x00\x00"); + $this->assertEquals(-0x20000, $result); + } + public function testPositive() + { + $result = h_parse($this->parser, "\x00\x02\x00\x00"); + $this->assertEquals(0x20000, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\xff\xfe\x00"); + $this->assertEquals(NULL, $result); + $result = h_parse($this->parser, "\x00\x02\x00"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Int64Test.php b/src/bindings/php/Tests/Int64Test.php new file mode 100644 index 0000000..4c0faa2 --- /dev/null +++ b/src/bindings/php/Tests/Int64Test.php @@ -0,0 +1,24 @@ +parser = h_int64(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00\x00"); + $this->assertEquals(-0x200000000, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Int8Test.php b/src/bindings/php/Tests/Int8Test.php new file mode 100644 index 0000000..164d773 --- /dev/null +++ b/src/bindings/php/Tests/Int8Test.php @@ -0,0 +1,24 @@ +parser = h_int8(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x88"); + $this->assertEquals(-0x78, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, ""); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From c89f3dc7c769f49de7607283042b4428259f1350 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:46:09 -0600 Subject: [PATCH 045/101] unsigned ints working too --- src/bindings/php/Tests/Uint16Test.php | 24 ++++++++++++++++++++++++ src/bindings/php/Tests/Uint32Test.php | 24 ++++++++++++++++++++++++ src/bindings/php/Tests/Uint64Test.php | 24 ++++++++++++++++++++++++ src/bindings/php/Tests/Uint8Test.php | 24 ++++++++++++++++++++++++ 4 files changed, 96 insertions(+) create mode 100644 src/bindings/php/Tests/Uint16Test.php create mode 100644 src/bindings/php/Tests/Uint32Test.php create mode 100644 src/bindings/php/Tests/Uint64Test.php create mode 100644 src/bindings/php/Tests/Uint8Test.php diff --git a/src/bindings/php/Tests/Uint16Test.php b/src/bindings/php/Tests/Uint16Test.php new file mode 100644 index 0000000..4639389 --- /dev/null +++ b/src/bindings/php/Tests/Uint16Test.php @@ -0,0 +1,24 @@ +parser = h_uint16(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x02\x00"); + $this->assertEquals(0x200, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\x02"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Uint32Test.php b/src/bindings/php/Tests/Uint32Test.php new file mode 100644 index 0000000..f9b0f0b --- /dev/null +++ b/src/bindings/php/Tests/Uint32Test.php @@ -0,0 +1,24 @@ +parser = h_uint32(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x00\x02\x00\x00"); + $this->assertEquals(0x20000, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\x00\x02\x00"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Uint64Test.php b/src/bindings/php/Tests/Uint64Test.php new file mode 100644 index 0000000..9910916 --- /dev/null +++ b/src/bindings/php/Tests/Uint64Test.php @@ -0,0 +1,24 @@ +parser = h_uint64(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00\x00"); + $this->assertEquals(0x200000000, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/Uint8Test.php b/src/bindings/php/Tests/Uint8Test.php new file mode 100644 index 0000000..6797949 --- /dev/null +++ b/src/bindings/php/Tests/Uint8Test.php @@ -0,0 +1,24 @@ +parser = h_uint8(); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x78"); + $this->assertEquals(0x78, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, ""); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From be08c128e0168f9d9414586f5f65433be3fa7171 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 20:49:23 -0600 Subject: [PATCH 046/101] h_int_range works --- src/bindings/php/Tests/IntRangeTest.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/bindings/php/Tests/IntRangeTest.php diff --git a/src/bindings/php/Tests/IntRangeTest.php b/src/bindings/php/Tests/IntRangeTest.php new file mode 100644 index 0000000..ce56fce --- /dev/null +++ b/src/bindings/php/Tests/IntRangeTest.php @@ -0,0 +1,23 @@ +parser = h_int_range(h_uint8(), 3, 10); + } + public function testSuccess() + { + $result = h_parse($this->parser, "\x05"); + $this->assertEquals(5, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "\xb"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 5fcd9fa88d14af6c0e4cd070e346cce34183466b Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 22:58:25 -0600 Subject: [PATCH 047/101] void*[] typemap compiles --- src/bindings/swig/hammer.i | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 60c7841..06b4515 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -164,7 +164,27 @@ %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } %typemap(in) void*[] { - + if (IS_ARRAY == Z_TYPE_PP($input)) { + zval **data; + HashTable *arr = Z_ARRVAL_PP($input); + HashPosition pointer; + int size = zend_hash_num_elements(arr); + int i = 0; + int res = 0; + $1 = (void**)malloc((size+1)*sizeof(HParser*)); + for (zend_hash_internal_pointer_reset_ex(arr, &pointer); + zend_hash_get_current_data_ex(arr, (void**)&data, &pointer); + zend_hash_move_forward_ex(arr, &pointer), i++) { + res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0); + if (!SWIG_IsOk(res)) { + // TODO do we not *have* SWIG_TypeError? + SWIG_exception_fail(res, "that wasn't an HParser"); + } + } + } else { + // FIXME raise some error + $1 = NULL; + } } %typemap(in) uint8_t { @@ -181,9 +201,11 @@ RETVAL_STRINGL((char*)$1->token, $1->len, 1); } +/* TODO do we need this anymore? %typemap(out) struct HCountedArray_* { } +*/ %typemap(out) struct HParseResult_* { if ($1 == NULL) { // TODO: raise parse failure From 6c4a8f17c67165107a00441c4203662657b4b492 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 24 Nov 2013 23:10:27 -0600 Subject: [PATCH 048/101] need to figure out how to apply a function in zend to something other than an array; about to run out of battery though --- src/bindings/swig/hammer.i | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 06b4515..4e3b7a0 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -150,7 +150,7 @@ struct HParseResult_; static zval* hpt_to_php(const struct HParsedToken_ *token); - //static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); + static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); } %typemap(in) (const uint8_t* str, const size_t len) { @@ -247,7 +247,15 @@ } } } +/* +%typemap(in) (HPredicate* pred, void* user_data) { + } +*/ +%typemap(in) (const HAction a, void* user_data) { + $2 = $input; + $1 = call_action; + } #else #warning no Hammer typemaps defined #endif @@ -508,5 +516,19 @@ def int64(): return _h_int64() break; } } + + static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data) { + zval *callable = user_data; + zval *ret; + ALLOC_INIT_ZVAL(ret); + FIXME_SOME_ZEND_APPLY_FUNCTION(ret, (apply_func_t)callable TSRMLS_CC); + if (ret == NULL) { + // FIXME throw some error + return NULL; + } + // TODO: add reference to ret to parse-local data + HParsedToken *tok = h_make(p->arena, h_tt_php, ret); + return tok; + } } #endif From 9382f2720a63e20eebfe4fc31e9ea435a8808ca4 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Tue, 26 Nov 2013 11:12:29 -0800 Subject: [PATCH 049/101] call_action compiles; will test later, need to get python-bindings into build now. --- src/bindings/swig/hammer.i | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 4e3b7a0..49b9b6f 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -518,16 +518,23 @@ def int64(): return _h_int64() } static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data) { - zval *callable = user_data; - zval *ret; - ALLOC_INIT_ZVAL(ret); - FIXME_SOME_ZEND_APPLY_FUNCTION(ret, (apply_func_t)callable TSRMLS_CC); - if (ret == NULL) { + zval *args[1]; + zval ret; + // in PHP land, the HAction is passed by its name as a string + if (IS_STRING != Z_TYPE_P((zval*)user_data)) { + // FIXME throw some error + return NULL; + } + zval *callable; + callable = user_data; + args[0] = hpt_to_php(p->ast); + int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); + if (ok != SUCCESS) { // FIXME throw some error return NULL; } // TODO: add reference to ret to parse-local data - HParsedToken *tok = h_make(p->arena, h_tt_php, ret); + HParsedToken *tok = h_make(p->arena, h_tt_php, &ret); return tok; } } From 421b7f29c8674eee00cc2450c7fa29d9d664dcfe Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 16:45:13 -0800 Subject: [PATCH 050/101] whitespace test works just fine; that segfault was entirely my fault --- src/bindings/php/Tests/WhitespaceTest.php | 44 +++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/bindings/php/Tests/WhitespaceTest.php diff --git a/src/bindings/php/Tests/WhitespaceTest.php b/src/bindings/php/Tests/WhitespaceTest.php new file mode 100644 index 0000000..64da3a2 --- /dev/null +++ b/src/bindings/php/Tests/WhitespaceTest.php @@ -0,0 +1,44 @@ +parser1 = h_whitespace(h_ch("a")); + $this->parser2 = h_whitespace(h_end_p()); + } + public function testSuccess1() + { + $result1 = h_parse($this->parser1, "a"); + $result2 = h_parse($this->parser1, " a"); + $result3 = h_parse($this->parser1, " a"); + $result4 = h_parse($this->parser1, "\ta"); + // TODO fix these tests when h_ch is fixed + $this->assertEquals(97, $result1); + $this->assertEquals(97, $result2); + $this->assertEquals(97, $result3); + $this->assertEquals(97, $result4); + } + public function testFailure1() + { + $result = h_parse($this->parser1, "_a"); + $this->assertEquals(NULL, $result); + } + public function testSuccess2() + { + $result1 = h_parse($this->parser2, ""); + $result2 = h_parse($this->parser2, " "); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + } + public function testFailure2() + { + $result = h_parse($this->parser2, " x"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 596d619fb5b02e027c1682031c40e9c55e894ab9 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 16:54:26 -0800 Subject: [PATCH 051/101] h_left works --- src/bindings/php/Tests/LeftTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/bindings/php/Tests/LeftTest.php diff --git a/src/bindings/php/Tests/LeftTest.php b/src/bindings/php/Tests/LeftTest.php new file mode 100644 index 0000000..4f50e0e --- /dev/null +++ b/src/bindings/php/Tests/LeftTest.php @@ -0,0 +1,28 @@ +parser = h_left(h_ch("a"), h_ch(" ")); + } + public function testSuccess() + { + $result = h_parse($this->parser, "a "); + // TODO fix these tests when h_ch is fixed + $this->assertEquals(97, $result); + } + public function testFailure() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, " "); + $result3 = h_parse($this->parser, "ab"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + $this->assertEquals(NULL, $result3); + } +} +?> \ No newline at end of file From 72edbfa1678aa9d295562f3746291e32492abecb Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 16:58:27 -0800 Subject: [PATCH 052/101] so do h_right and h_middle --- src/bindings/php/Tests/MiddleTest.php | 36 +++++++++++++++++++++++++++ src/bindings/php/Tests/RightTest.php | 28 +++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/bindings/php/Tests/MiddleTest.php create mode 100644 src/bindings/php/Tests/RightTest.php diff --git a/src/bindings/php/Tests/MiddleTest.php b/src/bindings/php/Tests/MiddleTest.php new file mode 100644 index 0000000..c284b50 --- /dev/null +++ b/src/bindings/php/Tests/MiddleTest.php @@ -0,0 +1,36 @@ +parser = h_middle(h_ch(" "), h_ch("a"), h_ch(" ")); + } + public function testSuccess() + { + $result = h_parse($this->parser, " a "); + // TODO fix these tests when h_ch is fixed + $this->assertEquals(97, $result); + } + public function testFailure() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, " "); + $result3 = h_parse($this->parser, " a"); + $result4 = h_parse($this->parser, "a "); + $result5 = h_parse($this->parser, " b "); + $result6 = h_parse($this->parser, "ba "); + $result7 = h_parse($this->parser, " ab"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + $this->assertEquals(NULL, $result3); + $this->assertEquals(NULL, $result4); + $this->assertEquals(NULL, $result5); + $this->assertEquals(NULL, $result6); + $this->assertEquals(NULL, $result7); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/RightTest.php b/src/bindings/php/Tests/RightTest.php new file mode 100644 index 0000000..c664251 --- /dev/null +++ b/src/bindings/php/Tests/RightTest.php @@ -0,0 +1,28 @@ +parser = h_right(h_ch(" "), h_ch("a")); + } + public function testSuccess() + { + $result = h_parse($this->parser, " a"); + // TODO fix these tests when h_ch is fixed + $this->assertEquals(97, $result); + } + public function testFailure() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, " "); + $result3 = h_parse($this->parser, "ba"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + $this->assertEquals(NULL, $result3); + } +} +?> \ No newline at end of file From ce5a621ee3f20b082b95a36807367c8ee8edff1d Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 17:10:24 -0800 Subject: [PATCH 053/101] h_action test is written, but something is wrong with h_choice. --- src/bindings/php/Tests/ActionTest.php | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/bindings/php/Tests/ActionTest.php diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php new file mode 100644 index 0000000..699812c --- /dev/null +++ b/src/bindings/php/Tests/ActionTest.php @@ -0,0 +1,32 @@ +parser = h_action(h_sequence(h_choice(h_ch("a"), h_ch("A")), h_choice(h_ch("b"), h_ch("B"))), "actTest"); + } + public function testSuccess() + { + $result1 = h_parse($this->parser, "ab"); + $result2 = h_parse($this->parser, "AB"); + $result3 = h_parse($this->parser, "aB"); + $this->assertEquals("AB", $result1); + $this->assertEquals("AB", $result2); + $this->assertEquals("AB", $result3); + } + public function testFailure() + { + $result = h_parse($this->parser, "XX"); + $this->assertEquals(NULL, $result); + } +} + +?> \ No newline at end of file From 48d6cf6f8890525908f0e941d6e2ed3d05c15dea Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 17:17:18 -0800 Subject: [PATCH 054/101] h_in and h_not_in also have a wrong param count issue --- src/bindings/php/Tests/InTest.php | 24 ++++++++++++++++++++++++ src/bindings/php/Tests/NotInTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/bindings/php/Tests/InTest.php create mode 100644 src/bindings/php/Tests/NotInTest.php diff --git a/src/bindings/php/Tests/InTest.php b/src/bindings/php/Tests/InTest.php new file mode 100644 index 0000000..5c2ed8c --- /dev/null +++ b/src/bindings/php/Tests/InTest.php @@ -0,0 +1,24 @@ +parser = h_in("abc"); + } + public function testSuccess() + { + $result = h_parse($this->parser, "b"); + // TODO: fixme when h_ch is fixed + $this->assertEquals(98, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "d"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/NotInTest.php b/src/bindings/php/Tests/NotInTest.php new file mode 100644 index 0000000..44a12a7 --- /dev/null +++ b/src/bindings/php/Tests/NotInTest.php @@ -0,0 +1,24 @@ +parser = h_not_in("abc"); + } + public function testSuccess() + { + $result = h_parse($this->parser, "d"); + // TODO: fixme when h_ch is fixed + $this->assertEquals(100, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "b"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From aa10384709c14f65f160747e170d51a260336e33 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 30 Nov 2013 17:18:58 -0800 Subject: [PATCH 055/101] and so does h_sequence. time to fix this in swig. --- src/bindings/php/Tests/EndTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/bindings/php/Tests/EndTest.php diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php new file mode 100644 index 0000000..b3fc6c6 --- /dev/null +++ b/src/bindings/php/Tests/EndTest.php @@ -0,0 +1,24 @@ +parser = h_sequence(h_ch("a"), h_end_p()); + } + public function testSuccess() + { + $result = h_parse($this->parser, "a"); + // TODO: fixme when h_ch is fixed + $this->assertEquals(98, $result); + } + public function testFailure() + { + $result = h_parse($this->parser, "aa"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 4d649d93d303ca0362b26cc99bf729b4f4811f48 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 16:07:25 -0800 Subject: [PATCH 056/101] fixed ch; need to figure out what to do with an array of SWIG wrapped types for sequence/choice --- src/bindings/php/SConscript | 2 +- src/bindings/php/Tests/ActionTest.php | 2 +- src/bindings/php/Tests/ChTest.php | 2 +- src/bindings/php/Tests/EndTest.php | 10 +++++--- src/bindings/php/Tests/LeftTest.php | 4 ++-- src/bindings/php/Tests/MiddleTest.php | 4 ++-- src/bindings/php/Tests/RightTest.php | 4 ++-- src/bindings/php/Tests/WhitespaceTest.php | 10 ++++---- src/bindings/swig/hammer.i | 29 +++++++++++++++++++++++ 9 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 919677b..94c9d83 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -23,7 +23,7 @@ phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_p AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) -phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") +phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --debug --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) testruns.append(phptest) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 699812c..250dd24 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -11,7 +11,7 @@ class ActionTest extends PHPUnit_Framework_TestCase } protected function setUp() { - $this->parser = h_action(h_sequence(h_choice(h_ch("a"), h_ch("A")), h_choice(h_ch("b"), h_ch("B"))), "actTest"); + $this->parser = h_action(h_sequence(h_choice(ch("a"), ch("A")), h_choice(ch("b"), ch("B"))), "actTest"); } public function testSuccess() { diff --git a/src/bindings/php/Tests/ChTest.php b/src/bindings/php/Tests/ChTest.php index f18cdfb..e05ad24 100644 --- a/src/bindings/php/Tests/ChTest.php +++ b/src/bindings/php/Tests/ChTest.php @@ -8,7 +8,7 @@ class ChTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_ch("\xa2"); + $this->parser = ch("\xa2"); } public function testSuccess() { diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index b3fc6c6..55e05b8 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -7,18 +7,22 @@ class EndPTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_sequence(h_ch("a"), h_end_p()); + $this->parser = sequence(ch("a"), h_end_p()); } + public function testSuccess() { - $result = h_parse($this->parser, "a"); + echo 'in testSuccess\n'; +// $result = h_parse($this->parser, "a"); // TODO: fixme when h_ch is fixed - $this->assertEquals(98, $result); +// $this->assertEquals(98, $result); } +/* public function testFailure() { $result = h_parse($this->parser, "aa"); $this->assertEquals(NULL, $result); } +*/ } ?> \ No newline at end of file diff --git a/src/bindings/php/Tests/LeftTest.php b/src/bindings/php/Tests/LeftTest.php index 4f50e0e..1b2a906 100644 --- a/src/bindings/php/Tests/LeftTest.php +++ b/src/bindings/php/Tests/LeftTest.php @@ -7,13 +7,13 @@ class LeftTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_left(h_ch("a"), h_ch(" ")); + $this->parser = h_left(ch("a"), ch(" ")); } public function testSuccess() { $result = h_parse($this->parser, "a "); // TODO fix these tests when h_ch is fixed - $this->assertEquals(97, $result); + $this->assertEquals("a", $result); } public function testFailure() { diff --git a/src/bindings/php/Tests/MiddleTest.php b/src/bindings/php/Tests/MiddleTest.php index c284b50..99dbb87 100644 --- a/src/bindings/php/Tests/MiddleTest.php +++ b/src/bindings/php/Tests/MiddleTest.php @@ -7,13 +7,13 @@ class MiddleTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_middle(h_ch(" "), h_ch("a"), h_ch(" ")); + $this->parser = h_middle(ch(" "), ch("a"), ch(" ")); } public function testSuccess() { $result = h_parse($this->parser, " a "); // TODO fix these tests when h_ch is fixed - $this->assertEquals(97, $result); + $this->assertEquals("a", $result); } public function testFailure() { diff --git a/src/bindings/php/Tests/RightTest.php b/src/bindings/php/Tests/RightTest.php index c664251..d5d4428 100644 --- a/src/bindings/php/Tests/RightTest.php +++ b/src/bindings/php/Tests/RightTest.php @@ -7,13 +7,13 @@ class RightTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_right(h_ch(" "), h_ch("a")); + $this->parser = h_right(ch(" "), ch("a")); } public function testSuccess() { $result = h_parse($this->parser, " a"); // TODO fix these tests when h_ch is fixed - $this->assertEquals(97, $result); + $this->assertEquals("a", $result); } public function testFailure() { diff --git a/src/bindings/php/Tests/WhitespaceTest.php b/src/bindings/php/Tests/WhitespaceTest.php index 64da3a2..73c4d45 100644 --- a/src/bindings/php/Tests/WhitespaceTest.php +++ b/src/bindings/php/Tests/WhitespaceTest.php @@ -8,7 +8,7 @@ class WhitespaceTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = h_whitespace(h_ch("a")); + $this->parser1 = h_whitespace(ch("a")); $this->parser2 = h_whitespace(h_end_p()); } public function testSuccess1() @@ -18,10 +18,10 @@ class WhitespaceTest extends PHPUnit_Framework_TestCase $result3 = h_parse($this->parser1, " a"); $result4 = h_parse($this->parser1, "\ta"); // TODO fix these tests when h_ch is fixed - $this->assertEquals(97, $result1); - $this->assertEquals(97, $result2); - $this->assertEquals(97, $result3); - $this->assertEquals(97, $result4); + $this->assertEquals("a", $result1); + $this->assertEquals("a", $result2); + $this->assertEquals("a", $result3); + $this->assertEquals("a", $result4); } public function testFailure1() { diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 49b9b6f..be69675 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -538,4 +538,33 @@ def int64(): return _h_int64() return tok; } } + +%pragma(php) code=" + +function ch($ch) +{ + if (is_string($ch)) + return h_token($ch); + else + return h_ch($ch); +} + +function sequence() +{ + echo 'in sequence\n'; + $numargs = func_num_args(); + $arg_list = func_get_args(); + var_dump($arg_list); + for ($i = 0; $i < $numargs; $i++) + { + var_dump($arg_list[$i] instanceof _p_HParser_); + if (! $arg_list[$i] instanceof _p_HParser_) + { + echo 'PHP says that is not an HParser!'; + return NULL; + } + } + //return hammer::h_sequence__a($arg_list); +} +" #endif From d544c2f4bb2964ee757c2a5e148cac452c77ced1 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 17:21:05 -0800 Subject: [PATCH 057/101] sequence is still segfaulting; its inner parsers seem to be getting corrupted somehow --- src/bindings/php/Tests/EndTest.php | 8 ++------ src/bindings/swig/hammer.i | 22 +++++++++------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 55e05b8..92e4965 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -12,17 +12,13 @@ class EndPTest extends PHPUnit_Framework_TestCase public function testSuccess() { - echo 'in testSuccess\n'; -// $result = h_parse($this->parser, "a"); - // TODO: fixme when h_ch is fixed -// $this->assertEquals(98, $result); + $result = h_parse($this->parser, "a"); + $this->assertEquals("a", $result); } -/* public function testFailure() { $result = h_parse($this->parser, "aa"); $this->assertEquals(NULL, $result); } -*/ } ?> \ No newline at end of file diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index be69675..eb6428a 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -549,22 +549,18 @@ function ch($ch) return h_ch($ch); } +function choice() +{ + $arg_list = func_get_args(); + $arg_list[] = NULL; + return h_choice__a($arg_list); +} + function sequence() { - echo 'in sequence\n'; - $numargs = func_num_args(); $arg_list = func_get_args(); - var_dump($arg_list); - for ($i = 0; $i < $numargs; $i++) - { - var_dump($arg_list[$i] instanceof _p_HParser_); - if (! $arg_list[$i] instanceof _p_HParser_) - { - echo 'PHP says that is not an HParser!'; - return NULL; - } - } - //return hammer::h_sequence__a($arg_list); + $arg_list[] = NULL; + return h_sequence__a($arg_list); } " #endif From 9f55409246afee482212220ff4ecda513cfd0ba4 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 20:55:04 -0800 Subject: [PATCH 058/101] EndTest is still failing, but the void*[] typemap isn't segfaulting anymore --- src/bindings/php/Tests/EndTest.php | 4 +++- src/bindings/swig/hammer.i | 24 ++++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 92e4965..0b7ef42 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -12,12 +12,14 @@ class EndPTest extends PHPUnit_Framework_TestCase public function testSuccess() { - $result = h_parse($this->parser, "a"); + $result = h_parse($this->parser, ["a"]); + var_dump($result); $this->assertEquals("a", $result); } public function testFailure() { $result = h_parse($this->parser, "aa"); + var_dump($result); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index eb6428a..5311873 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -171,18 +171,22 @@ int size = zend_hash_num_elements(arr); int i = 0; int res = 0; - $1 = (void**)malloc((size+1)*sizeof(HParser*)); - for (zend_hash_internal_pointer_reset_ex(arr, &pointer); - zend_hash_get_current_data_ex(arr, (void**)&data, &pointer); - zend_hash_move_forward_ex(arr, &pointer), i++) { - res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0); - if (!SWIG_IsOk(res)) { - // TODO do we not *have* SWIG_TypeError? - SWIG_exception_fail(res, "that wasn't an HParser"); + $1 = (void**)malloc((size)*sizeof(HParser*)); + for (i=0; i Date: Sun, 1 Dec 2013 21:04:54 -0800 Subject: [PATCH 059/101] nothing_p works; EndTest's failure case is producing an empty array (successful but empty sequence), success case is *also* producing an empty array --- src/bindings/php/Tests/EndTest.php | 6 +++--- src/bindings/php/Tests/NothingTest.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 src/bindings/php/Tests/NothingTest.php diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 0b7ef42..53955ed 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -12,15 +12,15 @@ class EndPTest extends PHPUnit_Framework_TestCase public function testSuccess() { - $result = h_parse($this->parser, ["a"]); + $result = h_parse($this->parser, "a"); var_dump($result); - $this->assertEquals("a", $result); + $this->assertEquals(array("a"), $result); } public function testFailure() { $result = h_parse($this->parser, "aa"); var_dump($result); - $this->assertEquals(NULL, $result); + $this->assertEquals(array(), $result); } } ?> \ No newline at end of file diff --git a/src/bindings/php/Tests/NothingTest.php b/src/bindings/php/Tests/NothingTest.php new file mode 100644 index 0000000..fa31b55 --- /dev/null +++ b/src/bindings/php/Tests/NothingTest.php @@ -0,0 +1,19 @@ +parser = h_nothing_p(); + } + + public function testFailure() + { + $result = h_parse($this->parser, "a"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 1ce63c26ec1aeefe030e28dd3b01d78168b0a965 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:11:15 -0800 Subject: [PATCH 060/101] sequence is definitely broken, results aren't landing in output array --- src/bindings/php/Tests/EndTest.php | 2 +- src/bindings/php/Tests/SequenceTest.php | 39 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/bindings/php/Tests/SequenceTest.php diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 53955ed..6a871fa 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -20,7 +20,7 @@ class EndPTest extends PHPUnit_Framework_TestCase { $result = h_parse($this->parser, "aa"); var_dump($result); - $this->assertEquals(array(), $result); + $this->assertEquals(NULL, $result); } } ?> \ No newline at end of file diff --git a/src/bindings/php/Tests/SequenceTest.php b/src/bindings/php/Tests/SequenceTest.php new file mode 100644 index 0000000..67ae1f0 --- /dev/null +++ b/src/bindings/php/Tests/SequenceTest.php @@ -0,0 +1,39 @@ +parser1 = sequence(ch("a"), ch("b")); + $this->parser2 = sequence(ch("a"), h_whitespace(ch("b"))); + } + + public function testSuccess1() + { + $result = h_parse($this->parser1, "ab"); + $this->assertEquals(array("a", "b"), $result); + } + + public function testFailure1() + { + $result1 = h_parse($this->parser1, "a"); + $result2 = h_parse($this->parser2, "b"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + } + + public function testSuccess2() + { + $result1 = h_parse($this->parser2, "ab"); + $result2 = h_parse($this->parser2, "a b"); + $result3 = h_parse($this->parser2, "a b"); + $this->assertEquals(array("a", "b"), $result1); + $this->assertEquals(array("a", "b"), $result2); + $this->assertEquals(array("a", "b"), $result3); + } +} +?> \ No newline at end of file From 80d4460e6e19723f60cd4aaec3c040a650632fde Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:14:16 -0800 Subject: [PATCH 061/101] choice isn't putting its results in the right place either --- src/bindings/php/Tests/ChoiceTest.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/bindings/php/Tests/ChoiceTest.php diff --git a/src/bindings/php/Tests/ChoiceTest.php b/src/bindings/php/Tests/ChoiceTest.php new file mode 100644 index 0000000..42bb0a9 --- /dev/null +++ b/src/bindings/php/Tests/ChoiceTest.php @@ -0,0 +1,27 @@ +parser = choice(ch("a"), ch("b")); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, "b"); + $this->assertEquals("a", $result1); + $this->assertEquals("b", $result2); + } + + public function testFailure() + { + $result = h_parse($this->parser, "c"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 378710844bdbd4d5c01b8a7e6c665e2862b42bb3 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:18:33 -0800 Subject: [PATCH 062/101] h_butnot is fine --- src/bindings/php/Tests/ButNotTest.php | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/bindings/php/Tests/ButNotTest.php diff --git a/src/bindings/php/Tests/ButNotTest.php b/src/bindings/php/Tests/ButNotTest.php new file mode 100644 index 0000000..9f8117a --- /dev/null +++ b/src/bindings/php/Tests/ButNotTest.php @@ -0,0 +1,35 @@ +parser1 = h_butnot(ch("a"), h_token("ab")); + $this->parser2 = h_butnot(h_ch_range('0', '9'), ch('6')); + } + + public function testSuccess1() + { + $result1 = h_parse($this->parser1, "a"); + $result2 = h_parse($this->parser1, "aa"); + $this->assertEquals("a", $result1); + $this->assertEquals("a", $result1); + } + + public function testFailure1() + { + $result = h_parse($this->parser1, "ab"); + $this->assertEquals(NULL, $result); + } + + public function testFailure2() + { + $result = h_parse($this->parser2, "6"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From 0c9ab03fd793dd9eef621b9f9b07b06c01029486 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:21:00 -0800 Subject: [PATCH 063/101] h_difference works --- src/bindings/php/Tests/DifferenceTest.php | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/bindings/php/Tests/DifferenceTest.php diff --git a/src/bindings/php/Tests/DifferenceTest.php b/src/bindings/php/Tests/DifferenceTest.php new file mode 100644 index 0000000..88c1903 --- /dev/null +++ b/src/bindings/php/Tests/DifferenceTest.php @@ -0,0 +1,25 @@ +parser = h_difference(h_token("ab"), ch("a")); + } + + public function testSuccess() + { + $result = h_parse($this->parser, "ab"); + $this->assertEquals("ab", $result); + } + + public function testFailure() + { + $result = h_parse($this->parser, "a"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file From a10572e7510310add05c764a838ea2f4991aa06b Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:25:28 -0800 Subject: [PATCH 064/101] AFAIK h_xor just needs h_ch_range working correctly --- src/bindings/php/Tests/XorTest.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/bindings/php/Tests/XorTest.php diff --git a/src/bindings/php/Tests/XorTest.php b/src/bindings/php/Tests/XorTest.php new file mode 100644 index 0000000..67e8bf3 --- /dev/null +++ b/src/bindings/php/Tests/XorTest.php @@ -0,0 +1,29 @@ +parser = h_xor(h_ch_range("0", "6"), h_ch_range("5", "9")); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "0"); + $result2 = h_parse($this->parser, "9"); + $this->assertEquals("0", $result1); + $this->assertEquals("9", $result2); + } + + public function testFailure() + { + $result1 = h_parse($this->parser, "5"); + $result2 = h_parse($this->parser, "a"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + } +} +?> \ No newline at end of file From e9de06636d351dd9c87e1fc36fcfd8daa1382dc1 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:29:11 -0800 Subject: [PATCH 065/101] h_many is failing because of the problem with choice not returning results correctly --- src/bindings/php/Tests/ManyTest.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/bindings/php/Tests/ManyTest.php diff --git a/src/bindings/php/Tests/ManyTest.php b/src/bindings/php/Tests/ManyTest.php new file mode 100644 index 0000000..ef1d096 --- /dev/null +++ b/src/bindings/php/Tests/ManyTest.php @@ -0,0 +1,25 @@ +parser = h_many(choice(ch("a"), ch("b"))); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, ""); + $result2 = h_parse($this->parser, "a"); + $result3 = h_parse($this->parser, "b"); + $result4 = h_parse($this->parser, "aabbaba"); + $this->assertEquals(array(), $result); + $this->assertEquals(array("a"), $result); + $this->assertEquals(array("b"), $result); + $this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result); + } +} +?> \ No newline at end of file From eef5378f169131d19067f09ce98535637161d19c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:33:02 -0800 Subject: [PATCH 066/101] h_many1's test is failing for the same reason as h_many --- src/bindings/php/Tests/Many1Test.php | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/bindings/php/Tests/Many1Test.php diff --git a/src/bindings/php/Tests/Many1Test.php b/src/bindings/php/Tests/Many1Test.php new file mode 100644 index 0000000..61356e7 --- /dev/null +++ b/src/bindings/php/Tests/Many1Test.php @@ -0,0 +1,31 @@ +parser = h_many1(choice(ch("a"), ch("b"))); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, "b"); + $result3 = h_parse($this->parser, "aabbaba"); + $this->assertEquals(array("a"), $result1); + $this->assertEquals(array("b"), $result2); + $this->assertEquals(array("c"), $result3); + } + + public function testFailure() + { + $result1 = h_parse($this->parser, ""); + $result2 = h_parse($this->parser, "daabbabadef"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + } +} +?> \ No newline at end of file From eb2855dcb46fe9a462948032dae8256b02b4cf30 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:37:09 -0800 Subject: [PATCH 067/101] h_repeat_n's test is failing for the same reason as h_many --- src/bindings/php/Tests/RepeatNTest.php | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/bindings/php/Tests/RepeatNTest.php diff --git a/src/bindings/php/Tests/RepeatNTest.php b/src/bindings/php/Tests/RepeatNTest.php new file mode 100644 index 0000000..e6db964 --- /dev/null +++ b/src/bindings/php/Tests/RepeatNTest.php @@ -0,0 +1,27 @@ +parser = h_repeat_n(choice(ch("a"), ch("b")), 2); + } + + public function testSuccess() + { + $result = h_parse($this->parser, "abdef"); + $this->assertEquals(array("a", "b"), $result); + } + + public function testFailure() + { + $result1 = h_parse($this->parser, "adef"); + $result2 = h_parse($this->parser, "dabdef"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + } +} +?> \ No newline at end of file From a234bdfab3162f22401e73fd4fef26b41747d70a Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:44:45 -0800 Subject: [PATCH 068/101] still more tests failing because sequence/choice don't return right --- src/bindings/php/Tests/IgnoreTest.php | 25 +++++++++++++++++++ src/bindings/php/Tests/OptionalTest.php | 33 +++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/bindings/php/Tests/IgnoreTest.php create mode 100644 src/bindings/php/Tests/OptionalTest.php diff --git a/src/bindings/php/Tests/IgnoreTest.php b/src/bindings/php/Tests/IgnoreTest.php new file mode 100644 index 0000000..82ef554 --- /dev/null +++ b/src/bindings/php/Tests/IgnoreTest.php @@ -0,0 +1,25 @@ +parser = sequence(ch("a"), h_ignore(ch("b")), ch("c")); + } + + public function testSuccess() + { + $result = h_parse($this->parser, "abc"); + $this->assertEquals(array("a", "c"), $result); + } + + public function testFailure() + { + $result = h_parse($this->parser, "ac"); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/OptionalTest.php b/src/bindings/php/Tests/OptionalTest.php new file mode 100644 index 0000000..22b15df --- /dev/null +++ b/src/bindings/php/Tests/OptionalTest.php @@ -0,0 +1,33 @@ +parser = sequence(ch("a"), h_optional(choice(ch("b"), ch("c"))), ch("d")); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "abd"); + $result2 = h_parse($this->parser, "acd"); + $result3 = h_parse($this->parser, "ad"); + $this->assertEquals(array("a", "b", "d"), $result1); + $this->assertEquals(array("a", "c", "d"), $result2); + $this->assertEquals(array("a", NULL, "d"), $result3); + } + + public function testFailure() + { + $result1 = h_parse($this->parser, "aed"); + $result2 = h_parse($this->parser, "ab"); + $result3 = h_parse($this->parser, "ac"); + $this->assertEquals(NULL, $result1); + $this->assertEquals(NULL, $result2); + $this->assertEquals(NULL, $result3); + } +} +?> \ No newline at end of file From 5c5a10b5c1d56e42153bc1dc7b88571f7d3d510b Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 21:51:57 -0800 Subject: [PATCH 069/101] sepby also plagued by sequence/choice return issues --- src/bindings/php/Tests/SepBy1Test.php | 31 +++++++++++++++++++++++++++ src/bindings/php/Tests/SepByTest.php | 27 +++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/bindings/php/Tests/SepBy1Test.php create mode 100644 src/bindings/php/Tests/SepByTest.php diff --git a/src/bindings/php/Tests/SepBy1Test.php b/src/bindings/php/Tests/SepBy1Test.php new file mode 100644 index 0000000..a5a36cc --- /dev/null +++ b/src/bindings/php/Tests/SepBy1Test.php @@ -0,0 +1,31 @@ +parser = h_sepBy1(choice(ch("1"), ch("2"), ch("3")), ch(",")); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "1,2,3"); + $result2 = h_parse($this->parser, "1,3,2"); + $result3 = h_parse($this->parser, "1,3"); + $result4 = h_parse($this->parser, "3"); + $this->assertEquals(array("1", "2", "3"), $result1); + $this->assertEquals(array("1", "3", "2"), $result2); + $this->assertEquals(array("1", "3"), $result3); + $this->assertEquals(array("3"), $result4); + } + + public function testFailure() + { + $result = h_parse($this->parser, ""); + $this->assertEquals(NULL, $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/SepByTest.php b/src/bindings/php/Tests/SepByTest.php new file mode 100644 index 0000000..fdf4ed4 --- /dev/null +++ b/src/bindings/php/Tests/SepByTest.php @@ -0,0 +1,27 @@ +parser = h_sepBy(choice(ch("1"), ch("2"), ch("3")), ch(",")); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "1,2,3"); + $result2 = h_parse($this->parser, "1,3,2"); + $result3 = h_parse($this->parser, "1,3"); + $result4 = h_parse($this->parser, "3"); + $result5 = h_parse($this->parser, ""); + $this->assertEquals(array("1", "2", "3"), $result1); + $this->assertEquals(array("1", "3", "2"), $result2); + $this->assertEquals(array("1", "3"), $result3); + $this->assertEquals(array("3"), $result4); + $this->assertEquals(array(), $result5); + } +} +?> \ No newline at end of file From 60d096bc16c389cc6f0965bac6a5cd812345087c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 22:09:45 -0800 Subject: [PATCH 070/101] more tests written, need to fix that retval problem stat --- src/bindings/php/Tests/AndTest.php | 35 +++++++++++++++++++++++++ src/bindings/php/Tests/EpsilonPTest.php | 35 +++++++++++++++++++++++++ src/bindings/php/Tests/LeftrecTest.php | 24 +++++++++++++++++ src/bindings/php/Tests/NotTest.php | 35 +++++++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 src/bindings/php/Tests/AndTest.php create mode 100644 src/bindings/php/Tests/EpsilonPTest.php create mode 100644 src/bindings/php/Tests/LeftrecTest.php create mode 100644 src/bindings/php/Tests/NotTest.php diff --git a/src/bindings/php/Tests/AndTest.php b/src/bindings/php/Tests/AndTest.php new file mode 100644 index 0000000..03f9258 --- /dev/null +++ b/src/bindings/php/Tests/AndTest.php @@ -0,0 +1,35 @@ +parser1 = sequence(h_and(ch("0")), ch("0")); + $this->parser2 = sequence(h_and(ch("0")), ch("1")); + $this->parser3 = sequence(ch("1"), h_and(ch("2"))); + } + + public function testSuccess1() + { + $result = h_parse($this->parser1, "0"); + $this->assertEquals(array("0"), $result); + } + + public function testFailure2() + { + $result = h_parse($this->parser2, "0"); + $this->assertEquals(NULL, $result); + } + + public function testSuccess3() + { + $result = h_parse($this->parser3, "12"); + $this->assertEquals(array("1"), $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/EpsilonPTest.php b/src/bindings/php/Tests/EpsilonPTest.php new file mode 100644 index 0000000..432afef --- /dev/null +++ b/src/bindings/php/Tests/EpsilonPTest.php @@ -0,0 +1,35 @@ +parser1 = sequence(ch("a"), h_epsilon_p(), ch("b")); + $this->parser2 = sequence(h_epsilon_p(), ch("a")); + $this->parser3 = sequence(ch("a"), h_epsilon_p()); + } + + public function testSuccess1() + { + $result = h_parse($this->parser1, "ab"); + $this->assertEquals(array("a", "b"), $result); + } + + public function testSuccess2() + { + $result = h_parse($this->parser2, "a"); + $this->assertEquals(array("a"), $result); + } + + public function testSuccess3() + { + $result = h_parse($this->parser3, "ab"); + $this->assertEquals(array("a"), $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/LeftrecTest.php b/src/bindings/php/Tests/LeftrecTest.php new file mode 100644 index 0000000..1a2878e --- /dev/null +++ b/src/bindings/php/Tests/LeftrecTest.php @@ -0,0 +1,24 @@ +parser = h_indirect(); + h_bind_indirect($this->parser, choice(sequence($this->parser, ch("a")), ch("a"))); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, "aa"); + $result3 = h_parse($this->parser, "aaa"); + $this->assertEquals("a", $result1); + $this->assertEquals(array("a", "a"), $result); + $this->assertEquals(array(array("a", "a"), "a"), $result); + } +} +?> \ No newline at end of file diff --git a/src/bindings/php/Tests/NotTest.php b/src/bindings/php/Tests/NotTest.php new file mode 100644 index 0000000..a2c76aa --- /dev/null +++ b/src/bindings/php/Tests/NotTest.php @@ -0,0 +1,35 @@ +parser1 = sequence(ch("a"), choice(ch("+"), h_token("++")), ch("b")); + $this->parser2 = sequence(ch("a"), choice(sequence(ch("+"), h_not(ch("+"))), h_token("++")), ch("b")); + } + + public function testSuccess1() + { + $result = h_parse($this->parser1, "a+b"); + $this->assertEquals(array("a", "+", "b"), $result); + } + + public function testFailure1() + { + $result = h_parse($this->parser1, "a++b"); + $this->assertEquals(NULL, $result); + } + + public function testSuccess2() + { + $result1 = h_parse($this->parser2, "a+b"); + $result2 = h_parse($this->parser2, "a++b"); + $this->assertEquals(array("a", array("+"), "b"), $result1); + $this->assertEquals(array("a", "++", "b"), $result2); + } +} +?> \ No newline at end of file From 96470902e2555016ee813612e6524c8adf2df306 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 22:13:24 -0800 Subject: [PATCH 071/101] all tests written. --- src/bindings/php/Tests/RightrecTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/bindings/php/Tests/RightrecTest.php diff --git a/src/bindings/php/Tests/RightrecTest.php b/src/bindings/php/Tests/RightrecTest.php new file mode 100644 index 0000000..9580fde --- /dev/null +++ b/src/bindings/php/Tests/RightrecTest.php @@ -0,0 +1,24 @@ +parser = h_indirect(); + h_bind_indirect($this->parser, choice(sequence(ch("a"), $this->parser), h_epsilon_p())); + } + + public function testSuccess() + { + $result1 = h_parse($this->parser, "a"); + $result2 = h_parse($this->parser, "aa"); + $result3 = h_parse($this->parser, "aaa"); + $this->assertEquals(array("a"), $result1); + $this->assertEquals(array("a", array("a")), $result2); + $this->assertEquals(array("a", array("a", array("a"))), $result3); + } +} +?> \ No newline at end of file From 4735d179087161834aa0537fab7c6d85ce21e2d0 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 1 Dec 2013 22:14:51 -0800 Subject: [PATCH 072/101] ActionTest has something wrong with its argument. --- src/bindings/php/Tests/ActionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 250dd24..619ea4a 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -11,7 +11,7 @@ class ActionTest extends PHPUnit_Framework_TestCase } protected function setUp() { - $this->parser = h_action(h_sequence(h_choice(ch("a"), ch("A")), h_choice(ch("b"), ch("B"))), "actTest"); + $this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); } public function testSuccess() { From a09bd5328679d536571d70d4b23684580c5df937 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Tue, 10 Dec 2013 00:53:35 +0100 Subject: [PATCH 073/101] Fixed sequence, choice, h_in and h_not_in. ChRange needs its output coerced to char and we're good. --- src/bindings/php/Tests/ActionTest.php | 18 +++++++++--------- src/bindings/php/Tests/EndTest.php | 2 -- src/bindings/php/Tests/LeftrecTest.php | 20 +++++++++++++++----- src/bindings/php/Tests/Many1Test.php | 2 +- src/bindings/php/Tests/ManyTest.php | 8 ++++---- src/bindings/swig/hammer.i | 9 ++++----- 6 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 619ea4a..0b7540d 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -11,21 +11,21 @@ class ActionTest extends PHPUnit_Framework_TestCase } protected function setUp() { - $this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); + //$this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); } public function testSuccess() { - $result1 = h_parse($this->parser, "ab"); - $result2 = h_parse($this->parser, "AB"); - $result3 = h_parse($this->parser, "aB"); - $this->assertEquals("AB", $result1); - $this->assertEquals("AB", $result2); - $this->assertEquals("AB", $result3); + /* $result1 = h_parse($this->parser, "ab"); */ + /* $result2 = h_parse($this->parser, "AB"); */ + /* $result3 = h_parse($this->parser, "aB"); */ + /* $this->assertEquals("AB", $result1); */ + /* $this->assertEquals("AB", $result2); */ + /* $this->assertEquals("AB", $result3); */ } public function testFailure() { - $result = h_parse($this->parser, "XX"); - $this->assertEquals(NULL, $result); + //$result = h_parse($this->parser, "XX"); + //$this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 6a871fa..773bc36 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -13,13 +13,11 @@ class EndPTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, "a"); - var_dump($result); $this->assertEquals(array("a"), $result); } public function testFailure() { $result = h_parse($this->parser, "aa"); - var_dump($result); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/LeftrecTest.php b/src/bindings/php/Tests/LeftrecTest.php index 1a2878e..63d662a 100644 --- a/src/bindings/php/Tests/LeftrecTest.php +++ b/src/bindings/php/Tests/LeftrecTest.php @@ -11,13 +11,23 @@ class LeftrecTest extends PHPUnit_Framework_TestCase h_bind_indirect($this->parser, choice(sequence($this->parser, ch("a")), ch("a"))); } - public function testSuccess() + public function testSuccess1() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, "aa"); - $result3 = h_parse($this->parser, "aaa"); - $this->assertEquals("a", $result1); + $result = h_parse($this->parser, "a"); + $this->assertEquals("a", $result); + } + + public function testSuccess2() + { + $result = h_parse($this->parser, "aa"); + var_dump($result); $this->assertEquals(array("a", "a"), $result); + } + + public function testSuccess3() + { + $result = h_parse($this->parser, "aaa"); + var_dump($result); $this->assertEquals(array(array("a", "a"), "a"), $result); } } diff --git a/src/bindings/php/Tests/Many1Test.php b/src/bindings/php/Tests/Many1Test.php index 61356e7..cf5071c 100644 --- a/src/bindings/php/Tests/Many1Test.php +++ b/src/bindings/php/Tests/Many1Test.php @@ -17,7 +17,7 @@ class Many1Test extends PHPUnit_Framework_TestCase $result3 = h_parse($this->parser, "aabbaba"); $this->assertEquals(array("a"), $result1); $this->assertEquals(array("b"), $result2); - $this->assertEquals(array("c"), $result3); + $this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result3); } public function testFailure() diff --git a/src/bindings/php/Tests/ManyTest.php b/src/bindings/php/Tests/ManyTest.php index ef1d096..6d249a0 100644 --- a/src/bindings/php/Tests/ManyTest.php +++ b/src/bindings/php/Tests/ManyTest.php @@ -16,10 +16,10 @@ class ManyTest extends PHPUnit_Framework_TestCase $result2 = h_parse($this->parser, "a"); $result3 = h_parse($this->parser, "b"); $result4 = h_parse($this->parser, "aabbaba"); - $this->assertEquals(array(), $result); - $this->assertEquals(array("a"), $result); - $this->assertEquals(array("b"), $result); - $this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result); + $this->assertEquals(array(), $result1); + $this->assertEquals(array("a"), $result2); + $this->assertEquals(array("b"), $result3); + $this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result4); } } ?> \ No newline at end of file diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 5311873..49dec23 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -162,10 +162,9 @@ // RETVAL_STRINGL((char*)$1, $2, 1); // } %apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } - +%apply (const uint8_t* str, const size_t len) { (const uint8_t* charset, size_t length) } %typemap(in) void*[] { if (IS_ARRAY == Z_TYPE_PP($input)) { - zval **data; HashTable *arr = Z_ARRVAL_PP($input); HashPosition pointer; int size = zend_hash_num_elements(arr); @@ -173,8 +172,8 @@ int res = 0; $1 = (void**)malloc((size)*sizeof(HParser*)); for (i=0; itoken_data.bytes.token, token->token_data.bytes.len, 1); - printf("Being returned from hpt_to_php: %s\n", Z_STRVAL_P(ret)); return ret; case TT_SINT: ZVAL_LONG(ret, token->token_data.sint); @@ -566,5 +564,6 @@ function sequence() $arg_list[] = NULL; return h_sequence__a($arg_list); } + " #endif From de02a2450b2918c0680a9e115ab6060a226ca005 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Tue, 10 Dec 2013 01:06:21 +0100 Subject: [PATCH 074/101] decrufted tests that rely on h_ch; still need to do h_action and h_attr_bool --- src/bindings/php/Tests/InTest.php | 3 +-- src/bindings/php/Tests/LeftTest.php | 1 - src/bindings/php/Tests/MiddleTest.php | 1 - src/bindings/php/Tests/NotInTest.php | 3 +-- src/bindings/php/Tests/RightTest.php | 1 - src/bindings/php/Tests/WhitespaceTest.php | 1 - 6 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/bindings/php/Tests/InTest.php b/src/bindings/php/Tests/InTest.php index 5c2ed8c..6d1c562 100644 --- a/src/bindings/php/Tests/InTest.php +++ b/src/bindings/php/Tests/InTest.php @@ -12,8 +12,7 @@ class InTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, "b"); - // TODO: fixme when h_ch is fixed - $this->assertEquals(98, $result); + $this->assertEquals("b", $result); } public function testFailure() { diff --git a/src/bindings/php/Tests/LeftTest.php b/src/bindings/php/Tests/LeftTest.php index 1b2a906..c671a80 100644 --- a/src/bindings/php/Tests/LeftTest.php +++ b/src/bindings/php/Tests/LeftTest.php @@ -12,7 +12,6 @@ class LeftTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, "a "); - // TODO fix these tests when h_ch is fixed $this->assertEquals("a", $result); } public function testFailure() diff --git a/src/bindings/php/Tests/MiddleTest.php b/src/bindings/php/Tests/MiddleTest.php index 99dbb87..1ccb9da 100644 --- a/src/bindings/php/Tests/MiddleTest.php +++ b/src/bindings/php/Tests/MiddleTest.php @@ -12,7 +12,6 @@ class MiddleTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, " a "); - // TODO fix these tests when h_ch is fixed $this->assertEquals("a", $result); } public function testFailure() diff --git a/src/bindings/php/Tests/NotInTest.php b/src/bindings/php/Tests/NotInTest.php index 44a12a7..4a220d3 100644 --- a/src/bindings/php/Tests/NotInTest.php +++ b/src/bindings/php/Tests/NotInTest.php @@ -12,8 +12,7 @@ class NotInTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, "d"); - // TODO: fixme when h_ch is fixed - $this->assertEquals(100, $result); + $this->assertEquals("d", $result); } public function testFailure() { diff --git a/src/bindings/php/Tests/RightTest.php b/src/bindings/php/Tests/RightTest.php index d5d4428..3c5b06e 100644 --- a/src/bindings/php/Tests/RightTest.php +++ b/src/bindings/php/Tests/RightTest.php @@ -12,7 +12,6 @@ class RightTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result = h_parse($this->parser, " a"); - // TODO fix these tests when h_ch is fixed $this->assertEquals("a", $result); } public function testFailure() diff --git a/src/bindings/php/Tests/WhitespaceTest.php b/src/bindings/php/Tests/WhitespaceTest.php index 73c4d45..96c2f38 100644 --- a/src/bindings/php/Tests/WhitespaceTest.php +++ b/src/bindings/php/Tests/WhitespaceTest.php @@ -17,7 +17,6 @@ class WhitespaceTest extends PHPUnit_Framework_TestCase $result2 = h_parse($this->parser1, " a"); $result3 = h_parse($this->parser1, " a"); $result4 = h_parse($this->parser1, "\ta"); - // TODO fix these tests when h_ch is fixed $this->assertEquals("a", $result1); $this->assertEquals("a", $result2); $this->assertEquals("a", $result3); From 8c074420f71b35b89fac560bac79620135a846de Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 11 Dec 2013 06:49:52 +0100 Subject: [PATCH 075/101] redefine in() and not_in() in terms of action with 'chr' --- src/bindings/php/Tests/InTest.php | 2 +- src/bindings/php/Tests/NotInTest.php | 2 +- src/bindings/swig/hammer.i | 34 +++++++++++++++++++++------- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/bindings/php/Tests/InTest.php b/src/bindings/php/Tests/InTest.php index 6d1c562..cdc1e93 100644 --- a/src/bindings/php/Tests/InTest.php +++ b/src/bindings/php/Tests/InTest.php @@ -7,7 +7,7 @@ class InTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_in("abc"); + $this->parser = in("abc"); } public function testSuccess() { diff --git a/src/bindings/php/Tests/NotInTest.php b/src/bindings/php/Tests/NotInTest.php index 4a220d3..f06e53f 100644 --- a/src/bindings/php/Tests/NotInTest.php +++ b/src/bindings/php/Tests/NotInTest.php @@ -7,7 +7,7 @@ class NotInTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_not_in("abc"); + $this->parser = not_in("abc"); } public function testSuccess() { diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index 49dec23..d7cf3a0 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -204,11 +204,19 @@ RETVAL_STRINGL((char*)$1->token, $1->len, 1); } -/* TODO do we need this anymore? -%typemap(out) struct HCountedArray_* { - +%typemap(in) HAction* { + if (IS_CALLABLE == Z_TYPE_PP($input)) { + if (!zend_make_callable($1, *$input TSRMLS_CC)) { + // FIXME some error + $1 = NULL; + } + // don't need an else here, $1 gets populated + } else { + // FIXME some error + $1 = NULL; + } } -*/ + %typemap(out) struct HParseResult_* { if ($1 == NULL) { // TODO: raise parse failure @@ -255,10 +263,6 @@ } */ -%typemap(in) (const HAction a, void* user_data) { - $2 = $input; - $1 = call_action; - } #else #warning no Hammer typemaps defined #endif @@ -565,5 +569,19 @@ function sequence() return h_sequence__a($arg_list); } +function action($p, $act) +{ + return h_action($p, $act); +} + +function in($charset) +{ + return action(h_in($charset), 'chr'); +} + +function not_in($charset) +{ + return action(h_not_in($charset), 'chr'); +} " #endif From 42b25f478482dd46aec81fcfd8f02db27eec7d7e Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 15 Dec 2013 20:28:20 +0100 Subject: [PATCH 076/101] refactor SWIG PHP definitions into their own file --- src/bindings/php/SConscript | 6 +- src/bindings/php/hammer.i | 229 ++++++++++++++++++++++++++++++++++ src/bindings/swig/hammer.i | 239 ------------------------------------ 3 files changed, 232 insertions(+), 242 deletions(-) create mode 100644 src/bindings/php/hammer.i diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index 94c9d83..fc4c1d1 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -10,10 +10,10 @@ phpenv.Append(CCFLAGS = ['-fpic', '-DSWIG', '-Wno-all', '-Wno-extra', '-Wno-erro phpenv.Append(LIBS = ['hammer']) phpenv.Append(LIBPATH = ['../../']) -swig_src = phpenv.Command("hammer.i", "../swig/hammer.i", Copy("$TARGET", "$SOURCE")) -bindings_src = phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], 'hammer.i', 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') +swig = ['hammer.i'] +bindings_src = phpenv.Command(['hammer.php', 'hammer_wrap.c', 'php_hammer.h'], swig, 'swig -php -DHAMMER_INTERNAL__NO_STDARG_H -Isrc/ $SOURCE') libhammer_php = phpenv.SharedLibrary('hammer', ['hammer_wrap.c']) -Default(swig_src, bindings_src, libhammer_php) +Default(swig, bindings_src, libhammer_php) phptestenv = phpenv.Clone() phptestenv['ENV']['LD_LIBRARY_PATH'] = os.path.dirname(str(libhammer_shared[0])) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i new file mode 100644 index 0000000..e2a6877 --- /dev/null +++ b/src/bindings/php/hammer.i @@ -0,0 +1,229 @@ +%module hammer; + +%ignore HCountedArray_; + +%inline %{ + static int h_tt_php; + %} + +%init %{ + h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + %} + +%inline { + struct HParsedToken_; + struct HParseResult_; + static zval* hpt_to_php(const struct HParsedToken_ *token); + + static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); + } + +%typemap(in) (const uint8_t* str, const size_t len) { + $1 = (uint8_t*)(*$input)->value.str.val; + $2 = (*$input)->value.str.len; + } + +%apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } +%apply (const uint8_t* str, const size_t len) { (const uint8_t* charset, size_t length) } + +%typemap(in) void*[] { + if (IS_ARRAY == Z_TYPE_PP($input)) { + HashTable *arr = Z_ARRVAL_PP($input); + HashPosition pointer; + int size = zend_hash_num_elements(arr); + int i = 0; + int res = 0; + $1 = (void**)malloc((size+1)*sizeof(HParser*)); + for (i=0; itoken, $1->len, 1); + } + +/* TODO do we need this anymore? +%typemap(out) struct HCountedArray_* { + + } +*/ +%typemap(out) struct HParseResult_* { + if ($1 == NULL) { + // TODO: raise parse failure + RETVAL_NULL(); + } else { + if ($1->ast == NULL) { + RETVAL_NULL(); + } else { + switch($1->ast->token_type) { + case TT_NONE: + RETVAL_NULL(); + break; + case TT_BYTES: + RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1); + break; + case TT_SINT: + RETVAL_LONG($1->ast->token_data.sint); + break; + case TT_UINT: + RETVAL_LONG($1->ast->token_data.uint); + break; + case TT_SEQUENCE: + array_init($result); + for (int i=0; i < $1->ast->token_data.seq->used; i++) { + add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i])); + } + break; + default: + /* if (token->token_type == h_tt_php) { */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ + /* return return_value; */ + /* } else { */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ + /* } */ + break; + } + } + } + } +/* +%typemap(in) (HPredicate* pred, void* user_data) { + + } +*/ +%typemap(in) (const HAction a, void* user_data) { + $2 = $input; + $1 = call_action; + } + +%include "../swig/hammer.i"; + +%inline { + static zval* hpt_to_php(const HParsedToken *token) { + zval *ret; + ALLOC_INIT_ZVAL(ret); + if (token == NULL) { + ZVAL_NULL(ret); + return ret; + } + switch (token->token_type) { + case TT_NONE: + ZVAL_NULL(ret); + return ret; + case TT_BYTES: + ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); + return ret; + case TT_SINT: + ZVAL_LONG(ret, token->token_data.sint); + return ret; + case TT_UINT: + ZVAL_LONG(ret, token->token_data.uint); + return ret; + case TT_SEQUENCE: + array_init(ret); + for (int i=0; i < token->token_data.seq->used; i++) { + add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); + } + return ret; + default: + /* if (token->token_type == h_tt_php) { */ + /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh + /* return return_value; */ + /* } else { */ + /* // I guess that's a python thing */ + /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ + /* // TODO: support registry */ + /* } */ + break; + } + } + + static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data) { + zval *args[1]; + zval ret; + // in PHP land, the HAction is passed by its name as a string + if (IS_STRING != Z_TYPE_P((zval*)user_data)) { + // FIXME throw some error + return NULL; + } + zval *callable; + callable = user_data; + args[0] = hpt_to_php(p->ast); + int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); + if (ok != SUCCESS) { + // FIXME throw some error + return NULL; + } + // TODO: add reference to ret to parse-local data + HParsedToken *tok = h_make(p->arena, h_tt_php, &ret); + return tok; + } + } + +%pragma(php) code=" + +function ch($ch) +{ + if (is_string($ch)) + return h_token($ch); + else + return h_ch($ch); +} + +function choice() +{ + $arg_list = func_get_args(); + $arg_list[] = NULL; + return h_choice__a($arg_list); +} + +function sequence() +{ + $arg_list = func_get_args(); + $arg_list[] = NULL; + return h_sequence__a($arg_list); +} + +function action($p, $act) +{ + return h_action($p, $act); +} + +function in($charset) +{ + return action(h_in($charset), 'chr'); +} + +function not_in($charset) +{ + return action(h_not_in($charset), 'chr'); +} +" + diff --git a/src/bindings/swig/hammer.i b/src/bindings/swig/hammer.i index d7cf3a0..122ffe4 100644 --- a/src/bindings/swig/hammer.i +++ b/src/bindings/swig/hammer.i @@ -1,5 +1,4 @@ %module hammer -%nodefaultctor; %nodefaultctor; @@ -132,141 +131,6 @@ #warning no uint8_t* typemaps defined #endif -//%include "typemaps.i" - -#if defined(SWIGPHP) -%ignore HCountedArray_; - -%inline %{ - static int h_tt_php; - %} - -%init %{ - h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); - %} - -%inline { - struct HParsedToken_; - struct HParseResult_; - static zval* hpt_to_php(const struct HParsedToken_ *token); - - static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); - } - -%typemap(in) (const uint8_t* str, const size_t len) { - $1 = (uint8_t*)(*$input)->value.str.val; - $2 = (*$input)->value.str.len; - } - -//%typemap(out) (const uint8_t* str, const size_t len) { -// RETVAL_STRINGL((char*)$1, $2, 1); -// } -%apply (const uint8_t* str, const size_t len) { (const uint8_t* input, size_t length) } -%apply (const uint8_t* str, const size_t len) { (const uint8_t* charset, size_t length) } -%typemap(in) void*[] { - if (IS_ARRAY == Z_TYPE_PP($input)) { - HashTable *arr = Z_ARRVAL_PP($input); - HashPosition pointer; - int size = zend_hash_num_elements(arr); - int i = 0; - int res = 0; - $1 = (void**)malloc((size)*sizeof(HParser*)); - for (i=0; itoken, $1->len, 1); - } - -%typemap(in) HAction* { - if (IS_CALLABLE == Z_TYPE_PP($input)) { - if (!zend_make_callable($1, *$input TSRMLS_CC)) { - // FIXME some error - $1 = NULL; - } - // don't need an else here, $1 gets populated - } else { - // FIXME some error - $1 = NULL; - } - } - -%typemap(out) struct HParseResult_* { - if ($1 == NULL) { - // TODO: raise parse failure - RETVAL_NULL(); - } else { - if ($1->ast == NULL) { - RETVAL_NULL(); - } else { - switch($1->ast->token_type) { - case TT_NONE: - RETVAL_NULL(); - break; - case TT_BYTES: - RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1); - break; - case TT_SINT: - RETVAL_LONG($1->ast->token_data.sint); - break; - case TT_UINT: - RETVAL_LONG($1->ast->token_data.uint); - break; - case TT_SEQUENCE: - array_init($result); - for (int i=0; i < $1->ast->token_data.seq->used; i++) { - add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i])); - } - break; - default: - /* if (token->token_type == h_tt_php) { */ - /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ - /* return return_value; */ - /* } else { */ - /* // I guess that's a python thing */ - /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ - /* // TODO: support registry */ - /* } */ - break; - } - } - } - } -/* -%typemap(in) (HPredicate* pred, void* user_data) { - - } -*/ -#else - #warning no Hammer typemaps defined -#endif - // All the include paths are relative to the build, i.e., ../../. If you need to build these manually (i.e., not with scons), keep that in mind. %{ #include "allocator.h" @@ -480,108 +344,5 @@ def int64(): return _h_int64() %} #endif -//%apply const char* { const uint8_t* } -#if defined(SWIGPHP) -%inline { - static zval* hpt_to_php(const HParsedToken *token) { - zval *ret; - ALLOC_INIT_ZVAL(ret); - if (token == NULL) { - ZVAL_NULL(ret); - return ret; - } - switch (token->token_type) { - case TT_NONE: - ZVAL_NULL(ret); - return ret; - case TT_BYTES: - ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); - return ret; - case TT_SINT: - ZVAL_LONG(ret, token->token_data.sint); - return ret; - case TT_UINT: - ZVAL_LONG(ret, token->token_data.uint); - return ret; - case TT_SEQUENCE: - array_init(ret); - for (int i=0; i < token->token_data.seq->used; i++) { - add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); - } - return ret; - default: - /* if (token->token_type == h_tt_php) { */ - /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh - /* return return_value; */ - /* } else { */ - /* // I guess that's a python thing */ - /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ - /* // TODO: support registry */ - /* } */ - break; - } - } - static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data) { - zval *args[1]; - zval ret; - // in PHP land, the HAction is passed by its name as a string - if (IS_STRING != Z_TYPE_P((zval*)user_data)) { - // FIXME throw some error - return NULL; - } - zval *callable; - callable = user_data; - args[0] = hpt_to_php(p->ast); - int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); - if (ok != SUCCESS) { - // FIXME throw some error - return NULL; - } - // TODO: add reference to ret to parse-local data - HParsedToken *tok = h_make(p->arena, h_tt_php, &ret); - return tok; - } - } - -%pragma(php) code=" - -function ch($ch) -{ - if (is_string($ch)) - return h_token($ch); - else - return h_ch($ch); -} - -function choice() -{ - $arg_list = func_get_args(); - $arg_list[] = NULL; - return h_choice__a($arg_list); -} - -function sequence() -{ - $arg_list = func_get_args(); - $arg_list[] = NULL; - return h_sequence__a($arg_list); -} - -function action($p, $act) -{ - return h_action($p, $act); -} - -function in($charset) -{ - return action(h_in($charset), 'chr'); -} - -function not_in($charset) -{ - return action(h_not_in($charset), 'chr'); -} -" -#endif From aae140a420adeec709ad063c5db9bc5c0a4c1488 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 00:39:30 +0100 Subject: [PATCH 077/101] map SWIG argument correctly --- src/bindings/php/hammer.i | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index e2a6877..97d7e64 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -40,7 +40,7 @@ // FIXME raise some error arg1 = NULL; } else { - res = SWIG_ConvertPtr(*data, &(arg1[i]), SWIGTYPE_p_HParser_, 0 | 0); + res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0); if (!SWIG_IsOK(res)) { // TODO do we not *have* SWIG_TypeError? SWIG_exception_fail(res, "that wasn't an HParser"); @@ -170,6 +170,7 @@ zval ret; // in PHP land, the HAction is passed by its name as a string if (IS_STRING != Z_TYPE_P((zval*)user_data)) { + printf("user_data wasn't a string"); // FIXME throw some error return NULL; } @@ -178,6 +179,7 @@ args[0] = hpt_to_php(p->ast); int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { + printf("call_user_function failed"); // FIXME throw some error return NULL; } From ab23a29b0e5b35b61be6e8b51772ea2beeec1172 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 03:33:01 +0100 Subject: [PATCH 078/101] refactor hpt_to_php to eliminate code duplication --- src/bindings/php/Tests/ActionTest.php | 18 ++--- src/bindings/php/hammer.i | 107 ++++++++++---------------- 2 files changed, 48 insertions(+), 77 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 0b7540d..619ea4a 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -11,21 +11,21 @@ class ActionTest extends PHPUnit_Framework_TestCase } protected function setUp() { - //$this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); + $this->parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); } public function testSuccess() { - /* $result1 = h_parse($this->parser, "ab"); */ - /* $result2 = h_parse($this->parser, "AB"); */ - /* $result3 = h_parse($this->parser, "aB"); */ - /* $this->assertEquals("AB", $result1); */ - /* $this->assertEquals("AB", $result2); */ - /* $this->assertEquals("AB", $result3); */ + $result1 = h_parse($this->parser, "ab"); + $result2 = h_parse($this->parser, "AB"); + $result3 = h_parse($this->parser, "aB"); + $this->assertEquals("AB", $result1); + $this->assertEquals("AB", $result2); + $this->assertEquals("AB", $result3); } public function testFailure() { - //$result = h_parse($this->parser, "XX"); - //$this->assertEquals(NULL, $result); + $result = h_parse($this->parser, "XX"); + $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 97d7e64..67f6dd5 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -1,4 +1,5 @@ %module hammer; +%include "exception.i"; %ignore HCountedArray_; @@ -13,7 +14,7 @@ %inline { struct HParsedToken_; struct HParseResult_; - static zval* hpt_to_php(const struct HParsedToken_ *token); + void hpt_to_php(zval *return_value, const struct HParsedToken_ *token); static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); } @@ -37,18 +38,17 @@ for (i=0; iast == NULL) { - RETVAL_NULL(); - } else { - switch($1->ast->token_type) { - case TT_NONE: - RETVAL_NULL(); - break; - case TT_BYTES: - RETVAL_STRINGL((char*)$1->ast->token_data.bytes.token, $1->ast->token_data.bytes.len, 1); - break; - case TT_SINT: - RETVAL_LONG($1->ast->token_data.sint); - break; - case TT_UINT: - RETVAL_LONG($1->ast->token_data.uint); - break; - case TT_SEQUENCE: - array_init($result); - for (int i=0; i < $1->ast->token_data.seq->used; i++) { - add_next_index_zval($result, hpt_to_php($1->ast->token_data.seq->elements[i])); - } - break; - default: - /* if (token->token_type == h_tt_php) { */ - /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, what else could I do with it? */ - /* return return_value; */ - /* } else { */ - /* // I guess that's a python thing */ - /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ - /* // TODO: support registry */ - /* } */ - break; - } - } + hpt_to_php($result, $1->ast); } } /* @@ -126,41 +94,44 @@ %include "../swig/hammer.i"; %inline { - static zval* hpt_to_php(const HParsedToken *token) { - zval *ret; - ALLOC_INIT_ZVAL(ret); - if (token == NULL) { - ZVAL_NULL(ret); - return ret; + void hpt_to_php(zval *return_value, const HParsedToken *token) { + if (!token) { + RETVAL_NULL(); + return; } switch (token->token_type) { case TT_NONE: - ZVAL_NULL(ret); - return ret; + RETVAL_NULL(); + break; case TT_BYTES: - ZVAL_STRINGL(ret, (char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); - return ret; + RETVAL_STRINGL((char*)token->token_data.bytes.token, token->token_data.bytes.len, 1); + break; case TT_SINT: - ZVAL_LONG(ret, token->token_data.sint); - return ret; + RETVAL_LONG(token->token_data.sint); + break; case TT_UINT: - ZVAL_LONG(ret, token->token_data.uint); - return ret; + RETVAL_LONG(token->token_data.uint); + break; case TT_SEQUENCE: - array_init(ret); + array_init(return_value); for (int i=0; i < token->token_data.seq->used; i++) { - add_next_index_zval(ret, hpt_to_php(token->token_data.seq->elements[i])); + zval *tmp; + ALLOC_INIT_ZVAL(tmp); + hpt_to_php(tmp, token->token_data.seq->elements[i]); + add_next_index_zval(return_value, tmp); } - return ret; + break; default: - /* if (token->token_type == h_tt_php) { */ - /* ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_swig__p_void); // it's a void*, wh - /* return return_value; */ - /* } else { */ - /* // I guess that's a python thing */ - /* //return (zval*)SWIG_NewPointerObj((void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); */ - /* // TODO: support registry */ - /* } */ + if (token->token_type == h_tt_php) { + RETVAL_RESOURCE(token->token_data.user); + } else { + int res = 0; + res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); + if (!SWIG_IsOK(res)) { + SWIG_exception(SWIG_TypeError, "hpt_to_php: that wasn't an HParsedToken"); + } + // TODO: support registry + } break; } } @@ -170,13 +141,13 @@ zval ret; // in PHP land, the HAction is passed by its name as a string if (IS_STRING != Z_TYPE_P((zval*)user_data)) { - printf("user_data wasn't a string"); + printf("user_data wasn't a string\n"); // FIXME throw some error return NULL; } zval *callable; callable = user_data; - args[0] = hpt_to_php(p->ast); + hpt_to_php(args[0], p->ast); int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { printf("call_user_function failed"); From 3ba14c01f1f4d16916917257fe5381c752751d9b Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 10:25:50 +0100 Subject: [PATCH 079/101] call_action does what it should, now just need to figure out what to do with that resource --- src/bindings/php/Tests/ActionTest.php | 18 ++++++++--- src/bindings/php/hammer.i | 45 +++++++-------------------- 2 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 619ea4a..00ac776 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -1,23 +1,31 @@ parser = h_action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); + $this->parser = action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); } public function testSuccess() { $result1 = h_parse($this->parser, "ab"); + var_dump($result1); $result2 = h_parse($this->parser, "AB"); + var_dump($result2); $result3 = h_parse($this->parser, "aB"); + var_dump($result3); $this->assertEquals("AB", $result1); $this->assertEquals("AB", $result2); $this->assertEquals("AB", $result3); diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 67f6dd5..f0608fd 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -67,11 +67,6 @@ RETVAL_STRINGL((char*)$1->token, $1->len, 1); } -/* TODO do we need this anymore? -%typemap(out) struct HCountedArray_* { - - } -*/ %typemap(out) struct HParseResult_* { if ($1 == NULL) { /* If we want parse errors to be exceptions, this is the place to do it */ @@ -81,15 +76,6 @@ hpt_to_php($result, $1->ast); } } -/* -%typemap(in) (HPredicate* pred, void* user_data) { - - } -*/ -%typemap(in) (const HAction a, void* user_data) { - $2 = $input; - $1 = call_action; - } %include "../swig/hammer.i"; @@ -136,28 +122,26 @@ } } - static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data) { + static HParsedToken* call_action(const HParseResult *p, void *user_data) { zval *args[1]; - zval ret; - // in PHP land, the HAction is passed by its name as a string - if (IS_STRING != Z_TYPE_P((zval*)user_data)) { - printf("user_data wasn't a string\n"); - // FIXME throw some error - return NULL; - } - zval *callable; - callable = user_data; + zval ret, func; + ZVAL_STRING(&func, (const char*)user_data, 0); hpt_to_php(args[0], p->ast); - int ok = call_user_function(EG(function_table), NULL, callable, &ret, 1, args TSRMLS_CC); + int ok = call_user_function(EG(function_table), NULL, &func, &ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { - printf("call_user_function failed"); + printf("call_user_function failed\n"); // FIXME throw some error return NULL; } + printf("Value being returned is %s\n", Z_STRVAL(ret)); // TODO: add reference to ret to parse-local data HParsedToken *tok = h_make(p->arena, h_tt_php, &ret); return tok; } + + HParser* action(HParser *parser, const char *name) { + return h_action(parser, call_action, (void*)name); + } } %pragma(php) code=" @@ -184,19 +168,14 @@ function sequence() return h_sequence__a($arg_list); } -function action($p, $act) -{ - return h_action($p, $act); -} - function in($charset) { - return action(h_in($charset), 'chr'); + return action(h_in($charset), \"chr\"); } function not_in($charset) { - return action(h_not_in($charset), 'chr'); + return action(h_not_in($charset), \"chr\"); } " From 34ad3f58fa71142dc65c54a0f96e5580e2e7f4f2 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 10:57:59 +0100 Subject: [PATCH 080/101] h_tt_php registered as resource, now to work out how to decode them --- src/bindings/php/hammer.i | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index f0608fd..fbdcc59 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -5,10 +5,13 @@ %inline %{ static int h_tt_php; + static int le_h_tt_php_descriptor; %} %init %{ +#define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + le_h_tt_php_descriptor = zend_register_list_destructors_ex(NULL, NULL, PHP_H_TT_PHP_DESCRIPTOR_RES_NAME, module_number); %} %inline { @@ -109,7 +112,8 @@ break; default: if (token->token_type == h_tt_php) { - RETVAL_RESOURCE(token->token_data.user); + //RETVAL_RESOURCE(token->token_data.user); + ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_h_tt_php_descriptor); } else { int res = 0; res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); From 53a661442e431ffd54f90f3c80ef9f64063d3eb9 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 11:03:50 +0100 Subject: [PATCH 081/101] swap order of params for hpt_to_php --- src/bindings/php/hammer.i | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index fbdcc59..d2a5eca 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -11,13 +11,14 @@ %init %{ #define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); + // TODO: implement h_arena_free, register a token dtor here le_h_tt_php_descriptor = zend_register_list_destructors_ex(NULL, NULL, PHP_H_TT_PHP_DESCRIPTOR_RES_NAME, module_number); %} %inline { struct HParsedToken_; struct HParseResult_; - void hpt_to_php(zval *return_value, const struct HParsedToken_ *token); + void hpt_to_php(const struct HParsedToken_ *token, zval *return_value); static struct HParsedToken_* call_action(const struct HParseResult_ *p, void* user_data); } @@ -76,14 +77,14 @@ //SWIG_exception(SWIG_TypeError, "typemap: should have been an HParseResult*, was NULL"); RETVAL_NULL(); } else { - hpt_to_php($result, $1->ast); + hpt_to_php($1->ast, $result); } } %include "../swig/hammer.i"; %inline { - void hpt_to_php(zval *return_value, const HParsedToken *token) { + void hpt_to_php(const HParsedToken *token, zval *return_value) { if (!token) { RETVAL_NULL(); return; @@ -106,7 +107,7 @@ for (int i=0; i < token->token_data.seq->used; i++) { zval *tmp; ALLOC_INIT_ZVAL(tmp); - hpt_to_php(tmp, token->token_data.seq->elements[i]); + hpt_to_php(token->token_data.seq->elements[i], tmp); add_next_index_zval(return_value, tmp); } break; @@ -130,7 +131,7 @@ zval *args[1]; zval ret, func; ZVAL_STRING(&func, (const char*)user_data, 0); - hpt_to_php(args[0], p->ast); + hpt_to_php(p->ast, args[0]); int ok = call_user_function(EG(function_table), NULL, &func, &ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { printf("call_user_function failed\n"); From 6c9410d8de3ddcb70d717a61c3901404638ac8ec Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 13:13:17 +0100 Subject: [PATCH 082/101] action works! need to clean up xor and ch_range, and write attr_bool --- src/bindings/php/Tests/ActionTest.php | 3 --- src/bindings/php/hammer.i | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 00ac776..ee8f0cf 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -21,11 +21,8 @@ class ActionTest extends PHPUnit_Framework_TestCase public function testSuccess() { $result1 = h_parse($this->parser, "ab"); - var_dump($result1); $result2 = h_parse($this->parser, "AB"); - var_dump($result2); $result3 = h_parse($this->parser, "aB"); - var_dump($result3); $this->assertEquals("AB", $result1); $this->assertEquals("AB", $result2); $this->assertEquals("AB", $result3); diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index d2a5eca..a5be96e 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -4,12 +4,12 @@ %ignore HCountedArray_; %inline %{ +#define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" static int h_tt_php; static int le_h_tt_php_descriptor; %} %init %{ -#define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); // TODO: implement h_arena_free, register a token dtor here le_h_tt_php_descriptor = zend_register_list_destructors_ex(NULL, NULL, PHP_H_TT_PHP_DESCRIPTOR_RES_NAME, module_number); @@ -113,8 +113,9 @@ break; default: if (token->token_type == h_tt_php) { - //RETVAL_RESOURCE(token->token_data.user); - ZEND_REGISTER_RESOURCE(return_value, token->token_data.user, le_h_tt_php_descriptor); + zval *tmp; + tmp = (zval*)token->token_data.user; + RETVAL_ZVAL(tmp, 0, 0); } else { int res = 0; res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); @@ -129,18 +130,19 @@ static HParsedToken* call_action(const HParseResult *p, void *user_data) { zval *args[1]; - zval ret, func; + zval func; + zval *ret; + ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); hpt_to_php(p->ast, args[0]); - int ok = call_user_function(EG(function_table), NULL, &func, &ret, 1, args TSRMLS_CC); + int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { printf("call_user_function failed\n"); // FIXME throw some error return NULL; } - printf("Value being returned is %s\n", Z_STRVAL(ret)); - // TODO: add reference to ret to parse-local data - HParsedToken *tok = h_make(p->arena, h_tt_php, &ret); + // Whatever the zval is, stuff it into a token + HParsedToken *tok = h_make(p->arena, h_tt_php, ret); return tok; } From 2730d9ffd73d4b963f629a4db9fad8c02eebfceb Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 13:18:54 +0100 Subject: [PATCH 083/101] fix ch_range; confirm action works with sequences too --- src/bindings/php/Tests/ActionTest.php | 11 +++++++---- src/bindings/php/Tests/ChRangeTest.php | 2 +- src/bindings/php/hammer.i | 5 +++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index ee8f0cf..2912533 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -4,7 +4,10 @@ include_once 'hammer.php'; function actTest($token) { if (is_array($token) === true) { - return strtoupper(join('', $token)); + foreach($token as $chr) { + $ret[] = strtoupper($chr); + } + return $ret; } else { return strtoupper($token); } @@ -23,9 +26,9 @@ class ActionTest extends PHPUnit_Framework_TestCase $result1 = h_parse($this->parser, "ab"); $result2 = h_parse($this->parser, "AB"); $result3 = h_parse($this->parser, "aB"); - $this->assertEquals("AB", $result1); - $this->assertEquals("AB", $result2); - $this->assertEquals("AB", $result3); + $this->assertEquals(["A", "B"], $result1); + $this->assertEquals(["A", "B"], $result2); + $this->assertEquals(["A", "B"], $result3); } public function testFailure() { diff --git a/src/bindings/php/Tests/ChRangeTest.php b/src/bindings/php/Tests/ChRangeTest.php index b726a5d..433c2ce 100644 --- a/src/bindings/php/Tests/ChRangeTest.php +++ b/src/bindings/php/Tests/ChRangeTest.php @@ -8,7 +8,7 @@ class ChRangeTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_ch_range("a", "c"); + $this->parser = ch_range("a", "c"); } public function testSuccess() { diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index a5be96e..174cb98 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -175,6 +175,11 @@ function sequence() return h_sequence__a($arg_list); } +function ch_range($low, $high) +{ + return action(h_ch_range($low, $high), \"chr\"); +} + function in($charset) { return action(h_in($charset), \"chr\"); From c2cde65764fba775c7828d493e11bcd291b48164 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 13:21:27 +0100 Subject: [PATCH 084/101] xor uses correct version of ch_range; commented out broken underlying C bits of leftrec --- src/bindings/php/Tests/LeftrecTest.php | 4 +++- src/bindings/php/Tests/XorTest.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/Tests/LeftrecTest.php b/src/bindings/php/Tests/LeftrecTest.php index 63d662a..52ed931 100644 --- a/src/bindings/php/Tests/LeftrecTest.php +++ b/src/bindings/php/Tests/LeftrecTest.php @@ -16,7 +16,8 @@ class LeftrecTest extends PHPUnit_Framework_TestCase $result = h_parse($this->parser, "a"); $this->assertEquals("a", $result); } - + /* These don't work in the underlying C so they won't work here either */ +/* public function testSuccess2() { $result = h_parse($this->parser, "aa"); @@ -30,5 +31,6 @@ class LeftrecTest extends PHPUnit_Framework_TestCase var_dump($result); $this->assertEquals(array(array("a", "a"), "a"), $result); } +*/ } ?> \ No newline at end of file diff --git a/src/bindings/php/Tests/XorTest.php b/src/bindings/php/Tests/XorTest.php index 67e8bf3..c9a25f0 100644 --- a/src/bindings/php/Tests/XorTest.php +++ b/src/bindings/php/Tests/XorTest.php @@ -7,7 +7,7 @@ class XorTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_xor(h_ch_range("0", "6"), h_ch_range("5", "9")); + $this->parser = h_xor(ch_range("0", "6"), ch_range("5", "9")); } public function testSuccess() From bd48af7b9017c365aa8e07abedbf98c452f7acad Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Mon, 16 Dec 2013 13:42:14 +0100 Subject: [PATCH 085/101] implement predicate; decruft; quiet phpunit --- src/bindings/php/SConscript | 2 +- src/bindings/php/Tests/PredicateTest.php | 31 ++++++++++++++++++++++++ src/bindings/php/hammer.i | 24 +++++++++++++++--- 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/bindings/php/Tests/PredicateTest.php diff --git a/src/bindings/php/SConscript b/src/bindings/php/SConscript index fc4c1d1..34728af 100644 --- a/src/bindings/php/SConscript +++ b/src/bindings/php/SConscript @@ -23,7 +23,7 @@ phplib = phptestenv.Command(os.path.join(phpextprefix, "hammer.so"), libhammer_p AlwaysBuild(phplib) phpprefix = os.popen("php-config --prefix").read().rstrip() phpincl = phptestenv.Command(os.path.join(os.path.join(phpprefix, "etc/conf.d"), "hammer.ini"), "hammer.ini", Copy("$TARGET", "$SOURCE")) -phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit -v --debug --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") +phptestexec = phptestenv.Command(phptests, [phplib, phpincl], "phpenv exec phpunit --include-path " + os.path.dirname(libhammer_php[0].path) +" src/bindings/php/Tests") phptest = Alias("testphp", [phptestexec], phptestexec) AlwaysBuild(phptest) testruns.append(phptest) diff --git a/src/bindings/php/Tests/PredicateTest.php b/src/bindings/php/Tests/PredicateTest.php new file mode 100644 index 0000000..1df45e2 --- /dev/null +++ b/src/bindings/php/Tests/PredicateTest.php @@ -0,0 +1,31 @@ +parser = predicate(h_many1(choice(ch('a'), ch('b'))), "predTest"); + } + public function testSuccess() + { + $result1 = h_parse($this->parser, "aa"); + $result2 = h_parse($this->parser, "bb"); + $this->assertEquals(["a", "a"], $result1); + $this->assertEquals(["b", "b"], $result2); + } + public function testFailure() + { + $result = h_parse($this->parser, "ab"); + $this->assertEquals(NULL, $result); + } +} + +?> \ No newline at end of file diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 174cb98..c975360 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -4,15 +4,11 @@ %ignore HCountedArray_; %inline %{ -#define PHP_H_TT_PHP_DESCRIPTOR_RES_NAME "Hammer Token" static int h_tt_php; - static int le_h_tt_php_descriptor; %} %init %{ h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); - // TODO: implement h_arena_free, register a token dtor here - le_h_tt_php_descriptor = zend_register_list_destructors_ex(NULL, NULL, PHP_H_TT_PHP_DESCRIPTOR_RES_NAME, module_number); %} %inline { @@ -146,9 +142,29 @@ return tok; } + static int call_predicate(HParseResult *p, void *user_data) { + zval *args[1]; + zval func; + zval *ret; + ALLOC_INIT_ZVAL(ret); + ZVAL_STRING(&func, (const char*)user_data, 0); + hpt_to_php(p->ast, args[0]); + int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); + if (ok != SUCCESS) { + printf("call_user_function failed\n"); + // FIXME throw some error + return 0; + } + return Z_LVAL_P(ret); + } + HParser* action(HParser *parser, const char *name) { return h_action(parser, call_action, (void*)name); } + + HParser* predicate(HParser *parser, const char *name) { + return h_attr_bool(parser, call_predicate, (void*)name); + } } %pragma(php) code=" From b9ce12f3b61a67e8eaef01af0828b9103ff2194a Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 18 Dec 2013 00:32:56 +0100 Subject: [PATCH 086/101] Great PHP Symbol Renaming; debug build works, optimised build segfaults. is it gcc? fuck it all and let travis sort it out --- src/bindings/php/Tests/ActionTest.php | 10 ++-- src/bindings/php/Tests/AndTest.php | 12 ++--- src/bindings/php/Tests/ButNotTest.php | 12 ++--- src/bindings/php/Tests/ChRangeTest.php | 6 +-- src/bindings/php/Tests/ChTest.php | 6 +-- src/bindings/php/Tests/ChoiceTest.php | 8 +-- src/bindings/php/Tests/DifferenceTest.php | 6 +-- src/bindings/php/Tests/EndTest.php | 6 +-- src/bindings/php/Tests/EpsilonPTest.php | 12 ++--- src/bindings/php/Tests/IgnoreTest.php | 6 +-- src/bindings/php/Tests/InTest.php | 6 +-- src/bindings/php/Tests/Int16Test.php | 10 ++-- src/bindings/php/Tests/Int32Test.php | 10 ++-- src/bindings/php/Tests/Int64Test.php | 6 +-- src/bindings/php/Tests/Int8Test.php | 6 +-- src/bindings/php/Tests/IntRangeTest.php | 6 +-- src/bindings/php/Tests/LeftTest.php | 10 ++-- src/bindings/php/Tests/LeftrecTest.php | 10 ++-- src/bindings/php/Tests/Many1Test.php | 12 ++--- src/bindings/php/Tests/ManyTest.php | 10 ++-- src/bindings/php/Tests/MiddleTest.php | 18 +++---- src/bindings/php/Tests/NotInTest.php | 6 +-- src/bindings/php/Tests/NotTest.php | 12 ++--- src/bindings/php/Tests/NothingTest.php | 4 +- src/bindings/php/Tests/OptionalTest.php | 14 +++--- src/bindings/php/Tests/PredicateTest.php | 8 +-- src/bindings/php/Tests/RepeatNTest.php | 8 +-- src/bindings/php/Tests/RightTest.php | 10 ++-- src/bindings/php/Tests/RightrecTest.php | 10 ++-- src/bindings/php/Tests/SepBy1Test.php | 12 ++--- src/bindings/php/Tests/SepByTest.php | 12 ++--- src/bindings/php/Tests/SequenceTest.php | 16 +++--- src/bindings/php/Tests/TokenTest.php | 6 +-- src/bindings/php/Tests/Uint16Test.php | 6 +-- src/bindings/php/Tests/Uint32Test.php | 6 +-- src/bindings/php/Tests/Uint64Test.php | 6 +-- src/bindings/php/Tests/Uint8Test.php | 6 +-- src/bindings/php/Tests/WhitespaceTest.php | 20 ++++---- src/bindings/php/Tests/XorTest.php | 10 ++-- src/bindings/php/hammer.i | 60 ++++++++++++++++++----- 40 files changed, 228 insertions(+), 192 deletions(-) diff --git a/src/bindings/php/Tests/ActionTest.php b/src/bindings/php/Tests/ActionTest.php index 2912533..f4e6a56 100644 --- a/src/bindings/php/Tests/ActionTest.php +++ b/src/bindings/php/Tests/ActionTest.php @@ -19,20 +19,20 @@ class ActionTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = action(sequence(choice(ch("a"), ch("A")), choice(ch("b"), ch("B"))), "actTest"); + $this->parser = hammer_action(hammer_sequence(hammer_choice(hammer_ch("a"), hammer_ch("A")), hammer_choice(hammer_ch("b"), hammer_ch("B"))), "actTest"); } public function testSuccess() { - $result1 = h_parse($this->parser, "ab"); - $result2 = h_parse($this->parser, "AB"); - $result3 = h_parse($this->parser, "aB"); + $result1 = hammer_parse($this->parser, "ab"); + $result2 = hammer_parse($this->parser, "AB"); + $result3 = hammer_parse($this->parser, "aB"); $this->assertEquals(["A", "B"], $result1); $this->assertEquals(["A", "B"], $result2); $this->assertEquals(["A", "B"], $result3); } public function testFailure() { - $result = h_parse($this->parser, "XX"); + $result = hammer_parse($this->parser, "XX"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/AndTest.php b/src/bindings/php/Tests/AndTest.php index 03f9258..91cb115 100644 --- a/src/bindings/php/Tests/AndTest.php +++ b/src/bindings/php/Tests/AndTest.php @@ -9,26 +9,26 @@ class AndTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = sequence(h_and(ch("0")), ch("0")); - $this->parser2 = sequence(h_and(ch("0")), ch("1")); - $this->parser3 = sequence(ch("1"), h_and(ch("2"))); + $this->parser1 = hammer_sequence(hammer_and(hammer_ch("0")), hammer_ch("0")); + $this->parser2 = hammer_sequence(hammer_and(hammer_ch("0")), hammer_ch("1")); + $this->parser3 = hammer_sequence(hammer_ch("1"), hammer_and(hammer_ch("2"))); } public function testSuccess1() { - $result = h_parse($this->parser1, "0"); + $result = hammer_parse($this->parser1, "0"); $this->assertEquals(array("0"), $result); } public function testFailure2() { - $result = h_parse($this->parser2, "0"); + $result = hammer_parse($this->parser2, "0"); $this->assertEquals(NULL, $result); } public function testSuccess3() { - $result = h_parse($this->parser3, "12"); + $result = hammer_parse($this->parser3, "12"); $this->assertEquals(array("1"), $result); } } diff --git a/src/bindings/php/Tests/ButNotTest.php b/src/bindings/php/Tests/ButNotTest.php index 9f8117a..f1af3dd 100644 --- a/src/bindings/php/Tests/ButNotTest.php +++ b/src/bindings/php/Tests/ButNotTest.php @@ -8,27 +8,27 @@ class ButNotTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = h_butnot(ch("a"), h_token("ab")); - $this->parser2 = h_butnot(h_ch_range('0', '9'), ch('6')); + $this->parser1 = hammer_butnot(hammer_ch("a"), hammer_token("ab")); + $this->parser2 = hammer_butnot(hammer_ch_range('0', '9'), hammer_ch('6')); } public function testSuccess1() { - $result1 = h_parse($this->parser1, "a"); - $result2 = h_parse($this->parser1, "aa"); + $result1 = hammer_parse($this->parser1, "a"); + $result2 = hammer_parse($this->parser1, "aa"); $this->assertEquals("a", $result1); $this->assertEquals("a", $result1); } public function testFailure1() { - $result = h_parse($this->parser1, "ab"); + $result = hammer_parse($this->parser1, "ab"); $this->assertEquals(NULL, $result); } public function testFailure2() { - $result = h_parse($this->parser2, "6"); + $result = hammer_parse($this->parser2, "6"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/ChRangeTest.php b/src/bindings/php/Tests/ChRangeTest.php index 433c2ce..52f3732 100644 --- a/src/bindings/php/Tests/ChRangeTest.php +++ b/src/bindings/php/Tests/ChRangeTest.php @@ -8,16 +8,16 @@ class ChRangeTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = ch_range("a", "c"); + $this->parser = hammer_ch_range("a", "c"); } public function testSuccess() { - $result = h_parse($this->parser, "b"); + $result = hammer_parse($this->parser, "b"); $this->assertEquals("b", $result); } public function testFailure() { - $result = h_parse($this->parser, "d"); + $result = hammer_parse($this->parser, "d"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/ChTest.php b/src/bindings/php/Tests/ChTest.php index e05ad24..a38c655 100644 --- a/src/bindings/php/Tests/ChTest.php +++ b/src/bindings/php/Tests/ChTest.php @@ -8,16 +8,16 @@ class ChTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = ch("\xa2"); + $this->parser = hammer_ch("\xa2"); } public function testSuccess() { - $result = h_parse($this->parser, "\xa2"); + $result = hammer_parse($this->parser, "\xa2"); $this->assertEquals("\xa2", $result); } public function testFailure() { - $result = h_parse($this->parser, "95"); + $result = hammer_parse($this->parser, "95"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/ChoiceTest.php b/src/bindings/php/Tests/ChoiceTest.php index 42bb0a9..cd9e413 100644 --- a/src/bindings/php/Tests/ChoiceTest.php +++ b/src/bindings/php/Tests/ChoiceTest.php @@ -7,20 +7,20 @@ class ChoiceTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = choice(ch("a"), ch("b")); + $this->parser = hammer_choice(hammer_ch("a"), hammer_ch("b")); } public function testSuccess() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, "b"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, "b"); $this->assertEquals("a", $result1); $this->assertEquals("b", $result2); } public function testFailure() { - $result = h_parse($this->parser, "c"); + $result = hammer_parse($this->parser, "c"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/DifferenceTest.php b/src/bindings/php/Tests/DifferenceTest.php index 88c1903..297aa42 100644 --- a/src/bindings/php/Tests/DifferenceTest.php +++ b/src/bindings/php/Tests/DifferenceTest.php @@ -7,18 +7,18 @@ class DifferenceTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_difference(h_token("ab"), ch("a")); + $this->parser = hammer_difference(hammer_token("ab"), hammer_ch("a")); } public function testSuccess() { - $result = h_parse($this->parser, "ab"); + $result = hammer_parse($this->parser, "ab"); $this->assertEquals("ab", $result); } public function testFailure() { - $result = h_parse($this->parser, "a"); + $result = hammer_parse($this->parser, "a"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/EndTest.php b/src/bindings/php/Tests/EndTest.php index 773bc36..d6af2af 100644 --- a/src/bindings/php/Tests/EndTest.php +++ b/src/bindings/php/Tests/EndTest.php @@ -7,17 +7,17 @@ class EndPTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = sequence(ch("a"), h_end_p()); + $this->parser = hammer_sequence(hammer_ch("a"), hammer_end()); } public function testSuccess() { - $result = h_parse($this->parser, "a"); + $result = hammer_parse($this->parser, "a"); $this->assertEquals(array("a"), $result); } public function testFailure() { - $result = h_parse($this->parser, "aa"); + $result = hammer_parse($this->parser, "aa"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/EpsilonPTest.php b/src/bindings/php/Tests/EpsilonPTest.php index 432afef..41100cc 100644 --- a/src/bindings/php/Tests/EpsilonPTest.php +++ b/src/bindings/php/Tests/EpsilonPTest.php @@ -9,26 +9,26 @@ class EpsilonPTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = sequence(ch("a"), h_epsilon_p(), ch("b")); - $this->parser2 = sequence(h_epsilon_p(), ch("a")); - $this->parser3 = sequence(ch("a"), h_epsilon_p()); + $this->parser1 = hammer_sequence(hammer_ch("a"), hammer_epsilon(), hammer_ch("b")); + $this->parser2 = hammer_sequence(hammer_epsilon(), hammer_ch("a")); + $this->parser3 = hammer_sequence(hammer_ch("a"), hammer_epsilon()); } public function testSuccess1() { - $result = h_parse($this->parser1, "ab"); + $result = hammer_parse($this->parser1, "ab"); $this->assertEquals(array("a", "b"), $result); } public function testSuccess2() { - $result = h_parse($this->parser2, "a"); + $result = hammer_parse($this->parser2, "a"); $this->assertEquals(array("a"), $result); } public function testSuccess3() { - $result = h_parse($this->parser3, "ab"); + $result = hammer_parse($this->parser3, "ab"); $this->assertEquals(array("a"), $result); } } diff --git a/src/bindings/php/Tests/IgnoreTest.php b/src/bindings/php/Tests/IgnoreTest.php index 82ef554..805ae08 100644 --- a/src/bindings/php/Tests/IgnoreTest.php +++ b/src/bindings/php/Tests/IgnoreTest.php @@ -7,18 +7,18 @@ class IgnoreTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = sequence(ch("a"), h_ignore(ch("b")), ch("c")); + $this->parser = hammer_sequence(hammer_ch("a"), hammer_ignore(hammer_ch("b")), hammer_ch("c")); } public function testSuccess() { - $result = h_parse($this->parser, "abc"); + $result = hammer_parse($this->parser, "abc"); $this->assertEquals(array("a", "c"), $result); } public function testFailure() { - $result = h_parse($this->parser, "ac"); + $result = hammer_parse($this->parser, "ac"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/InTest.php b/src/bindings/php/Tests/InTest.php index cdc1e93..e209f1f 100644 --- a/src/bindings/php/Tests/InTest.php +++ b/src/bindings/php/Tests/InTest.php @@ -7,16 +7,16 @@ class InTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = in("abc"); + $this->parser = hammer_in("abc"); } public function testSuccess() { - $result = h_parse($this->parser, "b"); + $result = hammer_parse($this->parser, "b"); $this->assertEquals("b", $result); } public function testFailure() { - $result = h_parse($this->parser, "d"); + $result = hammer_parse($this->parser, "d"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Int16Test.php b/src/bindings/php/Tests/Int16Test.php index 4b170cc..f9f10cb 100644 --- a/src/bindings/php/Tests/Int16Test.php +++ b/src/bindings/php/Tests/Int16Test.php @@ -8,22 +8,22 @@ class Int16Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_int16(); + $this->parser = hammer_int16(); } public function testNegative() { - $result = h_parse($this->parser, "\xfe\x00"); + $result = hammer_parse($this->parser, "\xfe\x00"); $this->assertEquals(-0x200, $result); } public function testPositive() { - $result = h_parse($this->parser, "\x02\x00"); + $result = hammer_parse($this->parser, "\x02\x00"); $this->assertEquals(0x200, $result); } public function testFailure() { - $result = h_parse($this->parser, "\xfe"); + $result = hammer_parse($this->parser, "\xfe"); $this->assertEquals(NULL, $result); - $result = h_parse($this->parser, "\x02"); + $result = hammer_parse($this->parser, "\x02"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Int32Test.php b/src/bindings/php/Tests/Int32Test.php index c538aa2..5798195 100644 --- a/src/bindings/php/Tests/Int32Test.php +++ b/src/bindings/php/Tests/Int32Test.php @@ -8,23 +8,23 @@ class Int32Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_int32(); + $this->parser = hammer_int32(); } public function testNegative() { - $result = h_parse($this->parser, "\xff\xfe\x00\x00"); + $result = hammer_parse($this->parser, "\xff\xfe\x00\x00"); $this->assertEquals(-0x20000, $result); } public function testPositive() { - $result = h_parse($this->parser, "\x00\x02\x00\x00"); + $result = hammer_parse($this->parser, "\x00\x02\x00\x00"); $this->assertEquals(0x20000, $result); } public function testFailure() { - $result = h_parse($this->parser, "\xff\xfe\x00"); + $result = hammer_parse($this->parser, "\xff\xfe\x00"); $this->assertEquals(NULL, $result); - $result = h_parse($this->parser, "\x00\x02\x00"); + $result = hammer_parse($this->parser, "\x00\x02\x00"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Int64Test.php b/src/bindings/php/Tests/Int64Test.php index 4c0faa2..631a39f 100644 --- a/src/bindings/php/Tests/Int64Test.php +++ b/src/bindings/php/Tests/Int64Test.php @@ -8,16 +8,16 @@ class Int64Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_int64(); + $this->parser = hammer_int64(); } public function testSuccess() { - $result = h_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00\x00"); + $result = hammer_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00\x00"); $this->assertEquals(-0x200000000, $result); } public function testFailure() { - $result = h_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00"); + $result = hammer_parse($this->parser, "\xff\xff\xff\xfe\x00\x00\x00"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Int8Test.php b/src/bindings/php/Tests/Int8Test.php index 164d773..b0769ec 100644 --- a/src/bindings/php/Tests/Int8Test.php +++ b/src/bindings/php/Tests/Int8Test.php @@ -8,16 +8,16 @@ class Int8Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_int8(); + $this->parser = hammer_int8(); } public function testSuccess() { - $result = h_parse($this->parser, "\x88"); + $result = hammer_parse($this->parser, "\x88"); $this->assertEquals(-0x78, $result); } public function testFailure() { - $result = h_parse($this->parser, ""); + $result = hammer_parse($this->parser, ""); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/IntRangeTest.php b/src/bindings/php/Tests/IntRangeTest.php index ce56fce..4d300e3 100644 --- a/src/bindings/php/Tests/IntRangeTest.php +++ b/src/bindings/php/Tests/IntRangeTest.php @@ -7,16 +7,16 @@ class IntRangeTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_int_range(h_uint8(), 3, 10); + $this->parser = hammer_int_range(hammer_uint8(), 3, 10); } public function testSuccess() { - $result = h_parse($this->parser, "\x05"); + $result = hammer_parse($this->parser, "\x05"); $this->assertEquals(5, $result); } public function testFailure() { - $result = h_parse($this->parser, "\xb"); + $result = hammer_parse($this->parser, "\xb"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/LeftTest.php b/src/bindings/php/Tests/LeftTest.php index c671a80..e0ef01e 100644 --- a/src/bindings/php/Tests/LeftTest.php +++ b/src/bindings/php/Tests/LeftTest.php @@ -7,18 +7,18 @@ class LeftTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_left(ch("a"), ch(" ")); + $this->parser = hammer_left(hammer_ch("a"), hammer_ch(" ")); } public function testSuccess() { - $result = h_parse($this->parser, "a "); + $result = hammer_parse($this->parser, "a "); $this->assertEquals("a", $result); } public function testFailure() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, " "); - $result3 = h_parse($this->parser, "ab"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, " "); + $result3 = hammer_parse($this->parser, "ab"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); $this->assertEquals(NULL, $result3); diff --git a/src/bindings/php/Tests/LeftrecTest.php b/src/bindings/php/Tests/LeftrecTest.php index 52ed931..e578a31 100644 --- a/src/bindings/php/Tests/LeftrecTest.php +++ b/src/bindings/php/Tests/LeftrecTest.php @@ -7,27 +7,27 @@ class LeftrecTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_indirect(); - h_bind_indirect($this->parser, choice(sequence($this->parser, ch("a")), ch("a"))); + $this->parser = hammer_indirect(); + hammer_bind_indirect($this->parser, hammer_choice(hammer_sequence($this->parser, hammer_ch("a")), hammer_ch("a"))); } public function testSuccess1() { - $result = h_parse($this->parser, "a"); + $result = hammer_parse($this->parser, "a"); $this->assertEquals("a", $result); } /* These don't work in the underlying C so they won't work here either */ /* public function testSuccess2() { - $result = h_parse($this->parser, "aa"); + $result = hammer_parse($this->parser, "aa"); var_dump($result); $this->assertEquals(array("a", "a"), $result); } public function testSuccess3() { - $result = h_parse($this->parser, "aaa"); + $result = hammer_parse($this->parser, "aaa"); var_dump($result); $this->assertEquals(array(array("a", "a"), "a"), $result); } diff --git a/src/bindings/php/Tests/Many1Test.php b/src/bindings/php/Tests/Many1Test.php index cf5071c..50a6c41 100644 --- a/src/bindings/php/Tests/Many1Test.php +++ b/src/bindings/php/Tests/Many1Test.php @@ -7,14 +7,14 @@ class Many1Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_many1(choice(ch("a"), ch("b"))); + $this->parser = hammer_many1(hammer_choice(hammer_ch("a"), hammer_ch("b"))); } public function testSuccess() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, "b"); - $result3 = h_parse($this->parser, "aabbaba"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, "b"); + $result3 = hammer_parse($this->parser, "aabbaba"); $this->assertEquals(array("a"), $result1); $this->assertEquals(array("b"), $result2); $this->assertEquals(array("a", "a", "b", "b", "a", "b", "a"), $result3); @@ -22,8 +22,8 @@ class Many1Test extends PHPUnit_Framework_TestCase public function testFailure() { - $result1 = h_parse($this->parser, ""); - $result2 = h_parse($this->parser, "daabbabadef"); + $result1 = hammer_parse($this->parser, ""); + $result2 = hammer_parse($this->parser, "daabbabadef"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); } diff --git a/src/bindings/php/Tests/ManyTest.php b/src/bindings/php/Tests/ManyTest.php index 6d249a0..b2abee2 100644 --- a/src/bindings/php/Tests/ManyTest.php +++ b/src/bindings/php/Tests/ManyTest.php @@ -7,15 +7,15 @@ class ManyTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_many(choice(ch("a"), ch("b"))); + $this->parser = hammer_many(hammer_choice(hammer_ch("a"), hammer_ch("b"))); } public function testSuccess() { - $result1 = h_parse($this->parser, ""); - $result2 = h_parse($this->parser, "a"); - $result3 = h_parse($this->parser, "b"); - $result4 = h_parse($this->parser, "aabbaba"); + $result1 = hammer_parse($this->parser, ""); + $result2 = hammer_parse($this->parser, "a"); + $result3 = hammer_parse($this->parser, "b"); + $result4 = hammer_parse($this->parser, "aabbaba"); $this->assertEquals(array(), $result1); $this->assertEquals(array("a"), $result2); $this->assertEquals(array("b"), $result3); diff --git a/src/bindings/php/Tests/MiddleTest.php b/src/bindings/php/Tests/MiddleTest.php index 1ccb9da..93b6c48 100644 --- a/src/bindings/php/Tests/MiddleTest.php +++ b/src/bindings/php/Tests/MiddleTest.php @@ -7,22 +7,22 @@ class MiddleTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_middle(ch(" "), ch("a"), ch(" ")); + $this->parser = hammer_middle(hammer_ch(" "), hammer_ch("a"), hammer_ch(" ")); } public function testSuccess() { - $result = h_parse($this->parser, " a "); + $result = hammer_parse($this->parser, " a "); $this->assertEquals("a", $result); } public function testFailure() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, " "); - $result3 = h_parse($this->parser, " a"); - $result4 = h_parse($this->parser, "a "); - $result5 = h_parse($this->parser, " b "); - $result6 = h_parse($this->parser, "ba "); - $result7 = h_parse($this->parser, " ab"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, " "); + $result3 = hammer_parse($this->parser, " a"); + $result4 = hammer_parse($this->parser, "a "); + $result5 = hammer_parse($this->parser, " b "); + $result6 = hammer_parse($this->parser, "ba "); + $result7 = hammer_parse($this->parser, " ab"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); $this->assertEquals(NULL, $result3); diff --git a/src/bindings/php/Tests/NotInTest.php b/src/bindings/php/Tests/NotInTest.php index f06e53f..c5a2fdf 100644 --- a/src/bindings/php/Tests/NotInTest.php +++ b/src/bindings/php/Tests/NotInTest.php @@ -7,16 +7,16 @@ class NotInTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = not_in("abc"); + $this->parser = hammer_not_in("abc"); } public function testSuccess() { - $result = h_parse($this->parser, "d"); + $result = hammer_parse($this->parser, "d"); $this->assertEquals("d", $result); } public function testFailure() { - $result = h_parse($this->parser, "b"); + $result = hammer_parse($this->parser, "b"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/NotTest.php b/src/bindings/php/Tests/NotTest.php index a2c76aa..15eb77a 100644 --- a/src/bindings/php/Tests/NotTest.php +++ b/src/bindings/php/Tests/NotTest.php @@ -8,26 +8,26 @@ class NotTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = sequence(ch("a"), choice(ch("+"), h_token("++")), ch("b")); - $this->parser2 = sequence(ch("a"), choice(sequence(ch("+"), h_not(ch("+"))), h_token("++")), ch("b")); + $this->parser1 = hammer_sequence(hammer_ch("a"), hammer_choice(hammer_ch("+"), hammer_token("++")), hammer_ch("b")); + $this->parser2 = hammer_sequence(hammer_ch("a"), hammer_choice(hammer_sequence(hammer_ch("+"), hammer_not(hammer_ch("+"))), hammer_token("++")), hammer_ch("b")); } public function testSuccess1() { - $result = h_parse($this->parser1, "a+b"); + $result = hammer_parse($this->parser1, "a+b"); $this->assertEquals(array("a", "+", "b"), $result); } public function testFailure1() { - $result = h_parse($this->parser1, "a++b"); + $result = hammer_parse($this->parser1, "a++b"); $this->assertEquals(NULL, $result); } public function testSuccess2() { - $result1 = h_parse($this->parser2, "a+b"); - $result2 = h_parse($this->parser2, "a++b"); + $result1 = hammer_parse($this->parser2, "a+b"); + $result2 = hammer_parse($this->parser2, "a++b"); $this->assertEquals(array("a", array("+"), "b"), $result1); $this->assertEquals(array("a", "++", "b"), $result2); } diff --git a/src/bindings/php/Tests/NothingTest.php b/src/bindings/php/Tests/NothingTest.php index fa31b55..f827e47 100644 --- a/src/bindings/php/Tests/NothingTest.php +++ b/src/bindings/php/Tests/NothingTest.php @@ -7,12 +7,12 @@ class NothingPTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_nothing_p(); + $this->parser = hammer_nothing(); } public function testFailure() { - $result = h_parse($this->parser, "a"); + $result = hammer_parse($this->parser, "a"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/OptionalTest.php b/src/bindings/php/Tests/OptionalTest.php index 22b15df..e150415 100644 --- a/src/bindings/php/Tests/OptionalTest.php +++ b/src/bindings/php/Tests/OptionalTest.php @@ -7,14 +7,14 @@ class OptionalTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = sequence(ch("a"), h_optional(choice(ch("b"), ch("c"))), ch("d")); + $this->parser = hammer_sequence(hammer_ch("a"), hammer_optional(hammer_choice(hammer_ch("b"), hammer_ch("c"))), hammer_ch("d")); } public function testSuccess() { - $result1 = h_parse($this->parser, "abd"); - $result2 = h_parse($this->parser, "acd"); - $result3 = h_parse($this->parser, "ad"); + $result1 = hammer_parse($this->parser, "abd"); + $result2 = hammer_parse($this->parser, "acd"); + $result3 = hammer_parse($this->parser, "ad"); $this->assertEquals(array("a", "b", "d"), $result1); $this->assertEquals(array("a", "c", "d"), $result2); $this->assertEquals(array("a", NULL, "d"), $result3); @@ -22,9 +22,9 @@ class OptionalTest extends PHPUnit_Framework_TestCase public function testFailure() { - $result1 = h_parse($this->parser, "aed"); - $result2 = h_parse($this->parser, "ab"); - $result3 = h_parse($this->parser, "ac"); + $result1 = hammer_parse($this->parser, "aed"); + $result2 = hammer_parse($this->parser, "ab"); + $result3 = hammer_parse($this->parser, "ac"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); $this->assertEquals(NULL, $result3); diff --git a/src/bindings/php/Tests/PredicateTest.php b/src/bindings/php/Tests/PredicateTest.php index 1df45e2..cc891d6 100644 --- a/src/bindings/php/Tests/PredicateTest.php +++ b/src/bindings/php/Tests/PredicateTest.php @@ -12,18 +12,18 @@ class PredicateTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = predicate(h_many1(choice(ch('a'), ch('b'))), "predTest"); + $this->parser = hammer_predicate(hammer_many1(hammer_choice(hammer_ch('a'), hammer_ch('b'))), "predTest"); } public function testSuccess() { - $result1 = h_parse($this->parser, "aa"); - $result2 = h_parse($this->parser, "bb"); + $result1 = hammer_parse($this->parser, "aa"); + $result2 = hammer_parse($this->parser, "bb"); $this->assertEquals(["a", "a"], $result1); $this->assertEquals(["b", "b"], $result2); } public function testFailure() { - $result = h_parse($this->parser, "ab"); + $result = hammer_parse($this->parser, "ab"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/RepeatNTest.php b/src/bindings/php/Tests/RepeatNTest.php index e6db964..5441ef6 100644 --- a/src/bindings/php/Tests/RepeatNTest.php +++ b/src/bindings/php/Tests/RepeatNTest.php @@ -7,19 +7,19 @@ class RepeatNTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_repeat_n(choice(ch("a"), ch("b")), 2); + $this->parser = hammer_repeat_n(hammer_choice(hammer_ch("a"), hammer_ch("b")), 2); } public function testSuccess() { - $result = h_parse($this->parser, "abdef"); + $result = hammer_parse($this->parser, "abdef"); $this->assertEquals(array("a", "b"), $result); } public function testFailure() { - $result1 = h_parse($this->parser, "adef"); - $result2 = h_parse($this->parser, "dabdef"); + $result1 = hammer_parse($this->parser, "adef"); + $result2 = hammer_parse($this->parser, "dabdef"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); } diff --git a/src/bindings/php/Tests/RightTest.php b/src/bindings/php/Tests/RightTest.php index 3c5b06e..215aace 100644 --- a/src/bindings/php/Tests/RightTest.php +++ b/src/bindings/php/Tests/RightTest.php @@ -7,18 +7,18 @@ class RightTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_right(ch(" "), ch("a")); + $this->parser = hammer_right(hammer_ch(" "), hammer_ch("a")); } public function testSuccess() { - $result = h_parse($this->parser, " a"); + $result = hammer_parse($this->parser, " a"); $this->assertEquals("a", $result); } public function testFailure() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, " "); - $result3 = h_parse($this->parser, "ba"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, " "); + $result3 = hammer_parse($this->parser, "ba"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); $this->assertEquals(NULL, $result3); diff --git a/src/bindings/php/Tests/RightrecTest.php b/src/bindings/php/Tests/RightrecTest.php index 9580fde..ed21b35 100644 --- a/src/bindings/php/Tests/RightrecTest.php +++ b/src/bindings/php/Tests/RightrecTest.php @@ -7,15 +7,15 @@ class RightrecTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_indirect(); - h_bind_indirect($this->parser, choice(sequence(ch("a"), $this->parser), h_epsilon_p())); + $this->parser = hammer_indirect(); + hammer_bind_indirect($this->parser, hammer_choice(hammer_sequence(hammer_ch("a"), $this->parser), hammer_epsilon())); } public function testSuccess() { - $result1 = h_parse($this->parser, "a"); - $result2 = h_parse($this->parser, "aa"); - $result3 = h_parse($this->parser, "aaa"); + $result1 = hammer_parse($this->parser, "a"); + $result2 = hammer_parse($this->parser, "aa"); + $result3 = hammer_parse($this->parser, "aaa"); $this->assertEquals(array("a"), $result1); $this->assertEquals(array("a", array("a")), $result2); $this->assertEquals(array("a", array("a", array("a"))), $result3); diff --git a/src/bindings/php/Tests/SepBy1Test.php b/src/bindings/php/Tests/SepBy1Test.php index a5a36cc..57a5aff 100644 --- a/src/bindings/php/Tests/SepBy1Test.php +++ b/src/bindings/php/Tests/SepBy1Test.php @@ -7,15 +7,15 @@ class SepBy1Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_sepBy1(choice(ch("1"), ch("2"), ch("3")), ch(",")); + $this->parser = hammer_sep_by1(hammer_choice(hammer_ch("1"), hammer_ch("2"), hammer_ch("3")), hammer_ch(",")); } public function testSuccess() { - $result1 = h_parse($this->parser, "1,2,3"); - $result2 = h_parse($this->parser, "1,3,2"); - $result3 = h_parse($this->parser, "1,3"); - $result4 = h_parse($this->parser, "3"); + $result1 = hammer_parse($this->parser, "1,2,3"); + $result2 = hammer_parse($this->parser, "1,3,2"); + $result3 = hammer_parse($this->parser, "1,3"); + $result4 = hammer_parse($this->parser, "3"); $this->assertEquals(array("1", "2", "3"), $result1); $this->assertEquals(array("1", "3", "2"), $result2); $this->assertEquals(array("1", "3"), $result3); @@ -24,7 +24,7 @@ class SepBy1Test extends PHPUnit_Framework_TestCase public function testFailure() { - $result = h_parse($this->parser, ""); + $result = hammer_parse($this->parser, ""); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/SepByTest.php b/src/bindings/php/Tests/SepByTest.php index fdf4ed4..17c8e16 100644 --- a/src/bindings/php/Tests/SepByTest.php +++ b/src/bindings/php/Tests/SepByTest.php @@ -7,16 +7,16 @@ class SepByTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_sepBy(choice(ch("1"), ch("2"), ch("3")), ch(",")); + $this->parser = hammer_sep_by(hammer_choice(hammer_ch("1"), hammer_ch("2"), hammer_ch("3")), hammer_ch(",")); } public function testSuccess() { - $result1 = h_parse($this->parser, "1,2,3"); - $result2 = h_parse($this->parser, "1,3,2"); - $result3 = h_parse($this->parser, "1,3"); - $result4 = h_parse($this->parser, "3"); - $result5 = h_parse($this->parser, ""); + $result1 = hammer_parse($this->parser, "1,2,3"); + $result2 = hammer_parse($this->parser, "1,3,2"); + $result3 = hammer_parse($this->parser, "1,3"); + $result4 = hammer_parse($this->parser, "3"); + $result5 = hammer_parse($this->parser, ""); $this->assertEquals(array("1", "2", "3"), $result1); $this->assertEquals(array("1", "3", "2"), $result2); $this->assertEquals(array("1", "3"), $result3); diff --git a/src/bindings/php/Tests/SequenceTest.php b/src/bindings/php/Tests/SequenceTest.php index 67ae1f0..bafb4f1 100644 --- a/src/bindings/php/Tests/SequenceTest.php +++ b/src/bindings/php/Tests/SequenceTest.php @@ -8,29 +8,29 @@ class SequenceTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = sequence(ch("a"), ch("b")); - $this->parser2 = sequence(ch("a"), h_whitespace(ch("b"))); + $this->parser1 = hammer_sequence(hammer_ch("a"), hammer_ch("b")); + $this->parser2 = hammer_sequence(hammer_ch("a"), hammer_whitespace(hammer_ch("b"))); } public function testSuccess1() { - $result = h_parse($this->parser1, "ab"); + $result = hammer_parse($this->parser1, "ab"); $this->assertEquals(array("a", "b"), $result); } public function testFailure1() { - $result1 = h_parse($this->parser1, "a"); - $result2 = h_parse($this->parser2, "b"); + $result1 = hammer_parse($this->parser1, "a"); + $result2 = hammer_parse($this->parser2, "b"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); } public function testSuccess2() { - $result1 = h_parse($this->parser2, "ab"); - $result2 = h_parse($this->parser2, "a b"); - $result3 = h_parse($this->parser2, "a b"); + $result1 = hammer_parse($this->parser2, "ab"); + $result2 = hammer_parse($this->parser2, "a b"); + $result3 = hammer_parse($this->parser2, "a b"); $this->assertEquals(array("a", "b"), $result1); $this->assertEquals(array("a", "b"), $result2); $this->assertEquals(array("a", "b"), $result3); diff --git a/src/bindings/php/Tests/TokenTest.php b/src/bindings/php/Tests/TokenTest.php index 492c17f..90c278d 100644 --- a/src/bindings/php/Tests/TokenTest.php +++ b/src/bindings/php/Tests/TokenTest.php @@ -8,16 +8,16 @@ class TokenTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_token("95\xa2"); + $this->parser = hammer_token("95\xa2"); } public function testSuccess() { - $result = h_parse($this->parser, "95\xa2"); + $result = hammer_parse($this->parser, "95\xa2"); $this->assertEquals("95\xa2", $result); } public function testFailure() { - $result = h_parse($this->parser, "95"); + $result = hammer_parse($this->parser, "95"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Uint16Test.php b/src/bindings/php/Tests/Uint16Test.php index 4639389..31c99cd 100644 --- a/src/bindings/php/Tests/Uint16Test.php +++ b/src/bindings/php/Tests/Uint16Test.php @@ -8,16 +8,16 @@ class Uint16Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_uint16(); + $this->parser = hammer_uint16(); } public function testSuccess() { - $result = h_parse($this->parser, "\x02\x00"); + $result = hammer_parse($this->parser, "\x02\x00"); $this->assertEquals(0x200, $result); } public function testFailure() { - $result = h_parse($this->parser, "\x02"); + $result = hammer_parse($this->parser, "\x02"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Uint32Test.php b/src/bindings/php/Tests/Uint32Test.php index f9b0f0b..593de66 100644 --- a/src/bindings/php/Tests/Uint32Test.php +++ b/src/bindings/php/Tests/Uint32Test.php @@ -8,16 +8,16 @@ class Uint32Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_uint32(); + $this->parser = hammer_uint32(); } public function testSuccess() { - $result = h_parse($this->parser, "\x00\x02\x00\x00"); + $result = hammer_parse($this->parser, "\x00\x02\x00\x00"); $this->assertEquals(0x20000, $result); } public function testFailure() { - $result = h_parse($this->parser, "\x00\x02\x00"); + $result = hammer_parse($this->parser, "\x00\x02\x00"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Uint64Test.php b/src/bindings/php/Tests/Uint64Test.php index 9910916..e61edb6 100644 --- a/src/bindings/php/Tests/Uint64Test.php +++ b/src/bindings/php/Tests/Uint64Test.php @@ -8,16 +8,16 @@ class Uint64Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_uint64(); + $this->parser = hammer_uint64(); } public function testSuccess() { - $result = h_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00\x00"); + $result = hammer_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00\x00"); $this->assertEquals(0x200000000, $result); } public function testFailure() { - $result = h_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00"); + $result = hammer_parse($this->parser, "\x00\x00\x00\x02\x00\x00\x00"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/Uint8Test.php b/src/bindings/php/Tests/Uint8Test.php index 6797949..6ebfa28 100644 --- a/src/bindings/php/Tests/Uint8Test.php +++ b/src/bindings/php/Tests/Uint8Test.php @@ -8,16 +8,16 @@ class Uint8Test extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_uint8(); + $this->parser = hammer_uint8(); } public function testSuccess() { - $result = h_parse($this->parser, "\x78"); + $result = hammer_parse($this->parser, "\x78"); $this->assertEquals(0x78, $result); } public function testFailure() { - $result = h_parse($this->parser, ""); + $result = hammer_parse($this->parser, ""); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/WhitespaceTest.php b/src/bindings/php/Tests/WhitespaceTest.php index 96c2f38..c5f6e90 100644 --- a/src/bindings/php/Tests/WhitespaceTest.php +++ b/src/bindings/php/Tests/WhitespaceTest.php @@ -8,15 +8,15 @@ class WhitespaceTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser1 = h_whitespace(ch("a")); - $this->parser2 = h_whitespace(h_end_p()); + $this->parser1 = hammer_whitespace(hammer_ch("a")); + $this->parser2 = hammer_whitespace(hammer_end()); } public function testSuccess1() { - $result1 = h_parse($this->parser1, "a"); - $result2 = h_parse($this->parser1, " a"); - $result3 = h_parse($this->parser1, " a"); - $result4 = h_parse($this->parser1, "\ta"); + $result1 = hammer_parse($this->parser1, "a"); + $result2 = hammer_parse($this->parser1, " a"); + $result3 = hammer_parse($this->parser1, " a"); + $result4 = hammer_parse($this->parser1, "\ta"); $this->assertEquals("a", $result1); $this->assertEquals("a", $result2); $this->assertEquals("a", $result3); @@ -24,19 +24,19 @@ class WhitespaceTest extends PHPUnit_Framework_TestCase } public function testFailure1() { - $result = h_parse($this->parser1, "_a"); + $result = hammer_parse($this->parser1, "_a"); $this->assertEquals(NULL, $result); } public function testSuccess2() { - $result1 = h_parse($this->parser2, ""); - $result2 = h_parse($this->parser2, " "); + $result1 = hammer_parse($this->parser2, ""); + $result2 = hammer_parse($this->parser2, " "); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); } public function testFailure2() { - $result = h_parse($this->parser2, " x"); + $result = hammer_parse($this->parser2, " x"); $this->assertEquals(NULL, $result); } } diff --git a/src/bindings/php/Tests/XorTest.php b/src/bindings/php/Tests/XorTest.php index c9a25f0..1d20d1e 100644 --- a/src/bindings/php/Tests/XorTest.php +++ b/src/bindings/php/Tests/XorTest.php @@ -7,21 +7,21 @@ class XorTest extends PHPUnit_Framework_TestCase protected function setUp() { - $this->parser = h_xor(ch_range("0", "6"), ch_range("5", "9")); + $this->parser = hammer_xor(hammer_ch_range("0", "6"), hammer_ch_range("5", "9")); } public function testSuccess() { - $result1 = h_parse($this->parser, "0"); - $result2 = h_parse($this->parser, "9"); + $result1 = hammer_parse($this->parser, "0"); + $result2 = hammer_parse($this->parser, "9"); $this->assertEquals("0", $result1); $this->assertEquals("9", $result2); } public function testFailure() { - $result1 = h_parse($this->parser, "5"); - $result2 = h_parse($this->parser, "a"); + $result1 = hammer_parse($this->parser, "5"); + $result2 = hammer_parse($this->parser, "a"); $this->assertEquals(NULL, $result1); $this->assertEquals(NULL, $result2); } diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index c975360..63038cc 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -77,6 +77,42 @@ } } +%rename("hammer_token") h_token; +%rename("hammer_int_range") h_int_range; +%rename("hammer_bits") h_bits; +%rename("hammer_int64") h_int64; +%rename("hammer_int32") h_int32; +%rename("hammer_int16") h_int16; +%rename("hammer_int8") h_int8; +%rename("hammer_uint64") h_uint64; +%rename("hammer_uint32") h_uint32; +%rename("hammer_uint16") h_uint16; +%rename("hammer_uint8") h_uint8; +%rename("hammer_whitespace") h_whitespace; +%rename("hammer_left") h_left; +%rename("hammer_right") h_right; +%rename("hammer_middle") h_middle; +%rename("hammer_end") h_end_p; +%rename("hammer_nothing") h_nothing_p; +%rename("hammer_butnot") h_butnot; +%rename("hammer_difference") h_difference; +%rename("hammer_xor") h_xor; +%rename("hammer_many") h_many; +%rename("hammer_many1") h_many1; +%rename("hammer_repeat_n") h_repeat_n; +%rename("hammer_optional") h_optional; +%rename("hammer_ignore") h_ignore; +%rename("hammer_sep_by") h_sepBy; +%rename("hammer_sep_by1") h_sepBy1; +%rename("hammer_epsilon") h_epsilon_p; +%rename("hammer_length_value") h_length_value; +%rename("hammer_and") h_and; +%rename("hammer_not") h_not; +%rename("hammer_indirect") h_indirect; +%rename("hammer_bind_indirect") h_bind_indirect; +%rename("hammer_compile") h_compile; +%rename("hammer_parse") h_parse; + %include "../swig/hammer.i"; %inline { @@ -158,52 +194,52 @@ return Z_LVAL_P(ret); } - HParser* action(HParser *parser, const char *name) { + HParser* hammer_action(HParser *parser, const char *name) { return h_action(parser, call_action, (void*)name); } - HParser* predicate(HParser *parser, const char *name) { + HParser* hammer_predicate(HParser *parser, const char *name) { return h_attr_bool(parser, call_predicate, (void*)name); } } %pragma(php) code=" -function ch($ch) +function hammer_ch($ch) { if (is_string($ch)) - return h_token($ch); + return hammer_token($ch); else return h_ch($ch); } -function choice() +function hammer_choice() { $arg_list = func_get_args(); $arg_list[] = NULL; return h_choice__a($arg_list); } -function sequence() +function hammer_sequence() { $arg_list = func_get_args(); $arg_list[] = NULL; return h_sequence__a($arg_list); } -function ch_range($low, $high) +function hammer_ch_range($low, $high) { - return action(h_ch_range($low, $high), \"chr\"); + return hammer_action(h_ch_range($low, $high), \"chr\"); } -function in($charset) +function hammer_in($charset) { - return action(h_in($charset), \"chr\"); + return hammer_action(h_in($charset), \"chr\"); } -function not_in($charset) +function hammer_not_in($charset) { - return action(h_not_in($charset), \"chr\"); + return hammer_action(h_not_in($charset), \"chr\"); } " From f9eebda67326de8a7c00f81caf46d9dd54957b29 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 18 Dec 2013 14:25:52 +0100 Subject: [PATCH 087/101] fix segfault with optimized code; initialize TSRM stuff --- SConstruct | 2 +- src/bindings/php/hammer.i | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/SConstruct b/SConstruct index dac0107..a9f9c67 100644 --- a/SConstruct +++ b/SConstruct @@ -69,7 +69,7 @@ dbg = env.Clone(VARIANT='debug') dbg.Append(CCFLAGS=['-g']) opt = env.Clone(VARIANT='opt') -opt.Append(CCFLAGS="-O3") +opt.Append(CCFLAGS=["-O3"]) if GetOption("variant") == 'debug': env = dbg diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 63038cc..92857db 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -1,5 +1,8 @@ %module hammer; %include "exception.i"; +%{ +#include "allocator.h" + %} %ignore HCountedArray_; @@ -8,6 +11,7 @@ %} %init %{ + TSRMLS_FETCH(); h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); %} @@ -161,9 +165,11 @@ } static HParsedToken* call_action(const HParseResult *p, void *user_data) { - zval *args[1]; + zval **args; zval func; zval *ret; + args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers + MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); hpt_to_php(p->ast, args[0]); @@ -179,9 +185,11 @@ } static int call_predicate(HParseResult *p, void *user_data) { - zval *args[1]; + zval **args; zval func; zval *ret; + args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers + MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); hpt_to_php(p->ast, args[0]); From 4826607e674bbd20de83f89a5007285d1dbab2b3 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 18 Dec 2013 14:36:00 +0100 Subject: [PATCH 088/101] add TSRMLS_FETCH at top of blocks that need tsrm_ls --- src/bindings/php/hammer.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 92857db..58bfbad 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -168,6 +168,7 @@ zval **args; zval func; zval *ret; + TSRMLS_FETCH(); args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); @@ -188,6 +189,7 @@ zval **args; zval func; zval *ret; + TSRMLS_FETCH(); args = (zval**)h_arena_malloc(p->arena, sizeof(*args) * 1); // one-element array of pointers MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); From 8286ce087d0f3fccebc003a197c0a03c6298613c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Wed, 18 Dec 2013 14:55:26 +0100 Subject: [PATCH 089/101] hpt_to_php needs TSRMLS_FETCH too; update swig to version perl uses --- .travis.yml | 2 +- src/bindings/php/hammer.i | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d909225..7801ab4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ matrix: env: BINDINGS=php CC=clang before_install: - sudo apt-get update -qq - - if [ "$BINDINGS" != "none" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; swig -version; fi + - if [ "$BINDINGS" != "none" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi - if [ "$BINDINGS" == "python" ]; then sudo apt-get install -qq python-dev; fi install: true diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 58bfbad..3835c28 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -121,6 +121,7 @@ %inline { void hpt_to_php(const HParsedToken *token, zval *return_value) { + TSRMLS_FETCH(); if (!token) { RETVAL_NULL(); return; From 80eed33825cc477514ce241c59fb82538e0e75f8 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 15:27:57 +0100 Subject: [PATCH 090/101] use only zend_throw_exception, not SWIG exception wrappers --- src/bindings/php/hammer.i | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 3835c28..9f3f7e0 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -42,18 +42,18 @@ for (i=0; i Date: Sat, 21 Dec 2013 15:41:14 +0100 Subject: [PATCH 091/101] apparently zts needs a TSRMLS_C declaration for invocations of zend_exception_get_default() --- src/bindings/php/hammer.i | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 9f3f7e0..6089020 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -43,17 +43,17 @@ zval **data; if (zend_hash_index_find(arr, i, (void**)&data) == FAILURE) { $1 = NULL; - zend_throw_exception(zend_exception_get_default(), "index in parser array out of bounds", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "index in parser array out of bounds", 0 TSRMLS_CC); } else { res = SWIG_ConvertPtr(*data, &($1[i]), SWIGTYPE_p_HParser_, 0 | 0); if (!SWIG_IsOK(res)) { - zend_throw_exception(zend_exception_get_default(), "that wasn't an HParser", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "that wasn't an HParser", 0 TSRMLS_CC); } } } } else { $1 = NULL; - zend_throw_exception(zend_exception_get_default(), "that wasn't an array of HParsers", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "that wasn't an array of HParsers", 0 TSRMLS_CC); } } @@ -157,7 +157,7 @@ int res = 0; res = SWIG_ConvertPtr(return_value, (void*)token, SWIGTYPE_p_HParsedToken_, 0 | 0); if (!SWIG_IsOK(res)) { - zend_throw_exception(zend_exception_get_default(), "hpt_to_php: that wasn't an HParsedToken", 0 TSRMLS_CC); + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "hpt_to_php: that wasn't an HParsedToken", 0 TSRMLS_CC); } // TODO: support registry } From 1f256ac7c827f6ae7cfff40691d6331a4c484d59 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 16:01:13 +0100 Subject: [PATCH 092/101] this may be fixed on 2.0.4 but not 2.0.8? https://groups.google.com/forum/#!topic/librets/uN0UKRO7juE --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7801ab4..a778c2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,8 @@ matrix: env: BINDINGS=php CC=clang before_install: - sudo apt-get update -qq - - if [ "$BINDINGS" != "none" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi + - if [ "$BINDINGS" != "none" ]; then sudo apt-get install -qq swig; fi + - if [ "$BINDINGS" != "perl" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi - if [ "$BINDINGS" == "python" ]; then sudo apt-get install -qq python-dev; fi install: true From 838bf54aa047949dd76c3f654110d4f4976ce13d Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 16:06:12 +0100 Subject: [PATCH 093/101] what happens if we declare tsrm_ls explicitly at global scope? --- src/bindings/php/hammer.i | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 6089020..2e19d4e 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -11,7 +11,9 @@ %} %init %{ - TSRMLS_FETCH(); +#ifdef ZTS + void ***tsrm_ls; +#endif h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); %} From bb58af5738da6c2eef6159cbba90438f78c05d08 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 16:08:28 +0100 Subject: [PATCH 094/101] ok, outside of the init block then --- src/bindings/php/hammer.i | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 2e19d4e..318ec3a 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -1,4 +1,7 @@ %module hammer; +#ifdef ZTS + void ***tsrm_ls; +#endif %include "exception.i"; %{ #include "allocator.h" @@ -11,9 +14,6 @@ %} %init %{ -#ifdef ZTS - void ***tsrm_ls; -#endif h_tt_php = h_allocate_token_type("com.upstandinghackers.hammer.php"); %} From c67391cfbb06c2d0ade97ed57b98a23afba9f39e Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 18:55:44 +0100 Subject: [PATCH 095/101] what happens when we call hpt_to_php with TSRMLS_CC? --- src/bindings/php/hammer.i | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 318ec3a..f24a063 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -1,6 +1,6 @@ %module hammer; #ifdef ZTS - void ***tsrm_ls; +// void ***tsrm_ls; #endif %include "exception.i"; %{ @@ -79,7 +79,7 @@ //SWIG_exception(SWIG_TypeError, "typemap: should have been an HParseResult*, was NULL"); RETVAL_NULL(); } else { - hpt_to_php($1->ast, $result); + hpt_to_php($1->ast, $result TSRMLS_CC); } } @@ -146,7 +146,7 @@ for (int i=0; i < token->token_data.seq->used; i++) { zval *tmp; ALLOC_INIT_ZVAL(tmp); - hpt_to_php(token->token_data.seq->elements[i], tmp); + hpt_to_php(token->token_data.seq->elements[i], tmp TSRMLS_CC); add_next_index_zval(return_value, tmp); } break; @@ -176,7 +176,7 @@ MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); - hpt_to_php(p->ast, args[0]); + hpt_to_php(p->ast, args[0] TSRMLS_CC); int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { printf("call_user_function failed\n"); @@ -197,7 +197,7 @@ MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); - hpt_to_php(p->ast, args[0]); + hpt_to_php(p->ast, args[0] TSRMLS_CC); int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { printf("call_user_function failed\n"); From d6dbf4ba4130c04a057c3917b77e560205f10076 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 19:46:57 +0100 Subject: [PATCH 096/101] SWIG doesn't like adding TSRMLS_* macros to fn decls, so TSRMLS_FETCH it is --- src/bindings/php/hammer.i | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index f24a063..7f9b9d3 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -146,7 +146,7 @@ for (int i=0; i < token->token_data.seq->used; i++) { zval *tmp; ALLOC_INIT_ZVAL(tmp); - hpt_to_php(token->token_data.seq->elements[i], tmp TSRMLS_CC); + hpt_to_php(token->token_data.seq->elements[i], tmp); add_next_index_zval(return_value, tmp); } break; @@ -176,11 +176,10 @@ MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); - hpt_to_php(p->ast, args[0] TSRMLS_CC); + hpt_to_php(p->ast, args[0]); int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { - printf("call_user_function failed\n"); - // FIXME throw some error + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "call_action failed", 0 TSRMLS_CC); return NULL; } // Whatever the zval is, stuff it into a token @@ -197,11 +196,10 @@ MAKE_STD_ZVAL(args[0]); ALLOC_INIT_ZVAL(ret); ZVAL_STRING(&func, (const char*)user_data, 0); - hpt_to_php(p->ast, args[0] TSRMLS_CC); + hpt_to_php(p->ast, args[0]); int ok = call_user_function(EG(function_table), NULL, &func, ret, 1, args TSRMLS_CC); if (ok != SUCCESS) { - printf("call_user_function failed\n"); - // FIXME throw some error + zend_throw_exception(zend_exception_get_default(TSRMLS_C), "call_predicate failed", 0 TSRMLS_CC); return 0; } return Z_LVAL_P(ret); From c52e8bdbf0b908b784303e3f0c6df1b2d552433c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 19:47:13 +0100 Subject: [PATCH 097/101] no, it's perl that needs 2.0.8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a778c2a..e55bf3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,7 @@ matrix: before_install: - sudo apt-get update -qq - if [ "$BINDINGS" != "none" ]; then sudo apt-get install -qq swig; fi - - if [ "$BINDINGS" != "perl" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi + - if [ "$BINDINGS" == "perl" ]; then sudo add-apt-repository ppa:dns/irc -y; sudo apt-get update -qq; sudo apt-get install -qq swig=2.0.8-1irc1~12.04; fi - if [ "$BINDINGS" == "python" ]; then sudo apt-get install -qq python-dev; fi install: true From 500257d11154f5a8db4cbfc4c3d27ce1b5410138 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 19:57:23 +0100 Subject: [PATCH 098/101] remove spurious TSRMLS_CC --- src/bindings/php/hammer.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 7f9b9d3..44d4fd8 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -79,7 +79,7 @@ //SWIG_exception(SWIG_TypeError, "typemap: should have been an HParseResult*, was NULL"); RETVAL_NULL(); } else { - hpt_to_php($1->ast, $result TSRMLS_CC); + hpt_to_php($1->ast, $result); } } From 9ea27e9203c9566db463b742089cc35a082c557c Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sat, 21 Dec 2013 19:59:48 +0100 Subject: [PATCH 099/101] let's see what config travis uses, shall we? --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e55bf3f..ab0bdf1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,7 +62,7 @@ before_install: install: true before_script: - - if [ "$BINDINGS" == "php" ]; then phpenv config-add src/bindings/php/hammer.ini; fi + - if [ "$BINDINGS" == "php" ]; then phpenv exec php-config; phpenv config-add src/bindings/php/hammer.ini; fi script: - scons bindings=$BINDINGS test notifications: From 10dffd3ee45779c437041975e7d5c3e1cdb9f078 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 22 Dec 2013 17:42:14 +0100 Subject: [PATCH 100/101] trying to fix missing function name for call_action --- src/bindings/php/hammer.i | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 44d4fd8..895a1ac 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -206,11 +206,13 @@ } HParser* hammer_action(HParser *parser, const char *name) { - return h_action(parser, call_action, (void*)name); + const char *fname = strdup(name); + return h_action(parser, call_action, (void*)fname); } HParser* hammer_predicate(HParser *parser, const char *name) { - return h_attr_bool(parser, call_predicate, (void*)name); + const char *fname = strdup(name); + return h_attr_bool(parser, call_predicate, (void*)fname); } } From ecfe8a64d64ed71ea42790985b0637eb096c2801 Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" Date: Sun, 22 Dec 2013 18:27:59 +0100 Subject: [PATCH 101/101] tidying php-bindings directory and travis output --- .travis.yml | 2 +- src/bindings/php/hammer.i | 3 - src/bindings/php/hammer.xml | 514 ------------------------------------ 3 files changed, 1 insertion(+), 518 deletions(-) delete mode 100644 src/bindings/php/hammer.xml diff --git a/.travis.yml b/.travis.yml index ab0bdf1..e55bf3f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,7 +62,7 @@ before_install: install: true before_script: - - if [ "$BINDINGS" == "php" ]; then phpenv exec php-config; phpenv config-add src/bindings/php/hammer.ini; fi + - if [ "$BINDINGS" == "php" ]; then phpenv config-add src/bindings/php/hammer.ini; fi script: - scons bindings=$BINDINGS test notifications: diff --git a/src/bindings/php/hammer.i b/src/bindings/php/hammer.i index 895a1ac..11fb12a 100644 --- a/src/bindings/php/hammer.i +++ b/src/bindings/php/hammer.i @@ -1,7 +1,4 @@ %module hammer; -#ifdef ZTS -// void ***tsrm_ls; -#endif %include "exception.i"; %{ #include "allocator.h" diff --git a/src/bindings/php/hammer.xml b/src/bindings/php/hammer.xml deleted file mode 100644 index 4510e63..0000000 --- a/src/bindings/php/hammer.xml +++ /dev/null @@ -1,514 +0,0 @@ - - - - A library for defining parsers (character- or binary-oriented) inline. - ... - - - - mlp - Meredith L. Patterson - mlp@upstandinghackers.com - lead - - - - LGPL - - - 0.1 - 2013-11-15 - alpha - First cut of extension. - - - - Hammer C library -
-
-
- - - - - - - - - void free() - Deallocate a parse result - - Free the memory allocated to a parse result when the result is no longer needed. - - - - - - - void report() - Output benchmarking results in a human-readable format - - - - - - - - object HParseResult parse(string str) - Parse an input - Top-level function to call a parser that has been built over some piece of input. - --> - - int compile(string backend, array params) - Generate parse tables for the given parsing backend - - Some of the parsing backends must transform a parser into a set of parse tables before they can be used. See the documentation for the parser backend in question for information about the [params] parameter, or pass in NULL for the defaults. - - Returns -1 if the grammar cannot be compiled with the specified options; 0 otherwise. - - - - object HBenchmarkResults benchmark(array testcases) - Benchmark this parser using all the applicable parsing backends against a set of test cases you provide - - - - - - - object HParser hammer_token(string token) - Parse a token (primitive) - - Given a string, returns a parser that parses that string value. - - Result token type: string - - - - - - - object HParser hammer_ch(string ch) - Parse a character (primitive) - - Given a single character, returns a parser that parses that character. - - Result token type: string - - - - - object HParser hammer_ch_range(string lower, string upper) - Parse a character within the given range (primitive) - - Given two single-character bounds, lower and upper, returns a parser that parses a single character within the range [lower, upper] (inclusive). - - Result token type: string - - - - - object HParser hammer_int_range(object HParser p, int lower, int upper) - Parse an integer within the given range (primitive) - - Given an integer parser, p, and two integer bounds, lower and upper, returns a parser that parses an integral value within the range [lower, upper] (inclusive). - - Result token type: int - - - - - object HParser hammer_bits(int len, bool sign) - Parse a specified number of bits (primitive) - - Returns a parser that parses the specified number of bits. sign == true if signed, false if unsigned. - - Result token type: int - - - - - object HParser hammer_int64() - Parse a 64-bit signed integer (primitive) - - Returns a parser that parses a signed 8-byte integer value. - - Result token type: int - - - - - object HParser hammer_int32() - Parse a 32-bit signed integer (primitive) - - Returns a parser that parses a signed 4-byte integer value. - - Result token type: int - - - - - object HParser hammer_int16() - Parse a 16-bit signed integer (primitive) - - Returns a parser that parses a signed 2-byte integer value. - - Result token type: int - - - - - object HParser hammer_int8() - Parse an 8-bit signed integer (primitive) - - Returns a parser that parses a signed 1-byte integer value. - - Result token type: int - - - - - object HParser hammer_uint64() - Parse a 64-bit unsigned integer (primitive) - - Returns a parser that parses an unsigned 8-byte integer value. - - Result token type: int - - - - - object HParser hammer_uint32() - Parse a 32-bit unsigned integer (primitive) - - Returns a parser that parses an unsigned 4-byte integer value. - - Result token type: int - - - - - object HParser hammer_uint16() - Parse a 16-bit unsigned integer (primitive) - - Returns a parser that parses an unsigned 2-byte integer value. - - Result token type: int - - - - - object HParser hammer_uint8() - Parse an 8-bit unsigned integer (primitive) - - Returns a parser that parses an unsigned 1-byte integer value. - - Result token type: int - - - - - object HParser hammer_whitespace(object HParser p) - Parse something preceded by whitespace (higher-order) - - Given a parser, p, returns a parser that skips any whitespace and then applies p. - - Result token type: p's result type - - - - - object HParser hammer_left(object HParser p, object HParser q) - Take the leftmost result of two parsers (higher-order) - - Given two parsers, p and q, returns a parser that parses them in sequence but only returns p's result. - - Result token type: p's result type - - - - - object HParser hammer_right(object HParser p, object HParser q) - Take the rightmost result of two parsers (higher-order) - - Given two parsers, p and q, returns a parser that parses them in sequence but only returns q's result. - - Result token type: q's result type - - - - - object HParser hammer_middle(object HParser p, object HParser x, object HParser q) - Take the middle result of three parsers (higher-order) - - Given three parsers, p, x, and q, returns a parser that parses them in sequence but only returns x's result. - - Result token type: x's result type - - - - - object HParser hammer_action(object HParser p, callback f) - Attach a semantic action to a parser (higher-order) - - Given another parser, p, and a function, f, returns a parser that applies p, then applies f to everything in the AST of p's result. - - Result token type: any - - - - - object HParser hammer_in(string charset) - Parse a character that appears in charset (primitive) - - Parse a single character in the given charset. - - Result token type: string - - - - - object HParser hammer_not_in(string charset) - Parse a character that does not appear in charset (primitive) - - Parse a single character *not* in the given charset. - - Result token type: string - - - - - object HParser hammer_end_p() - Recognize the end-of-input (primitive) - - A no-argument parser that succeeds if there is no more input to parse. - - Result token type: none. - - - - - object HParser hammer_nothing_p() - This parser always fails (primitive) - - hammer_nothing_p is primarily useful when stubbing out a larger parser. If you define a rule as hammer_nothing_p(), the top-level parser will run, but if a rule containing hammer_nothing_p is invoked, the parse will fail. - - Result token type: there is no result token for this parser. - - - - - object HParser hammer_sequence(array p_array) - Apply a list of parsers sequentially (higher-order) - - Given an array of parsers, p_array, apply each parser in order. The parse succeeds only if all parsers succeed. - - Result token type: array - - - - - object HParser hammer_choice(array p_array) - Apply any one of a list of parsers (higher-order) - - Given an array of parsers, p_array, apply each parser in order. The first parser to succeed produces the result; if no parsers succeed, the parse fails. - - Result token type: the type of the first successful parser's result - - - - - object HParser hammer_butnot(object HParser p1, object HParser p2) - Parse p1 but not p2 (higher-order) - - Given two parsers, p1 and p2, this parser succeeds in the following cases: - - * if p1 succeeds and p2 fails (starting from the same place in the input stream) - * if both succeed but p1's result is as long as or longer than p2's - - Result token type: p1's result type. - - - - - object HParser hammer_difference(object HParser p1, object HParser p2) - Parse p1 but not p2 (higher-order) - - Given two parsers, p1 and p2, this parser succeeds in the following cases: - - * if p1 succeeds and p2 fails (starting from the same place in the input stream) - * if both succeed but p2's result is *strictly* shorter than p1's - - Result token type: p1's result type. - - - - - object HParser hammer_xor(object HParser p1, object HParser p2) - Parse p1 or p2 but not both (higher-order) - - Given two parsers, p1 and p2, this parser suceeds if *either* p1 or p2 succeed, but not if they both do. - - Result token type: the result type of whichever parser succeeded - - - - - object HParser hammer_many(object HParser p) - Parse zero or more instances of p (higher-order) - - Given a parser, p, this parser succeeds for zero or more repetitions of p. - - Result token type: array - - - - - object HParser hammer_many1(object HParser p) - Parse one or more instances of p (higher-order) - - Given a parser, p, this parser succeeds for one or more repetitions of p. - - Result token type: array - - - - - object HParser hammer_repeat_n(object HParser p, int n) - Parse exactly n instances of p (higher-order) - - Given a parser, p, this parser succeeds for exactly N repetitions of p. - - Result token type: array - - - - - object HParser hammer_optional(object HParser p) - Mark a parser as optional, like ? in regular expressions (higher-order) - - Given a parser, p, this parser succeeds with the value p parsed or with an empty result. - - Result token type: If p succeeded, the type of its result; if not, nothing. - - - - - object HParser hammer_ignore(object HParser p) - Apply p but leave its result out of the final AST (higher-order) - - Given a parser, p, this parser succeeds if p succeeds, but doesn't include p's result in the final result. - - Result token type: none. - - - - - object HParser hammer_sepBy(object HParser p, object HParser sep) - Parse a (possibly empty) sequence of values separated by a separator (higher-order) - - Given a parser, p, and a parser for a separator, sep, this parser matches a (possibly empty) list of things that p can parse, separated by sep. For example, if p is hammer_many1(hammer_ch_range('0', '9')) and sep is hammer_ch(','), hammer_sepBy(p, sep) will match a comma-separated list of integers. - - Result token type: array - - - - - object HParser hammer_sepBy1(object HParser p, object HParser sep) - Parse a sequence of values separated by a separator (higher-order) - - Given a parser, p, and a parser for a separator, sep, this parser matches a list of things that p can parse, separated by sep. Unlike hammer_sepBy, this ensures that the result has at least one element. For example, if p is hammer_many(hammer_ch_range('0', '9')), hammer_sepBy1(p, sep) will match a comma-separated list of integers. - - Result token type: array - - - - - object HParser hammer_epsilon_p() - Parse the empty string (primitive) - - This parser always returns a zero-length match, i.e., the empty string. - - Result token type: none - - - - - object HParser hammer_length_value(object HParser length, object HParser value) - Parse (length) repetitions of (value) (higher-order) - - This parser applies its first argument to read an unsigned integer value, then applies its second argument that many times. length should produce an integer value; this is checked at runtime. Specifically, length's token type must be int. - - Result token type: array - - - - - object HParser hammer_attr_bool(object HParser p, callback pred) - Ensure that some property holds for the AST (higher-order) - - This parser attaches a predicate function, which returns true or false, to a parser. The function is evaluated over the parser's result. The parse only succeeds if pred returns true. - - hammer_attr_bool will check whether p's result exists and whether p's result AST exists; you do not need to check for this in your predicate function. - - Result token type: p's result type if pred succeeds, otherwise the parse fails. - - - - - object HParser hammer_and(object HParser p) - Verify that p succeeds, but don't actually apply it (higher-order) - - This parser asserts that a conditional syntax is satisfied, but doesn't consume that conditional syntax. This is useful for lookahead. As an example: - - Suppose you already have a parser, hex_p, that parses numbers in hexadecimal format (including the leading "0x"). Then - - hammer_sequence(hammer_and(hammer_token("0x")), hex_p) - - checks to see whether there is a leading "0x", does not consume the "0x", then applies hex_p to parse the hexadecimal number. - - This parser succeeds if p succeeds, and fails if p fails. - - Result token type: none - - - - - object HParser hammer_not(object HParser p) - Verify that p does not succeed, and don't consume any input (higher-order) - - This parser asserts that a conditional syntax is *not* satisfied, and doesn't consume the additional syntax. As a somewhat contrived example: - - Since hammer_choice applies its arguments in order, the following parser: - - hammer_sequence(hammer_ch('a'), hammer_choice(hammer_ch('+'), hammer_token('++')), hammer_ch('b')) - - will not parse "a++b", because once hammer_choice has succeeded, it will not backtrack and try other alternatives if a later parser in the sequence fails. Instead, you can force the use of the second alternative by turning the hammer_ch('+') alternative into a sequence with hammer_not: - - hammer_sequence(hammer_ch('a'), hammer_choice(hammer_sequence(hammer_ch('+'), hammer_not('+')), hammer_token('++')), hammer_ch('b')) - - If the input string is "a+b", the first alternative is applied; if the input string is "a++b", the second alternative is applied. - - Result token type: none - - - - - object HParser hammer_indirect() - Forward-declare a parser to be used recursively (higher-order) - - Create a parser that calls out to another, as yet unknown, parser. Note that the inner parser must be bound later, using hammer_bind_indirect(). This can be used to create recursive parsers. - - Result token type: the type of whatever parser is bound to it with hammer_bind_indirect(). - - - - - void hammer_bind_indirect(object HParser p) - Set the inner parser of an indirect parser. - - See hammer_indirect() for details. - - - -