Commits

Anonymous committed f2b8139

General mechanism to handle PCRE compile options, but only a few options implemented

Comments (0)

Files changed (4)

String/mush_string_c_regexp.c

 #include "mush_string_c_regexp.h"
 #include <stdio.h>
 
-pcre * regexp_compile( char * pattern, int *errorcode, const char **errptr, int *erroffset ) {
+pcre * regexp_compile( char * pattern, int options, int *errorcode, const char **errptr, int *erroffset ) {
 	pcre * result;
 	//const char * errptr2 = "askldjflajsdlfjasdlfaskldjfalksdjflakjdflajflskdjf";
 	//int erroffset;
-	result = pcre_compile2( pattern, 0, errorcode, errptr, erroffset, NULL );
+	result = pcre_compile2( pattern, options, errorcode, errptr, erroffset, NULL );
 	//printf( "Got error code: %d\n", *errorcode );
 	//return result;
 	if (result == NULL) {
 	}*/
 	
 }
+
+int pcre_compile_option_anchored() {
+	return PCRE_ANCHORED;
+}
+
+int pcre_compile_option_caseless() {
+	return PCRE_CASELESS;
+}
+
+int pcre_compile_option_dotall() {
+	return PCRE_DOTALL;
+}

String/mush_string_c_regexp.h

 #include <pcre.h>
 
-pcre * regexp_compile( char * pattern, int *errorcode, const char **errptr, int *erroffset );
+pcre * regexp_compile( char * pattern, int options, int *errorcode, const char **errptr, int *erroffset );
 int regexp_exec( pcre * pattern, char * subject, int subject_size, int * ovector, int ovecsize );
+
+/*
+ * Wrappers for various constants. According to Sather tutorial those should be
+ * reachable directly from Sather code, but I could never get it to work
+ */
+int pcre_compile_option_anchored();
+int pcre_compile_option_caseless();
+int pcre_compile_option_dotall();
 	shared C_name : STR := "pcre *";
 	shared C_header : STR := "mush_string_c_regexp.h";
 
-	regexp_compile( pattern : STR, inout error_code : C_INT, inout error_string_ptr : EXT_OB, inout error_offset : C_INT ) : SAME;  -- TODO: add options and tableptr
+	regexp_compile( pattern : STR, options : C_INT, inout error_code : C_INT, inout error_string_ptr : EXT_OB, inout error_offset : C_INT ) : SAME;  -- TODO: add options and tableptr
 	regexp_exec( pattern : SAME, subject : STR, subject_size : C_INT, ovector : C_PTR, ovector_size : C_INT ) : C_INT; -- TODO: add options and other stuff
 	pcre_copy_substring( subject : STR, ovector : C_PTR, ovector_size : C_INT, string_number : C_INT, buffer : STR, buff_size : C_INT ) : C_INT;
 
+	-- Compile options
+	pcre_compile_option_anchored : C_INT;
+	pcre_compile_option_caseless : C_INT;
+	pcre_compile_option_dotall : C_INT;
+
 	-- TODO: remember about memory deallocation!
 end;
 
 	-- Wrapped C object holding the regexp internally
 
 	create (pattern : STR) : SAME is
+		return create(pattern, #(0));
+	end;
+
+	create (pattern : STR, options : MUSH_STRING_REGEXP_COMPILE_OPTION) : SAME is
 		-- Creates object from given pattern. For pattern syntax see "man pcresyntax". Remember currently backslashes must be escaped!
 		res ::= new;
 		-- Initialize those to some bogus values
 		error_code : C_INT := #(234124);
 		error_offset : C_INT := #(2323442);
 		error_string_ptr : EXT_OB;
-		res.pcre := MUSH_STRING_C_REGEXP::regexp_compile( pattern, inout error_code, inout error_string_ptr, inout error_offset );
+		res.pcre := MUSH_STRING_C_REGEXP::regexp_compile( pattern, options.c_int, inout error_code, inout error_string_ptr, inout error_offset );
 		if void(res.pcre) then
 			error_string ::= STR::create_from_c_string( error_string_ptr );
 			-- #OUT + "Error code: " + error_code.int + ", error_offset: " + error_offset.int + ", error_string: " + error_string + "\n";
 	end;
 end;
 
---class MUSH_STRING_REGEXP_OPTIONS < $MUSH_OPTIONS is
---	include MUSH_OPTIONS{MUSH_STRING_REGEXP_OPTION};
---
---end;
---
---immutable class MUSH_STRING_REGEXP_OPTION < $MUSH_OPTION is
---	include MUSH_OPTION{INT};
---	-- private attr value : T
---
---	create (val : T) : SAME is
---		res := new;
---		res.val := val;
---		return res;
---	end;
---
---	plus (option : SAME) is
---		create( val + option.val );
---	end;
---
---	is_eq (other : SAME) : BOOL is
---		val = other.val;
---	end;
---
---	anchored : SAME is
---		return enum(MUSH_STRING_C_REGEXP::pcre_option_anchored);
---	end;
---	
---	caseless : SAME is
---		return enum(MUSH_STRING_C_REGEXP::pcre_option_caseless);
---	end;
---
---	dotall : SAME is
---		return enum(MUSH_STRING_C_REGEXP::pcre_option_dotall);
---	end;
---end;
+-- TODO: this should be generalized into some MUSH_OPTION partial class
+immutable class MUSH_STRING_REGEXP_COMPILE_OPTION is
+	
+	private attr val : INT;
+
+	create (v : INT) : SAME is
+		res : SAME;
+		res := res.val( v );
+		return res;
+	end;
+
+	plus (option : SAME ) : SAME is
+		return #(val + option.val);
+	end;
+
+	int : INT is
+		return val;
+	end;
+
+	c_int : C_INT is
+		return #(val);
+	end;
+
+	anchored : SAME is
+		return #(MUSH_STRING_C_REGEXP::pcre_compile_option_anchored.int);
+	end;
+	
+	caseless : SAME is
+		return #(MUSH_STRING_C_REGEXP::pcre_compile_option_caseless.int);
+	end;
+
+	dotall : SAME is
+		return #(MUSH_STRING_C_REGEXP::pcre_compile_option_dotall.int);
+	end;
+
+end;
 
 class MUSH_STRING_REGEXP_COMPILE_RESULT < $IS_EQ, $STR is
 	include MUSH_DESCRIPTIVE_ENUM{INT};
 		--#OUT + "creating from val: " + val + "\n";
 		res.val := val;
 		res.description := description;
-		-- TODO: add to the list of all
 		if void(all) then
 			all := #;
 		end;

String/string_test.sa

 		test( "alphanum match 4", match[4], "2" );
 	end;
 
+	test_options is
+		re ::= #MUSH_STRING_REGEXP( "abc", MUSH_STRING_REGEXP_COMPILE_OPTION::caseless );
+		match ::= re.match( "!ABCD" );
+		test( "options match caseless", match[0].str, "ABC" );
+		re := #MUSH_STRING_REGEXP( "abc.", MUSH_STRING_REGEXP_COMPILE_OPTION::caseless + MUSH_STRING_REGEXP_COMPILE_OPTION::dotall );
+		match := re.match( "!ABC\nD" );
+		test( "options match caseless + dotall", match[0].str, "ABC\n" );
+		re := #MUSH_STRING_REGEXP( "abc.", MUSH_STRING_REGEXP_COMPILE_OPTION::caseless );
+		match := re.match( "!ABC\nD" );
+		test( "options match no dotall no match on newline", void(match).str, "true" );
+	end;
+
 	main is
 		class_name( "MUSH_STRING_REGEXP" );
 		test_simple;
 		test_alphanum;
 		test_creation_exceptions;
+		test_options;
 		finish;
 	end;