static VALUE rg_match_all(gint argc, VALUE *argv, VALUE self) { VALUE rb_string, rb_start_position, rb_match_options, rb_options; VALUE rb_frozen_string, rb_match_info; GMatchInfo *match_info = NULL; GError *error = NULL; const gchar *string; gssize string_len = -1; gint start_position = 0; GRegexMatchFlags match_options = 0; rb_scan_args(argc, argv, "11", &rb_string, &rb_options); rbg_scan_options(rb_options, "start_position", &rb_start_position, "match_options", &rb_match_options, NULL); if (OBJ_FROZEN(rb_string)) { rb_frozen_string = rb_string; } else { rb_frozen_string = rb_str_dup(rb_string); rb_str_freeze(rb_frozen_string); } string = RVAL2CSTR(rb_frozen_string); string_len = RSTRING_LEN(rb_frozen_string); if (!NIL_P(rb_start_position)) start_position = NUM2INT(rb_start_position); if (!NIL_P(rb_match_options)) match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options); g_regex_match_all_full(_SELF(self), string, string_len, start_position, match_options, &match_info, &error); if (error) RAISE_GERROR(error); if (!match_info) return Qnil; rb_match_info = GMATCHINFO2RVAL(match_info); g_match_info_unref(match_info); rb_iv_set(rb_match_info, "@string", rb_frozen_string); return rb_match_info; }
/* unlike PCRE, partial matching won't return the actual substrings/matches */ static int Gregex_dfa_exec (lua_State *L) { TArgExec argE; TGrgx *ud; gboolean res; checkarg_dfa_exec (L, &argE, &ud); gerror_free (ud); res = g_regex_match_all_full (ud->pr, argE.text, (int)argE.textlen, argE.startoffset, (GRegexMatchFlags)argE.eflags, &ud->match_info, &ud->error); if (ALG_ISMATCH (res)) { int i, start_pos, end_pos; int max = g_match_info_get_match_count (ud->match_info); g_match_info_fetch_pos (ud->match_info, 0, &start_pos, NULL); lua_pushinteger (L, start_pos + 1); /* 1-st return value */ lua_newtable (L); /* 2-nd return value */ for (i=0; i<max; i++) { g_match_info_fetch_pos (ud->match_info, i, NULL, &end_pos); /* I don't know why these offsets aren't incremented by 1 to match Lua indexing? */ lua_pushinteger (L, end_pos); lua_rawseti (L, -2, i+1); } lua_pushinteger (L, max); /* 3-rd return value */ minfo_free (ud); return 3; } else if (g_match_info_is_partial_match(ud->match_info)) { lua_pushboolean(L,1); minfo_free (ud); return 1; } else { minfo_free (ud); if (ALG_NOMATCH (res)) return lua_pushnil (L), 1; else return generate_error (L, ud, 0); } }