1414#include <re/re.h>
1515#include <re/groups.h>
1616
17- // TODO
18- #define OUT_CHAR (c ) do { if (outn < 1) { goto overflow; } *outs++ = (c); outn--; } while (0)
19- #define OUT_GROUP (s ) do { if (outn < strlen((s))) { goto overflow; } outs += sprintf(outs, "%s", (s)); outn -= strlen((s)); } while (0)
17+ #define OUT_CHAR (c ) \
18+ do { \
19+ if (outn < 1) { goto overflow; } \
20+ *outs++ = (c); outn--; \
21+ } while (0)
22+
23+ #define OUT_GROUP (s ) \
24+ do { \
25+ if (outn < strlen((s))) { goto overflow; } \
26+ outs += sprintf(outs, "%s", (s)); \
27+ outn -= strlen((s)); \
28+ } while (0)
2029
21- // TODO: return values: syntax error, nonexistent group error (digit overflow is the same thing), success
2230bool
2331re_interpolate_groups (const char * fmt , char esc ,
2432 const char * group0 , unsigned groupc , const char * groupv [], const char * nonexistent ,
@@ -89,11 +97,18 @@ re_interpolate_groups(const char *fmt, char esc,
8997 group *= 10 ;
9098 group += * p - '0' ;
9199
92- // TODO: explain this
93- // digit overflow, we cap to groupc + 1
94- // groupc + 1 is always out of bounds
95- // this is a simple way to avoid needing to handle digit overflow for subsequent digits,
96- // assuming groupc *= 10 is <= UINT_MAX
100+ /*
101+ * We need to handle numeric overflow somehow here,
102+ * as we would with using strtol() or similar. But
103+ * we don't need to distinguish this as a special
104+ * error code, semantically it's the same as a group
105+ * that doesn't exist.
106+ *
107+ * groupc + 1 is always out of bounds. So we cap to that,
108+ * using it as a simple way to avoid needing to handle
109+ * numeric overflow for subsequent digits. This assumes
110+ * groupc *= 10 is <= UINT_MAX.
111+ */
97112 if (group > groupc ) {
98113 group = groupc + 1 ;
99114 }
@@ -106,8 +121,15 @@ re_interpolate_groups(const char *fmt, char esc,
106121 assert (groupv [group - 1 ] != NULL );
107122 OUT_GROUP (groupv [group - 1 ]);
108123 } else if (nonexistent == NULL ) {
109- // TODO: maybe want to indicate this independently from syntax errors
110- // TODO: no need, you can pre-check the entire syntax by running with 0 groups
124+ /*
125+ * We could indicate this independently from syntax errors,
126+ * with some way to return different error codes.
127+ *
128+ * But there's no need, you can pre-check the fmt syntax
129+ * by running ahead of time with groupc == 0 and pass
130+ * nonexistent != NULL, because that eliminates the
131+ * possibility for group-related errors.
132+ */
111133 goto error ;
112134 } else {
113135 OUT_GROUP (nonexistent );
0 commit comments