50 END,
BRANCH,
ANY,
EXACT,
ANYOF,
ANYBUT,
OPEN,
CLOSE,
BOL,
EOL,
STAR,
PLUS,
87 assert(offset < r->code_size);
119 emit(r, old_data_size);
127 case 'n': res =
'\n';
break;
128 case 'r': res =
'\r';
break;
129 case 't': res =
'\t';
break;
130 case '0': res = 0;
break;
131 case 'S': res =
NONSPACE << 8;
break;
132 case 's': res =
SPACE << 8;
break;
133 case 'd': res =
DIGIT << 8;
break;
134 default: res = (*re)[-1];
break;
148 emit(r, old_data_size);
155 if ((esc & 0xff) == 0) {
204 int op, esc, branch_start, last_op, fixup, cap_no, level;
246 if (*(*re)++ !=
')') {
285 fixup = branch_start + 2;
286 r->
code[fixup] = 0xff;
306 while (*re !=
'\0') {
319 static void dump(
const struct slre *, FILE *);
326 static const char *
match(
const struct slre *,
int,
const char *,
int,
int *,
331 int saved_offset, matched_offset;
333 saved_offset = matched_offset = *ofs;
335 while (!
match(r, pc + 2, s, len, ofs, NULL)) {
337 if (!
match(r, pc + r->
code[pc + 1], s, len, ofs, NULL)) {
338 matched_offset = saved_offset;
343 *ofs = matched_offset;
348 int saved_offset = *ofs;
350 while (!
match(r, pc + 2, s, len, ofs, NULL)) {
352 if (!
match(r, pc + r->
code[pc + 1], s, len, ofs, NULL))
359 static int is_any_of(
const unsigned char *p,
int len,
const char *s,
int *ofs) {
364 for (i = 0; i < len; i++)
373 static int is_any_but(
const unsigned char *p,
int len,
const char *s,
379 for (i = 0; i < len; i++)
389 return tolower(* (
const unsigned char *) s);
392 static int casecmp(
const void *p1,
const void *p2,
size_t len) {
393 const char *s1 = (
const char *) p1, *s2 = (
const char *) p2;
399 }
while (diff == 0 && s1[-1] !=
'\0' && --len > 0);
404 static const char *
match(
const struct slre *r,
int pc,
const char *s,
int len,
405 int *ofs,
struct cap *caps) {
407 const char *error_string = NULL;
408 int (*cmp)(
const void *string1,
const void *string2,
size_t len);
410 while (error_string == NULL && r->
code[pc] !=
END) {
412 assert(pc < r->code_size);
413 assert(pc < (
int) (
sizeof(r->
code) /
sizeof(r->
code[0])));
415 switch (r->
code[pc]) {
418 error_string =
match(r, pc + 3, s, len, ofs, caps);
419 if (error_string != NULL) {
421 error_string =
match(r, pc + r->
code[pc + 1], s, len, ofs, caps);
423 pc += r->
code[pc + 2];
430 if (n <= len - *ofs && !cmp(s + *ofs, r->
data + r->
code[pc + 1], n)) {
440 if (
match(r, pc + 2, s, len, ofs, caps) != NULL) {
443 pc += r->
code[pc + 1];
449 pc += r->
code[pc + 1];
455 pc += r->
code[pc + 1];
459 if ((error_string =
match(r, pc + 2, s, len, ofs, caps)) != NULL)
463 pc += r->
code[pc + 1];
467 if ((error_string =
match(r, pc + 2, s, len, ofs, caps)) != NULL)
471 pc += r->
code[pc + 1];
476 if (*ofs < len && isspace(((
const unsigned char *)s)[*ofs])) {
485 if (*ofs <len && !isspace(((
const unsigned char *)s)[*ofs])) {
494 if (*ofs < len && isdigit(((
const unsigned char *)s)[*ofs])) {
538 caps[r->
code[pc + 1]].
ptr = s + *ofs;
544 caps[r->
code[pc + 1]].
len = (s + *ofs) -
554 printf(
"unknown cmd (%d) at %d\n", r->
code[pc], pc);
571 static const char *
match2(
const struct slre *r,
const char *buf,
int len,
577 error_string =
match(r, 0, buf, len, &ofs, caps);
579 for (i = 0; i < len && error_string != NULL; i++) {
581 error_string =
match(r, 0, buf, len, &ofs, caps);
593 case sizeof(float): fmt =
"f";
break;
594 case sizeof(double): fmt =
"lf";
break;
595 default:
return "SLRE_FLOAT: unsupported size";
598 sprintf(buf,
"%%%d%s", cap->
len, fmt);
599 return sscanf(cap->
ptr, buf, p) == 1 ? NULL :
"SLRE_FLOAT: capture failed";
603 if ((
int) len <= cap->len) {
604 return "SLRE_STRING: buffer size too small";
606 memcpy(p, cap->
ptr, cap->
len);
607 ((
char *) p)[cap->
len] =
'\0';
616 case sizeof(char): fmt =
"hh";
break;
617 case sizeof(short): fmt =
"h";
break;
618 case sizeof(int): fmt =
"d";
break;
619 default:
return "SLRE_INT: unsupported size";
622 sprintf(buf,
"%%%d%s", cap->
len, fmt);
623 return sscanf(cap->
ptr, buf, p) == 1 ? NULL :
"SLRE_INT: capture failed";
626 static const char *
capture(
const struct cap *caps,
int num_caps, va_list ap) {
630 const char *err = NULL;
632 for (i = 0; i < num_caps; i++) {
633 type = va_arg(ap,
int);
634 size = va_arg(ap,
size_t);
635 p = va_arg(ap,
void *);
640 default: err =
"Unknown type, expected SLRE_(INT|FLOAT|STRING)";
break;
647 const char *buf,
int buf_len, ...) {
651 const char *error_string = NULL;
654 if ((error_string =
compile2(&slre, re)) == NULL &&
655 (error_string =
match2(&slre, buf, buf_len, caps)) == NULL) {
656 va_start(ap, buf_len);
static int casecmp(const void *p1, const void *p2, size_t len)
const char * slre_match(enum slre_option options, const char *re, const char *buf, int buf_len,...)
static const char * match2(const struct slre *r, const char *buf, int len, struct cap *caps)
static void exact_one_char(struct slre *r, int ch)
static const char * capture_int(const struct cap *cap, void *p, size_t len)
static void quantifier(struct slre *r, int prev, int op)
static const char * error_no_match
static const char * capture_float(const struct cap *cap, void *p, size_t len)
static int is_any_but(const unsigned char *p, int len, const char *s, int *ofs)
static void fixup_branch(struct slre *r, int fixup)
static const char * meta_characters
static void emit(struct slre *r, int code)
static const char * compile2(struct slre *r, const char *re)
static void compile(struct slre *r, const char **re)
static void relocate(struct slre *r, int begin, int shift)
static const char * capture(const struct cap *caps, int num_caps, va_list ap)
static int lowercase(const char *s)
static void loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
static int get_escape_char(const char **re)
static void loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs)
const char * error_string
static void anyof(struct slre *r, const char **re)
static const char * capture_string(const struct cap *cap, void *p, size_t len)
static const char * match(const struct slre *, int, const char *, int, int *, struct cap *)
static int is_any_of(const unsigned char *p, int len, const char *s, int *ofs)
static void exact(struct slre *r, const char **re)
static void store_char_in_data(struct slre *r, int ch)
static void set_jump_offset(struct slre *r, int pc, int offset)