Skip to content

Commit 40eb2bb

Browse files
committed
First step in making parsedate.y thread safe - use a pure parser
1 parent 291066c commit 40eb2bb

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

ext/standard/parsedate.y

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/* SUPPRESS 593 on yynewstate *//* Label was not used */
1919
/* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */
2020

21+
2122
#ifdef WIN32
2223
# include "config.w32.h"
2324
#else
@@ -60,6 +61,9 @@ extern time_t timezone;
6061
# endif
6162
#endif
6263

64+
65+
66+
6367
#define yylhs date_yylhs
6468
#define yylen date_yylen
6569
#define yydefred date_yydefred
@@ -74,7 +78,6 @@ extern time_t timezone;
7478
#define yylex date_lex
7579
#define yyerror date_error
7680

77-
static int date_lex(void);
7881

7982
/* See the LeapYears table in Convert. */
8083
#define EPOCH 1970
@@ -156,13 +159,18 @@ static time_t yyRelSeconds;
156159

157160
extern struct tm *localtime(const time_t *timep);
158161

162+
/* YYSTYPE is not yet defined at this point */
163+
static int date_lex(void *yylval);
164+
159165
static void date_error(char *s);
166+
160167
%}
161168

169+
%pure_parser
162170
%expect 6
163171

164172
%union {
165-
time_t Number;
173+
time_t Number;
166174
enum _MERIDIAN Meridian;
167175
}
168176

@@ -703,7 +711,7 @@ RelativeMonth(time_t Start, time_t RelMonth)
703711
}
704712

705713

706-
static int LookupWord(char *buff, int length)
714+
static int LookupWord(char *buff, int length, YYSTYPE *yylval)
707715
{
708716
char *p;
709717
STRING q;
@@ -718,29 +726,29 @@ static int LookupWord(char *buff, int length)
718726
for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
719727
q = tp->name;
720728
if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
721-
yylval.Number = tp->value;
729+
yylval->Number = tp->value;
722730
return tp->type;
723731
}
724732
}
725733
else
726734
for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
727735
if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
728-
yylval.Number = tp->value;
736+
yylval->Number = tp->value;
729737
return tp->type;
730738
}
731739

732740
/* Try for a timezone. */
733741
for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
734742
if (c == tp->name[0] && p[1] == tp->name[1]
735743
&& strcmp(p, tp->name) == 0) {
736-
yylval.Number = tp->value;
744+
yylval->Number = tp->value;
737745
return tp->type;
738746
}
739747

740748
/* Try the units table. */
741749
for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
742750
if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
743-
yylval.Number = tp->value;
751+
yylval->Number = tp->value;
744752
return tp->type;
745753
}
746754

@@ -750,7 +758,7 @@ static int LookupWord(char *buff, int length)
750758
for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
751759
if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
752760
p[length] = 's';
753-
yylval.Number = tp->value;
761+
yylval->Number = tp->value;
754762
return tp->type;
755763
}
756764
p[length] = 's';
@@ -766,11 +774,11 @@ static int LookupWord(char *buff, int length)
766774
/* Try the meridians. */
767775
if (buff[1] == 'm' && buff[2] == '\0') {
768776
if (buff[0] == 'a') {
769-
yylval.Meridian = MERam;
777+
yylval->Meridian = MERam;
770778
return tMERIDIAN;
771779
}
772780
if (buff[0] == 'p') {
773-
yylval.Meridian = MERpm;
781+
yylval->Meridian = MERpm;
774782
return tMERIDIAN;
775783
}
776784
}
@@ -781,18 +789,18 @@ static int LookupWord(char *buff, int length)
781789
for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
782790
if (c == tp->name[0] && p[1] == tp->name[1]
783791
&& strcmp(p, tp->name) == 0) {
784-
yylval.Number = tp->value;
792+
yylval->Number = tp->value;
785793
return tp->type;
786794
}
787795
}
788796

789797
/* Unknown word -- assume GMT timezone. */
790-
yylval.Number = 0;
798+
yylval->Number = 0;
791799
return tZONE;
792800
}
793801

794802

795-
static int date_lex(void)
803+
static int date_lex(YYSTYPE *yylval)
796804
{
797805
char c;
798806
char *p;
@@ -835,7 +843,7 @@ static int date_lex(void)
835843
for (i = 0; (c = *yyInput++) != '\0' && CTYPE(isdigit, (int)c); )
836844
i = 10 * i + c - '0';
837845
yyInput--;
838-
yylval.Number = sign < 0 ? -i : i;
846+
yylval->Number = sign < 0 ? -i : i;
839847
return sign ? tSNUMBER : tUNUMBER;
840848
}
841849

@@ -846,7 +854,7 @@ static int date_lex(void)
846854
*p++ = CTYPE(isupper, (int)c) ? tolower(c) : c;
847855
*p = '\0';
848856
yyInput--;
849-
return LookupWord(buff, p - buff);
857+
return LookupWord(buff, p - buff, yylval);
850858
}
851859

852860
return *yyInput++;

0 commit comments

Comments
 (0)