{"thread":{"id":"34772","subject":"Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","startedAt":"2013-08-26T20:10:43Z","lastAt":"2013-08-27T04:38:52Z","messageCount":9,"participants":["Lance","Lukas Fleischer","Jeff King","Andreas Schwab","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"225927","messageId":"521BB643.304@gmail.com","threadId":"34772","inReplyTo":null,"subject":"Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Lance","fromEmail":"lancethepants@gmail.com","sentAt":"2013-08-26T20:10:43Z","receivedAt":"2013-08-26T20:10:43Z","isPatch":false,"sender":{"key":"lancethepants@gmail.com","avatar":"https://gravatar.com/avatar/88dd92f9e4060d50dc978b7ace37c6b24daa5dcd3d2b744ef0aa670c75813a5c?d=mp&s=160"},"body":"Up until the latest release, I've been able to compile git for a uclibc \nbased embedded linux. The toolchain I use is from \"entware\", which is \nbased off of the openwrt toolchain.\nhttps://code.google.com/p/wl500g-repo/\n\nSomewhere between git 1.8.3.4 & 1.8.4 there seems to be some changes \nthat breaks compilation for my particular situation.  When cross \ncompiling I receive the following error.  I also receive the same error \nwhen compiling natively on the uclibc based device itself.\nNot sure if being uclibc based has anything to do with it, but is \nnoteworthy. I am not a c programmer.\nBoth the cross compiler, and embedded device's version off gcc is 4.6.3.\nPrevious versions compile fine\n\n     CC config.o\nconfig.c: In function 'get_next_char':\nconfig.c:220:14: error: expected identifier before '(' token\nconfig.c:220:14: error: expected statement before ')' token\nconfig.c:220:14: error: expected statement before ')' token\nconfig.c:224:11: error: expected identifier before '(' token\n\nLance\n"},{"id":"225929","messageId":"20130826201804.GB13130@blizzard","threadId":"34772","inReplyTo":"521BB643.304@gmail.com","subject":"Re: Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Lukas Fleischer","fromEmail":"git@cryptocrack.de","sentAt":"2013-08-26T20:18:04Z","receivedAt":"2013-08-26T20:18:04Z","isPatch":false,"sender":{"key":"git@cryptocrack.de","avatar":null},"body":"On Mon, Aug 26, 2013 at 02:10:43PM -0600, Lance wrote:\n> Up until the latest release, I've been able to compile git for a\n> uclibc based embedded linux. The toolchain I use is from \"entware\",\n> which is based off of the openwrt toolchain.\n> https://code.google.com/p/wl500g-repo/\n> \n> Somewhere between git 1.8.3.4 & 1.8.4 there seems to be some changes\n> that breaks compilation for my particular situation.  When cross\n> compiling I receive the following error.  I also receive the same\n> error when compiling natively on the uclibc based device itself.\n> Not sure if being uclibc based has anything to do with it, but is\n> noteworthy. I am not a c programmer.\n> Both the cross compiler, and embedded device's version off gcc is 4.6.3.\n> Previous versions compile fine\n> \n>     CC config.o\n> config.c: In function 'get_next_char':\n> config.c:220:14: error: expected identifier before '(' token\n> config.c:220:14: error: expected statement before ')' token\n> config.c:220:14: error: expected statement before ')' token\n> config.c:224:11: error: expected identifier before '(' token\n\nDoes changing line 220 of config.c to\n\n    int c = (cf->fgetc)(cf);\n\nfix it?\n\n> \n> Lance\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"225930","messageId":"521BBA98.7010102@gmail.com","threadId":"34772","inReplyTo":"20130826201804.GB13130@blizzard","subject":"Re: Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Lance","fromEmail":"lancethepants@gmail.com","sentAt":"2013-08-26T20:29:12Z","receivedAt":"2013-08-26T20:29:12Z","isPatch":false,"sender":{"key":"lancethepants@gmail.com","avatar":"https://gravatar.com/avatar/88dd92f9e4060d50dc978b7ace37c6b24daa5dcd3d2b744ef0aa670c75813a5c?d=mp&s=160"},"body":"\nOn 8/26/2013 2:18 PM, Lukas Fleischer wrote:\n> On Mon, Aug 26, 2013 at 02:10:43PM -0600, Lance wrote:\n>> Up until the latest release, I've been able to compile git for a\n>> uclibc based embedded linux. The toolchain I use is from \"entware\",\n>> which is based off of the openwrt toolchain.\n>> https://code.google.com/p/wl500g-repo/\n>>\n>> Somewhere between git 1.8.3.4 & 1.8.4 there seems to be some changes\n>> that breaks compilation for my particular situation.  When cross\n>> compiling I receive the following error.  I also receive the same\n>> error when compiling natively on the uclibc based device itself.\n>> Not sure if being uclibc based has anything to do with it, but is\n>> noteworthy. I am not a c programmer.\n>> Both the cross compiler, and embedded device's version off gcc is 4.6.3.\n>> Previous versions compile fine\n>>\n>>      CC config.o\n>> config.c: In function 'get_next_char':\n>> config.c:220:14: error: expected identifier before '(' token\n>> config.c:220:14: error: expected statement before ')' token\n>> config.c:220:14: error: expected statement before ')' token\n>> config.c:224:11: error: expected identifier before '(' token\n> Does changing line 220 of config.c to\n>\n>      int c = (cf->fgetc)(cf);\n>\n> fix it?\nI also had to change line 224 to the following\n\n                 c = (cf->fgetc)(cf);\n\nOnce both places were changes, it compiled successfully.\nthanks\n>> Lance\n>> --\n>> To unsubscribe from this list: send the line \"unsubscribe git\" in\n>> the body of a message to majordomo@vger.kernel.org\n>> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"225931","messageId":"20130826203154.GA21357@blizzard","threadId":"34772","inReplyTo":"521BBA98.7010102@gmail.com","subject":"Re: Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Lukas Fleischer","fromEmail":"git@cryptocrack.de","sentAt":"2013-08-26T20:31:54Z","receivedAt":"2013-08-26T20:31:54Z","isPatch":false,"sender":{"key":"git@cryptocrack.de","avatar":null},"body":"On Mon, Aug 26, 2013 at 02:29:12PM -0600, Lance wrote:\n> [...]\n> >>     CC config.o\n> >>config.c: In function 'get_next_char':\n> >>config.c:220:14: error: expected identifier before '(' token\n> >>config.c:220:14: error: expected statement before ')' token\n> >>config.c:220:14: error: expected statement before ')' token\n> >>config.c:224:11: error: expected identifier before '(' token\n> >Does changing line 220 of config.c to\n> >\n> >     int c = (cf->fgetc)(cf);\n> >\n> >fix it?\n> I also had to change line 224 to the following\n> \n>                 c = (cf->fgetc)(cf);\n> \n> Once both places were changes, it compiled successfully.\n\nSounds like a parser bug to me. Should we patch this in Git in order to\nmake it compile with (broken?) GCC versions?\n> [...]\n"},{"id":"225934","messageId":"20130826205901.GC23598@sigill.intra.peff.net","threadId":"34772","inReplyTo":"20130826203154.GA21357@blizzard","subject":"Re: Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-08-26T20:59:01Z","receivedAt":"2013-08-26T20:59:01Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 26, 2013 at 10:31:54PM +0200, Lukas Fleischer wrote:\n\n> > I also had to change line 224 to the following\n> > \n> >                 c = (cf->fgetc)(cf);\n> > \n> > Once both places were changes, it compiled successfully.\n> \n> Sounds like a parser bug to me. Should we patch this in Git in order to\n> make it compile with (broken?) GCC versions?\n\nHmm. I wonder if fgetc is a macro in uclibc? Just grepping their\nstdio.h, it looks like that is a possibility.\n\nI think they are probably wrong to do so (but I'd have to check the\nstandard). However, the cleaner workaround would probably be to call the\nfgetc struct member something else.\n\n-Peff\n"},{"id":"225936","messageId":"87fvtwi2jd.fsf@igel.home","threadId":"34772","inReplyTo":"20130826203154.GA21357@blizzard","subject":"Re: Issue with compiling git 1.8.4 under uclibc with gcc 4.6.3","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2013-08-26T21:07:50Z","receivedAt":"2013-08-26T21:07:50Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Lukas Fleischer <git@cryptocrack.de> writes:\n\n> On Mon, Aug 26, 2013 at 02:29:12PM -0600, Lance wrote:\n>> [...]\n>> >>     CC config.o\n>> >>config.c: In function 'get_next_char':\n>> >>config.c:220:14: error: expected identifier before '(' token\n>> >>config.c:220:14: error: expected statement before ')' token\n>> >>config.c:220:14: error: expected statement before ')' token\n>> >>config.c:224:11: error: expected identifier before '(' token\n>> >Does changing line 220 of config.c to\n>> >\n>> >     int c = (cf->fgetc)(cf);\n>> >\n>> >fix it?\n>> I also had to change line 224 to the following\n>> \n>>                 c = (cf->fgetc)(cf);\n>> \n>> Once both places were changes, it compiled successfully.\n>\n> Sounds like a parser bug to me.\n\nNo, it isn't.  fgetc may be a function-like macro that expands to an\narbitrary expression (same for ungetc or ftell, or any other indentifier\nthat matches a C library function, for that matter).\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"225942","messageId":"20130826215718.GB6219@sigill.intra.peff.net","threadId":"34772","inReplyTo":"20130826205901.GC23598@sigill.intra.peff.net","subject":"[PATCH] config: do not use C function names as struct members","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2013-08-26T21:57:18Z","receivedAt":"2013-08-26T21:57:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Aug 26, 2013 at 04:59:01PM -0400, Jeff King wrote:\n\n> Hmm. I wonder if fgetc is a macro in uclibc? Just grepping their\n> stdio.h, it looks like that is a possibility.\n> \n> I think they are probably wrong to do so (but I'd have to check the\n> standard). However, the cleaner workaround would probably be to call the\n> fgetc struct member something else.\n\nNope, it's allowed. I think we should do the patch below:\n\n-- >8 --\nSubject: config: do not use C function names as struct members\n\nAccording to C99, section 7.1.4:\n\n  Any function declared in a header may be additionally\n  implemented as a function-like macro defined in the\n  header.\n\nTherefore calling our struct member function pointer \"fgetc\"\nmay run afoul of unwanted macro expansion when we call:\n\n  char c = cf->fgetc(cf);\n\nThis turned out to be a problem on uclibc, which defines\nfgetc as a macro and causes compilation failure.\n\nThe standard suggests fixing this in a few ways:\n\n  1. Using extra parentheses to inhibit the function-like\n     macro expansion. E.g., \"(cf->fgetc)(cf)\". This is\n     undesirable as it's ugly, and each call site needs to\n     remember to use it (and on systems without the macro,\n     forgetting will compile just fine).\n\n  2. Using #undef (because a conforming implementation must\n     also be providing fgetc as a function). This is\n     undesirable because presumably the implementation was\n     using the macro for a performance benefit, and we are\n     dropping that optimization.\n\nInstead, we can simply use non-colliding names.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n config.c | 32 ++++++++++++++++----------------\n 1 file changed, 16 insertions(+), 16 deletions(-)\n\ndiff --git a/config.c b/config.c\nindex e13a7b6..9f9bf0c 100644\n--- a/config.c\n+++ b/config.c\n@@ -27,9 +27,9 @@ struct config_source {\n \tstruct strbuf value;\n \tstruct strbuf var;\n \n-\tint (*fgetc)(struct config_source *c);\n-\tint (*ungetc)(int c, struct config_source *conf);\n-\tlong (*ftell)(struct config_source *c);\n+\tint (*do_fgetc)(struct config_source *c);\n+\tint (*do_ungetc)(int c, struct config_source *conf);\n+\tlong (*do_ftell)(struct config_source *c);\n };\n \n static struct config_source *cf;\n@@ -217,13 +217,13 @@ static int get_next_char(void)\n \n static int get_next_char(void)\n {\n-\tint c = cf->fgetc(cf);\n+\tint c = cf->do_fgetc(cf);\n \n \tif (c == '\\r') {\n \t\t/* DOS like systems */\n-\t\tc = cf->fgetc(cf);\n+\t\tc = cf->do_fgetc(cf);\n \t\tif (c != '\\n') {\n-\t\t\tcf->ungetc(c, cf);\n+\t\t\tcf->do_ungetc(c, cf);\n \t\t\tc = '\\r';\n \t\t}\n \t}\n@@ -992,9 +992,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n \t\ttop.u.file = f;\n \t\ttop.name = filename;\n \t\ttop.die_on_error = 1;\n-\t\ttop.fgetc = config_file_fgetc;\n-\t\ttop.ungetc = config_file_ungetc;\n-\t\ttop.ftell = config_file_ftell;\n+\t\ttop.do_fgetc = config_file_fgetc;\n+\t\ttop.do_ungetc = config_file_ungetc;\n+\t\ttop.do_ftell = config_file_ftell;\n \n \t\tret = do_config_from(&top, fn, data);\n \n@@ -1013,9 +1013,9 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,\n \ttop.u.buf.pos = 0;\n \ttop.name = name;\n \ttop.die_on_error = 0;\n-\ttop.fgetc = config_buf_fgetc;\n-\ttop.ungetc = config_buf_ungetc;\n-\ttop.ftell = config_buf_ftell;\n+\ttop.do_fgetc = config_buf_fgetc;\n+\ttop.do_ungetc = config_buf_ungetc;\n+\ttop.do_ftell = config_buf_ftell;\n \n \treturn do_config_from(&top, fn, data);\n }\n@@ -1196,7 +1196,7 @@ static int store_aux(const char *key, const char *value, void *cb)\n \t\t\t\treturn 1;\n \t\t\t}\n \n-\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n+\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n \t\t\tstore.seen++;\n \t\t}\n \t\tbreak;\n@@ -1223,19 +1223,19 @@ static int store_aux(const char *key, const char *value, void *cb)\n \t\t * Do not increment matches: this is no match, but we\n \t\t * just made sure we are in the desired section.\n \t\t */\n-\t\tstore.offset[store.seen] = cf->ftell(cf);\n+\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n \t\t/* fallthru */\n \tcase SECTION_END_SEEN:\n \tcase START:\n \t\tif (matches(key, value)) {\n-\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n+\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n \t\t\tstore.state = KEY_SEEN;\n \t\t\tstore.seen++;\n \t\t} else {\n \t\t\tif (strrchr(key, '.') - key == store.baselen &&\n \t\t\t      !strncmp(key, store.key, store.baselen)) {\n \t\t\t\t\tstore.state = SECTION_SEEN;\n-\t\t\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n+\t\t\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n \t\t\t}\n \t\t}\n \t}\n-- \n1.8.4.2.g87d4a77\n"},{"id":"225946","messageId":"20130827005601.GA14679@blizzard","threadId":"34772","inReplyTo":"20130826215718.GB6219@sigill.intra.peff.net","subject":"Re: [PATCH] config: do not use C function names as struct members","fromName":"Lukas Fleischer","fromEmail":"git@cryptocrack.de","sentAt":"2013-08-27T00:56:01Z","receivedAt":"2013-08-27T00:56:01Z","isPatch":true,"sender":{"key":"git@cryptocrack.de","avatar":null},"body":"On Mon, Aug 26, 2013 at 05:57:18PM -0400, Jeff King wrote:\n> On Mon, Aug 26, 2013 at 04:59:01PM -0400, Jeff King wrote:\n> \n> > Hmm. I wonder if fgetc is a macro in uclibc? Just grepping their\n> > stdio.h, it looks like that is a possibility.\n> > \n> > I think they are probably wrong to do so (but I'd have to check the\n> > standard). However, the cleaner workaround would probably be to call the\n> > fgetc struct member something else.\n> \n> Nope, it's allowed. I think we should do the patch below:\n> \n> -- >8 --\n> Subject: config: do not use C function names as struct members\n> [...]\n> \n> Instead, we can simply use non-colliding names.\n\nYes, this sounds like a better idea to me. So, FWIW, +1 from me.\n\n> \n> Signed-off-by: Jeff King <peff@peff.net>\n> ---\n>  config.c | 32 ++++++++++++++++----------------\n>  1 file changed, 16 insertions(+), 16 deletions(-)\n> \n> [...]\n"},{"id":"225979","messageId":"xmqq8uznhhnn.fsf@gitster.dls.corp.google.com","threadId":"34772","inReplyTo":"20130826215718.GB6219@sigill.intra.peff.net","subject":"Re: [PATCH] config: do not use C function names as struct members","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-08-27T04:38:52Z","receivedAt":"2013-08-27T04:38:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Mon, Aug 26, 2013 at 04:59:01PM -0400, Jeff King wrote:\n>\n>> Hmm. I wonder if fgetc is a macro in uclibc? Just grepping their\n>> stdio.h, it looks like that is a possibility.\n>> \n>> I think they are probably wrong to do so (but I'd have to check the\n>> standard). However, the cleaner workaround would probably be to call the\n>> fgetc struct member something else.\n>\n> Nope, it's allowed. I think we should do the patch below:\n\nThanks.\n\n> -- >8 --\n> Subject: config: do not use C function names as struct members\n>\n> According to C99, section 7.1.4:\n>\n>   Any function declared in a header may be additionally\n>   implemented as a function-like macro defined in the\n>   header.\n>\n> Therefore calling our struct member function pointer \"fgetc\"\n> may run afoul of unwanted macro expansion when we call:\n>\n>   char c = cf->fgetc(cf);\n>\n> This turned out to be a problem on uclibc, which defines\n> fgetc as a macro and causes compilation failure.\n>\n> The standard suggests fixing this in a few ways:\n>\n>   1. Using extra parentheses to inhibit the function-like\n>      macro expansion. E.g., \"(cf->fgetc)(cf)\". This is\n>      undesirable as it's ugly, and each call site needs to\n>      remember to use it (and on systems without the macro,\n>      forgetting will compile just fine).\n>\n>   2. Using #undef (because a conforming implementation must\n>      also be providing fgetc as a function). This is\n>      undesirable because presumably the implementation was\n>      using the macro for a performance benefit, and we are\n>      dropping that optimization.\n>\n> Instead, we can simply use non-colliding names.\n>\n> Signed-off-by: Jeff King <peff@peff.net>\n> ---\n>  config.c | 32 ++++++++++++++++----------------\n>  1 file changed, 16 insertions(+), 16 deletions(-)\n>\n> diff --git a/config.c b/config.c\n> index e13a7b6..9f9bf0c 100644\n> --- a/config.c\n> +++ b/config.c\n> @@ -27,9 +27,9 @@ struct config_source {\n>  \tstruct strbuf value;\n>  \tstruct strbuf var;\n>  \n> -\tint (*fgetc)(struct config_source *c);\n> -\tint (*ungetc)(int c, struct config_source *conf);\n> -\tlong (*ftell)(struct config_source *c);\n> +\tint (*do_fgetc)(struct config_source *c);\n> +\tint (*do_ungetc)(int c, struct config_source *conf);\n> +\tlong (*do_ftell)(struct config_source *c);\n>  };\n>  \n>  static struct config_source *cf;\n> @@ -217,13 +217,13 @@ static int get_next_char(void)\n>  \n>  static int get_next_char(void)\n>  {\n> -\tint c = cf->fgetc(cf);\n> +\tint c = cf->do_fgetc(cf);\n>  \n>  \tif (c == '\\r') {\n>  \t\t/* DOS like systems */\n> -\t\tc = cf->fgetc(cf);\n> +\t\tc = cf->do_fgetc(cf);\n>  \t\tif (c != '\\n') {\n> -\t\t\tcf->ungetc(c, cf);\n> +\t\t\tcf->do_ungetc(c, cf);\n>  \t\t\tc = '\\r';\n>  \t\t}\n>  \t}\n> @@ -992,9 +992,9 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)\n>  \t\ttop.u.file = f;\n>  \t\ttop.name = filename;\n>  \t\ttop.die_on_error = 1;\n> -\t\ttop.fgetc = config_file_fgetc;\n> -\t\ttop.ungetc = config_file_ungetc;\n> -\t\ttop.ftell = config_file_ftell;\n> +\t\ttop.do_fgetc = config_file_fgetc;\n> +\t\ttop.do_ungetc = config_file_ungetc;\n> +\t\ttop.do_ftell = config_file_ftell;\n>  \n>  \t\tret = do_config_from(&top, fn, data);\n>  \n> @@ -1013,9 +1013,9 @@ int git_config_from_buf(config_fn_t fn, const char *name, const char *buf,\n>  \ttop.u.buf.pos = 0;\n>  \ttop.name = name;\n>  \ttop.die_on_error = 0;\n> -\ttop.fgetc = config_buf_fgetc;\n> -\ttop.ungetc = config_buf_ungetc;\n> -\ttop.ftell = config_buf_ftell;\n> +\ttop.do_fgetc = config_buf_fgetc;\n> +\ttop.do_ungetc = config_buf_ungetc;\n> +\ttop.do_ftell = config_buf_ftell;\n>  \n>  \treturn do_config_from(&top, fn, data);\n>  }\n> @@ -1196,7 +1196,7 @@ static int store_aux(const char *key, const char *value, void *cb)\n>  \t\t\t\treturn 1;\n>  \t\t\t}\n>  \n> -\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n> +\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n>  \t\t\tstore.seen++;\n>  \t\t}\n>  \t\tbreak;\n> @@ -1223,19 +1223,19 @@ static int store_aux(const char *key, const char *value, void *cb)\n>  \t\t * Do not increment matches: this is no match, but we\n>  \t\t * just made sure we are in the desired section.\n>  \t\t */\n> -\t\tstore.offset[store.seen] = cf->ftell(cf);\n> +\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n>  \t\t/* fallthru */\n>  \tcase SECTION_END_SEEN:\n>  \tcase START:\n>  \t\tif (matches(key, value)) {\n> -\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n> +\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n>  \t\t\tstore.state = KEY_SEEN;\n>  \t\t\tstore.seen++;\n>  \t\t} else {\n>  \t\t\tif (strrchr(key, '.') - key == store.baselen &&\n>  \t\t\t      !strncmp(key, store.key, store.baselen)) {\n>  \t\t\t\t\tstore.state = SECTION_SEEN;\n> -\t\t\t\t\tstore.offset[store.seen] = cf->ftell(cf);\n> +\t\t\t\t\tstore.offset[store.seen] = cf->do_ftell(cf);\n>  \t\t\t}\n>  \t\t}\n>  \t}\n"}]}