config: do not use C function names as struct members

According to C99, section 7.1.4: Any function declared in a header may be additionally implemented as a function-like macro defined in the header. Therefore calling our struct member function pointer "fgetc" may run afoul of unwanted macro expansion when we call: char c = cf->fgetc(cf); This turned out to be a problem on uclibc, which defines fgetc as a macro and causes compilation failure. The standard suggests fixing this in a few ways: 1. Using extra parentheses to inhibit the function-like macro expansion. E.g., "(cf->fgetc)(cf)". This is undesirable as it's ugly, and each call site needs to remember to use it (and on systems without the macro, forgetting will compile just fine). 2. Using #undef (because a conforming implementation must also be providing fgetc as a function). This is undesirable because presumably the implementation was using the macro for a performance benefit, and we are dropping that optimization. Instead, we can simply use non-colliding names. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Aug 26, 2013 at 17:57 UTC 49d6cfa5c2874d78360dc4b16558bb45b5f8e003
1 file changed +16 -16
config.c
+16 -16
@@ -27,9 +27,9 @@ struct config_source {
27 struct strbuf value;
28 struct strbuf var;
29
30 - int (*fgetc)(struct config_source *c);
31 - int (*ungetc)(int c, struct config_source *conf);
32 - long (*ftell)(struct config_source *c);
30 + int (*do_fgetc)(struct config_source *c);
31 + int (*do_ungetc)(int c, struct config_source *conf);
32 + long (*do_ftell)(struct config_source *c);
33 };
34
35 static struct config_source *cf;
@@ -217,13 +217,13 @@ int git_config_from_parameters(config_fn_t fn, void *data)
217
218 static int get_next_char(void)
219 {
220 - int c = cf->fgetc(cf);
220 + int c = cf->do_fgetc(cf);
221
222 if (c == '\r') {
223 /* DOS like systems */
224 - c = cf->fgetc(cf);
224 + c = cf->do_fgetc(cf);
225 if (c != '\n') {
226 - cf->ungetc(c, cf);
226 + cf->do_ungetc(c, cf);
227 c = '\r';
228 }
229 }
@@ -982,9 +982,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
982 top.u.file = f;
983 top.name = filename;
984 top.die_on_error = 1;
985 - top.fgetc = config_file_fgetc;
986 - top.ungetc = config_file_ungetc;
987 - top.ftell = config_file_ftell;
985 + top.do_fgetc = config_file_fgetc;
986 + top.do_ungetc = config_file_ungetc;
987 + top.do_ftell = config_file_ftell;
988
989 ret = do_config_from(&top, fn, data);
990
@@ -1003,9 +1003,9 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,
1003 top.u.buf.pos = 0;
1004 top.name = name;
1005 top.die_on_error = 0;
1006 - top.fgetc = config_buf_fgetc;
1007 - top.ungetc = config_buf_ungetc;
1008 - top.ftell = config_buf_ftell;
1006 + top.do_fgetc = config_buf_fgetc;
1007 + top.do_ungetc = config_buf_ungetc;
1008 + top.do_ftell = config_buf_ftell;
1009
1010 return do_config_from(&top, fn, data);
1011 }
@@ -1186,7 +1186,7 @@ static int store_aux(const char *key, const char *value, void *cb)
1186 return 1;
1187 }
1188
1189 - store.offset[store.seen] = cf->ftell(cf);
1189 + store.offset[store.seen] = cf->do_ftell(cf);
1190 store.seen++;
1191 }
1192 break;
@@ -1213,19 +1213,19 @@ static int store_aux(const char *key, const char *value, void *cb)
1213 * Do not increment matches: this is no match, but we
1214 * just made sure we are in the desired section.
1215 */
1216 - store.offset[store.seen] = cf->ftell(cf);
1216 + store.offset[store.seen] = cf->do_ftell(cf);
1217 /* fallthru */
1218 case SECTION_END_SEEN:
1219 case START:
1220 if (matches(key, value)) {
1221 - store.offset[store.seen] = cf->ftell(cf);
1221 + store.offset[store.seen] = cf->do_ftell(cf);
1222 store.state = KEY_SEEN;
1223 store.seen++;
1224 } else {
1225 if (strrchr(key, '.') - key == store.baselen &&
1226 !strncmp(key, store.key, store.baselen)) {
1227 store.state = SECTION_SEEN;
1228 - store.offset[store.seen] = cf->ftell(cf);
1228 + store.offset[store.seen] = cf->do_ftell(cf);
1229 }
1230 }
1231 }