/** @license 2022 Neil Edelman, distributed under the terms of the [MIT License](https://opensource.org/licenses/MIT). Lexer for journal entries. @std C89/90 */ #include #include #include #include #include static int parse_uint(const char *s, const char *e, unsigned *u) { uint32_t n = 0; for ( ; s < e; ++s) { unsigned digit = (unsigned)(*s - '0'); assert(digit < 10); if(n > (UINT_MAX - digit) / 10) return errno = ERANGE, 0; /* check */ n = n * 10 + digit; } *u = n; return 1; } static int lex_line(const char *YYCURSOR, unsigned *const u) { const char *YYMARKER, *o1, *o2, *o3, *o4; /*!stags:re2c format = 'const char *@@;\n'; */ /*!re2c re2c:yyfill:enable = 0; re2c:flags:tags = 1; re2c:define:YYCTYPE = char; octet = [0-9] | [1-9][0-9] | [1][0-9][0-9] | [2][0-4][0-9] | [2][5][0-5]; dot = [.]; end = [\x00]; @o1 octet dot @o2 octet dot @o3 octet dot @o4 octet end { unsigned u1, u2, u3, u4; if(!parse_uint(o1, o2 - 1, &u1) || !parse_uint(o2, o3 - 1, &u2) || !parse_uint(o3, o4 - 1, &u3) || !parse_uint(o4, YYCURSOR - 1, &u4)) return 0; *u = u4 + (u3 << 8) + (u2 << 16) + (u1 << 24); return 1; } * { return 0; } */ } int main(int argc, char **argv) { unsigned u; int success; success = lex_line("1.2.3.4", &u); assert(success); printf("%x\n", u); return EXIT_SUCCESS; }