Example #1
0
  void test_options() {
    String *pat = String::create(state, ".");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    TS_ASSERT_EQUALS(as<Integer>(re->options(state))->to_native(), 0);
  }
Example #2
0
/** Send a TPDU through whatever gateway is available.  */
short_code_action submitSMS(const char *imsi, const TLSubmit& submit,
                            const std::string &body, short_code_params *scp)
{
	LOG(INFO) << "from " << imsi << " message: " << submit;
	const TLAddress& address = submit.DA();

	// Check for direct e-mail address at start of message body.
	// FIXME -- This doesn't really follow the spec.  See GSM 03.40 3.8.
	static const Regexp emailAddress("^[[:graph:]]+@[[:graph:]]+ ");
	if (emailAddress.match(body.data())) {
		// FIXME -- Get the sender's E.164 to put in the subject line.
		char bodyCopy[body.length()+2];
		strcpy(bodyCopy,body.data());
		char* SMTPAddress = bodyCopy;
		char* term = strchr(bodyCopy,' ');
		// If term's NULL, the regexp is broken.
		assert(term);
		*term = '\0';
		char* SMTPPayload = term+1;
		LOG(INFO) << "sending SMTP to " << SMTPAddress << ": " << SMTPPayload;
		if (SMTPPayload) return sendEMail(SMTPAddress,SMTPPayload,"from OpenBTS gateway");
		else return sendEMail(SMTPAddress,"(empty)","from OpenBTS gateway");
	}

	// Send to smqueue or HTTP gateway, depending on what's defined in the config.
	if (gConfig.defines("SMS.HTTP.Gateway"))
		// If there is an external HTTP gateway, use it.
		return sendHTTP(address.digits(), body);
	else
		// Otherwise, we are looking for a SIP interface to smqueue.
		return sendSIP_init(imsi, submit, body, scp);
}
Example #3
0
  void test_initialize() {
    String *pat = String::create(state, ".");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    TS_ASSERT_EQUALS(re->source(), pat);
    TS_ASSERT_EQUALS(re->names(),  cNil);
  }
Example #4
0
  void test_create_with_named_captures() {
    String *pat = String::create(state, "(?<blah>.)");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    TS_ASSERT_EQUALS(re->source(), pat);
    TS_ASSERT(re->names()->kind_of_p(state, G(lookuptable)));
  }
Example #5
0
  void test_create_with_bad_pattern() {
    char buf[1024];
    memset(buf, 0, 1024);

    String *pat = String::create(state, "(?");
    Regexp* re = Regexp::create(state);
    TS_ASSERT_THROWS(re->initialize(state, pat, Fixnum::from(0)),
                     const RubyException &);
  }
Example #6
0
  void test_match_region_without_matches() {
    String *pat = String::create(state, "d");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    String *input = String::create(state, "abc");

    Fixnum* start = Fixnum::from(0);
    Fixnum* end =   Fixnum::from(3);
    Object* forward = cTrue;

    MatchData* matches = (MatchData*)re->match_region(state, input, start, end, forward);
    TS_ASSERT(matches->nil_p());
  }
