@@ -1067,19 +1067,13 @@ tok_backup(struct tok_state *tok, int c)
1067
1067
}
1068
1068
}
1069
1069
1070
-
1071
1070
static int
1072
- syntaxerror (struct tok_state * tok , const char * format , ...)
1071
+ _syntaxerror_range (struct tok_state * tok , const char * format ,
1072
+ Py_ssize_t col_offset , Py_ssize_t end_col_offset ,
1073
+ va_list vargs )
1073
1074
{
1074
1075
PyObject * errmsg , * errtext , * args ;
1075
- va_list vargs ;
1076
- #ifdef HAVE_STDARG_PROTOTYPES
1077
- va_start (vargs , format );
1078
- #else
1079
- va_start (vargs );
1080
- #endif
1081
1076
errmsg = PyUnicode_FromFormatV (format , vargs );
1082
- va_end (vargs );
1083
1077
if (!errmsg ) {
1084
1078
goto error ;
1085
1079
}
@@ -1089,7 +1083,14 @@ syntaxerror(struct tok_state *tok, const char *format, ...)
1089
1083
if (!errtext ) {
1090
1084
goto error ;
1091
1085
}
1092
- int offset = (int )PyUnicode_GET_LENGTH (errtext );
1086
+
1087
+ if (col_offset == 0 ) {
1088
+ col_offset = (int )PyUnicode_GET_LENGTH (errtext );
1089
+ }
1090
+ if (end_col_offset == 0 ) {
1091
+ col_offset = col_offset ;
1092
+ }
1093
+
1093
1094
Py_ssize_t line_len = strcspn (tok -> line_start , "\n" );
1094
1095
if (line_len != tok -> cur - tok -> line_start ) {
1095
1096
Py_DECREF (errtext );
@@ -1100,8 +1101,7 @@ syntaxerror(struct tok_state *tok, const char *format, ...)
1100
1101
goto error ;
1101
1102
}
1102
1103
1103
- args = Py_BuildValue ("(O(OiiN))" , errmsg ,
1104
- tok -> filename , tok -> lineno , offset , errtext );
1104
+ args = Py_BuildValue ("(O(OiiNii))" , errmsg , tok -> filename , tok -> lineno , col_offset , errtext , tok -> lineno , end_col_offset );
1105
1105
if (args ) {
1106
1106
PyErr_SetObject (PyExc_SyntaxError , args );
1107
1107
Py_DECREF (args );
@@ -1113,6 +1113,36 @@ syntaxerror(struct tok_state *tok, const char *format, ...)
1113
1113
return ERRORTOKEN ;
1114
1114
}
1115
1115
1116
+ static int
1117
+ syntaxerror (struct tok_state * tok , const char * format , ...) {
1118
+ va_list vargs ;
1119
+ #ifdef HAVE_STDARG_PROTOTYPES
1120
+ va_start (vargs , format );
1121
+ #else
1122
+ va_start (vargs );
1123
+ #endif
1124
+ int ret = _syntaxerror_range (tok , format , 0 , 0 , vargs );
1125
+ va_end (vargs );
1126
+ return ret ;
1127
+ }
1128
+
1129
+ static int
1130
+ syntaxerror_known_range (struct tok_state * tok ,
1131
+ Py_ssize_t col_offset , Py_ssize_t end_col_offset ,
1132
+ const char * format , ...) {
1133
+ va_list vargs ;
1134
+ #ifdef HAVE_STDARG_PROTOTYPES
1135
+ va_start (vargs , format );
1136
+ #else
1137
+ va_start (vargs );
1138
+ #endif
1139
+ int ret = _syntaxerror_range (tok , format , col_offset , end_col_offset , vargs );
1140
+ va_end (vargs );
1141
+ return ret ;
1142
+ }
1143
+
1144
+
1145
+
1116
1146
static int
1117
1147
indenterror (struct tok_state * tok )
1118
1148
{
@@ -1552,6 +1582,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
1552
1582
/* Number */
1553
1583
if (isdigit (c )) {
1554
1584
if (c == '0' ) {
1585
+ char * number_start = tok -> cur ;
1555
1586
/* Hex, octal or binary -- maybe. */
1556
1587
c = tok_nextc (tok );
1557
1588
if (c == 'x' || c == 'X' ) {
@@ -1580,6 +1611,8 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
1580
1611
if (c < '0' || c >= '8' ) {
1581
1612
tok_backup (tok , c );
1582
1613
if (isdigit (c )) {
1614
+ // Move to the actual current token that is incorrect
1615
+ tok_nextc (tok );
1583
1616
return syntaxerror (tok ,
1584
1617
"invalid digit '%c' in octal literal" , c );
1585
1618
}
@@ -1606,6 +1639,8 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
1606
1639
if (c != '0' && c != '1' ) {
1607
1640
tok_backup (tok , c );
1608
1641
if (isdigit (c )) {
1642
+ // Move to the actual current token that is incorrect
1643
+ tok_nextc (tok );
1609
1644
return syntaxerror (tok ,
1610
1645
"invalid digit '%c' in binary literal" , c );
1611
1646
}
@@ -1639,6 +1674,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
1639
1674
}
1640
1675
c = tok_nextc (tok );
1641
1676
}
1677
+ char * zeros_end = tok -> cur ;
1642
1678
if (isdigit (c )) {
1643
1679
nonzero = 1 ;
1644
1680
c = tok_decimal_tail (tok );
@@ -1659,10 +1695,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end)
1659
1695
else if (nonzero ) {
1660
1696
/* Old-style octal: now disallowed. */
1661
1697
tok_backup (tok , c );
1662
- return syntaxerror (tok ,
1663
- "leading zeros in decimal integer "
1664
- "literals are not permitted; "
1665
- "use an 0o prefix for octal integers" );
1698
+ return syntaxerror_known_range (
1699
+ tok , number_start - tok -> line_start ,
1700
+ zeros_end - tok -> line_start ,
1701
+ "leading zeros in decimal integer "
1702
+ "literals are not permitted; "
1703
+ "use an 0o prefix for octal integers" );
1666
1704
}
1667
1705
}
1668
1706
}
0 commit comments