- gsConfigScript = NULL;
- else
- gsConfigScript = value;
- } else {
- Log_Warning("Config", "Kernel config setting '%s' is not recognised", Arg);
- }
-
- }
-}
-
-/**
- * \fn void System_ExecuteScript()
- * \brief Reads and parses the boot configuration script
- */
-void System_ExecuteScript(void)
-{
- int fp;
- int fLen = 0;
- int i, j, k;
- int val;
- int result = 0;
- int variables[N_VARIABLES];
- int bReplaced[N_MAX_ARGS];
- char *fData;
- char *jmpTarget;
- tConfigFile *file;
- tConfigLine *line;
-
- // Open Script
- fp = VFS_Open(gsConfigScript, VFS_OPENFLAG_READ);
- if(fp == -1) {
- Log_Warning("Config", "Passed script '%s' does not exist", gsConfigScript);
- return;
- }
-
- // Get length
- VFS_Seek(fp, 0, SEEK_END);
- fLen = VFS_Tell(fp);
- Log_Debug("System", "VFS_Tell(%i) = %i", fp, fLen);
- VFS_Seek(fp, 0, SEEK_SET);
- // Read into memory buffer
- fData = malloc(fLen+1);
- VFS_Read(fp, fLen, fData);
- fData[fLen] = '\0';
- VFS_Close(fp);
-
-
- // Parse File
- file = System_Int_ParseFile(fData);
-
- // Parse each line
- for( i = 0; i < file->nLines; i++ )
- {
- line = &file->Lines[i];
- if( line->nParts == 0 ) continue; // Skip blank
-
- if(line->Parts[0][0] == ':') continue; // Ignore labels
-
- // Prescan and eliminate variables
- for( j = 1; j < line->nParts; j++ )
- {
- Log_Debug("Config", "Arg #%i is '%s'", j, line->Parts[j]);
- bReplaced[j] = 0;
- if( line->Parts[j][0] != '$' ) continue;
- if( line->Parts[j][1] == '?' ) {
- val = result;
- }
- else {
- val = atoi( &line->Parts[j][1] );
- if( val < 0 || val > N_VARIABLES ) continue;
- val = variables[ val ];
- }
- Log_Debug("Config", "Replaced arg %i ('%s') with 0x%x", j, line->Parts[j], val);
- line->Parts[j] = malloc( BITS/8+2+1 );
- sprintf(line->Parts[j], "0x%x", val);
- bReplaced[j] = 1;
- }
-
- // Find the command name
- for( j = 0; j < NUM_CONFIG_COMMANDS; j++ )
- {
- const char *args[N_MAX_ARGS];
-
- if(strcmp(line->Parts[0], caConfigCommands[j].Name) != 0) continue;
-
- Log_Debug("Config", "Command '%s', %i args passed", line->Parts[0], line->nParts-1);
-
- // Check against minimum argument count
- if( line->nParts - 1 < caConfigCommands[j].MinArgs ) {
- Log_Warning("Config",
- "Configuration command '%s' requires at least %i arguments, %i given",
- caConfigCommands[j].Name, caConfigCommands[j].MinArgs, line->nParts-1
- );
- break;
- }
-
- // Check for extra arguments
- if( line->nParts - 1 > caConfigCommands[j].MaxArgs ) {
- Log_Warning("Config",
- "Configuration command '%s' takes at most %i arguments, %i given",
- caConfigCommands[j].Name, caConfigCommands[j].MaxArgs, line->nParts-1
- );
- break;
- }
-
- // Fill in defaults
- for( k = caConfigCommands[j].MaxArgs-1; k > line->nParts - 1; k-- ) {
- args[k] = caConfigCommands[j].OptDefaults[k];
- }
-
- // Convert arguments to integers
- for( k = line->nParts-1; k--; )
- {
- if( k < 32 && (caConfigCommands[j].IntArgs & (1 << k)) ) {
- args[k] = (const char *)(Uint)atoi(line->Parts[k+1]);
- }
- else {
- args[k] = (char *)line->Parts[k+1];
- }
- Log_Debug("Config", "args[%i] = %p", k, args[k]);
- }
- switch( (enum eConfigCommands) caConfigCommands[j].Index )
- {
- case CC_LOADMODULE:
- result = Module_LoadFile( args[0], args[1] );
- break;
- case CC_SPAWN:
- result = Proc_Spawn( args[0] );
- break;
- case CC_MOUNT:
- result = VFS_Mount( args[0], args[1], args[2], args[3] );
- break;
- case CC_SYMLINK:
- result = VFS_Symlink( args[0], args[1] );
- break;
- case CC_OPEN:
- result = VFS_Open( args[0], (Uint)args[1] );
- break;
- case CC_CLOSE:
- VFS_Close( (Uint)args[0] );
- result = 0;
- break;
- case CC_MKDIR:
- result = VFS_MkDir( args[0] );
- break;
- case CC_IOCTL:
- result = VFS_IOCtl( (Uint)args[0], (Uint)args[1], (void *)args[2] );
- break;
- }
- Log_Debug("Config", "result = %i", result);
- break;
- }
- if( j < NUM_CONFIG_COMMANDS ) continue;
-
- // --- State and Variables ---
- if(strcmp(line->Parts[0], "set") == 0)
- {
- int to, value;
- if( line->nParts-1 != 2 ) {
- Log_Warning("Config", "Configuration command 'set' requires 2 arguments, %i given",
- line->nParts-1);
- continue;
- }
-
- to = atoi(line->Parts[1]);
- value = atoi(line->Parts[2]);
-
- variables[to] = value;
- result = value;
- }
- // if <val1> <op> <val2> <dest>
- else if(strcmp(line->Parts[0], "if") == 0)
- {
- if( line->nParts-1 != 4 ) {
- Log_Warning("Config", "Configuration command 'if' requires 4 arguments, %i given",
- line->nParts-1);
- }
-
- result = atoi(line->Parts[1]);
- val = atoi(line->Parts[3]);
-
- jmpTarget = line->Parts[4];
-
- Log_Log("Config", "IF 0x%x %s 0x%x THEN GOTO %s",
- result, line->Parts[2], val, jmpTarget);
-
- if( strcmp(line->Parts[2], "<" ) == 0 ) {
- if( result < val ) goto jumpToLabel;
- }
- else if( strcmp(line->Parts[2], "<=") == 0 ) {
- if( result <= val ) goto jumpToLabel;
- }
- else if( strcmp(line->Parts[2], ">" ) == 0 ) {
- if (result > val ) goto jumpToLabel;
- }
- else if( strcmp(line->Parts[2], ">=") == 0 ) {
- if( result >= val ) goto jumpToLabel;
- }
- else if( strcmp(line->Parts[2], "=") == 0 ) {
- if( result == val ) goto jumpToLabel;
- }
- else if( strcmp(line->Parts[2], "!=") == 0 ) {
- if( result != val ) goto jumpToLabel;
- }
- else {
- Log_Warning("Config", "Unknown comparision '%s' in `if`", line->Parts[2]);
- }
-
- }
- else if(strcmp(line->Parts[0], "goto") == 0) {
- if( line->nParts-1 != 1 ) {
- Log_Warning("Config", "Configuration command 'goto' requires 1 arguments, %i given",
- line->nParts-1);
- }
- jmpTarget = line->Parts[1];
-
- jumpToLabel:
- for( j = 0; j < file->nLines; j ++ )
- {
- if(file->Lines[j].nParts == 0)
- continue;
- if(file->Lines[j].Parts[0][0] != ':')
- continue;
- if( strcmp(file->Lines[j].Parts[0]+1, jmpTarget) == 0)
- break;
- }
- if( j == file->nLines )
- Log_Warning("Config", "Unable to find label '%s'", jmpTarget);