Skip to content

Commit ee70527

Browse files
removed goto labels (#6972)
* removed `goto` labels * style: '{' at end of line --------- Co-authored-by: Michael Chirico <[email protected]>
1 parent 3815402 commit ee70527

File tree

1 file changed

+36
-42
lines changed

1 file changed

+36
-42
lines changed

src/fread.c

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ static void parse_double_regular_core(const char **pch, double *target)
681681
static const int_fast32_t FLOAT_MAX_DIGITS = 18;
682682
const char *ch = *pch;
683683

684+
*target = NA_FLOAT64;
685+
684686
if (*ch=='0' && args.keepLeadingZeros && IS_DIGIT(ch[1])) return;
685687
bool neg, Eneg;
686688
ch += (neg = *ch=='-') + (*ch=='+');
@@ -710,7 +712,7 @@ static void parse_double_regular_core(const char **pch, double *target)
710712
ch++;
711713
e++;
712714
}
713-
if (*ch!=dec && *ch!='e' && *ch!='E') goto fail;
715+
if (*ch!=dec && *ch!='e' && *ch!='E') return;
714716
}
715717

716718
// Read the fractional part of the number, if it's present
@@ -743,17 +745,17 @@ static void parse_double_regular_core(const char **pch, double *target)
743745
}
744746
// Check that at least 1 digit was present in either the integer or
745747
// fractional part ("+1" here accounts for the decimal point char).
746-
if (ch == start + 1) goto fail;
748+
if (ch == start + 1) return;
747749
}
748750
// If there is no fractional part, then check that the integer part actually
749751
// exists (otherwise it's not a valid number)...
750752
else {
751-
if (ch == start) goto fail;
753+
if (ch == start) return;
752754
}
753755

754756
// Finally parse the "exponent" part of the number (if present)
755757
if (*ch=='E' || *ch=='e') {
756-
if (ch==start) goto fail; // something valid must be between [+|-] and E, character E alone is invalid.
758+
if (ch==start) return; // something valid must be between [+|-] and E, character E alone is invalid.
757759
ch += 1/*E*/ + (Eneg = ch[1]=='-') + (ch[1]=='+');
758760
int_fast32_t E = 0;
759761
if ((digit=AS_DIGIT(*ch))<10) {
@@ -769,11 +771,11 @@ static void parse_double_regular_core(const char **pch, double *target)
769771
}
770772
} else {
771773
// Not a single digit after "E"? Invalid number
772-
goto fail;
774+
return;
773775
}
774776
e += Eneg? -E : E;
775777
}
776-
if (e<-350 || e>350) goto fail;
778+
if (e<-350 || e>350) return;
777779

778780
long double r = (long double)acc;
779781
if (e < -300 || e > 300) {
@@ -792,10 +794,6 @@ static void parse_double_regular_core(const char **pch, double *target)
792794
r = e < 0 ? r/pow10lookup[-e] : r*pow10lookup[e];
793795
*target = (double)(neg? -r : r);
794796
*pch = ch;
795-
return;
796-
797-
fail:
798-
*target = NA_FLOAT64;
799797
}
800798

801799
static void parse_double_regular(FieldParseContext *ctx) {
@@ -903,7 +901,9 @@ static void parse_double_hexadecimal(FieldParseContext *ctx)
903901
uint64_t neg;
904902
bool Eneg, subnormal = 0;
905903
init();
904+
906905
ch += (neg = (*ch=='-')) + (*ch=='+');
906+
*target = NA_FLOAT64;
907907

908908
if (ch[0]=='0' && (ch[1]=='x' || ch[1]=='X') &&
909909
(ch[2]=='1' || (subnormal = ch[2]=='0')) && ch[3]=='.') {
@@ -916,7 +916,7 @@ static void parse_double_hexadecimal(FieldParseContext *ctx)
916916
ch++;
917917
}
918918
size_t ndigits = (uint_fast8_t)(ch - ch0);
919-
if (ndigits > 13 || !(*ch=='p' || *ch=='P')) goto fail;
919+
if (ndigits > 13 || !(*ch=='p' || *ch=='P')) return;
920920
acc <<= (13 - ndigits) * 4;
921921
ch += 1 + (Eneg = ch[1]=='-') + (ch[1]=='+');
922922
uint64_t E = 0;
@@ -925,7 +925,7 @@ static void parse_double_hexadecimal(FieldParseContext *ctx)
925925
ch++;
926926
}
927927
E = 1023 + (Eneg? -E : E) - subnormal;
928-
if (subnormal ? E : (E<1 || E>2046)) goto fail;
928+
if (subnormal ? E : (E<1 || E>2046)) return;
929929

930930
*((uint64_t*)target) = (neg << 63) | (E << 52) | (acc);
931931
*(ctx->ch) = ch;
@@ -942,9 +942,6 @@ static void parse_double_hexadecimal(FieldParseContext *ctx)
942942
*(ctx->ch) = ch + 8;
943943
return;
944944
}
945-
946-
fail:
947-
*target = NA_FLOAT64;
948945
}
949946