Example #7
0
/** Send a TPDU through whatever gateway is available.  */
short_code_action submitSMS(const char *imsi, const TLSubmit& submit,
                            const std::string &body, short_code_params *scp)
{
	LOG(INFO) << "from " << imsi << " message: " << submit;
	const TLAddress& address = submit.DA();

//#if 0
//This is broken under Unbuntu becasue of changes in the "mail" program.

	// Check for direct e-mail address at start of message body.
	// FIXME -- This doesn't really follow the spec.  See GSM 03.40 3.8.
	static const Regexp emailAddress("^[[:graph:]]+@[[:graph:]]+ ");
	if (emailAddress.match(body.data())) {
		char bodyCopy[body.length()+2];
		strcpy(bodyCopy,body.data());
		char* SMTPAddress = bodyCopy;
		char* term = strchr(bodyCopy,' ');
		// If term's NULL, the regexp emailAddress is broken.
		assert(term);
		*term = '\0';
		char* SMTPPayload = term+1;
		// Get the sender's E.164 to put in the subject line.
		char* clid = scp->scp_smq->my_hlr.getCLIDLocal(imsi);
		char subjectLine[200];
		if (!clid) sprintf(subjectLine,"from %s",imsi);
		else {
			sprintf(subjectLine,"from %s",clid);
			free(clid);
		}
		// Send it.
		LOG(INFO) << "sending SMTP to " << SMTPAddress << ": " << SMTPPayload;
		if (SMTPPayload) return sendEMail(SMTPAddress,SMTPPayload,subjectLine);
		else return sendEMail(SMTPAddress,"(empty)","from OpenBTS gateway");
	}
//#endif

	char* destinationNumber = scp->scp_smq->my_hlr.getIMSI2(address.digits());

	// Send to smqueue or HTTP gateway, depending on what's defined in the config.
	// And whether of not we can resolve the destination, and a global relay does not exist,
	// AND the message is not to a shortcode.
	if (gConfig.getStr("SIP.GlobalRelay.IP").length() == 0 && gConfig.getStr("SMS.HTTPGateway.URL").length() != 0 &&
		!destinationNumber)
		// If there is an external HTTP gateway, use it.
		return sendHTTP(address.digits(), body);

	free(destinationNumber);
	return sendSIP_init(imsi, submit, body, scp);
}
Example #8
0
  void test_match_start() {
    String *pat = String::create(state, ".");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    String *input = String::create(state, "abc");

    Fixnum* start = Fixnum::from(1);

    MatchData* matches = (MatchData*)re->match_start(state, input, start);
    TS_ASSERT(!matches->nil_p());
    TS_ASSERT_EQUALS(matches->region()->num_fields(), 0);
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 0))->to_native(), 1);
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 1))->to_native(), 2);
  }
Example #9
0
double ExmapTest::get_pid_size_from_ps(pid_t pid)
{
    list<string> lines;
    list<string> captures;
    ok(read_proc_output("ps -e -o pid,vsz", lines), "can read proc output");
    Regexp re;
    stringstream sstr;
    sstr << "\\s*" << pid << "\\s";
    re.compile(sstr.str());
    re.grep(lines);
    is((int) lines.size(), 1, "found line for pid");
    re.compile("\\s*(\\d+)\\s+(\\d+)$");
    re.match_capture(lines.front(), captures);
    is((int) captures.size(), 2, "Found my captures");
    int size = atoi(captures.back().c_str());
    return size * 1024.0;
}
Example #10
0
  void test_match_region() {
    String *pat = String::create(state, ".");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0), Qnil);

    String *input = String::create(state, "abc");

    Fixnum* start = Fixnum::from(0);
    Fixnum* end =   Fixnum::from(3);
    Object* forward = Qtrue;

    MatchData* matches = (MatchData*)re->match_region(state, input, start, end, forward);
    TS_ASSERT(!matches->nil_p());
    TS_ASSERT_EQUALS(matches->region()->num_fields(), 0U);
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 0))->to_native(), 0);
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 1))->to_native(), 1);
  }
Example #11
0
  void test_match_region_with_backward_captures() {
    String *pat = String::create(state, ".(.)");
    Regexp* re = Regexp::create(state);
    re->initialize(state, pat, Fixnum::from(0));

    String *input = String::create(state, "abc");

    Fixnum* start = Fixnum::from(0);
    Fixnum* end =   Fixnum::from(3);
    Object* forward = cFalse;

    MatchData* matches = re->match_region(state, input, start, end, forward);
    TS_ASSERT(!matches->nil_p());
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 0))->to_native(), 1);
    TS_ASSERT_EQUALS(as<Integer>(matches->full()->at(state, 1))->to_native(), 3);

    TS_ASSERT_EQUALS(matches->region()->num_fields(), 1);
    TS_ASSERT_EQUALS(as<Integer>(as<Tuple>(matches->region()->at(state, 0))->at(state, 0))->to_native(), 2);
    TS_ASSERT_EQUALS(as<Integer>(as<Tuple>(matches->region()->at(state, 0))->at(state, 1))->to_native(), 3);
  }
