This commit is contained in:
dborth 2009-11-10 09:07:29 +00:00
parent 5ef584b880
commit 336d2c0758
9 changed files with 4541 additions and 4541 deletions

View File

@ -1,265 +1,265 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cross.cpp,v 1.7 2009/05/26 17:43:39 qbix79 Exp $ */
#include "dosbox.h"
#include "cross.h"
#include "support.h"
#include <string>
#include <stdlib.h>
#ifdef HW_RVL
#include "wiihardware.h"
#endif
#ifdef WIN32
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
#include <shlobj.h>
#endif
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
#include <sys/types.h>
#include <pwd.h>
#endif
#ifdef WIN32
static void W32_ConfDir(std::string& in,bool create) {
int c = create?1:0;
char result[MAX_PATH] = { 0 };
BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c);
if(!r || result[0] == 0) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c);
if(!r || result[0] == 0) {
char const * windir = getenv("windir");
if(!windir) windir = "c:\\windows";
safe_strncpy(result,windir,MAX_PATH);
char const* appdata = "\\Application Data";
size_t len = strlen(result);
if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata);
if(create) mkdir(result);
}
in = result;
}
#endif
void Cross::GetPlatformConfigDir(std::string& in) {
#ifdef WIN32
W32_ConfDir(in,false);
in += "\\DOSBox";
#elif defined(MACOSX)
in = "~/Library/Preferences";
ResolveHomedir(in);
#elif defined(HW_RVL)
in = "sd:/DOSBox";
#else
in = "~/.dosbox";
ResolveHomedir(in);
#endif
in += CROSS_FILESPLIT;
}
void Cross::GetPlatformConfigName(std::string& in) {
#ifdef WIN32
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
#elif defined(MACOSX)
#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences"
#elif defined(HW_RVL)
#define DEFAULT_CONFIG_FILE "dosbox.conf"
#else /*linux freebsd*/
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
#endif
in = DEFAULT_CONFIG_FILE;
}
void Cross::CreatePlatformConfigDir(std::string& in) {
#ifdef WIN32
W32_ConfDir(in,true);
in += "\\DOSBox";
mkdir(in.c_str());
#elif defined(MACOSX)
in = "~/Library/Preferences/";
ResolveHomedir(in);
//Don't create it. Assume it exists
#elif defined(HW_RVL)
in = "sd:/DOSBox";
CreateDir(in);
#else
in = "~/.dosbox";
ResolveHomedir(in);
mkdir(in.c_str(),0700);
#endif
in += CROSS_FILESPLIT;
}
void Cross::ResolveHomedir(std::string & temp_line) {
if(!temp_line.size() || temp_line[0] != '~') return; //No ~
if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant
char * home = getenv("HOME");
if(home) temp_line.replace(0,1,std::string(home));
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
} else { // The ~username variant
std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT);
if(namelen == std::string::npos) namelen = temp_line.size();
std::string username = temp_line.substr(1,namelen - 1);
struct passwd* pass = getpwnam(username.c_str());
if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~)
#endif // USERNAME lookup code
}
}
void Cross::CreateDir(std::string const& in) {
#ifdef WIN32
mkdir(in.c_str());
#else
mkdir(in.c_str(),0700);
#endif
}
#if defined (WIN32)
dir_information* open_directory(const char* dirname) {
if (dirname == NULL) return NULL;
size_t len = strlen(dirname);
if (len == 0) return NULL;
static dir_information dir;
safe_strncpy(dir.base_path,dirname,MAX_PATH);
if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*");
else strcat(dir.base_path,"\\*.*");
dir.handle = INVALID_HANDLE_VALUE;
return (access(dirname,0) ? NULL : &dir);
}
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
if (INVALID_HANDLE_VALUE == dirp->handle) {
return false;
}
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
else is_directory = false;
return true;
}
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
int result = FindNextFile(dirp->handle, &dirp->search_data);
if (result==0) return false;
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
else is_directory = false;
return true;
}
void close_directory(dir_information* dirp) {
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose(dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
}
}
#else
dir_information* open_directory(const char* dirname) {
static dir_information dir;
dir.dir=opendir(dirname);
safe_strncpy(dir.base_path,dirname,CROSS_LEN);
return dir.dir?&dir:NULL;
}
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
struct dirent* dentry = readdir(dirp->dir);
if (dentry==NULL) {
return false;
}
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
#ifdef DIRENT_HAS_D_TYPE
if(dentry->d_type == DT_DIR) {
is_directory = true;
return true;
} else if(dentry->d_type == DT_REG) {
is_directory = false;
return true;
}
#endif
// probably use d_type here instead of a full stat()
static char buffer[2*CROSS_LEN] = { 0 };
buffer[0] = 0;
strcpy(buffer,dirp->base_path);
strcat(buffer,entry_name);
struct stat status;
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
else is_directory = false;
return true;
}
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
struct dirent* dentry = readdir(dirp->dir);
if (dentry==NULL) {
return false;
}
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
#ifdef DIRENT_HAS_D_TYPE
if(dentry->d_type == DT_DIR) {
is_directory = true;
return true;
} else if(dentry->d_type == DT_REG) {
is_directory = false;
return true;
}
#endif
// probably use d_type here instead of a full stat()
static char buffer[2*CROSS_LEN] = { 0 };
buffer[0] = 0;
strcpy(buffer,dirp->base_path);
strcat(buffer,entry_name);
struct stat status;
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
else is_directory = false;
return true;
}
void close_directory(dir_information* dirp) {
closedir(dirp->dir);
}
#endif
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cross.cpp,v 1.7 2009-05-26 17:43:39 qbix79 Exp $ */
#include "dosbox.h"
#include "cross.h"
#include "support.h"
#include <string>
#include <stdlib.h>
#ifdef HW_RVL
#include "wiihardware.h"
#endif
#ifdef WIN32
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
#include <shlobj.h>
#endif
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
#include <sys/types.h>
#include <pwd.h>
#endif
#ifdef WIN32
static void W32_ConfDir(std::string& in,bool create) {
int c = create?1:0;
char result[MAX_PATH] = { 0 };
BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c);
if(!r || result[0] == 0) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c);
if(!r || result[0] == 0) {
char const * windir = getenv("windir");
if(!windir) windir = "c:\\windows";
safe_strncpy(result,windir,MAX_PATH);
char const* appdata = "\\Application Data";
size_t len = strlen(result);
if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata);
if(create) mkdir(result);
}
in = result;
}
#endif
void Cross::GetPlatformConfigDir(std::string& in) {
#ifdef WIN32
W32_ConfDir(in,false);
in += "\\DOSBox";
#elif defined(MACOSX)
in = "~/Library/Preferences";
ResolveHomedir(in);
#elif defined(HW_RVL)
in = "sd:/DOSBox";
#else
in = "~/.dosbox";
ResolveHomedir(in);
#endif
in += CROSS_FILESPLIT;
}
void Cross::GetPlatformConfigName(std::string& in) {
#ifdef WIN32
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
#elif defined(MACOSX)
#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences"
#elif defined(HW_RVL)
#define DEFAULT_CONFIG_FILE "dosbox.conf"
#else /*linux freebsd*/
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
#endif
in = DEFAULT_CONFIG_FILE;
}
void Cross::CreatePlatformConfigDir(std::string& in) {
#ifdef WIN32
W32_ConfDir(in,true);
in += "\\DOSBox";
mkdir(in.c_str());
#elif defined(MACOSX)
in = "~/Library/Preferences/";
ResolveHomedir(in);
//Don't create it. Assume it exists
#elif defined(HW_RVL)
in = "sd:/DOSBox";
CreateDir(in);
#else
in = "~/.dosbox";
ResolveHomedir(in);
mkdir(in.c_str(),0700);
#endif
in += CROSS_FILESPLIT;
}
void Cross::ResolveHomedir(std::string & temp_line) {
if(!temp_line.size() || temp_line[0] != '~') return; //No ~
if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant
char * home = getenv("HOME");
if(home) temp_line.replace(0,1,std::string(home));
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
} else { // The ~username variant
std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT);
if(namelen == std::string::npos) namelen = temp_line.size();
std::string username = temp_line.substr(1,namelen - 1);
struct passwd* pass = getpwnam(username.c_str());
if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~)
#endif // USERNAME lookup code
}
}
void Cross::CreateDir(std::string const& in) {
#ifdef WIN32
mkdir(in.c_str());
#else
mkdir(in.c_str(),0700);
#endif
}
#if defined (WIN32)
dir_information* open_directory(const char* dirname) {
if (dirname == NULL) return NULL;
size_t len = strlen(dirname);
if (len == 0) return NULL;
static dir_information dir;
safe_strncpy(dir.base_path,dirname,MAX_PATH);
if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*");
else strcat(dir.base_path,"\\*.*");
dir.handle = INVALID_HANDLE_VALUE;
return (access(dirname,0) ? NULL : &dir);
}
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
if (INVALID_HANDLE_VALUE == dirp->handle) {
return false;
}
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
else is_directory = false;
return true;
}
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
int result = FindNextFile(dirp->handle, &dirp->search_data);
if (result==0) return false;
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
else is_directory = false;
return true;
}
void close_directory(dir_information* dirp) {
if (dirp->handle != INVALID_HANDLE_VALUE) {
FindClose(dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE;
}
}
#else
dir_information* open_directory(const char* dirname) {
static dir_information dir;
dir.dir=opendir(dirname);
safe_strncpy(dir.base_path,dirname,CROSS_LEN);
return dir.dir?&dir:NULL;
}
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
struct dirent* dentry = readdir(dirp->dir);
if (dentry==NULL) {
return false;
}
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
#ifdef DIRENT_HAS_D_TYPE
if(dentry->d_type == DT_DIR) {
is_directory = true;
return true;
} else if(dentry->d_type == DT_REG) {
is_directory = false;
return true;
}
#endif
// probably use d_type here instead of a full stat()
static char buffer[2*CROSS_LEN] = { 0 };
buffer[0] = 0;
strcpy(buffer,dirp->base_path);
strcat(buffer,entry_name);
struct stat status;
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
else is_directory = false;
return true;
}
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
struct dirent* dentry = readdir(dirp->dir);
if (dentry==NULL) {
return false;
}
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
#ifdef DIRENT_HAS_D_TYPE
if(dentry->d_type == DT_DIR) {
is_directory = true;
return true;
} else if(dentry->d_type == DT_REG) {
is_directory = false;
return true;
}
#endif
// probably use d_type here instead of a full stat()
static char buffer[2*CROSS_LEN] = { 0 };
buffer[0] = 0;
strcpy(buffer,dirp->base_path);
strcat(buffer,entry_name);
struct stat status;
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
else is_directory = false;
return true;
}
void close_directory(dir_information* dirp) {
closedir(dirp->dir);
}
#endif

