@@ -61,6 +61,10 @@ typedef enum { qfalse = 0, qtrue = 1 } qboolean;
6161#define Q_stricmp strcasecmp
6262#define Log_Write BotLib_LogWrite
6363
64+ extern int PC_ExpectTokenString (pc_source_t * source , char * string );
65+ extern int PC_ExpectTokenType (pc_source_t * source , int type , int subtype , pc_token_t * token );
66+ extern int PC_ExpectAnyToken (pc_source_t * source , pc_token_t * token );
67+
6468static void PS_AppendDiagnostic (pc_script_t * script ,
6569 pc_error_level_t level ,
6670 const char * message )
@@ -133,6 +137,81 @@ static void PS_ReportDiagnostic(pc_script_t *script,
133137 PS_AppendDiagnostic (script , level , text );
134138}
135139
140+ static void PS_SyncDiagnosticsFromSource (pc_script_t * script )
141+ {
142+ if (script == NULL || script -> source == NULL )
143+ {
144+ return ;
145+ }
146+
147+ const pc_diagnostic_t * head = PC_GetDiagnostics (script -> source );
148+ const pc_diagnostic_t * cursor = head ;
149+ if (script -> last_source_diagnostic != NULL )
150+ {
151+ cursor = script -> last_source_diagnostic -> next ;
152+ }
153+
154+ int saved_line = script -> line ;
155+ while (cursor != NULL )
156+ {
157+ script -> line = cursor -> line ;
158+ PS_AppendDiagnostic (script , cursor -> level , cursor -> message );
159+ script -> last_source_diagnostic = cursor ;
160+ cursor = cursor -> next ;
161+ }
162+ script -> line = saved_line ;
163+ }
164+
165+ pc_script_t * PS_CreateScriptFromSource (pc_source_t * source )
166+ {
167+ if (source == NULL )
168+ {
169+ return NULL ;
170+ }
171+
172+ pc_script_t * script = (pc_script_t * )calloc (1 , sizeof (pc_script_t ));
173+ if (script == NULL )
174+ {
175+ BotLib_Print (PRT_FATAL , "PS_CreateScriptFromSource: out of memory\n" );
176+ return NULL ;
177+ }
178+
179+ script -> source = source ;
180+ script -> line = 1 ;
181+ script -> lastline = 1 ;
182+ script -> tokenavailable = 0 ;
183+ script -> diagnostics = NULL ;
184+ script -> diagnostics_tail = NULL ;
185+ script -> last_source_diagnostic = NULL ;
186+ script -> punctuations = default_punctuations ;
187+
188+ PS_SyncDiagnosticsFromSource (script );
189+
190+ return script ;
191+ }
192+
193+ void PS_FreeScript (pc_script_t * script )
194+ {
195+ if (script == NULL )
196+ {
197+ return ;
198+ }
199+
200+ pc_diagnostic_t * diag = script -> diagnostics ;
201+ while (diag != NULL )
202+ {
203+ pc_diagnostic_t * next = diag -> next ;
204+ if (diag -> message != NULL )
205+ {
206+ free ((void * )diag -> message );
207+ }
208+ free (diag );
209+ diag = next ;
210+ }
211+
212+ free (script );
213+ }
214+
136215static int COM_Compress (char * data_p )
137216{
138217 if (data_p == NULL )
@@ -985,11 +1064,45 @@ int PS_ReadPrimitive(pc_script_t *script, pc_token_t *token)
9851064//============================================================================
9861065int PS_ReadToken (pc_script_t * script , pc_token_t * token )
9871066{
988- //if there is a token available (from UnreadToken)
989- if (script -> tokenavailable )
990- {
991- script -> tokenavailable = 0 ;
992- memcpy (token , & script -> token , sizeof (pc_token_t ));
1067+ if (script == NULL || token == NULL )
1068+ {
1069+ return 0 ;
1070+ }
1071+
1072+ if (script -> source != NULL )
1073+ {
1074+ if (script -> tokenavailable )
1075+ {
1076+ script -> tokenavailable = 0 ;
1077+ memcpy (token , & script -> token , sizeof (pc_token_t ));
1078+ return 1 ;
1079+ }
1080+
1081+ script -> lastline = script -> line ;
1082+ int result = PC_ReadToken (script -> source , token );
1083+ PS_SyncDiagnosticsFromSource (script );
1084+ if (!result )
1085+ {
1086+ return 0 ;
1087+ }
1088+
1089+ if (token -> linescrossed > 0 )
1090+ {
1091+ script -> lastline = token -> line - token -> linescrossed ;
1092+ }
1093+ script -> line = token -> line ;
1094+ memcpy (& script -> token , token , sizeof (pc_token_t ));
1095+ script -> tokenavailable = 0 ;
1096+ script -> whitespace_p = NULL ;
1097+ script -> endwhitespace_p = NULL ;
1098+ return 1 ;
1099+ }
1100+
1101+ //if there is a token available (from UnreadToken)
1102+ if (script -> tokenavailable )
1103+ {
1104+ script -> tokenavailable = 0 ;
1105+ memcpy (token , & script -> token , sizeof (pc_token_t ));
9931106 return 1 ;
9941107 } //end if
9951108 //save script pointer
@@ -1057,22 +1170,47 @@ int PS_ReadToken(pc_script_t *script, pc_token_t *token)
10571170// Returns: -
10581171// Changes Globals: -
10591172//============================================================================
1060- int PS_ExpectTokenString (pc_script_t * script , char * string )
1173+ int PS_ExpectTokenString (pc_script_t * script , const char * string )
10611174{
1062- pc_token_t token ;
1175+ if (script == NULL || string == NULL )
1176+ {
1177+ return 0 ;
1178+ }
10631179
1064- if (!PS_ReadToken (script , & token ))
1065- {
1066- ScriptError (script , "couldn't find expected %s" , string );
1067- return 0 ;
1068- } //end if
1180+ if (script -> source != NULL )
1181+ {
1182+ pc_token_t peek ;
1183+ int has_peek = PC_PeekToken (script -> source , & peek );
1184+ int result = PC_ExpectTokenString (script -> source , (char * )string );
1185+ PS_SyncDiagnosticsFromSource (script );
1186+ if (has_peek )
1187+ {
1188+ script -> lastline = script -> line ;
1189+ if (peek .linescrossed > 0 )
1190+ {
1191+ script -> lastline = peek .line - peek .linescrossed ;
1192+ }
1193+ script -> line = peek .line ;
1194+ memcpy (& script -> token , & peek , sizeof (pc_token_t ));
1195+ script -> tokenavailable = 0 ;
1196+ }
1197+ return result != 0 ;
1198+ }
10691199
1070- if (strcmp (token .string , string ))
1071- {
1072- ScriptError (script , "expected %s, found %s" , string , token .string );
1073- return 0 ;
1074- } //end if
1075- return 1 ;
1200+ pc_token_t token ;
1201+
1202+ if (!PS_ReadToken (script , & token ))
1203+ {
1204+ ScriptError (script , "couldn't find expected %s" , string );
1205+ return 0 ;
1206+ } //end if
1207+
1208+ if (strcmp (token .string , string ))
1209+ {
1210+ ScriptError (script , "expected %s, found %s" , string , token .string );
1211+ return 0 ;
1212+ } //end if
1213+ return 1 ;
10761214} //end of the function PS_ExpectToken
10771215//============================================================================
10781216//
@@ -1082,55 +1220,81 @@ int PS_ExpectTokenString(pc_script_t *script, char *string)
10821220//============================================================================
10831221int PS_ExpectTokenType (pc_script_t * script , int type , int subtype , pc_token_t * token )
10841222{
1085- char str [MAX_TOKEN ];
1223+ if (script == NULL )
1224+ {
1225+ return 0 ;
1226+ }
10861227
1087- if (!PS_ReadToken (script , token ))
1088- {
1089- ScriptError (script , "couldn't read expected token" );
1090- return 0 ;
1091- } //end if
1228+ if (script -> source != NULL )
1229+ {
1230+ pc_token_t local ;
1231+ if (token == NULL )
1232+ {
1233+ memset (& local , 0 , sizeof (local ));
1234+ token = & local ;
1235+ }
1236+ int result = PC_ExpectTokenType (script -> source , type , subtype , token );
1237+ PS_SyncDiagnosticsFromSource (script );
1238+ script -> lastline = script -> line ;
1239+ if (token -> linescrossed > 0 )
1240+ {
1241+ script -> lastline = token -> line - token -> linescrossed ;
1242+ }
1243+ script -> line = token -> line ;
1244+ memcpy (& script -> token , token , sizeof (pc_token_t ));
1245+ script -> tokenavailable = 0 ;
1246+ return result != 0 ;
1247+ }
10921248
1093- if (token -> type != type )
1094- {
1095- if (type == TT_STRING ) strcpy (str , "string" );
1096- if (type == TT_LITERAL ) strcpy (str , "literal" );
1097- if (type == TT_NUMBER ) strcpy (str , "number" );
1098- if (type == TT_NAME ) strcpy (str , "name" );
1099- if (type == TT_PUNCTUATION ) strcpy (str , "punctuation" );
1100- ScriptError (script , "expected a %s, found %s" , str , token -> string );
1101- return 0 ;
1102- } //end if
1103- if (token -> type == TT_NUMBER )
1104- {
1105- if ((token -> subtype & subtype ) != subtype )
1106- {
1107- if (subtype & TT_DECIMAL ) strcpy (str , "decimal" );
1108- if (subtype & TT_HEX ) strcpy (str , "hex" );
1109- if (subtype & TT_OCTAL ) strcpy (str , "octal" );
1110- if (subtype & TT_BINARY ) strcpy (str , "binary" );
1111- if (subtype & TT_LONG ) strcat (str , " long" );
1112- if (subtype & TT_UNSIGNED ) strcat (str , " unsigned" );
1113- if (subtype & TT_FLOAT ) strcat (str , " float" );
1114- if (subtype & TT_INTEGER ) strcat (str , " integer" );
1115- ScriptError (script , "expected %s, found %s" , str , token -> string );
1116- return 0 ;
1117- } //end if
1118- } //end if
1119- else if (token -> type == TT_PUNCTUATION )
1120- {
1121- if (subtype < 0 )
1122- {
1123- ScriptError (script , "BUG: wrong punctuation subtype" );
1124- return 0 ;
1125- } //end if
1126- if (token -> subtype != subtype )
1127- {
1128- ScriptError (script , "expected %s, found %s" ,
1129- script -> punctuations [subtype ], token -> string );
1130- return 0 ;
1131- } //end if
1132- } //end else if
1133- return 1 ;
1249+ char str [MAX_TOKEN ];
1250+
1251+ if (!PS_ReadToken (script , token ))
1252+ {
1253+ ScriptError (script , "couldn't read expected token" );
1254+ return 0 ;
1255+ } //end if
1256+
1257+ if (token -> type != type )
1258+ {
1259+ if (type == TT_STRING ) strcpy (str , "string" );
1260+ if (type == TT_LITERAL ) strcpy (str , "literal" );
1261+ if (type == TT_NUMBER ) strcpy (str , "number" );
1262+ if (type == TT_NAME ) strcpy (str , "name" );
1263+ if (type == TT_PUNCTUATION ) strcpy (str , "punctuation" );
1264+ ScriptError (script , "expected a %s, found %s" , str , token -> string );
1265+ return 0 ;
1266+ } //end if
1267+ if (token -> type == TT_NUMBER )
1268+ {
1269+ if ((token -> subtype & subtype ) != subtype )
1270+ {
1271+ if (subtype & TT_DECIMAL ) strcpy (str , "decimal" );
1272+ if (subtype & TT_HEX ) strcpy (str , "hex" );
1273+ if (subtype & TT_OCTAL ) strcpy (str , "octal" );
1274+ if (subtype & TT_BINARY ) strcpy (str , "binary" );
1275+ if (subtype & TT_LONG ) strcat (str , " long" );
1276+ if (subtype & TT_UNSIGNED ) strcat (str , " unsigned" );
1277+ if (subtype & TT_FLOAT ) strcat (str , " float" );
1278+ if (subtype & TT_INTEGER ) strcat (str , " integer" );
1279+ ScriptError (script , "expected %s, found %s" , str , token -> string );
1280+ return 0 ;
1281+ } //end if
1282+ } //end if
1283+ else if (token -> type == TT_PUNCTUATION )
1284+ {
1285+ if (subtype < 0 )
1286+ {
1287+ ScriptError (script , "BUG: wrong punctuation subtype" );
1288+ return 0 ;
1289+ } //end if
1290+ if (token -> subtype != subtype )
1291+ {
1292+ ScriptError (script , "expected %s, found %s" ,
1293+ script -> punctuations [subtype ], token -> string );
1294+ return 0 ;
1295+ } //end if
1296+ } //end else if
1297+ return 1 ;
11341298} //end of the function PS_ExpectTokenType
11351299//============================================================================
11361300//
@@ -1195,8 +1359,53 @@ int PS_CheckTokenType(pc_script_t *script, int type, int subtype, pc_token_t *to
11951359// Returns: -
11961360// Changes Globals: -
11971361//============================================================================
1198- int PS_SkipUntilString (pc_script_t * script , char * string )
1362+ int PS_SkipUntilString (pc_script_t * script , const char * string )
11991363{
1364+ if (script == NULL || string == NULL )
1365+ {
1366+ return 0 ;
1367+ }
1368+
1369+ if (script -> source != NULL )
1370+ {
1371+ pc_token_t token ;
1372+ while (PC_PeekToken (script -> source , & token ))
1373+ {
1374+ if (!strcmp (token .string , string ))
1375+ {
1376+ int result = PC_ExpectTokenString (script -> source , (char * )string );
1377+ PS_SyncDiagnosticsFromSource (script );
1378+ script -> lastline = script -> line ;
1379+ if (token .linescrossed > 0 )
1380+ {
1381+ script -> lastline = token .line - token .linescrossed ;
1382+ }
1383+ script -> line = token .line ;
1384+ memcpy (& script -> token , & token , sizeof (pc_token_t ));
1385+ script -> tokenavailable = 0 ;
1386+ return result != 0 ;
1387+ }
1388+
1389+ if (!PC_ExpectAnyToken (script -> source , & token ))
1390+ {
1391+ PS_SyncDiagnosticsFromSource (script );
1392+ return 0 ;
1393+ }
1394+
1395+ PS_SyncDiagnosticsFromSource (script );
1396+ script -> lastline = script -> line ;
1397+ if (token .linescrossed > 0 )
1398+ {
1399+ script -> lastline = token .line - token .linescrossed ;
1400+ }
1401+ script -> line = token .line ;
1402+ memcpy (& script -> token , & token , sizeof (pc_token_t ));
1403+ script -> tokenavailable = 0 ;
1404+ }
1405+ PS_SyncDiagnosticsFromSource (script );
1406+ return 0 ;
1407+ }
1408+
12001409 pc_token_t token ;
12011410
12021411 while (PS_ReadToken (script , & token ))
0 commit comments