Example #12
0
boolean FileBrowser::Acceptable(const char* name) {
    boolean dir1 = IsADirectory(name);
    int m = dir1 ? directory_mode : mode;
    Regexp* r = dir1 ? directory_regexp : regexp;
    boolean mode_ok, name_ok;

    if (m != 0) {
	struct stat st;
	mode_ok = stat((char*)name, &st) == 0 && (st.st_mode & m) != 0;
    } else {
	mode_ok = true;
    }

    if (r != nil) {
	name_ok = r->Match(name, strlen(name), 0) >= 0;
    } else {
	name_ok = true;
    }

    return mode_ok && name_ok;
}
Example #13
0
bool FallBackHandler::received(Message &msg)
{
    switch (m_type)
    {	
	case Answered:
	{ 
	    GenObject* route = s_fallbacklist[msg.getValue("targetid")];
	    s_fallbacklist.remove(route);
	    return false;
	}
	break;
	case Hangup:
	{
	    GenObject* route = s_fallbacklist[msg.getValue("id")];
	    s_fallbacklist.remove(route);
	    return false;
	}
	break;
	case Disconnect:
	{	
	    String reason=msg.getValue("reason");	
	    if (m_stoperror && m_stoperror.matches(reason)) {
		//stop fallback on this error
		GenObject* route = s_fallbacklist[msg.getValue("id")];
		s_fallbacklist.remove(route);
		return false;
	    }

	    FallBackRoute* route = static_cast<FallBackRoute*>(s_fallbacklist[msg.getValue("id")]);
	    if (route) {
		Message* r = route->get();
		if (r) {
		    r->userData(msg.userData());
		    Engine::enqueue(r);
		    return true;
		}
		s_fallbacklist.remove(route);
	    }
	    return false;
	}
	break;
    }
    return false;
}
Example #14
0
int
SPString::m(Regexp & r)
{
  return r.match(*this);
}
Example #15
0
bool ExmapTest::run()
{
    SysInfoPtr sysinfo(new LinuxSysInfo);
    Snapshot snap(sysinfo);

    is(snap.num_procs(), 0, "zero procs before load");
    ok(snap.load(), "can load snapshot");
    ok(snap.num_procs() > 0, "some procs after load");

    list<ProcessPtr> allprocs = snap.procs();
    ok(!allprocs.empty(), "can get a list of procs");
    list<ProcessPtr>::iterator proc_it;
    list<ProcessPtr> procs;

    bool failed_to_get_sizes = false;
    SizesPtr sizes;
    for (proc_it = allprocs.begin(); proc_it != allprocs.end(); ++proc_it) {
	string cmdline = (*proc_it)->cmdline();
	if (cmdline== SA_EXE) {
	    procs.push_back(*proc_it);
	}
	sizes = (*proc_it)->sizes();
	if (!sizes) {
	    failed_to_get_sizes = true;
	}
    }
    ok(!failed_to_get_sizes, "can get sizes for every proc");

    is((int) procs.size(), NUM_INSTANCES, "can find all our sharedarray procs");

    ProcessPtr proc = procs.front();
    sizes = proc->sizes();
    ok(sizes->val(Sizes::VM) > NUM_ARRAYS * ARRAY_SIZE, "image is big enough");

    double ps_size = get_pid_size_from_ps(proc->pid());
    is_approx_rel(sizes->val(Sizes::VM),
		  ps_size,
		  0.001,
		  "exmap info matches ps output");

    ok(sizes->val(Sizes::RESIDENT) > 0, "nonzero resident size");
    ok(sizes->val(Sizes::EFFECTIVE_RESIDENT) > 0, "nonzero eff resident size");
    ok(sizes->val(Sizes::EFFECTIVE_RESIDENT) < sizes->val(Sizes::RESIDENT),
       "effective is smaller than eff resident");

    ok(sizes->val(Sizes::MAPPED) > 0, "nonzero mapped size");
    ok(sizes->val(Sizes::EFFECTIVE_MAPPED) > 0, "nonzero eff mapped size");
    ok(sizes->val(Sizes::EFFECTIVE_MAPPED) < sizes->val(Sizes::MAPPED),
       "effective is smaller than eff mapped");

    
    list<FilePtr> files;
    list<FilePtr>::iterator file_it;
    list<FilePtr> all_files = snap.files();
    
    ok(all_files.size() > 0, "can find some files");

    Regexp re;
    re.compile(SA_LIB + "$");
    failed_to_get_sizes = false;
    for (file_it = all_files.begin(); file_it != all_files.end(); ++file_it) {
	string name = (*file_it)->name();
	if (re.matches(name)) {
	    files.push_back(*file_it);
	}
	sizes = (*file_it)->sizes();
	if (!sizes) {
	    failed_to_get_sizes = true;
	}
    }
    ok(!failed_to_get_sizes, "can get sizes for every file");
    is((int) files.size(), 1, "shared lib only listed once");
    FilePtr shlib_file = files.front();
    ok(shlib_file->is_elf(), "shared lib recognised as elf file");

    list<ProcessPtr> procs_per_file = shlib_file->procs();
    is((int) procs_per_file.size(), NUM_INSTANCES,
       "right number of procs mapping the file");
    for (proc_it = procs_per_file.begin();
	 proc_it != procs_per_file.end();
	 ++proc_it) {
	ok(proc->cmdline() == SA_EXE, "each proc has correct cmdline");
    }

    for (proc_it = procs.begin();
	 proc_it != procs.end();
	 ++proc_it) {
	sizes = proc->sizes(shlib_file);
	long arrays_size = NUM_ARRAYS * ARRAY_SIZE;
	float delta = std::abs(arrays_size - (long) sizes->val(Sizes::VM));
	delta /= arrays_size;
	ok(delta < 0.01, "Shared lib has correct size in each proc");
    }
    
    Elf::SectionPtr text = shlib_file->elf()->section(".text");
    ok(text, "can find text section");
    ok(text->size() > 0, "text section has nonzero size");
    sizes = procs.front()->sizes(shlib_file, text->mem_range());
    /// This appears to be compiler and system dependent...
    /*
    is_approx_rel(sizes->val(Sizes::RESIDENT),
		  2.0 * text->size(),
		  0.001,
		  "lib text is resident and mapped twice (!)");
		  */
    
    Elf::SectionPtr bss = shlib_file->elf()->section(".bss");
    ok(bss, "can find bss section");
    ok(bss->size() > 0, "bss section has nonzero size");
    SizesPtr bss_sizes = procs.front()->sizes(shlib_file, bss->mem_range());
    ok(bss_sizes, "can get sizes for bss section");

    Elf::SectionPtr data = shlib_file->elf()->section(".data");
    ok(data, "can find data section");
    ok(data->size() > 0, "data section has nonzero size");
    SizesPtr data_sizes = procs.front()->sizes(shlib_file, data->mem_range());
    ok(data_sizes, "can get sizes for data section");

    is(data->size(), bss->size(), "data and bss sections have same size");

    is_approx(data_sizes->val(Sizes::MAPPED),
	      bss_sizes->val(Sizes::MAPPED),
	      Elf::page_size(),
	      "data and bss mapped within page of each other");
    
    is_approx(data_sizes->val(Sizes::RESIDENT),
	      bss_sizes->val(Sizes::RESIDENT),
	      Elf::page_size(),
	      "data and bss resident within page of each other");

    // Now get the all-proc sizes from the file
    sizes = shlib_file->sizes(bss->mem_range());
    // The totals should be a multiple of the individual
    is(sizes->val(Sizes::RESIDENT),
	    bss_sizes->val(Sizes::RESIDENT) * NUM_INSTANCES,
	    "Total resident for all procs the same as multiplying up one proc");
    is(sizes->val(Sizes::MAPPED),
	    bss_sizes->val(Sizes::MAPPED) * NUM_INSTANCES,
	    "Total mapped for all procs the same as multiplying up one proc");

    double bss_resident_arrays_size = 0;
    double data_resident_arrays_size = 0;
    double bss_writable_arrays_size = 0;
    double data_writable_arrays_size = 0;
    for (int i = 0; i < NUM_ARRAYS; ++i) {
	if (ARRAY_INFO[i].initialised) {
	    data_resident_arrays_size
		+= ARRAY_SIZE * ARRAY_INFO[i].resident_percent / 100;
	    data_writable_arrays_size
		+= ARRAY_SIZE * ARRAY_INFO[i].writable_percent / 100;
	}
	else {
	    bss_resident_arrays_size
		+= ARRAY_SIZE * ARRAY_INFO[i].resident_percent / 100;
	    bss_writable_arrays_size
		+= ARRAY_SIZE * ARRAY_INFO[i].writable_percent / 100;
	}
    }

    for (proc_it = procs.begin();
	 proc_it != procs.end();
	 ++proc_it) {
	
	sizes = proc->sizes(shlib_file, data->mem_range());
	is_approx(sizes->val(Sizes::RESIDENT),
		  data_resident_arrays_size,
		  Elf::page_size(),
		  "resident size for data in proc correct with a page");
	is_approx(sizes->val(Sizes::WRITABLE),
		  data_writable_arrays_size,
		  Elf::page_size(),
		  "writable size for data in proc correct with a page");
	
	sizes = proc->sizes(shlib_file, bss->mem_range());
	is_approx_rel(sizes->val(Sizes::RESIDENT),
		      bss_resident_arrays_size,
		      0.001,
		      "correct resident size for bss in proc");
	is_approx_rel(sizes->val(Sizes::WRITABLE),
		      bss_writable_arrays_size,
		      0.001,
		      "correct writable size for bss in proc");
    }


    for (int i = 0; i < NUM_ARRAYS; ++i) {
	const struct array_info *info = ARRAY_INFO + i;
	string symname = info->name;
	Elf::SymbolPtr sym = shlib_file->elf()->symbol(symname);
	ok(sym, "can find symbol " + symname);
	is(sym->size(), ARRAY_SIZE, symname + " has correct size");
	
	sizes = proc->sizes(shlib_file, sym->range());
	is_approx_rel((int) sizes->val(Sizes::RESIDENT),
		      ARRAY_SIZE * info->resident_percent / 100,
		      0.001,
		      symname + " has correct resident size");

	is_approx_rel(sizes->val(Sizes::WRITABLE),
		      ARRAY_SIZE * info->writable_percent / 100.0,
		      0.001,
		      symname + " has correct writable size");

	// Uninitialised space which is only read appears to be shared
	// amongst every proc in the system (a 'zero page'?). This is
	// good from a low-memusage point of view, but it means that
	// it is shared among nearly all running procs to varying
	// degrees. So we can't really account for it.
	if (symname == "uninit_readme" || symname == "uninit_readhalf") {
	    continue;
	}

	int expected_eff_resident = ARRAY_SIZE * info->resident_percent / 100;
	if (info->shared) {
	    expected_eff_resident /= NUM_INSTANCES;
	}
	// approximate match since the percentage (fixed pt)
	// arithmetic could put us off by a factor of 1/100 (and does...:-)
	is_approx((int) sizes->val(Sizes::EFFECTIVE_RESIDENT),
		  expected_eff_resident,
		  1 + (expected_eff_resident / 100),
		  symname + " has correct effective size");
    }


    // Non-elf maps

    procs.clear();
    for (proc_it = allprocs.begin(); proc_it != allprocs.end(); ++proc_it) {
	string cmdline = (*proc_it)->cmdline();
	if (cmdline == MI_EXE) {
	    procs.push_back(*proc_it);
	}
    }
    is((int) procs.size(), NUM_INSTANCES, "can find all our mapit procs");
    proc = procs.front();

    files.clear();
    re.compile("/" + MI_DAT + "$");
    for (file_it = all_files.begin(); file_it != all_files.end(); ++file_it) {
	string name = (*file_it)->name();
	if (re.matches(name)) {
	    files.push_back(*file_it);
	}
    }
    is((int) files.size(), 1, MI_DAT + " file only listed once");
    FilePtr mapped_file = files.front();

    ok(!mapped_file->is_elf(), MI_DAT + " isn't an elf file");
    off_t fsize = 0;
    double mi_data_size = 0;
    ok(file_size(MI_DAT, fsize), "can get file size");
    mi_data_size = fsize;
    ok(mi_data_size > 0, "file has nonzero size");
    
    for (proc_it = procs.begin();
	 proc_it != procs.end();
	 ++proc_it) {
	sizes = (*proc_it)->sizes(mapped_file);
	is_approx_rel(sizes->val(Sizes::VM),
		      mi_data_size,
		      0.001,
		      "correct data file size");
	is_approx_rel(sizes->val(Sizes::RESIDENT),
		      mi_data_size,
		      0.001,
		      "whole data file is resident");
	is_approx_rel(sizes->val(Sizes::EFFECTIVE_RESIDENT),
		      mi_data_size / NUM_INSTANCES,
		      0.001,
		      "data file is shared between instances correctly");
    }
    
    return true;
}
Example #16
0
// Decode the message line
// Command: verb transaction endpoint proto_name proto_version ...
// Response: code transaction comment ...
MGCPMessage* MGCPMessage::decodeMessage(const char* line, unsigned int len, unsigned int& trans,
	String& error, MGCPEngine* engine)
{
    String name, ver;
    int code = -1;
    unsigned int trID = 0;
    MGCPEndpointId id;

#ifdef PARSER_DEBUG
    String msgLine(line,len);
    Debug(engine,DebugAll,"Parse message line (len=%u): %s",
	msgLine.length(),msgLine.c_str());
#endif

    for (unsigned int item = 1; true; item++) {
	if (item == 6) {
#ifdef DEBUG
	    if (len) {
		String rest(line,len);
		Debug(engine,DebugAll,"Unparsed data on message line: '%s'",rest.c_str());
	    }
#endif
	    break;
	}

	// Response: the 3rd item is the comment
	bool comment = (item == 3) && (code != -1);

	// Get current item
	if (!(skipBlanks(line,len) || comment)) {
	    error = "Unexpected end of line";
	    return 0;
	}

	unsigned int itemLen = 0;
	if (comment)
	    itemLen = len;
	else
	    for (; itemLen < len && !isBlank(line[itemLen]); itemLen++)
		;
	String tmp(line,itemLen);
	len -= itemLen;
	line += itemLen;

	switch (item) {
	    // 1st item: verb (command or notification) or response code
	    // Verbs must be 4-character long. Responses must be numbers in the interval [0..999]
	    case 1:
		if (tmp.length() == 3) {
		    code = tmp.toInteger(-1,10);
		    if (code < 0 || code > 999)
			error << "Invalid response code " << tmp;
		}
		else if (tmp.length() == 4)
		    name = tmp.toUpper();
		else
		    error << "Invalid first item '" << tmp << "' length " << tmp.length();
		break;

	    // 2nd item: the transaction id
	    // Restriction: must be a number in the interval [1..999999999]
	    case 2:
		trID = tmp.toInteger(-1,10);
		if (!trID || trID > 999999999)
		    error << "Invalid transaction id '" << tmp << "'";
		// Set trans for command messages so they can be responded on error
		else if (code == -1)
		    trans = trID;
		break;

	    // 3rd item: endpoint id (code is -1) or response comment (code != -1)
	    case 3:
		if (code != -1)
		    name = tmp;
		else {
		    id.set(tmp);
		    if (!id.valid())
			error << "Invalid endpoint id '" << tmp << "'";
		}
		break;

	    // 4th item: protocol name if this is a verb (command)
	    case 4:
		ver = tmp.toUpper();
		if (ver != "MGCP")
		    error << "Invalid protocol '" << tmp << "'";
		break;

	    // 5th item: protocol version if this is a verb (command)
	    case 5:
		{
		    static const Regexp r("^[0-9]\\.[0-9]\\+$");
		    if (!r.matches(tmp))
			error << "Invalid protocol version '" << tmp << "'";
		}
		ver << " " << tmp;
		break;
	}
	if (error)
	    return 0;
	// Stop parse the rest if this is a response
	if (comment)
	    break;
    }
    // Check known commands
    if (code == -1 &&
	!(engine && (engine->allowUnkCmd() || engine->knownCommand(name)))) {
	error << "Unknown cmd '" << name << "'";
	return 0;
    }
    return new MGCPMessage(engine,name,code,trID,id.id(),ver);
}
Example #17
0
 // 'self' is passed in automatically by the primitive glue
 Regexp* Regexp::allocate(STATE, Object* self) {
   Regexp* re = Regexp::create(state);
   re->onig_data = NULL;
   re->klass(state, as<Class>(self));
   return re;
 }