View File

@ -1,144 +1,144 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: messages.cpp,v 1.23 2009/06/17 08:52:35 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosbox.h"
#include "cross.h"
#include "support.h"
#include "setup.h"
#include "control.h"
#include <list>
#include <string>
using namespace std;
#define LINE_IN_MAXLEN 2048
struct MessageBlock {
string name;
string val;
MessageBlock(const char* _name, const char* _val):
name(_name),val(_val){}
};
static list<MessageBlock> Lang;
typedef list<MessageBlock>::iterator itmb;
void MSG_Add(const char * _name, const char* _val) {
/* Find the message */
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
if((*tel).name==_name) {
// LOG_MSG("double entry for %s",_name); //Message file might be loaded before default text messages
return;
}
}
/* if the message doesn't exist add it */
Lang.push_back(MessageBlock(_name,_val));
}
void MSG_Replace(const char * _name, const char* _val) {
/* Find the message */
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
if((*tel).name==_name) {
Lang.erase(tel);
break;
}
}
/* Even if the message doesn't exist add it */
Lang.push_back(MessageBlock(_name,_val));
}
static void LoadMessageFile(const char * fname) {
if (!fname) return;
if(*fname=='\0') return;//empty string=no languagefile
FILE * mfile=fopen(fname,"rt");
/* This should never happen and since other modules depend on this use a normal printf */
if (!mfile) {
E_Exit("MSG:Can't load messages: %s",fname);
}
char linein[LINE_IN_MAXLEN];
char name[LINE_IN_MAXLEN];
char string[LINE_IN_MAXLEN*10];
/* Start out with empty strings */
name[0]=0;string[0]=0;
while(fgets(linein, LINE_IN_MAXLEN, mfile)!=0) {
/* Parse the read line */
/* First remove characters 10 and 13 from the line */
char * parser=linein;
char * writer=linein;
while (*parser) {
if (*parser!=10 && *parser!=13) {
*writer++=*parser;
}
*parser++;
}
*writer=0;
/* New string name */
if (linein[0]==':') {
string[0]=0;
strcpy(name,linein+1);
/* End of string marker */
} else if (linein[0]=='.') {
/* Replace/Add the string to the internal langaugefile */
/* Remove last newline (marker is \n.\n) */
size_t ll = strlen(string);
if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe.
MSG_Replace(name,string);
} else {
/* Normal string to be added */
strcat(string,linein);
strcat(string,"\n");
}
}
fclose(mfile);
}
const char * MSG_Get(char const * msg) {
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
if((*tel).name==msg)
{
return (*tel).val.c_str();
}
}
return "Message not Found!\n";
}
void MSG_Write(const char * location) {
FILE* out=fopen(location,"w+t");
if(out==NULL) return;//maybe an error?
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str());
}
fclose(out);
}
void MSG_Init(Section_prop * section) {
std::string file_name;
if (control->cmdline->FindString("-lang",file_name,true)) {
LoadMessageFile(file_name.c_str());
} else {
Prop_path* pathprop = section->Get_path("language");
if(pathprop) LoadMessageFile(pathprop->realpath.c_str());
}
}
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: messages.cpp,v 1.23 2009-06-17 08:52:35 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dosbox.h"
#include "cross.h"
#include "support.h"
#include "setup.h"
#include "control.h"
#include <list>
#include <string>
using namespace std;
#define LINE_IN_MAXLEN 2048
struct MessageBlock {
string name;
string val;
MessageBlock(const char* _name, const char* _val):
name(_name),val(_val){}
};
static list<MessageBlock> Lang;
typedef list<MessageBlock>::iterator itmb;
void MSG_Add(const char * _name, const char* _val) {
/* Find the message */
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
if((*tel).name==_name) {
// LOG_MSG("double entry for %s",_name); //Message file might be loaded before default text messages
return;
}
}
/* if the message doesn't exist add it */
Lang.push_back(MessageBlock(_name,_val));
}
void MSG_Replace(const char * _name, const char* _val) {
/* Find the message */
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
if((*tel).name==_name) {
Lang.erase(tel);
break;
}
}
/* Even if the message doesn't exist add it */
Lang.push_back(MessageBlock(_name,_val));
}
static void LoadMessageFile(const char * fname) {
if (!fname) return;
if(*fname=='\0') return;//empty string=no languagefile
FILE * mfile=fopen(fname,"rt");
/* This should never happen and since other modules depend on this use a normal printf */
if (!mfile) {
E_Exit("MSG:Can't load messages: %s",fname);
}
char linein[LINE_IN_MAXLEN];
char name[LINE_IN_MAXLEN];
char string[LINE_IN_MAXLEN*10];
/* Start out with empty strings */
name[0]=0;string[0]=0;
while(fgets(linein, LINE_IN_MAXLEN, mfile)!=0) {
/* Parse the read line */
/* First remove characters 10 and 13 from the line */
char * parser=linein;
char * writer=linein;
while (*parser) {
if (*parser!=10 && *parser!=13) {
*writer++=*parser;
}
*parser++;
}
*writer=0;
/* New string name */
if (linein[0]==':') {
string[0]=0;
strcpy(name,linein+1);
/* End of string marker */
} else if (linein[0]=='.') {
/* Replace/Add the string to the internal langaugefile */
/* Remove last newline (marker is \n.\n) */
size_t ll = strlen(string);
if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe.
MSG_Replace(name,string);
} else {
/* Normal string to be added */
strcat(string,linein);
strcat(string,"\n");
}
}
fclose(mfile);
}
const char * MSG_Get(char const * msg) {
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
if((*tel).name==msg)
{
return (*tel).val.c_str();
}
}
return "Message not Found!\n";
}
void MSG_Write(const char * location) {
FILE* out=fopen(location,"w+t");
if(out==NULL) return;//maybe an error?
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str());
}
fclose(out);
}
void MSG_Init(Section_prop * section) {
std::string file_name;
if (control->cmdline->FindString("-lang",file_name,true)) {
LoadMessageFile(file_name.c_str());
} else {
Prop_path* pathprop = section->Get_path("language");
if(pathprop) LoadMessageFile(pathprop->realpath.c_str());
}
}

