X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/73c04bcfe1096173b00431f0cdc742894b15eef0..08b89b0a244153b9f5bbb2f49c55ab0f7298122e:/icuSources/tools/tzcode/zic.c diff --git a/icuSources/tools/tzcode/zic.c b/icuSources/tools/tzcode/zic.c index 47f92d22..2ae1c334 100644 --- a/icuSources/tools/tzcode/zic.c +++ b/icuSources/tools/tzcode/zic.c @@ -3,7 +3,7 @@ ** 2006-07-17 by Arthur David Olson. */ -static char elsieid[] = "@(#)zic.c 8.7"; +static char elsieid[] = "@(#)zic.c 8.18"; #include "private.h" #include "locale.h" @@ -113,76 +113,80 @@ struct zone { zic_t z_untiltime; }; -extern int getopt P((int argc, char * const argv[], - const char * options)); -extern int link P((const char * fromname, const char * toname)); +extern int getopt(int argc, char * const argv[], + const char * options); +extern int link(const char * fromname, const char * toname); extern char * optarg; extern int optind; -static void addtt P((zic_t starttime, int type)); +static void addtt(zic_t starttime, int type); #ifdef ICU -static int addtype P((long gmtoff, long rawoff, long dstoff, +static int addtype(long gmtoff, long rawoff, long dstoff, const char * abbr, int isdst, - int ttisstd, int ttisgmt)); + int ttisstd, int ttisgmt); #else -static int addtype P((long gmtoff, const char * abbr, int isdst, - int ttisstd, int ttisgmt)); +static int addtype(long gmtoff, const char * abbr, int isdst, + int ttisstd, int ttisgmt); #endif -static void leapadd P((zic_t t, int positive, int rolling, int count)); -static void adjleap P((void)); -static void associate P((void)); -static int ciequal P((const char * ap, const char * bp)); -static void convert P((long val, char * buf)); -static void convert64 P((zic_t val, char * buf)); -static void dolink P((const char * fromfile, const char * tofile)); -static void doabbr P((char * abbr, const char * format, - const char * letters, int isdst, int doquotes)); -static void eat P((const char * name, int num)); -static void eats P((const char * name, int num, - const char * rname, int rnum)); -static long eitol P((int i)); -static void error P((const char * message)); -static char ** getfields P((char * buf)); -static long gethms P((const char * string, const char * errstrng, - int signable)); -static void infile P((const char * filename)); -static void inleap P((char ** fields, int nfields)); -static void inlink P((char ** fields, int nfields)); -static void inrule P((char ** fields, int nfields)); -static int inzcont P((char ** fields, int nfields)); -static int inzone P((char ** fields, int nfields)); -static int inzsub P((char ** fields, int nfields, int iscont)); -static int is32 P((zic_t x)); -static int itsabbr P((const char * abbr, const char * word)); -static int itsdir P((const char * name)); -static int lowerit P((int c)); -static char * memcheck P((char * tocheck)); -static int mkdirs P((char * filename)); -static void newabbr P((const char * abbr)); -static long oadd P((long t1, long t2)); -static void outzone P((const struct zone * zp, int ntzones)); -static void puttzcode P((long code, FILE * fp)); -static void puttzcode64 P((zic_t code, FILE * fp)); -static int rcomp P((const void * leftp, const void * rightp)); -static zic_t rpytime P((const struct rule * rp, int wantedy)); -static void rulesub P((struct rule * rp, +static void leapadd(zic_t t, int positive, int rolling, int count); +static void adjleap(void); +static void associate(void); +static int ciequal(const char * ap, const char * bp); +static void convert(long val, char * buf); +static void convert64(zic_t val, char * buf); +static void dolink(const char * fromfield, const char * tofield); +static void doabbr(char * abbr, const char * format, + const char * letters, int isdst, int doquotes); +static void eat(const char * name, int num); +static void eats(const char * name, int num, + const char * rname, int rnum); +static long eitol(int i); +static void error(const char * message); +static char ** getfields(char * buf); +static long gethms(const char * string, const char * errstrng, + int signable); +static void infile(const char * filename); +static void inleap(char ** fields, int nfields); +static void inlink(char ** fields, int nfields); +static void inrule(char ** fields, int nfields); +static int inzcont(char ** fields, int nfields); +static int inzone(char ** fields, int nfields); +static int inzsub(char ** fields, int nfields, int iscont); +static int is32(zic_t x); +static int itsabbr(const char * abbr, const char * word); +static int itsdir(const char * name); +static int lowerit(int c); +static char * memcheck(char * tocheck); +static int mkdirs(char * filename); +static void newabbr(const char * abbr); +static long oadd(long t1, long t2); +static void outzone(const struct zone * zp, int ntzones); +static void puttzcode(long code, FILE * fp); +static void puttzcode64(zic_t code, FILE * fp); +static int rcomp(const void * leftp, const void * rightp); +static zic_t rpytime(const struct rule * rp, int wantedy); +static void rulesub(struct rule * rp, const char * loyearp, const char * hiyearp, const char * typep, const char * monthp, - const char * dayp, const char * timep)); -static int stringoffset P((char * result, long offset)); -static int stringrule P((char * result, const struct rule * rp, - long dstoff, long gmtoff)); -static void stringzone P((char * result, - const struct zone * zp, int ntzones)); -static void setboundaries P((void)); -static zic_t tadd P((zic_t t1, long t2)); -static void usage P((void)); -static void writezone P((const char * name, const char * string)); -static int yearistype P((int year, const char * type)); - -#if !HAVE_STRERROR -static char * strerror P((int)); -#endif /* !HAVE_STRERROR */ + const char * dayp, const char * timep); +static int stringoffset(char * result, long offset); +static int stringrule(char * result, const struct rule * rp, + long dstoff, long gmtoff); +static void stringzone(char * result, + const struct zone * zp, int ntzones); +static void setboundaries(void); +static zic_t tadd(zic_t t1, long t2); +static void usage(FILE *stream, int status); +static void writezone(const char * name, const char * string); +static int yearistype(int year, const char * type); +#ifdef ICU +static void emit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, + const struct rule* rule, + int ruleIndex, int startYear); +static void emit_icu_link(FILE* f, const char* from, const char* to); +static void emit_icu_rule(FILE* f, const struct rule* r, int ruleIndex); +static int add_icu_final_rules(const struct rule* r1, const struct rule* r2); +#endif static int charcnt; static int errors; @@ -308,19 +312,16 @@ struct lookup { }; #ifdef ICU - /* Indices into rules[] for final rules. They will occur in pairs, * with finalRules[i] occurring before finalRules[i+1] in the year. * Each zone need only store a start year, a standard offset, and an * index into finalRules[]. FinalRules[] are aliases into rules[]. */ - -static const struct rule ** finalRules; -static int finalRulesCount; - +static const struct rule ** finalRules; +static int finalRulesCount; #endif -static struct lookup const * byword P((const char * string, - const struct lookup * lp)); +static struct lookup const * byword(const char * string, + const struct lookup * lp); static struct lookup const line_codes[] = { { "Rule", LC_RULE }, @@ -442,19 +443,6 @@ char * const ptr; ** Error handling. */ -#if !HAVE_STRERROR -static char * -strerror(errnum) -int errnum; -{ - extern char * sys_errlist[]; - extern int sys_nerr; - - return (errnum > 0 && errnum <= sys_nerr) ? - sys_errlist[errnum] : _("Unknown system error"); -} -#endif /* !HAVE_STRERROR */ - static void eats(name, num, rname, rnum) const char * const name; @@ -508,69 +496,87 @@ const char * const string; } static void -usage P((void)) +usage(FILE *stream, int status) { - (void) fprintf(stderr, _("%s: usage is %s \ -[ --version ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ -\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"), - progname, progname); - exit(EXIT_FAILURE); + (void) fprintf(stream, _("%s: usage is %s \ +[ --version ] [ --help ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ +\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n"), + progname, progname); + exit(status); } #ifdef ICU - /* File into which we will write supplemental ICU data. */ -static FILE * icuFile; - -void emit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, - const struct rule* rule, - int ruleIndex, int startYear) { - /* machine-readable section */ - fprintf(f, "zone %s %d %d %s", zoneName, zoneOffset, startYear, rule->r_name); - - /* human-readable section */ - fprintf(f, " # zone %s, offset %d, year >= %d, rule %s (%d)\n", - zoneName, zoneOffset, startYear, - rule->r_name, ruleIndex); +static FILE * icuFile; + +static void +emit_icu_zone(FILE* f, const char* zoneName, int zoneOffset, + const struct rule* rule, + int ruleIndex, int startYear) { + /* machine-readable section */ + fprintf(f, "zone %s %d %d %s", zoneName, zoneOffset, startYear, rule->r_name); + + /* human-readable section */ + fprintf(f, " # zone %s, offset %d, year >= %d, rule %s (%d)\n", + zoneName, zoneOffset, startYear, + rule->r_name, ruleIndex); } -void emit_icu_link(FILE* f, const char* from, const char* to) { - /* machine-readable section */ - fprintf(f, "link %s %s\n", from, to); +static void +emit_icu_link(FILE* f, const char* from, const char* to) { + /* machine-readable section */ + fprintf(f, "link %s %s\n", from, to); } static const char* DYCODE[] = {"DOM", "DOWGEQ", "DOWLEQ"}; -void emit_icu_rule(FILE* f, const struct rule* r, int ruleIndex) { - if (r->r_yrtype != NULL) { - warning("year types not supported by ICU"); - fprintf(stderr, "rule %s, file %s, line %d\n", - r->r_name, r->r_filename, r->r_linenum); +static void +emit_icu_rule(FILE* f, const struct rule* r, int ruleIndex) { + if (r->r_yrtype != NULL) { + warning("year types not supported by ICU"); + fprintf(stderr, "rule %s, file %s, line %d\n", + r->r_name, r->r_filename, r->r_linenum); } - /* machine-readable section */ - fprintf(f, "rule %s %s %d %d %d %d %d %d %d", - r->r_name, DYCODE[r->r_dycode], - r->r_month, r->r_dayofmonth, - (r->r_dycode == DC_DOM ? -1 : r->r_wday), - r->r_tod, r->r_todisstd, r->r_todisgmt, r->r_stdoff - ); - - /* human-readable section */ - fprintf(f, " # %d: %s, file %s, line %d", - ruleIndex, r->r_name, r->r_filename, r->r_linenum); - fprintf(f, ", mode %s", DYCODE[r->r_dycode]); - fprintf(f, ", %s, dom %d", mon_names[r->r_month].l_word, r->r_dayofmonth); - if (r->r_dycode != DC_DOM) { - fprintf(f, ", %s", wday_names[r->r_wday].l_word); - } - fprintf(f, ", time %d", r->r_tod); - fprintf(f, ", isstd %d", r->r_todisstd); - fprintf(f, ", isgmt %d", r->r_todisgmt); - fprintf(f, ", offset %ld", r->r_stdoff); - fprintf(f, "\n"); + /* machine-readable section */ + fprintf(f, "rule %s %s %d %d %d %ld %d %d %ld", + r->r_name, DYCODE[r->r_dycode], + r->r_month, r->r_dayofmonth, + (r->r_dycode == DC_DOM ? -1 : r->r_wday), + r->r_tod, r->r_todisstd, r->r_todisgmt, r->r_stdoff + ); + + /* human-readable section */ + fprintf(f, " # %d: %s, file %s, line %d", + ruleIndex, r->r_name, r->r_filename, r->r_linenum); + fprintf(f, ", mode %s", DYCODE[r->r_dycode]); + fprintf(f, ", %s, dom %d", mon_names[r->r_month].l_word, r->r_dayofmonth); + if (r->r_dycode != DC_DOM) { + fprintf(f, ", %s", wday_names[r->r_wday].l_word); + } + fprintf(f, ", time %ld", r->r_tod); + fprintf(f, ", isstd %d", r->r_todisstd); + fprintf(f, ", isgmt %d", r->r_todisgmt); + fprintf(f, ", offset %ld", r->r_stdoff); + fprintf(f, "\n"); } +static int +add_icu_final_rules(const struct rule* r1, const struct rule* r2) { + int i; + + for (i=0; i= HOURSPERDAY || + if (hh < 0 || mm < 0 || mm >= MINSPERHOUR || - ss < 0 || ss > SECSPERMIN) && - !(hh == HOURSPERDAY && mm == 0 && ss == 0)) { + ss < 0 || ss > SECSPERMIN) { error(errstring); return 0; } - if (noise && hh == HOURSPERDAY) + if (LONG_MAX / SECSPERHOUR < hh) { + error(_("time overflow")); + return 0; + } + if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0) warning(_("24:00 not handled by pre-1998 versions of zic")); - return eitol(sign) * - (eitol(hh * MINSPERHOUR + mm) * - eitol(SECSPERMIN) + eitol(ss)); + if (noise && (hh > HOURSPERDAY || + (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) +warning(_("values over 24 hours not handled by pre-2007 versions of zic")); + return oadd(eitol(sign) * hh * eitol(SECSPERHOUR), + eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss))); } static void @@ -1767,8 +1781,8 @@ const char * const string; (size_t) sizeof tzh.field, (size_t) 1, fp) tzh = tzh0; #ifdef ICU - * (ICUZoneinfoVersion*) &tzh.tzh_reserved = TZ_ICU_VERSION; - (void) strncpy(tzh.tzh_magic, TZ_ICU_MAGIC, sizeof tzh.tzh_magic); + * (ICUZoneinfoVersion*) &tzh.tzh_reserved = TZ_ICU_VERSION; + (void) strncpy(tzh.tzh_magic, TZ_ICU_MAGIC, sizeof tzh.tzh_magic); #else (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); #endif @@ -1805,10 +1819,10 @@ const char * const string; for (i = 0; i < typecnt; ++i) if (writetype[i]) { #ifdef ICU - puttzcode((long) rawoffs[i], fp); - puttzcode((long) dstoffs[i], fp); + puttzcode((long) rawoffs[i], fp); + puttzcode((long) dstoffs[i], fp); #else - puttzcode((long) gmtoffs[i], fp); + puttzcode(gmtoffs[i], fp); #endif (void) putc(isdsts[i], fp); (void) putc((unsigned char) indmap[abbrinds[i]], fp); @@ -2078,24 +2092,6 @@ const int zonecount; } } -#ifdef ICU - -int add_icu_final_rules(const struct rule* r1, const struct rule* r2) { - int i; - - for (i=0; iz_untilrule.r_loyear); + if (i < zonecount - 1) + updateminmax(zp->z_untilrule.r_loyear); for (j = 0; j < zp->z_nrules; ++j) { rp = &zp->z_rules[j]; if (rp->r_lowasnum) @@ -2168,7 +2165,7 @@ const int zonecount; wp = ecpyalloc(_("no POSIX environment variable for zone")); wp = ecatalloc(wp, " "); - wp = ecatalloc(wp, zpfirst->z_name); + wp = ecatalloc(wp, zpfirst->z_name); warning(wp); ifree(wp); } @@ -2181,8 +2178,11 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); else max_year = INT_MAX; } /* - ** For the benefit of older systems, generate data through 2037. + ** For the benefit of older systems, + ** generate data from 1900 through 2037. */ + if (min_year > 1900) + min_year = 1900; if (max_year < 2037) max_year = 2037; for (i = 0; i < zonecount; ++i) { @@ -2200,45 +2200,89 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); *startbuf = '\0'; startoff = zp->z_gmtoff; #ifdef ICU - finalRuleYear = finalRuleIndex = -1; - finalRule1 = finalRule2 = NULL; - if (i == (zonecount - 1)) { /* !useuntil */ - /* Look for exactly 2 rules that end at 'max' and - * note them. Determine max(r_loyear) for the 2 of - * them. */ - for (j=0; jz_nrules; ++j) { - rp = &zp->z_rules[j]; - if (rp->r_hiyear == INT_MAX) { - if (finalRule1 == NULL) { - finalRule1 = rp; - finalRuleYear = rp->r_loyear; - } else if (finalRule2 == NULL) { - finalRule2 = rp; - if (rp->r_loyear > finalRuleYear) { - finalRuleYear = rp->r_loyear; - } - } else { - error("more than two max rules found (ICU)"); - exit(EXIT_FAILURE); - } - } - } - if (finalRule1 != NULL && finalRule2 == NULL) { - error("only one max rule found (ICU)"); - exit(EXIT_FAILURE); - } - if (finalRule1 != NULL) { - /* Swap if necessary so finalRule1 occurs before - * finalRule2 */ - if (finalRule1->r_month > finalRule2->r_month) { - const struct rule* t = finalRule1; - finalRule1 = finalRule2; - finalRule2 = t; - } - /* Add final rule to our list */ - finalRuleIndex = add_icu_final_rules(finalRule1, finalRule2); - } - } + finalRuleYear = finalRuleIndex = -1; + finalRule1 = finalRule2 = NULL; + if (i == (zonecount - 1)) { /* !useuntil */ + /* Look for exactly 2 rules that end at 'max' and + * note them. Determine max(r_loyear) for the 2 of + * them. */ + for (j=0; jz_nrules; ++j) { + rp = &zp->z_rules[j]; + if (rp->r_hiyear == INT_MAX) { + if (rp->r_loyear > finalRuleYear) { + finalRuleYear = rp->r_loyear; + } + if (finalRule1 == NULL) { + finalRule1 = rp; + } else if (finalRule2 == NULL) { + finalRule2 = rp; + } else { + error("more than two max rules found (ICU)"); + exit(EXIT_FAILURE); + } + } else if (rp->r_hiyear >= finalRuleYear) { + /* There might be an overriding non-max rule + * to be applied to a specific year after one of + * max rule's start year. For example, + * + * Rule Foo 2010 max ... + * Rule Foo 2015 only ... + * + * In this case, we need to change the start year of + * the final (max) rules to the next year. */ + finalRuleYear = rp->r_hiyear + 1; + + /* When above adjustment is done, max_year might need + * to be adjusted, so the final rule will be properly + * evaluated and emitted by the later code block. + * + * Note: This may push the start year of the final + * rules ahead by 1 year unnecessarily. For example, + * If there are two rules, non-max rule and max rule + * starting in the same year, such as + * + * Rule Foo 2010 only .... + * Rule Foo 2010 max .... + * + * In this case, the final (max) rule actually starts + * in 2010, instead of 2010. We could make this tool + * more intelligent to detect such situation. But pushing + * final rule start year to 1 year ahead (in the worst case) + * will just populate a few extra transitions, and it still + * works fine. So for now, we're not trying to put additional + * logic to optimize the case. + */ + if (max_year < finalRuleYear) { + max_year = finalRuleYear; + } + } + } + if (finalRule1 != NULL) { + if (finalRule2 == NULL) { + warning("only one max rule found (ICU)"); + finalRuleYear = finalRuleIndex = -1; + finalRule1 = NULL; + } else { + if (finalRule1->r_stdoff == finalRule2->r_stdoff) { + /* America/Resolute in 2009a uses a pair of rules + * which does not change the offset. ICU ignores + * such rules without actual time transitions. */ + finalRuleYear = finalRuleIndex = -1; + finalRule1 = finalRule2 = NULL; + } else { + /* Swap if necessary so finalRule1 occurs before + * finalRule2 */ + if (finalRule1->r_month > finalRule2->r_month) { + const struct rule* t = finalRule1; + finalRule1 = finalRule2; + finalRule2 = t; + } + /* Add final rule to our list */ + finalRuleIndex = add_icu_final_rules(finalRule1, finalRule2); + } + } + } + } #endif if (zp->z_nrules == 0) { @@ -2247,7 +2291,7 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); (char *) NULL, stdoff != 0, FALSE); type = addtype(oadd(zp->z_gmtoff, stdoff), #ifdef ICU - zp->z_gmtoff, stdoff, + zp->z_gmtoff, stdoff, #endif startbuf, stdoff != 0, startttisstd, startttisgmt); @@ -2321,15 +2365,6 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); break; /* go on to next year */ rp = &zp->z_rules[k]; rp->r_todo = FALSE; -#ifdef ICU - if (year >= finalRuleYear && rp == finalRule1) { - emit_icu_zone(icuFile, - zpfirst->z_name, zp->z_gmtoff, - rp, finalRuleIndex, year); - /* only emit this for the first year */ - finalRule1 = NULL; - } -#endif if (useuntil && ktime >= untiltime) break; stdoff = rp->r_stdoff; @@ -2356,6 +2391,27 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); FALSE); } } +#ifdef ICU + if (year >= finalRuleYear && rp == finalRule1) { + /* We want to shift final year 1 year after + * the actual final rule takes effect (year + 1), + * because the previous type is valid until the first + * transition defined by the final rule. Otherwise + * we may see unexpected offset shift at the + * begining of the year when the final rule takes + * effect. + * + * Note: This may results some 64bit second transitions + * at the very end (year 2038). ICU 4.2 or older releases + * cannot handle 64bit second transitions and they are + * dropped from zoneinfo.txt. */ + emit_icu_zone(icuFile, + zpfirst->z_name, zp->z_gmtoff, + rp, finalRuleIndex, year + 1); + /* only emit this for the first year */ + finalRule1 = NULL; + } +#endif eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); doabbr(ab, zp->z_format, rp->r_abbrvar, @@ -2363,7 +2419,7 @@ wp = ecpyalloc(_("no POSIX environment variable for zone")); offset = oadd(zp->z_gmtoff, rp->r_stdoff); #ifdef ICU type = addtype(offset, zp->z_gmtoff, rp->r_stdoff, - ab, rp->r_stdoff != 0, + ab, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); #else type = addtype(offset, ab, rp->r_stdoff != 0, @@ -2384,8 +2440,8 @@ error(_("can't determine time zone abbreviation to use just after until time")); else addtt(starttime, #ifdef ICU addtype(startoff, - zp->z_gmtoff, startoff - zp->z_gmtoff, - startbuf, + zp->z_gmtoff, startoff - zp->z_gmtoff, + startbuf, startoff != zp->z_gmtoff, startttisstd, startttisgmt)); @@ -2481,10 +2537,10 @@ const int ttisgmt; error(_("internal error - addtype called with bad isdst/dstoff")); (void) exit(EXIT_FAILURE); } - if (gmtoff != (rawoff + dstoff)) { + if (gmtoff != (rawoff + dstoff)) { error(_("internal error - addtype called with bad gmt/raw/dstoff")); (void) exit(EXIT_FAILURE); - } + } #endif /* ** See if there's already an entry for this zone type. @@ -2493,7 +2549,7 @@ const int ttisgmt; for (i = 0; i < typecnt; ++i) { if (gmtoff == gmtoffs[i] && isdst == isdsts[i] && #ifdef ICU - rawoff == rawoffs[i] && dstoff == dstoffs[i] && + rawoff == rawoffs[i] && dstoff == dstoffs[i] && #endif strcmp(abbr, &chars[abbrinds[i]]) == 0 && ttisstd == ttisstds[i] && @@ -2508,10 +2564,14 @@ const int ttisgmt; error(_("too many local time types")); exit(EXIT_FAILURE); } + if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) { + error(_("UTC offset out of range")); + exit(EXIT_FAILURE); + } gmtoffs[i] = gmtoff; #ifdef ICU - rawoffs[i] = rawoff; - dstoffs[i] = dstoff; + rawoffs[i] = rawoff; + dstoffs[i] = dstoff; #endif isdsts[i] = isdst; ttisstds[i] = ttisstd; @@ -2562,7 +2622,7 @@ int count; } static void -adjleap P((void)) +adjleap(void) { register int i; register long last = 0; @@ -2692,9 +2752,12 @@ register char * cp; else while ((*dp = *cp++) != '"') if (*dp != '\0') ++dp; - else error(_( + else { + error(_( "Odd number of quotation marks" )); + exit(1); + } } while (*cp != '\0' && *cp != '#' && (!isascii(*cp) || !isspace((unsigned char) *cp))); if (isascii(*cp) && isspace((unsigned char) *cp)) @@ -2882,7 +2945,7 @@ wp = _("time zone abbreviation differs from POSIX standard"); static int mkdirs(argname) -char * const argname; +char * argname; { register char * name; register char * cp;