Example #18
0
  void test_allocate() {
    Class* sub = ontology::new_class(state, "RegexpSub", G(regexp), 0);
    Regexp* re = Regexp::allocate(state, sub);

    TS_ASSERT_EQUALS(re->klass(), sub);
  }
Example #19
0
  void Regexp::make_managed(STATE) {
    Regexp* obj = this;
    regex_t* reg = onig_data;

    assert(reg->chain == 0);

    ByteArray* reg_ba = ByteArray::create(state, sizeof(regex_t));
    memcpy(reg_ba->raw_bytes(), reg, sizeof(regex_t));

    regex_t* old_reg = reg;
    reg = reinterpret_cast<regex_t*>(reg_ba->raw_bytes());

    obj->onig_data = reg;
    write_barrier(state, reg_ba);

    if(reg->p) {
      ByteArray* pattern = ByteArray::create(state, reg->alloc);
      memcpy(pattern->raw_bytes(), reg->p, reg->alloc);

      reg->p = reinterpret_cast<unsigned char*>(pattern->raw_bytes());

      obj->write_barrier(state, pattern);
    }

    if(reg->exact) {
      int exact_size = reg->exact_end - reg->exact;
      ByteArray* exact = ByteArray::create(state, exact_size);
      memcpy(exact->raw_bytes(), reg->exact, exact_size);

      reg->exact = reinterpret_cast<unsigned char*>(exact->raw_bytes());
      reg->exact_end = reg->exact + exact_size;

      obj->write_barrier(state, exact);
    }

    int int_map_size = sizeof(int) * ONIG_CHAR_TABLE_SIZE;

    if(reg->int_map) {
      ByteArray* intmap = ByteArray::create(state, int_map_size);
      memcpy(intmap->raw_bytes(), reg->int_map, int_map_size);

      reg->int_map = reinterpret_cast<int*>(intmap->raw_bytes());

      obj->write_barrier(state, intmap);
    }

    if(reg->int_map_backward) {
      ByteArray* intmap_back = ByteArray::create(state, int_map_size);
      memcpy(intmap_back->raw_bytes(), reg->int_map_backward, int_map_size);

      reg->int_map_backward = reinterpret_cast<int*>(intmap_back->raw_bytes());

      obj->write_barrier(state, intmap_back);
    }

    if(reg->repeat_range) {
      int rrange_size = sizeof(OnigRepeatRange) * reg->repeat_range_alloc;
      ByteArray* rrange = ByteArray::create(state, rrange_size);
      memcpy(rrange->raw_bytes(), reg->repeat_range, rrange_size);

      reg->repeat_range = reinterpret_cast<OnigRepeatRange*>(rrange->raw_bytes());

      obj->write_barrier(state, rrange);
    }

    onig_free(old_reg);
  }
Example #20
0
 void test_create() {
   Regexp* re = Regexp::create(state);
   TS_ASSERT(re->source()->nil_p());
   TS_ASSERT(re->names()->nil_p());
   TS_ASSERT_EQUALS(re->klass(), G(regexp));
 }
Example #21
0
 // 'self' is passed in automatically by the primitive glue
 Regexp* Regexp::allocate(STATE, Object* self) {
   Regexp* re = Regexp::create(state);
   re->onig_data = 0;
   re->klass(state, (Class*)self);
   return re;
 }