View File

@ -1,392 +1,392 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: programs.cpp,v 1.37 2009/05/27 09:15:42 qbix79 Exp $ */
#include <vector>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "programs.h"
#include "callback.h"
#include "regs.h"
#include "support.h"
#include "cross.h"
#include "control.h"
#include "shell.h"
Bitu call_program;
/* This registers a file on the virtual drive and creates the correct structure for it*/
static Bit8u exe_block[]={
0xbc,0x00,0x04, //MOV SP,0x400 decrease stack size
0xbb,0x40,0x00, //MOV BX,0x040 for memory resize
0xb4,0x4a, //MOV AH,0x4A Resize memory block
0xcd,0x21, //INT 0x21
//pos 12 is callback number
0xFE,0x38,0x00,0x00, //CALLBack number
0xb8,0x00,0x4c, //Mov ax,4c00
0xcd,0x21, //INT 0x21
};
#define CB_POS 12
static std::vector<PROGRAMS_Main*> internal_progs;
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) {
Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK
memcpy(comdata,&exe_block,sizeof(exe_block));
comdata[CB_POS]=(Bit8u)(call_program&0xff);
comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff);
/* Copy save the pointer in the vector and save it's index */
if (internal_progs.size()>255) E_Exit("PROGRAMS_MakeFile program size too large (%d)",static_cast<int>(internal_progs.size()));
Bit8u index = (Bit8u)internal_progs.size();
internal_progs.push_back(main);
memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index));
Bit32u size=sizeof(exe_block)+sizeof(index);
VFILE_Register(name,comdata,size);
}
static Bitu PROGRAMS_Handler(void) {
/* This sets up everything for a program start up call */
Bitu size=sizeof(Bit8u);
Bit8u index;
/* Read the index from program code in memory */
PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block));
HostPt writer=(HostPt)&index;
for (;size>0;size--) *writer++=mem_readb(reader++);
Program * new_program;
if(index > internal_progs.size()) E_Exit("something is messing with the memory");
PROGRAMS_Main * handler = internal_progs[index];
(*handler)(&new_program);
new_program->Run();
delete new_program;
return CBRET_NONE;
}
/* Main functions used in all program */
Program::Program() {
/* Find the command line and setup the PSP */
psp = new DOS_PSP(dos.psp());
/* Scan environment for filename */
PhysPt envscan=PhysMake(psp->GetEnvironment(),0);
while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1;
envscan+=3;
CommandTail tail;
MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
if (tail.count<127) tail.buffer[tail.count]=0;
else tail.buffer[126]=0;
char filename[256+1];
MEM_StrCopy(envscan,filename,256);
cmd = new CommandLine(filename,tail.buffer);
}
extern std::string full_arguments;
void Program::ChangeToLongCmd() {
/*
* Get arguments directly from the shell instead of the psp.
* this is done in securemode: (as then the arguments to mount and friends
* can only be given on the shell ( so no int 21 4b)
* Securemode part is disabled as each of the internal command has already
* protection for it. (and it breaks games like cdman)
* it is also done for long arguments to as it is convient (as the total commandline can be longer then 127 characters.
* imgmount with lot's of parameters
* Length of arguments can be ~120. but switch when above 100 to be sure
*/
if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) {
CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str());
delete cmd;
cmd = temp;
}
full_arguments.assign(""); //Clear so it gets even more save
}
void Program::WriteOut(const char * format,...) {
char buf[2048];
va_list msg;
va_start(msg,format);
vsnprintf(buf,2047,format,msg);
va_end(msg);
Bit16u size = (Bit16u)strlen(buf);
DOS_WriteFile(STDOUT,(Bit8u *)buf,&size);
}
void Program::WriteOut_NoParsing(const char * format) {
Bit16u size = (Bit16u)strlen(format);
DOS_WriteFile(STDOUT,(Bit8u *)format,&size);
}
bool Program::GetEnvStr(const char * entry,std::string & result) {
/* Walk through the internal environment and see for a match */
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
char env_string[1024+1];
result.erase();
if (!entry[0]) return false;
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) return false;
env_read += (PhysPt)(strlen(env_string)+1);
char* equal = strchr(env_string,'=');
if (!equal) continue;
/* replace the = with \0 to get the length */
*equal = 0;
if (strlen(env_string) != strlen(entry)) continue;
if (strcasecmp(entry,env_string)!=0) continue;
/* restore the = to get the original result */
*equal = '=';
result = env_string;
return true;
} while (1);
return false;
}
bool Program::GetEnvNum(Bitu num,std::string & result) {
char env_string[1024+1];
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) break;
if (!num) { result=env_string;return true;}
env_read += (PhysPt)(strlen(env_string)+1);
num--;
} while (1);
return false;
}
Bitu Program::GetEnvCount(void) {
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
Bitu num=0;
while (mem_readb(env_read)!=0) {
for (;mem_readb(env_read);env_read++) {};
env_read++;
num++;
}
return num;
}
bool Program::SetEnv(const char * entry,const char * new_string) {
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
PhysPt env_write=env_read;
char env_string[1024+1];
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) break;
env_read += (PhysPt)(strlen(env_string)+1);
if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */
if ((strncasecmp(entry,env_string,strlen(entry))==0) &&
env_string[strlen(entry)]=='=') continue;
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
env_write += (PhysPt)(strlen(env_string)+1);
} while (1);
/* TODO Maybe save the program name sometime. not really needed though */
/* Save the new entry */
if (new_string[0]) {
std::string bigentry(entry);
for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it);
sprintf(env_string,"%s=%s",bigentry.c_str(),new_string);
// sprintf(env_string,"%s=%s",entry,new_string); //oldcode
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
env_write += (PhysPt)(strlen(env_string)+1);
}
/* Clear out the final piece of the environment */
mem_writed(env_write,0);
return true;
}
class CONFIG : public Program {
public:
void Run(void);
};
void MSG_Write(const char *);
void CONFIG::Run(void) {
FILE * f;
if (cmd->FindString("-writeconf",temp_line,true)
|| cmd->FindString("-wc",temp_line,true)) {
/* In secure mode don't allow a new configfile to be created */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
return;
}
f=fopen(temp_line.c_str(),"wb+");
if (!f) {
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
return;
}
fclose(f);
control->PrintConfig(temp_line.c_str());
return;
}
if (cmd->FindString("-writelang",temp_line,true)
||cmd->FindString("-wl",temp_line,true)) {
/* In secure mode don't allow a new languagefile to be created
* Who knows which kind of file we would overwriting. */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
return;
}
f=fopen(temp_line.c_str(),"wb+");
if (!f) {
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
return;
}
fclose(f);
MSG_Write(temp_line.c_str());
return;
}
/* Code for switching to secure mode */
if(cmd->FindExist("-securemode",true)) {
control->SwitchToSecureMode();
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON"));
return;
}
/* Code for getting the current configuration. *
* Official format: config -get "section property" *
* As a bonus it will set %CONFIG% to this value as well */
if(cmd->FindString("-get",temp_line,true)) {
std::string temp2 = "";
cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes
if(temp2 != "") temp_line = temp_line + " " + temp2;
std::string::size_type space = temp_line.find(" ");
if(space == std::string::npos) {
WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX"));
return;
}
//Copy the found property to a new string and erase from templine (mind the space)
std::string prop = temp_line.substr(space+1); temp_line.erase(space);
Section* sec = control->GetSection(temp_line.c_str());
if(!sec) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str());
return;
}
std::string val = sec->GetPropValue(prop.c_str());
if(val == NO_SUCH_PROPERTY) {
WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str());
return;
}
WriteOut("%s",val.c_str());
first_shell->SetEnv("CONFIG",val.c_str());
return;
}
/* Code for the configuration changes *
* Official format: config -set "section property=value" *
* Accepted: without quotes and/or without -set and/or without section *
* and/or the "=" replaced by a " " */
if (cmd->FindString("-set",temp_line,true)) { //get all arguments
std::string temp2 = "";
cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes
if(temp2!="") temp_line = temp_line + " " + temp2;
} else if(!cmd->GetStringRemain(temp_line)) {//no set
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified
return;
};
//Wanted input: n1 n2=n3
char copy[1024];
strcpy(copy,temp_line.c_str());
//seperate section from property
const char* temp = strchr(copy,' ');
if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0;
else {
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE"));
return;
}
//if n1 n2 n3 then replace last space with =
const char* sign = strchr(temp,'=');
if(!sign) {
sign = strchr(temp,' ');
if(sign) {
copy[sign - copy] = '=';
} else {
//2 items specified (no space nor = between n2 and n3
//assume that they posted: property value
//Try to determine the section.
Section* sec=control->GetSectionFromProperty(copy);
if(!sec){
if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore
WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy);
return;
} //Hack to allow config ems true
char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp);
sign = strchr(buffer,' ');
if(sign) buffer[sign - buffer] = '=';
strcpy(copy,sec->GetName());
temp = buffer;
}
}
/* Input processed. Now the real job starts
* copy contains the likely "sectionname"
* temp contains "property=value"
* the section is destroyed and a new input line is given to
* the configuration parser. Then the section is restarted.
*/
char* inputline = const_cast<char*>(temp);
Section* sec = 0;
sec = control->GetSection(copy);
if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;}
sec->ExecuteDestroy(false);
sec->HandleInputline(inputline);
sec->ExecuteInit(false);
return;
}
static void CONFIG_ProgramStart(Program * * make) {
*make=new CONFIG;
}
void PROGRAMS_Init(Section* /*sec*/) {
/* Setup a special callback to start virtual programs */
call_program=CALLBACK_Allocate();
CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program");
PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart);
MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n");
MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n");
MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n");
MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n");
MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n");
MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n");
MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n");
MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n");
}
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: programs.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */
#include <vector>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "programs.h"
#include "callback.h"
#include "regs.h"
#include "support.h"
#include "cross.h"
#include "control.h"
#include "shell.h"
Bitu call_program;
/* This registers a file on the virtual drive and creates the correct structure for it*/
static Bit8u exe_block[]={
0xbc,0x00,0x04, //MOV SP,0x400 decrease stack size
0xbb,0x40,0x00, //MOV BX,0x040 for memory resize
0xb4,0x4a, //MOV AH,0x4A Resize memory block
0xcd,0x21, //INT 0x21
//pos 12 is callback number
0xFE,0x38,0x00,0x00, //CALLBack number
0xb8,0x00,0x4c, //Mov ax,4c00
0xcd,0x21, //INT 0x21
};
#define CB_POS 12
static std::vector<PROGRAMS_Main*> internal_progs;
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) {
Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK
memcpy(comdata,&exe_block,sizeof(exe_block));
comdata[CB_POS]=(Bit8u)(call_program&0xff);
comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff);
/* Copy save the pointer in the vector and save it's index */
if (internal_progs.size()>255) E_Exit("PROGRAMS_MakeFile program size too large (%d)",static_cast<int>(internal_progs.size()));
Bit8u index = (Bit8u)internal_progs.size();
internal_progs.push_back(main);
memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index));
Bit32u size=sizeof(exe_block)+sizeof(index);
VFILE_Register(name,comdata,size);
}
static Bitu PROGRAMS_Handler(void) {
/* This sets up everything for a program start up call */
Bitu size=sizeof(Bit8u);
Bit8u index;
/* Read the index from program code in memory */
PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block));
HostPt writer=(HostPt)&index;
for (;size>0;size--) *writer++=mem_readb(reader++);
Program * new_program;
if(index > internal_progs.size()) E_Exit("something is messing with the memory");
PROGRAMS_Main * handler = internal_progs[index];
(*handler)(&new_program);
new_program->Run();
delete new_program;
return CBRET_NONE;
}
/* Main functions used in all program */
Program::Program() {
/* Find the command line and setup the PSP */
psp = new DOS_PSP(dos.psp());
/* Scan environment for filename */
PhysPt envscan=PhysMake(psp->GetEnvironment(),0);
while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1;
envscan+=3;
CommandTail tail;
MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
if (tail.count<127) tail.buffer[tail.count]=0;
else tail.buffer[126]=0;
char filename[256+1];
MEM_StrCopy(envscan,filename,256);
cmd = new CommandLine(filename,tail.buffer);
}
extern std::string full_arguments;
void Program::ChangeToLongCmd() {
/*
* Get arguments directly from the shell instead of the psp.
* this is done in securemode: (as then the arguments to mount and friends
* can only be given on the shell ( so no int 21 4b)
* Securemode part is disabled as each of the internal command has already
* protection for it. (and it breaks games like cdman)
* it is also done for long arguments to as it is convient (as the total commandline can be longer then 127 characters.
* imgmount with lot's of parameters
* Length of arguments can be ~120. but switch when above 100 to be sure
*/
if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) {
CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str());
delete cmd;
cmd = temp;
}
full_arguments.assign(""); //Clear so it gets even more save
}
void Program::WriteOut(const char * format,...) {
char buf[2048];
va_list msg;
va_start(msg,format);
vsnprintf(buf,2047,format,msg);
va_end(msg);
Bit16u size = (Bit16u)strlen(buf);
DOS_WriteFile(STDOUT,(Bit8u *)buf,&size);
}
void Program::WriteOut_NoParsing(const char * format) {
Bit16u size = (Bit16u)strlen(format);
DOS_WriteFile(STDOUT,(Bit8u *)format,&size);
}
bool Program::GetEnvStr(const char * entry,std::string & result) {
/* Walk through the internal environment and see for a match */
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
char env_string[1024+1];
result.erase();
if (!entry[0]) return false;
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) return false;
env_read += (PhysPt)(strlen(env_string)+1);
char* equal = strchr(env_string,'=');
if (!equal) continue;
/* replace the = with \0 to get the length */
*equal = 0;
if (strlen(env_string) != strlen(entry)) continue;
if (strcasecmp(entry,env_string)!=0) continue;
/* restore the = to get the original result */
*equal = '=';
result = env_string;
return true;
} while (1);
return false;
}
bool Program::GetEnvNum(Bitu num,std::string & result) {
char env_string[1024+1];
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) break;
if (!num) { result=env_string;return true;}
env_read += (PhysPt)(strlen(env_string)+1);
num--;
} while (1);
return false;
}
Bitu Program::GetEnvCount(void) {
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
Bitu num=0;
while (mem_readb(env_read)!=0) {
for (;mem_readb(env_read);env_read++) {};
env_read++;
num++;
}
return num;
}
bool Program::SetEnv(const char * entry,const char * new_string) {
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
PhysPt env_write=env_read;
char env_string[1024+1];
do {
MEM_StrCopy(env_read,env_string,1024);
if (!env_string[0]) break;
env_read += (PhysPt)(strlen(env_string)+1);
if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */
if ((strncasecmp(entry,env_string,strlen(entry))==0) &&
env_string[strlen(entry)]=='=') continue;
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
env_write += (PhysPt)(strlen(env_string)+1);
} while (1);
/* TODO Maybe save the program name sometime. not really needed though */
/* Save the new entry */
if (new_string[0]) {
std::string bigentry(entry);
for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it);
sprintf(env_string,"%s=%s",bigentry.c_str(),new_string);
// sprintf(env_string,"%s=%s",entry,new_string); //oldcode
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
env_write += (PhysPt)(strlen(env_string)+1);
}
/* Clear out the final piece of the environment */
mem_writed(env_write,0);
return true;
}
class CONFIG : public Program {
public:
void Run(void);
};
void MSG_Write(const char *);
void CONFIG::Run(void) {
FILE * f;
if (cmd->FindString("-writeconf",temp_line,true)
|| cmd->FindString("-wc",temp_line,true)) {
/* In secure mode don't allow a new configfile to be created */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
return;
}
f=fopen(temp_line.c_str(),"wb+");
if (!f) {
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
return;
}
fclose(f);
control->PrintConfig(temp_line.c_str());
return;
}
if (cmd->FindString("-writelang",temp_line,true)
||cmd->FindString("-wl",temp_line,true)) {
/* In secure mode don't allow a new languagefile to be created
* Who knows which kind of file we would overwriting. */
if(control->SecureMode()) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
return;
}
f=fopen(temp_line.c_str(),"wb+");
if (!f) {
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
return;
}
fclose(f);
MSG_Write(temp_line.c_str());
return;
}
/* Code for switching to secure mode */
if(cmd->FindExist("-securemode",true)) {
control->SwitchToSecureMode();
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON"));
return;
}
/* Code for getting the current configuration. *
* Official format: config -get "section property" *
* As a bonus it will set %CONFIG% to this value as well */
if(cmd->FindString("-get",temp_line,true)) {
std::string temp2 = "";
cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes
if(temp2 != "") temp_line = temp_line + " " + temp2;
std::string::size_type space = temp_line.find(" ");
if(space == std::string::npos) {
WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX"));
return;
}
//Copy the found property to a new string and erase from templine (mind the space)
std::string prop = temp_line.substr(space+1); temp_line.erase(space);
Section* sec = control->GetSection(temp_line.c_str());
if(!sec) {
WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str());
return;
}
std::string val = sec->GetPropValue(prop.c_str());
if(val == NO_SUCH_PROPERTY) {
WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str());
return;
}
WriteOut("%s",val.c_str());
first_shell->SetEnv("CONFIG",val.c_str());
return;
}
/* Code for the configuration changes *
* Official format: config -set "section property=value" *
* Accepted: without quotes and/or without -set and/or without section *
* and/or the "=" replaced by a " " */
if (cmd->FindString("-set",temp_line,true)) { //get all arguments
std::string temp2 = "";
cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes
if(temp2!="") temp_line = temp_line + " " + temp2;
} else if(!cmd->GetStringRemain(temp_line)) {//no set
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified
return;
};
//Wanted input: n1 n2=n3
char copy[1024];
strcpy(copy,temp_line.c_str());
//seperate section from property
const char* temp = strchr(copy,' ');
if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0;
else {
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE"));
return;
}
//if n1 n2 n3 then replace last space with =
const char* sign = strchr(temp,'=');
if(!sign) {
sign = strchr(temp,' ');
if(sign) {
copy[sign - copy] = '=';
} else {
//2 items specified (no space nor = between n2 and n3
//assume that they posted: property value
//Try to determine the section.
Section* sec=control->GetSectionFromProperty(copy);
if(!sec){
if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore
WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy);
return;
} //Hack to allow config ems true
char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp);
sign = strchr(buffer,' ');
if(sign) buffer[sign - buffer] = '=';
strcpy(copy,sec->GetName());
temp = buffer;
}
}
/* Input processed. Now the real job starts
* copy contains the likely "sectionname"
* temp contains "property=value"
* the section is destroyed and a new input line is given to
* the configuration parser. Then the section is restarted.
*/
char* inputline = const_cast<char*>(temp);
Section* sec = 0;
sec = control->GetSection(copy);
if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;}
sec->ExecuteDestroy(false);
sec->HandleInputline(inputline);
sec->ExecuteInit(false);
return;
}
static void CONFIG_ProgramStart(Program * * make) {
*make=new CONFIG;
}
void PROGRAMS_Init(Section* /*sec*/) {
/* Setup a special callback to start virtual programs */
call_program=CALLBACK_Allocate();
CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program");
PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart);
MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n");
MSG_Add("PROGRAM_CONFIG_USAGE","Config tool:\nUse -writeconf filename to write the current config.\nUse -writelang filename to write the current language strings.\n");
MSG_Add("PROGRAM_CONFIG_SECURE_ON","Switched to secure mode.\n");
MSG_Add("PROGRAM_CONFIG_SECURE_DISALLOW","This operation is not permitted in secure mode.\n");
MSG_Add("PROGRAM_CONFIG_SECTION_ERROR","Section %s doesn't exist.\n");
MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\n");
MSG_Add("PROGRAM_CONFIG_NO_PROPERTY","There is no property %s in section %s.\n");
MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +1,185 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: support.cpp,v 1.37 2009/05/27 09:15:42 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include <string>
#include "dosbox.h"
#include "debug.h"
#include "support.h"
#include "video.h"
void upcase(std::string &str) {
int (*tf)(int) = std::toupper;
std::transform(str.begin(), str.end(), str.begin(), tf);
}
void lowcase(std::string &str) {
int (*tf)(int) = std::tolower;
std::transform(str.begin(), str.end(), str.begin(), tf);
}
/*
Ripped some source from freedos for this one.
*/
/*
* replaces all instances of character o with character c
*/
void strreplace(char * str,char o,char n) {
while (*str) {
if (*str==o) *str=n;
str++;
}
}
char *ltrim(char *str) {
while (*str && isspace(*reinterpret_cast<unsigned char*>(str))) str++;
return str;
}
char *rtrim(char *str) {
char *p;
p = strchr(str, '\0');
while (--p >= str && isspace(*reinterpret_cast<unsigned char*>(p))) {};
p[1] = '\0';
return str;
}
char *trim(char *str) {
return ltrim(rtrim(str));
}
char * upcase(char * str) {
for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast<unsigned char*>(idx));
return str;
}
char * lowcase(char * str) {
for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast<unsigned char*>(idx));
return str;
}
bool ScanCMDBool(char * cmd,char const * const check) {
char * scan=cmd;size_t c_len=strlen(check);
while ((scan=strchr(scan,'/'))) {
/* found a / now see behind it */
scan++;
if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]=='/' || scan[c_len]==0)) {
/* Found a math now remove it from the string */
memmove(scan-1,scan+c_len,strlen(scan+c_len)+1);
trim(scan-1);
return true;
}
}
return false;
}
/* This scans the command line for a remaining switch and reports it else returns 0*/
char * ScanCMDRemain(char * cmd) {
char * scan,*found;;
if ((scan=found=strchr(cmd,'/'))) {
while ( *scan && !isspace(*reinterpret_cast<unsigned char*>(scan)) ) scan++;
*scan=0;
return found;
} else return 0;
}
char * StripWord(char *&line) {
char * scan=line;
scan=ltrim(scan);
if (*scan=='"') {
char * end_quote=strchr(scan+1,'"');
if (end_quote) {
*end_quote=0;
line=ltrim(++end_quote);
return (scan+1);
}
}
char * begin=scan;
for (char c = *scan ;(c = *scan);scan++) {
if (isspace(*reinterpret_cast<unsigned char*>(&c))) {
*scan++=0;
break;
}
}
line=scan;
return begin;
}
Bits ConvDecWord(char * word) {
bool negative=false;Bitu ret=0;
if (*word=='-') {
negative=true;
word++;
}
while (char c=*word) {
ret*=10;
ret+=c-'0';
word++;
}
if (negative) return 0-ret;
else return ret;
}
Bits ConvHexWord(char * word) {
Bitu ret=0;
while (char c=toupper(*reinterpret_cast<unsigned char*>(word))) {
ret*=16;
if (c>='0' && c<='9') ret+=c-'0';
else if (c>='A' && c<='F') ret+=10+(c-'A');
word++;
}
return ret;
}
double ConvDblWord(char * word) {
return 0.0f;
}
static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95)
void E_Exit(const char * format,...) {
#if C_DEBUG && C_HEAVY_DEBUG
DEBUG_HeavyWriteLogInstruction();
#endif
va_list msg;
va_start(msg,format);
vsprintf(buf,format,msg);
va_end(msg);
strcat(buf,"\n");
throw(buf);
}
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: support.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <cctype>
#include <string>
#include "dosbox.h"
#include "debug.h"
#include "support.h"
#include "video.h"
void upcase(std::string &str) {
int (*tf)(int) = std::toupper;
std::transform(str.begin(), str.end(), str.begin(), tf);
}
void lowcase(std::string &str) {
int (*tf)(int) = std::tolower;
std::transform(str.begin(), str.end(), str.begin(), tf);
}
/*
Ripped some source from freedos for this one.
*/
/*
* replaces all instances of character o with character c
*/
void strreplace(char * str,char o,char n) {
while (*str) {
if (*str==o) *str=n;
str++;
}
}
char *ltrim(char *str) {
while (*str && isspace(*reinterpret_cast<unsigned char*>(str))) str++;
return str;
}
char *rtrim(char *str) {
char *p;
p = strchr(str, '\0');
while (--p >= str && isspace(*reinterpret_cast<unsigned char*>(p))) {};
p[1] = '\0';
return str;
}
char *trim(char *str) {
return ltrim(rtrim(str));
}
char * upcase(char * str) {
for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast<unsigned char*>(idx));
return str;
}
char * lowcase(char * str) {
for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast<unsigned char*>(idx));
return str;
}
bool ScanCMDBool(char * cmd,char const * const check) {
char * scan=cmd;size_t c_len=strlen(check);
while ((scan=strchr(scan,'/'))) {
/* found a / now see behind it */
scan++;
if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]=='/' || scan[c_len]==0)) {
/* Found a math now remove it from the string */
memmove(scan-1,scan+c_len,strlen(scan+c_len)+1);
trim(scan-1);
return true;
}
}
return false;
}
/* This scans the command line for a remaining switch and reports it else returns 0*/
char * ScanCMDRemain(char * cmd) {
char * scan,*found;;
if ((scan=found=strchr(cmd,'/'))) {
while ( *scan && !isspace(*reinterpret_cast<unsigned char*>(scan)) ) scan++;
*scan=0;
return found;
} else return 0;
}
char * StripWord(char *&line) {
char * scan=line;
scan=ltrim(scan);
if (*scan=='"') {
char * end_quote=strchr(scan+1,'"');
if (end_quote) {
*end_quote=0;
line=ltrim(++end_quote);
return (scan+1);
}
}
char * begin=scan;
for (char c = *scan ;(c = *scan);scan++) {
if (isspace(*reinterpret_cast<unsigned char*>(&c))) {
*scan++=0;
break;
}
}
line=scan;
return begin;
}
Bits ConvDecWord(char * word) {
bool negative=false;Bitu ret=0;
if (*word=='-') {
negative=true;
word++;
}
while (char c=*word) {
ret*=10;
ret+=c-'0';
word++;
}
if (negative) return 0-ret;
else return ret;
}
Bits ConvHexWord(char * word) {
Bitu ret=0;
while (char c=toupper(*reinterpret_cast<unsigned char*>(word))) {
ret*=16;
if (c>='0' && c<='9') ret+=c-'0';
else if (c>='A' && c<='F') ret+=10+(c-'A');
word++;
}
return ret;
}
double ConvDblWord(char * word) {
return 0.0f;
}
static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95)
void E_Exit(const char * format,...) {
#if C_DEBUG && C_HEAVY_DEBUG
DEBUG_HeavyWriteLogInstruction();
#endif
va_list msg;
va_start(msg,format);
vsprintf(buf,format,msg);
va_end(msg);
strcat(buf,"\n");
throw(buf);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +1,202 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_batch.cpp,v 1.36 2009/07/03 19:36:56 qbix79 Exp $ */
#include <stdlib.h>
#include <string.h>
#include "shell.h"
#include "support.h"
BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) {
location = 0;
prev=host->bf;
echo=host->echo;
shell=host;
char totalname[DOS_PATHLENGTH+4];
DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation
cmd = new CommandLine(totalname,cmd_line);
filename = totalname;
//Test if file is openable
if (!DOS_OpenFile(totalname,128,&file_handle)) {
//TODO Come up with something better
E_Exit("SHELL:Can't open BatchFile %s",totalname);
}
DOS_CloseFile(file_handle);
}
BatchFile::~BatchFile() {
delete cmd;
shell->bf=prev;
shell->echo=echo;
}
bool BatchFile::ReadLine(char * line) {
//Open the batchfile and seek to stored postion
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET);
Bit8u c=0;Bit16u n=1;
char temp[CMD_MAXLINE];
emptyline:
char * cmd_write=temp;
do {
n=1;
DOS_ReadFile(file_handle,&c,&n);
if (n>0) {
/* Why are we filtering this ?
* Exclusion list: tab for batch files
* escape for ansi
* backspace for alien odyssey */
if (c>31 || c==0x1b || c=='\t' || c==8)
*cmd_write++=c;
}
} while (c!='\n' && n);
*cmd_write=0;
if (!n && cmd_write==temp) {
//Close file and delete bat file
DOS_CloseFile(file_handle);
delete this;
return false;
}
if (!strlen(temp)) goto emptyline;
if (temp[0]==':') goto emptyline;
/* Now parse the line read from the bat file for % stuff */
cmd_write=line;
char * cmd_read=temp;
char env_name[256];char * env_write;
while (*cmd_read) {
env_write=env_name;
if (*cmd_read=='%') {
cmd_read++;
if (cmd_read[0] == '%') {
cmd_read++;
*cmd_write++='%';
continue;
}
if (cmd_read[0] == '0') { /* Handle %0 */
const char *file_name = cmd->GetFileName();
cmd_read++;
strcpy(cmd_write,file_name);
cmd_write+=strlen(file_name);
continue;
}
char next = cmd_read[0];
if(next > '0' && next <= '9') {
/* Handle %1 %2 .. %9 */
cmd_read++; //Progress reader
next -= '0';
if (cmd->GetCount()<(unsigned int)next) continue;
std::string word;
if (!cmd->FindCommand(next,word)) continue;
strcpy(cmd_write,word.c_str());
cmd_write+=strlen(word.c_str());
continue;
} else {
/* Not a command line number has to be an environment */
char * first=strchr(cmd_read,'%');
/* No env afterall.Somewhat of a hack though as %% and % aren't handled consistent in dosbox. Maybe echo needs to parse % and %% as well. */
if (!first) {*cmd_write++ = '%';continue;}
*first++ = 0;
std::string env;
if (shell->GetEnvStr(cmd_read,env)) {
const char * equals=strchr(env.c_str(),'=');
if (!equals) continue;
equals++;
strcpy(cmd_write,equals);
cmd_write+=strlen(equals);
}
cmd_read=first;
}
} else {
*cmd_write++=*cmd_read++;
}
}
*cmd_write=0;
//Store current location and close bat file
this->location = 0;
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
DOS_CloseFile(file_handle);
return true;
}
bool BatchFile::Goto(char * where) {
//Open bat file and search for the where string
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}
char cmd_buffer[CMD_MAXLINE];
char * cmd_write;
/* Scan till we have a match or return false */
Bit8u c;Bit16u n;
again:
cmd_write=cmd_buffer;
do {
n=1;
DOS_ReadFile(file_handle,&c,&n);
if (n>0) {
if (c>31)
*cmd_write++=c;
}
} while (c!='\n' && n);
*cmd_write++ = 0;
char *nospace = trim(cmd_buffer);
if (nospace[0] == ':') {
nospace++; //Skip :
//Strip spaces and = from it.
while(*nospace && (isspace(*reinterpret_cast<unsigned char*>(nospace)) || (*nospace == '=')))
nospace++;
//label is until space/=/eol
char* const beginlabel = nospace;
while(*nospace && !isspace(*reinterpret_cast<unsigned char*>(nospace)) && (*nospace != '='))
nospace++;
*nospace = 0;
if (strcasecmp(beginlabel,where)==0) {
//Found it! Store location and continue
this->location = 0;
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
DOS_CloseFile(file_handle);
return true;
}
}
if (!n) {
DOS_CloseFile(file_handle);
delete this;
return false;
}
goto again;
return false;
}
void BatchFile::Shift(void) {
cmd->Shift(1);
}
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_batch.cpp,v 1.36 2009-07-03 19:36:56 qbix79 Exp $ */
#include <stdlib.h>
#include <string.h>
#include "shell.h"
#include "support.h"
BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) {
location = 0;
prev=host->bf;
echo=host->echo;
shell=host;
char totalname[DOS_PATHLENGTH+4];
DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation
cmd = new CommandLine(totalname,cmd_line);
filename = totalname;
//Test if file is openable
if (!DOS_OpenFile(totalname,128,&file_handle)) {
//TODO Come up with something better
E_Exit("SHELL:Can't open BatchFile %s",totalname);
}
DOS_CloseFile(file_handle);
}
BatchFile::~BatchFile() {
delete cmd;
shell->bf=prev;
shell->echo=echo;
}
bool BatchFile::ReadLine(char * line) {
//Open the batchfile and seek to stored postion
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET);
Bit8u c=0;Bit16u n=1;
char temp[CMD_MAXLINE];
emptyline:
char * cmd_write=temp;
do {
n=1;
DOS_ReadFile(file_handle,&c,&n);
if (n>0) {
/* Why are we filtering this ?
* Exclusion list: tab for batch files
* escape for ansi
* backspace for alien odyssey */
if (c>31 || c==0x1b || c=='\t' || c==8)
*cmd_write++=c;
}
} while (c!='\n' && n);
*cmd_write=0;
if (!n && cmd_write==temp) {
//Close file and delete bat file
DOS_CloseFile(file_handle);
delete this;
return false;
}
if (!strlen(temp)) goto emptyline;
if (temp[0]==':') goto emptyline;
/* Now parse the line read from the bat file for % stuff */
cmd_write=line;
char * cmd_read=temp;
char env_name[256];char * env_write;
while (*cmd_read) {
env_write=env_name;
if (*cmd_read=='%') {
cmd_read++;
if (cmd_read[0] == '%') {
cmd_read++;
*cmd_write++='%';
continue;
}
if (cmd_read[0] == '0') { /* Handle %0 */
const char *file_name = cmd->GetFileName();
cmd_read++;
strcpy(cmd_write,file_name);
cmd_write+=strlen(file_name);
continue;
}
char next = cmd_read[0];
if(next > '0' && next <= '9') {
/* Handle %1 %2 .. %9 */
cmd_read++; //Progress reader
next -= '0';
if (cmd->GetCount()<(unsigned int)next) continue;
std::string word;
if (!cmd->FindCommand(next,word)) continue;
strcpy(cmd_write,word.c_str());
cmd_write+=strlen(word.c_str());
continue;
} else {
/* Not a command line number has to be an environment */
char * first=strchr(cmd_read,'%');
/* No env afterall.Somewhat of a hack though as %% and % aren't handled consistent in dosbox. Maybe echo needs to parse % and %% as well. */
if (!first) {*cmd_write++ = '%';continue;}
*first++ = 0;
std::string env;
if (shell->GetEnvStr(cmd_read,env)) {
const char * equals=strchr(env.c_str(),'=');
if (!equals) continue;
equals++;
strcpy(cmd_write,equals);
cmd_write+=strlen(equals);
}
cmd_read=first;
}
} else {
*cmd_write++=*cmd_read++;
}
}
*cmd_write=0;
//Store current location and close bat file
this->location = 0;
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
DOS_CloseFile(file_handle);
return true;
}
bool BatchFile::Goto(char * where) {
//Open bat file and search for the where string
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}
char cmd_buffer[CMD_MAXLINE];
char * cmd_write;
/* Scan till we have a match or return false */
Bit8u c;Bit16u n;
again:
cmd_write=cmd_buffer;
do {
n=1;
DOS_ReadFile(file_handle,&c,&n);
if (n>0) {
if (c>31)
*cmd_write++=c;
}
} while (c!='\n' && n);
*cmd_write++ = 0;
char *nospace = trim(cmd_buffer);
if (nospace[0] == ':') {
nospace++; //Skip :
//Strip spaces and = from it.
while(*nospace && (isspace(*reinterpret_cast<unsigned char*>(nospace)) || (*nospace == '=')))
nospace++;
//label is until space/=/eol
char* const beginlabel = nospace;
while(*nospace && !isspace(*reinterpret_cast<unsigned char*>(nospace)) && (*nospace != '='))
nospace++;
*nospace = 0;
if (strcasecmp(beginlabel,where)==0) {
//Found it! Store location and continue
this->location = 0;
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
DOS_CloseFile(file_handle);
return true;
}
}
if (!n) {
DOS_CloseFile(file_handle);
delete this;
return false;
}
goto again;
return false;
}
void BatchFile::Shift(void) {
cmd->Shift(1);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff