[ruby/yarp] Use smaller regexp options

https://github.com/ruby/yarp/commit/4deb7c3ae0
This commit is contained in:
Kevin Newton 2023-06-26 09:51:24 -04:00 committed by git
parent 515bd42144
commit ec59b95cfd

View File

@ -269,60 +269,74 @@ yp_regexp_parse_expression(yp_regexp_parser_t *parser);
typedef enum { typedef enum {
YP_REGEXP_OPTION_STATE_INVALID, YP_REGEXP_OPTION_STATE_INVALID,
YP_REGEXP_OPTION_STATE_TOGGLEABLE, YP_REGEXP_OPTION_STATE_TOGGLEABLE,
YP_REGEXP_OPTION_STATE_ADDABLE YP_REGEXP_OPTION_STATE_ADDABLE,
YP_REGEXP_OPTION_STATE_ADDED,
YP_REGEXP_OPTION_STATE_REMOVED
} yp_regexp_option_state_t; } yp_regexp_option_state_t;
enum { // These are the options that are configurable on the regular expression (or
option_slots = 128 // from within a group).
}; #define YP_REGEXP_OPTION_STATE_SLOT_MINIMUM 'a'
#define YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM 'x'
#define YP_REGEXP_OPTION_STATE_SLOTS (YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM + 1)
// This is the set of options that are configurable on the regular expression. // This is the set of options that are configurable on the regular expression.
typedef yp_regexp_option_state_t yp_regexp_options_t[option_slots]; typedef struct { unsigned char values[YP_REGEXP_OPTION_STATE_SLOTS]; } yp_regexp_options_t;
// Initialize a new set of options to their default values. // Initialize a new set of options to their default values.
static void static void
yp_regexp_options_init(yp_regexp_options_t *options) { yp_regexp_options_init(yp_regexp_options_t *options) {
memset(options, YP_REGEXP_OPTION_STATE_INVALID, sizeof(yp_regexp_option_state_t) * option_slots); memset(options, YP_REGEXP_OPTION_STATE_INVALID, sizeof(uint8_t) * YP_REGEXP_OPTION_STATE_SLOTS);
(*options)['i'] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; options->values['i' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE;
(*options)['m'] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; options->values['m' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE;
(*options)['x'] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; options->values['x' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE;
(*options)['d'] = YP_REGEXP_OPTION_STATE_ADDABLE; options->values['d' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_ADDABLE;
(*options)['a'] = YP_REGEXP_OPTION_STATE_ADDABLE; options->values['a' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_ADDABLE;
(*options)['u'] = YP_REGEXP_OPTION_STATE_ADDABLE; options->values['u' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_ADDABLE;
} }
// Attempt to add the given option to the set of options. Returns true if it was // Attempt to add the given option to the set of options. Returns true if it was
// added, false if it was already present. // added, false if it was already present.
static bool static bool
yp_regexp_options_add(yp_regexp_options_t *options, unsigned char option) { yp_regexp_options_add(yp_regexp_options_t *options, unsigned char key) {
if (option >= option_slots) { if (key >= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM) {
return false; key -= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM;
}
switch ((*options)[option]) { switch (options->values[key]) {
case YP_REGEXP_OPTION_STATE_INVALID: case YP_REGEXP_OPTION_STATE_INVALID:
return false; case YP_REGEXP_OPTION_STATE_REMOVED:
case YP_REGEXP_OPTION_STATE_TOGGLEABLE: return false;
case YP_REGEXP_OPTION_STATE_ADDABLE: case YP_REGEXP_OPTION_STATE_TOGGLEABLE:
(*options)[option] = YP_REGEXP_OPTION_STATE_INVALID; case YP_REGEXP_OPTION_STATE_ADDABLE:
return true; options->values[key] = YP_REGEXP_OPTION_STATE_ADDED;
return true;
case YP_REGEXP_OPTION_STATE_ADDED:
return true;
}
} }
return false; return false;
} }
// Attempt to remove the given option from the set of options. Returns true if // Attempt to remove the given option from the set of options. Returns true if
// it was removed, false if it was already absent. // it was removed, false if it was already absent.
static bool static bool
yp_regexp_options_remove(yp_regexp_options_t *options, unsigned char option) { yp_regexp_options_remove(yp_regexp_options_t *options, unsigned char key) {
if (option >= option_slots) { if (key >= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM) {
return false; key -= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM;
}
switch ((*options)[option]) { switch (options->values[key]) {
case YP_REGEXP_OPTION_STATE_INVALID: case YP_REGEXP_OPTION_STATE_INVALID:
case YP_REGEXP_OPTION_STATE_ADDABLE: case YP_REGEXP_OPTION_STATE_ADDABLE:
return false; return false;
case YP_REGEXP_OPTION_STATE_TOGGLEABLE: case YP_REGEXP_OPTION_STATE_TOGGLEABLE:
(*options)[option] = YP_REGEXP_OPTION_STATE_INVALID; case YP_REGEXP_OPTION_STATE_ADDED:
return true; case YP_REGEXP_OPTION_STATE_REMOVED:
options->values[key] = YP_REGEXP_OPTION_STATE_REMOVED;
return true;
}
} }
return false; return false;
} }