950947
/*
@@ -961,28 +958,29 @@ static void parse_iso8601_date_core(const char **pch, int32_t *target)
961958

962959
int32_t year=0, month=0, day=0;
963960

961+
*target = NA_INT32;
962+
964963
str_to_i32_core(&ch, &year, true);
965964

966965
// .Date(.Machine$integer.max*c(-1, 1)):
967966
// -5877641-06-24 -- 5881580-07-11
968967
// rather than fiddle with dates within those terminal years (unlikely
969968
// to be showing up in data sets any time soon), just truncate towards 0
970969
if (year == NA_INT32 || year < -5877640 || year > 5881579 || *ch != '-')
971-
goto fail;
970+
return;
972971

973972
// Multiples of 4, excluding 3/4 of centuries
974973
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year/100 % 4 == 0);
975974
ch++;
976975

977976
str_to_i32_core(&ch, &month, true);
978977
if (month == NA_INT32 || month < 1 || month > 12 || *ch != '-')
979-
goto fail;
978+
return;
980979
ch++;
981980

982981
str_to_i32_core(&ch, &day, true);
983-
if (day == NA_INT32 || day < 1 ||
984-
(day > (isLeapYear ? leapYearDays[month-1] : normYearDays[month-1])))
985-
goto fail;
982+
if (day == NA_INT32 || day < 1 || (day > (isLeapYear ? leapYearDays[month-1] : normYearDays[month-1])))
983+
return;
986984

987985
*target =
988986
(year/400 - 4)*cumDaysCycleYears[400] + // days to beginning of 400-year cycle
@@ -991,10 +989,6 @@ static void parse_iso8601_date_core(const char **pch, int32_t *target)
991989
day-1; // day within month (subtract 1: 1970-01-01 -> 0)
992990

993991
*pch = ch;
994-
return;
995-
996-
fail:
997-
*target = NA_INT32;
998992
}
999993

1000994
static void parse_iso8601_date(FieldParseContext *ctx) {
@@ -1009,27 +1003,33 @@ static void parse_iso8601_timestamp(FieldParseContext *ctx)
10091003
int32_t date, hour=0, minute=0, tz_hour=0, tz_minute=0;
10101004
double second=0;
10111005

1006+
*target = NA_FLOAT64;
1007+
10121008
parse_iso8601_date_core(&ch, &date);
10131009
if (date == NA_INT32)
1014-
goto fail;
1015-
if (*ch != ' ' && *ch != 'T')
1016-
goto date_only;
1017-
// allows date-only field in a column with UTC-marked datetimes to be parsed as UTC too; test 2150.13
1010+
return;
1011+
if (*ch != ' ' && *ch != 'T') {
1012+
*target = 86400 * (double)date;
1013+
1014+
*(ctx->ch) = ch;
1015+
return;
1016+
}
1017+
// allows date-only field in a column with UTC-marked datetimes to be parsed as UTC too; test 2150.13
10181018
ch++;
10191019

10201020
str_to_i32_core(&ch, &hour, true);
10211021
if (hour == NA_INT32 || hour < 0 || hour > 23 || *ch != ':')
1022-
goto fail;
1022+
return;
10231023
ch++;
10241024

10251025
str_to_i32_core(&ch, &minute, true);
10261026
if (minute == NA_INT32 || minute < 0 || minute > 59 || *ch != ':')
1027-
goto fail;
1027+
return;
10281028
ch++;
10291029

10301030
parse_double_regular_core(&ch, &second);
10311031
if (second == NA_FLOAT64 || second < 0 || second >= 60)
1032-
goto fail;
1032+
return;
10331033

10341034
if (*ch == 'Z') {
10351035
ch++; // "Zulu time"=UTC
@@ -1041,41 +1041,35 @@ static void parse_iso8601_timestamp(FieldParseContext *ctx)
10411041
// three recognized formats: [+-]AA:BB, [+-]AABB, and [+-]AA
10421042
str_to_i32_core(&ch, &tz_hour, true);
10431043
if (tz_hour == NA_INT32)
1044-
goto fail;
1044+
return;
10451045
if (ch - start == 5 && tz_hour != 0) { // +AABB
10461046
if (abs(tz_hour) > 2400)
1047-
goto fail;
1047+
return;
10481048
tz_minute = tz_hour % 100;
10491049
tz_hour /= 100;
10501050
} else if (ch - start == 3) {
10511051
if (abs(tz_hour) > 24)
1052-
goto fail;
1052+
return;
10531053
if (*ch == ':') {
10541054
ch++;
10551055
str_to_i32_core(&ch, &tz_minute, true);
10561056
if (tz_minute == NA_INT32)
1057-
goto fail;
1057+
return;
10581058
}
10591059
}
10601060
} else {
10611061
if (!args.noTZasUTC)
1062-
goto fail;
1062+
return;
10631063
// if neither Z nor UTC offset is present, then it's local time and that's not directly supported yet; see news for v1.13.0
10641064
// but user can specify that the unmarked datetimes are UTC by passing tz="UTC"
10651065
// if local time is UTC (env variable TZ is "" or "UTC", not unset) then local time is UTC, and that's caught by fread at R level too
10661066
}
10671067
}
10681068

1069-
date_only:
1070-
10711069
// cast upfront needed to prevent silent overflow
10721070
*target = 86400*(double)date + 3600*(hour - tz_hour) + 60*(minute - tz_minute) + second;
10731071

10741072
*(ctx->ch) = ch;
1075-
return;
1076-
1077-
fail:
1078-
*target = NA_FLOAT64;
10791073
}
10801074

10811075
static void parse_empty(FieldParseContext *ctx)

0 commit comments

Comments
 (0)