mirror of
https://github.com/retro100/dosbox-wii.git
synced 2025-01-12 18:29:07 +01:00
sync
This commit is contained in:
parent
5ef584b880
commit
336d2c0758
@ -1,265 +1,265 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002-2009 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 $ */
|
/* $Id: cross.cpp,v 1.7 2009-05-26 17:43:39 qbix79 Exp $ */
|
||||||
|
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "cross.h"
|
#include "cross.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
#include "wiihardware.h"
|
#include "wiihardware.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#ifndef _WIN32_IE
|
#ifndef _WIN32_IE
|
||||||
#define _WIN32_IE 0x0400
|
#define _WIN32_IE 0x0400
|
||||||
#endif
|
#endif
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static void W32_ConfDir(std::string& in,bool create) {
|
static void W32_ConfDir(std::string& in,bool create) {
|
||||||
int c = create?1:0;
|
int c = create?1:0;
|
||||||
char result[MAX_PATH] = { 0 };
|
char result[MAX_PATH] = { 0 };
|
||||||
BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c);
|
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) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c);
|
||||||
if(!r || result[0] == 0) {
|
if(!r || result[0] == 0) {
|
||||||
char const * windir = getenv("windir");
|
char const * windir = getenv("windir");
|
||||||
if(!windir) windir = "c:\\windows";
|
if(!windir) windir = "c:\\windows";
|
||||||
safe_strncpy(result,windir,MAX_PATH);
|
safe_strncpy(result,windir,MAX_PATH);
|
||||||
char const* appdata = "\\Application Data";
|
char const* appdata = "\\Application Data";
|
||||||
size_t len = strlen(result);
|
size_t len = strlen(result);
|
||||||
if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata);
|
if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata);
|
||||||
if(create) mkdir(result);
|
if(create) mkdir(result);
|
||||||
}
|
}
|
||||||
in = result;
|
in = result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Cross::GetPlatformConfigDir(std::string& in) {
|
void Cross::GetPlatformConfigDir(std::string& in) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
W32_ConfDir(in,false);
|
W32_ConfDir(in,false);
|
||||||
in += "\\DOSBox";
|
in += "\\DOSBox";
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
in = "~/Library/Preferences";
|
in = "~/Library/Preferences";
|
||||||
ResolveHomedir(in);
|
ResolveHomedir(in);
|
||||||
#elif defined(HW_RVL)
|
#elif defined(HW_RVL)
|
||||||
in = "sd:/DOSBox";
|
in = "sd:/DOSBox";
|
||||||
#else
|
#else
|
||||||
in = "~/.dosbox";
|
in = "~/.dosbox";
|
||||||
ResolveHomedir(in);
|
ResolveHomedir(in);
|
||||||
#endif
|
#endif
|
||||||
in += CROSS_FILESPLIT;
|
in += CROSS_FILESPLIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cross::GetPlatformConfigName(std::string& in) {
|
void Cross::GetPlatformConfigName(std::string& in) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences"
|
#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences"
|
||||||
#elif defined(HW_RVL)
|
#elif defined(HW_RVL)
|
||||||
#define DEFAULT_CONFIG_FILE "dosbox.conf"
|
#define DEFAULT_CONFIG_FILE "dosbox.conf"
|
||||||
#else /*linux freebsd*/
|
#else /*linux freebsd*/
|
||||||
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
||||||
#endif
|
#endif
|
||||||
in = DEFAULT_CONFIG_FILE;
|
in = DEFAULT_CONFIG_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cross::CreatePlatformConfigDir(std::string& in) {
|
void Cross::CreatePlatformConfigDir(std::string& in) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
W32_ConfDir(in,true);
|
W32_ConfDir(in,true);
|
||||||
in += "\\DOSBox";
|
in += "\\DOSBox";
|
||||||
mkdir(in.c_str());
|
mkdir(in.c_str());
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
in = "~/Library/Preferences/";
|
in = "~/Library/Preferences/";
|
||||||
ResolveHomedir(in);
|
ResolveHomedir(in);
|
||||||
//Don't create it. Assume it exists
|
//Don't create it. Assume it exists
|
||||||
#elif defined(HW_RVL)
|
#elif defined(HW_RVL)
|
||||||
in = "sd:/DOSBox";
|
in = "sd:/DOSBox";
|
||||||
CreateDir(in);
|
CreateDir(in);
|
||||||
#else
|
#else
|
||||||
in = "~/.dosbox";
|
in = "~/.dosbox";
|
||||||
ResolveHomedir(in);
|
ResolveHomedir(in);
|
||||||
mkdir(in.c_str(),0700);
|
mkdir(in.c_str(),0700);
|
||||||
#endif
|
#endif
|
||||||
in += CROSS_FILESPLIT;
|
in += CROSS_FILESPLIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cross::ResolveHomedir(std::string & temp_line) {
|
void Cross::ResolveHomedir(std::string & temp_line) {
|
||||||
if(!temp_line.size() || temp_line[0] != '~') return; //No ~
|
if(!temp_line.size() || temp_line[0] != '~') return; //No ~
|
||||||
|
|
||||||
if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant
|
if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant
|
||||||
char * home = getenv("HOME");
|
char * home = getenv("HOME");
|
||||||
if(home) temp_line.replace(0,1,std::string(home));
|
if(home) temp_line.replace(0,1,std::string(home));
|
||||||
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
||||||
} else { // The ~username variant
|
} else { // The ~username variant
|
||||||
std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT);
|
std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT);
|
||||||
if(namelen == std::string::npos) namelen = temp_line.size();
|
if(namelen == std::string::npos) namelen = temp_line.size();
|
||||||
std::string username = temp_line.substr(1,namelen - 1);
|
std::string username = temp_line.substr(1,namelen - 1);
|
||||||
struct passwd* pass = getpwnam(username.c_str());
|
struct passwd* pass = getpwnam(username.c_str());
|
||||||
if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~)
|
if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~)
|
||||||
#endif // USERNAME lookup code
|
#endif // USERNAME lookup code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cross::CreateDir(std::string const& in) {
|
void Cross::CreateDir(std::string const& in) {
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
mkdir(in.c_str());
|
mkdir(in.c_str());
|
||||||
#else
|
#else
|
||||||
mkdir(in.c_str(),0700);
|
mkdir(in.c_str(),0700);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined (WIN32)
|
#if defined (WIN32)
|
||||||
|
|
||||||
dir_information* open_directory(const char* dirname) {
|
dir_information* open_directory(const char* dirname) {
|
||||||
if (dirname == NULL) return NULL;
|
if (dirname == NULL) return NULL;
|
||||||
|
|
||||||
size_t len = strlen(dirname);
|
size_t len = strlen(dirname);
|
||||||
if (len == 0) return NULL;
|
if (len == 0) return NULL;
|
||||||
|
|
||||||
static dir_information dir;
|
static dir_information dir;
|
||||||
|
|
||||||
safe_strncpy(dir.base_path,dirname,MAX_PATH);
|
safe_strncpy(dir.base_path,dirname,MAX_PATH);
|
||||||
|
|
||||||
if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*");
|
if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*");
|
||||||
else strcat(dir.base_path,"\\*.*");
|
else strcat(dir.base_path,"\\*.*");
|
||||||
|
|
||||||
dir.handle = INVALID_HANDLE_VALUE;
|
dir.handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
return (access(dirname,0) ? NULL : &dir);
|
return (access(dirname,0) ? NULL : &dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
||||||
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
|
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
|
||||||
if (INVALID_HANDLE_VALUE == dirp->handle) {
|
if (INVALID_HANDLE_VALUE == dirp->handle) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
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;
|
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
||||||
else is_directory = false;
|
else is_directory = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
||||||
int result = FindNextFile(dirp->handle, &dirp->search_data);
|
int result = FindNextFile(dirp->handle, &dirp->search_data);
|
||||||
if (result==0) return false;
|
if (result==0) return false;
|
||||||
|
|
||||||
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
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;
|
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
||||||
else is_directory = false;
|
else is_directory = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_directory(dir_information* dirp) {
|
void close_directory(dir_information* dirp) {
|
||||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||||
FindClose(dirp->handle);
|
FindClose(dirp->handle);
|
||||||
dirp->handle = INVALID_HANDLE_VALUE;
|
dirp->handle = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
dir_information* open_directory(const char* dirname) {
|
dir_information* open_directory(const char* dirname) {
|
||||||
static dir_information dir;
|
static dir_information dir;
|
||||||
dir.dir=opendir(dirname);
|
dir.dir=opendir(dirname);
|
||||||
safe_strncpy(dir.base_path,dirname,CROSS_LEN);
|
safe_strncpy(dir.base_path,dirname,CROSS_LEN);
|
||||||
return dir.dir?&dir:NULL;
|
return dir.dir?&dir:NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
||||||
struct dirent* dentry = readdir(dirp->dir);
|
struct dirent* dentry = readdir(dirp->dir);
|
||||||
if (dentry==NULL) {
|
if (dentry==NULL) {
|
||||||
return false;
|
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,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
||||||
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
||||||
|
|
||||||
#ifdef DIRENT_HAS_D_TYPE
|
#ifdef DIRENT_HAS_D_TYPE
|
||||||
if(dentry->d_type == DT_DIR) {
|
if(dentry->d_type == DT_DIR) {
|
||||||
is_directory = true;
|
is_directory = true;
|
||||||
return true;
|
return true;
|
||||||
} else if(dentry->d_type == DT_REG) {
|
} else if(dentry->d_type == DT_REG) {
|
||||||
is_directory = false;
|
is_directory = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// probably use d_type here instead of a full stat()
|
// probably use d_type here instead of a full stat()
|
||||||
static char buffer[2*CROSS_LEN] = { 0 };
|
static char buffer[2*CROSS_LEN] = { 0 };
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
strcpy(buffer,dirp->base_path);
|
strcpy(buffer,dirp->base_path);
|
||||||
strcat(buffer,entry_name);
|
strcat(buffer,entry_name);
|
||||||
struct stat status;
|
struct stat status;
|
||||||
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
||||||
else is_directory = false;
|
else is_directory = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
||||||
struct dirent* dentry = readdir(dirp->dir);
|
struct dirent* dentry = readdir(dirp->dir);
|
||||||
if (dentry==NULL) {
|
if (dentry==NULL) {
|
||||||
return false;
|
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,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
||||||
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
||||||
|
|
||||||
#ifdef DIRENT_HAS_D_TYPE
|
#ifdef DIRENT_HAS_D_TYPE
|
||||||
if(dentry->d_type == DT_DIR) {
|
if(dentry->d_type == DT_DIR) {
|
||||||
is_directory = true;
|
is_directory = true;
|
||||||
return true;
|
return true;
|
||||||
} else if(dentry->d_type == DT_REG) {
|
} else if(dentry->d_type == DT_REG) {
|
||||||
is_directory = false;
|
is_directory = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// probably use d_type here instead of a full stat()
|
// probably use d_type here instead of a full stat()
|
||||||
static char buffer[2*CROSS_LEN] = { 0 };
|
static char buffer[2*CROSS_LEN] = { 0 };
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
strcpy(buffer,dirp->base_path);
|
strcpy(buffer,dirp->base_path);
|
||||||
strcat(buffer,entry_name);
|
strcat(buffer,entry_name);
|
||||||
struct stat status;
|
struct stat status;
|
||||||
|
|
||||||
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
||||||
else is_directory = false;
|
else is_directory = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void close_directory(dir_information* dirp) {
|
void close_directory(dir_information* dirp) {
|
||||||
closedir(dirp->dir);
|
closedir(dirp->dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,144 +1,144 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002-2009 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 $ */
|
/* $Id: messages.cpp,v 1.23 2009-06-17 08:52:35 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "cross.h"
|
#include "cross.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LINE_IN_MAXLEN 2048
|
#define LINE_IN_MAXLEN 2048
|
||||||
|
|
||||||
struct MessageBlock {
|
struct MessageBlock {
|
||||||
string name;
|
string name;
|
||||||
string val;
|
string val;
|
||||||
MessageBlock(const char* _name, const char* _val):
|
MessageBlock(const char* _name, const char* _val):
|
||||||
name(_name),val(_val){}
|
name(_name),val(_val){}
|
||||||
};
|
};
|
||||||
|
|
||||||
static list<MessageBlock> Lang;
|
static list<MessageBlock> Lang;
|
||||||
typedef list<MessageBlock>::iterator itmb;
|
typedef list<MessageBlock>::iterator itmb;
|
||||||
|
|
||||||
void MSG_Add(const char * _name, const char* _val) {
|
void MSG_Add(const char * _name, const char* _val) {
|
||||||
/* Find the message */
|
/* Find the message */
|
||||||
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
|
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
|
||||||
if((*tel).name==_name) {
|
if((*tel).name==_name) {
|
||||||
// LOG_MSG("double entry for %s",_name); //Message file might be loaded before default text messages
|
// LOG_MSG("double entry for %s",_name); //Message file might be loaded before default text messages
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if the message doesn't exist add it */
|
/* if the message doesn't exist add it */
|
||||||
Lang.push_back(MessageBlock(_name,_val));
|
Lang.push_back(MessageBlock(_name,_val));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSG_Replace(const char * _name, const char* _val) {
|
void MSG_Replace(const char * _name, const char* _val) {
|
||||||
/* Find the message */
|
/* Find the message */
|
||||||
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
|
for(itmb tel=Lang.begin();tel!=Lang.end();tel++) {
|
||||||
if((*tel).name==_name) {
|
if((*tel).name==_name) {
|
||||||
Lang.erase(tel);
|
Lang.erase(tel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Even if the message doesn't exist add it */
|
/* Even if the message doesn't exist add it */
|
||||||
Lang.push_back(MessageBlock(_name,_val));
|
Lang.push_back(MessageBlock(_name,_val));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LoadMessageFile(const char * fname) {
|
static void LoadMessageFile(const char * fname) {
|
||||||
if (!fname) return;
|
if (!fname) return;
|
||||||
if(*fname=='\0') return;//empty string=no languagefile
|
if(*fname=='\0') return;//empty string=no languagefile
|
||||||
FILE * mfile=fopen(fname,"rt");
|
FILE * mfile=fopen(fname,"rt");
|
||||||
/* This should never happen and since other modules depend on this use a normal printf */
|
/* This should never happen and since other modules depend on this use a normal printf */
|
||||||
if (!mfile) {
|
if (!mfile) {
|
||||||
E_Exit("MSG:Can't load messages: %s",fname);
|
E_Exit("MSG:Can't load messages: %s",fname);
|
||||||
}
|
}
|
||||||
char linein[LINE_IN_MAXLEN];
|
char linein[LINE_IN_MAXLEN];
|
||||||
char name[LINE_IN_MAXLEN];
|
char name[LINE_IN_MAXLEN];
|
||||||
char string[LINE_IN_MAXLEN*10];
|
char string[LINE_IN_MAXLEN*10];
|
||||||
/* Start out with empty strings */
|
/* Start out with empty strings */
|
||||||
name[0]=0;string[0]=0;
|
name[0]=0;string[0]=0;
|
||||||
while(fgets(linein, LINE_IN_MAXLEN, mfile)!=0) {
|
while(fgets(linein, LINE_IN_MAXLEN, mfile)!=0) {
|
||||||
/* Parse the read line */
|
/* Parse the read line */
|
||||||
/* First remove characters 10 and 13 from the line */
|
/* First remove characters 10 and 13 from the line */
|
||||||
char * parser=linein;
|
char * parser=linein;
|
||||||
char * writer=linein;
|
char * writer=linein;
|
||||||
while (*parser) {
|
while (*parser) {
|
||||||
if (*parser!=10 && *parser!=13) {
|
if (*parser!=10 && *parser!=13) {
|
||||||
*writer++=*parser;
|
*writer++=*parser;
|
||||||
}
|
}
|
||||||
*parser++;
|
*parser++;
|
||||||
}
|
}
|
||||||
*writer=0;
|
*writer=0;
|
||||||
/* New string name */
|
/* New string name */
|
||||||
if (linein[0]==':') {
|
if (linein[0]==':') {
|
||||||
string[0]=0;
|
string[0]=0;
|
||||||
strcpy(name,linein+1);
|
strcpy(name,linein+1);
|
||||||
/* End of string marker */
|
/* End of string marker */
|
||||||
} else if (linein[0]=='.') {
|
} else if (linein[0]=='.') {
|
||||||
/* Replace/Add the string to the internal langaugefile */
|
/* Replace/Add the string to the internal langaugefile */
|
||||||
/* Remove last newline (marker is \n.\n) */
|
/* Remove last newline (marker is \n.\n) */
|
||||||
size_t ll = strlen(string);
|
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.
|
if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe.
|
||||||
MSG_Replace(name,string);
|
MSG_Replace(name,string);
|
||||||
} else {
|
} else {
|
||||||
/* Normal string to be added */
|
/* Normal string to be added */
|
||||||
strcat(string,linein);
|
strcat(string,linein);
|
||||||
strcat(string,"\n");
|
strcat(string,"\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(mfile);
|
fclose(mfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * MSG_Get(char const * msg) {
|
const char * MSG_Get(char const * msg) {
|
||||||
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
|
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
|
||||||
if((*tel).name==msg)
|
if((*tel).name==msg)
|
||||||
{
|
{
|
||||||
return (*tel).val.c_str();
|
return (*tel).val.c_str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "Message not Found!\n";
|
return "Message not Found!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MSG_Write(const char * location) {
|
void MSG_Write(const char * location) {
|
||||||
FILE* out=fopen(location,"w+t");
|
FILE* out=fopen(location,"w+t");
|
||||||
if(out==NULL) return;//maybe an error?
|
if(out==NULL) return;//maybe an error?
|
||||||
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
|
for(itmb tel=Lang.begin();tel!=Lang.end();tel++){
|
||||||
fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str());
|
fprintf(out,":%s\n%s\n.\n",(*tel).name.c_str(),(*tel).val.c_str());
|
||||||
}
|
}
|
||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSG_Init(Section_prop * section) {
|
void MSG_Init(Section_prop * section) {
|
||||||
std::string file_name;
|
std::string file_name;
|
||||||
if (control->cmdline->FindString("-lang",file_name,true)) {
|
if (control->cmdline->FindString("-lang",file_name,true)) {
|
||||||
LoadMessageFile(file_name.c_str());
|
LoadMessageFile(file_name.c_str());
|
||||||
} else {
|
} else {
|
||||||
Prop_path* pathprop = section->Get_path("language");
|
Prop_path* pathprop = section->Get_path("language");
|
||||||
if(pathprop) LoadMessageFile(pathprop->realpath.c_str());
|
if(pathprop) LoadMessageFile(pathprop->realpath.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,392 +1,392 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002-2009 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 $ */
|
/* $Id: programs.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "programs.h"
|
#include "programs.h"
|
||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "regs.h"
|
#include "regs.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "cross.h"
|
#include "cross.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
|
||||||
Bitu call_program;
|
Bitu call_program;
|
||||||
|
|
||||||
/* This registers a file on the virtual drive and creates the correct structure for it*/
|
/* This registers a file on the virtual drive and creates the correct structure for it*/
|
||||||
|
|
||||||
static Bit8u exe_block[]={
|
static Bit8u exe_block[]={
|
||||||
0xbc,0x00,0x04, //MOV SP,0x400 decrease stack size
|
0xbc,0x00,0x04, //MOV SP,0x400 decrease stack size
|
||||||
0xbb,0x40,0x00, //MOV BX,0x040 for memory resize
|
0xbb,0x40,0x00, //MOV BX,0x040 for memory resize
|
||||||
0xb4,0x4a, //MOV AH,0x4A Resize memory block
|
0xb4,0x4a, //MOV AH,0x4A Resize memory block
|
||||||
0xcd,0x21, //INT 0x21
|
0xcd,0x21, //INT 0x21
|
||||||
//pos 12 is callback number
|
//pos 12 is callback number
|
||||||
0xFE,0x38,0x00,0x00, //CALLBack number
|
0xFE,0x38,0x00,0x00, //CALLBack number
|
||||||
0xb8,0x00,0x4c, //Mov ax,4c00
|
0xb8,0x00,0x4c, //Mov ax,4c00
|
||||||
0xcd,0x21, //INT 0x21
|
0xcd,0x21, //INT 0x21
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CB_POS 12
|
#define CB_POS 12
|
||||||
|
|
||||||
static std::vector<PROGRAMS_Main*> internal_progs;
|
static std::vector<PROGRAMS_Main*> internal_progs;
|
||||||
|
|
||||||
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) {
|
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main) {
|
||||||
Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK
|
Bit8u * comdata=(Bit8u *)malloc(32); //MEM LEAK
|
||||||
memcpy(comdata,&exe_block,sizeof(exe_block));
|
memcpy(comdata,&exe_block,sizeof(exe_block));
|
||||||
comdata[CB_POS]=(Bit8u)(call_program&0xff);
|
comdata[CB_POS]=(Bit8u)(call_program&0xff);
|
||||||
comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff);
|
comdata[CB_POS+1]=(Bit8u)((call_program>>8)&0xff);
|
||||||
|
|
||||||
/* Copy save the pointer in the vector and save it's index */
|
/* 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()));
|
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();
|
Bit8u index = (Bit8u)internal_progs.size();
|
||||||
internal_progs.push_back(main);
|
internal_progs.push_back(main);
|
||||||
|
|
||||||
memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index));
|
memcpy(&comdata[sizeof(exe_block)],&index,sizeof(index));
|
||||||
Bit32u size=sizeof(exe_block)+sizeof(index);
|
Bit32u size=sizeof(exe_block)+sizeof(index);
|
||||||
VFILE_Register(name,comdata,size);
|
VFILE_Register(name,comdata,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Bitu PROGRAMS_Handler(void) {
|
static Bitu PROGRAMS_Handler(void) {
|
||||||
/* This sets up everything for a program start up call */
|
/* This sets up everything for a program start up call */
|
||||||
Bitu size=sizeof(Bit8u);
|
Bitu size=sizeof(Bit8u);
|
||||||
Bit8u index;
|
Bit8u index;
|
||||||
/* Read the index from program code in memory */
|
/* Read the index from program code in memory */
|
||||||
PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block));
|
PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block));
|
||||||
HostPt writer=(HostPt)&index;
|
HostPt writer=(HostPt)&index;
|
||||||
for (;size>0;size--) *writer++=mem_readb(reader++);
|
for (;size>0;size--) *writer++=mem_readb(reader++);
|
||||||
Program * new_program;
|
Program * new_program;
|
||||||
if(index > internal_progs.size()) E_Exit("something is messing with the memory");
|
if(index > internal_progs.size()) E_Exit("something is messing with the memory");
|
||||||
PROGRAMS_Main * handler = internal_progs[index];
|
PROGRAMS_Main * handler = internal_progs[index];
|
||||||
(*handler)(&new_program);
|
(*handler)(&new_program);
|
||||||
new_program->Run();
|
new_program->Run();
|
||||||
delete new_program;
|
delete new_program;
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Main functions used in all program */
|
/* Main functions used in all program */
|
||||||
|
|
||||||
|
|
||||||
Program::Program() {
|
Program::Program() {
|
||||||
/* Find the command line and setup the PSP */
|
/* Find the command line and setup the PSP */
|
||||||
psp = new DOS_PSP(dos.psp());
|
psp = new DOS_PSP(dos.psp());
|
||||||
/* Scan environment for filename */
|
/* Scan environment for filename */
|
||||||
PhysPt envscan=PhysMake(psp->GetEnvironment(),0);
|
PhysPt envscan=PhysMake(psp->GetEnvironment(),0);
|
||||||
while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1;
|
while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1;
|
||||||
envscan+=3;
|
envscan+=3;
|
||||||
CommandTail tail;
|
CommandTail tail;
|
||||||
MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
|
MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128);
|
||||||
if (tail.count<127) tail.buffer[tail.count]=0;
|
if (tail.count<127) tail.buffer[tail.count]=0;
|
||||||
else tail.buffer[126]=0;
|
else tail.buffer[126]=0;
|
||||||
char filename[256+1];
|
char filename[256+1];
|
||||||
MEM_StrCopy(envscan,filename,256);
|
MEM_StrCopy(envscan,filename,256);
|
||||||
cmd = new CommandLine(filename,tail.buffer);
|
cmd = new CommandLine(filename,tail.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern std::string full_arguments;
|
extern std::string full_arguments;
|
||||||
|
|
||||||
void Program::ChangeToLongCmd() {
|
void Program::ChangeToLongCmd() {
|
||||||
/*
|
/*
|
||||||
* Get arguments directly from the shell instead of the psp.
|
* Get arguments directly from the shell instead of the psp.
|
||||||
* this is done in securemode: (as then the arguments to mount and friends
|
* 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)
|
* can only be given on the shell ( so no int 21 4b)
|
||||||
* Securemode part is disabled as each of the internal command has already
|
* Securemode part is disabled as each of the internal command has already
|
||||||
* protection for it. (and it breaks games like cdman)
|
* 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.
|
* 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
|
* imgmount with lot's of parameters
|
||||||
* Length of arguments can be ~120. but switch when above 100 to be sure
|
* Length of arguments can be ~120. but switch when above 100 to be sure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) {
|
if(/*control->SecureMode() ||*/ cmd->Get_arglength() > 100) {
|
||||||
CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str());
|
CommandLine* temp = new CommandLine(cmd->GetFileName(),full_arguments.c_str());
|
||||||
delete cmd;
|
delete cmd;
|
||||||
cmd = temp;
|
cmd = temp;
|
||||||
}
|
}
|
||||||
full_arguments.assign(""); //Clear so it gets even more save
|
full_arguments.assign(""); //Clear so it gets even more save
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::WriteOut(const char * format,...) {
|
void Program::WriteOut(const char * format,...) {
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
va_list msg;
|
va_list msg;
|
||||||
|
|
||||||
va_start(msg,format);
|
va_start(msg,format);
|
||||||
vsnprintf(buf,2047,format,msg);
|
vsnprintf(buf,2047,format,msg);
|
||||||
va_end(msg);
|
va_end(msg);
|
||||||
|
|
||||||
Bit16u size = (Bit16u)strlen(buf);
|
Bit16u size = (Bit16u)strlen(buf);
|
||||||
DOS_WriteFile(STDOUT,(Bit8u *)buf,&size);
|
DOS_WriteFile(STDOUT,(Bit8u *)buf,&size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Program::WriteOut_NoParsing(const char * format) {
|
void Program::WriteOut_NoParsing(const char * format) {
|
||||||
Bit16u size = (Bit16u)strlen(format);
|
Bit16u size = (Bit16u)strlen(format);
|
||||||
DOS_WriteFile(STDOUT,(Bit8u *)format,&size);
|
DOS_WriteFile(STDOUT,(Bit8u *)format,&size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Program::GetEnvStr(const char * entry,std::string & result) {
|
bool Program::GetEnvStr(const char * entry,std::string & result) {
|
||||||
/* Walk through the internal environment and see for a match */
|
/* Walk through the internal environment and see for a match */
|
||||||
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
||||||
char env_string[1024+1];
|
char env_string[1024+1];
|
||||||
result.erase();
|
result.erase();
|
||||||
if (!entry[0]) return false;
|
if (!entry[0]) return false;
|
||||||
do {
|
do {
|
||||||
MEM_StrCopy(env_read,env_string,1024);
|
MEM_StrCopy(env_read,env_string,1024);
|
||||||
if (!env_string[0]) return false;
|
if (!env_string[0]) return false;
|
||||||
env_read += (PhysPt)(strlen(env_string)+1);
|
env_read += (PhysPt)(strlen(env_string)+1);
|
||||||
char* equal = strchr(env_string,'=');
|
char* equal = strchr(env_string,'=');
|
||||||
if (!equal) continue;
|
if (!equal) continue;
|
||||||
/* replace the = with \0 to get the length */
|
/* replace the = with \0 to get the length */
|
||||||
*equal = 0;
|
*equal = 0;
|
||||||
if (strlen(env_string) != strlen(entry)) continue;
|
if (strlen(env_string) != strlen(entry)) continue;
|
||||||
if (strcasecmp(entry,env_string)!=0) continue;
|
if (strcasecmp(entry,env_string)!=0) continue;
|
||||||
/* restore the = to get the original result */
|
/* restore the = to get the original result */
|
||||||
*equal = '=';
|
*equal = '=';
|
||||||
result = env_string;
|
result = env_string;
|
||||||
return true;
|
return true;
|
||||||
} while (1);
|
} while (1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Program::GetEnvNum(Bitu num,std::string & result) {
|
bool Program::GetEnvNum(Bitu num,std::string & result) {
|
||||||
char env_string[1024+1];
|
char env_string[1024+1];
|
||||||
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
||||||
do {
|
do {
|
||||||
MEM_StrCopy(env_read,env_string,1024);
|
MEM_StrCopy(env_read,env_string,1024);
|
||||||
if (!env_string[0]) break;
|
if (!env_string[0]) break;
|
||||||
if (!num) { result=env_string;return true;}
|
if (!num) { result=env_string;return true;}
|
||||||
env_read += (PhysPt)(strlen(env_string)+1);
|
env_read += (PhysPt)(strlen(env_string)+1);
|
||||||
num--;
|
num--;
|
||||||
} while (1);
|
} while (1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitu Program::GetEnvCount(void) {
|
Bitu Program::GetEnvCount(void) {
|
||||||
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
||||||
Bitu num=0;
|
Bitu num=0;
|
||||||
while (mem_readb(env_read)!=0) {
|
while (mem_readb(env_read)!=0) {
|
||||||
for (;mem_readb(env_read);env_read++) {};
|
for (;mem_readb(env_read);env_read++) {};
|
||||||
env_read++;
|
env_read++;
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Program::SetEnv(const char * entry,const char * new_string) {
|
bool Program::SetEnv(const char * entry,const char * new_string) {
|
||||||
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
PhysPt env_read=PhysMake(psp->GetEnvironment(),0);
|
||||||
PhysPt env_write=env_read;
|
PhysPt env_write=env_read;
|
||||||
char env_string[1024+1];
|
char env_string[1024+1];
|
||||||
do {
|
do {
|
||||||
MEM_StrCopy(env_read,env_string,1024);
|
MEM_StrCopy(env_read,env_string,1024);
|
||||||
if (!env_string[0]) break;
|
if (!env_string[0]) break;
|
||||||
env_read += (PhysPt)(strlen(env_string)+1);
|
env_read += (PhysPt)(strlen(env_string)+1);
|
||||||
if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */
|
if (!strchr(env_string,'=')) continue; /* Remove corrupt entry? */
|
||||||
if ((strncasecmp(entry,env_string,strlen(entry))==0) &&
|
if ((strncasecmp(entry,env_string,strlen(entry))==0) &&
|
||||||
env_string[strlen(entry)]=='=') continue;
|
env_string[strlen(entry)]=='=') continue;
|
||||||
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
|
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
|
||||||
env_write += (PhysPt)(strlen(env_string)+1);
|
env_write += (PhysPt)(strlen(env_string)+1);
|
||||||
} while (1);
|
} while (1);
|
||||||
/* TODO Maybe save the program name sometime. not really needed though */
|
/* TODO Maybe save the program name sometime. not really needed though */
|
||||||
/* Save the new entry */
|
/* Save the new entry */
|
||||||
if (new_string[0]) {
|
if (new_string[0]) {
|
||||||
std::string bigentry(entry);
|
std::string bigentry(entry);
|
||||||
for (std::string::iterator it = bigentry.begin(); it != bigentry.end(); ++it) *it = toupper(*it);
|
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",bigentry.c_str(),new_string);
|
||||||
// sprintf(env_string,"%s=%s",entry,new_string); //oldcode
|
// sprintf(env_string,"%s=%s",entry,new_string); //oldcode
|
||||||
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
|
MEM_BlockWrite(env_write,env_string,(Bitu)(strlen(env_string)+1));
|
||||||
env_write += (PhysPt)(strlen(env_string)+1);
|
env_write += (PhysPt)(strlen(env_string)+1);
|
||||||
}
|
}
|
||||||
/* Clear out the final piece of the environment */
|
/* Clear out the final piece of the environment */
|
||||||
mem_writed(env_write,0);
|
mem_writed(env_write,0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CONFIG : public Program {
|
class CONFIG : public Program {
|
||||||
public:
|
public:
|
||||||
void Run(void);
|
void Run(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
void MSG_Write(const char *);
|
void MSG_Write(const char *);
|
||||||
|
|
||||||
void CONFIG::Run(void) {
|
void CONFIG::Run(void) {
|
||||||
FILE * f;
|
FILE * f;
|
||||||
if (cmd->FindString("-writeconf",temp_line,true)
|
if (cmd->FindString("-writeconf",temp_line,true)
|
||||||
|| cmd->FindString("-wc",temp_line,true)) {
|
|| cmd->FindString("-wc",temp_line,true)) {
|
||||||
/* In secure mode don't allow a new configfile to be created */
|
/* In secure mode don't allow a new configfile to be created */
|
||||||
if(control->SecureMode()) {
|
if(control->SecureMode()) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
|
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
f=fopen(temp_line.c_str(),"wb+");
|
f=fopen(temp_line.c_str(),"wb+");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
|
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
control->PrintConfig(temp_line.c_str());
|
control->PrintConfig(temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (cmd->FindString("-writelang",temp_line,true)
|
if (cmd->FindString("-writelang",temp_line,true)
|
||||||
||cmd->FindString("-wl",temp_line,true)) {
|
||cmd->FindString("-wl",temp_line,true)) {
|
||||||
/* In secure mode don't allow a new languagefile to be created
|
/* In secure mode don't allow a new languagefile to be created
|
||||||
* Who knows which kind of file we would overwriting. */
|
* Who knows which kind of file we would overwriting. */
|
||||||
if(control->SecureMode()) {
|
if(control->SecureMode()) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
|
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
f=fopen(temp_line.c_str(),"wb+");
|
f=fopen(temp_line.c_str(),"wb+");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
|
WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
MSG_Write(temp_line.c_str());
|
MSG_Write(temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code for switching to secure mode */
|
/* Code for switching to secure mode */
|
||||||
if(cmd->FindExist("-securemode",true)) {
|
if(cmd->FindExist("-securemode",true)) {
|
||||||
control->SwitchToSecureMode();
|
control->SwitchToSecureMode();
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON"));
|
WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Code for getting the current configuration. *
|
/* Code for getting the current configuration. *
|
||||||
* Official format: config -get "section property" *
|
* Official format: config -get "section property" *
|
||||||
* As a bonus it will set %CONFIG% to this value as well */
|
* As a bonus it will set %CONFIG% to this value as well */
|
||||||
if(cmd->FindString("-get",temp_line,true)) {
|
if(cmd->FindString("-get",temp_line,true)) {
|
||||||
std::string temp2 = "";
|
std::string temp2 = "";
|
||||||
cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes
|
cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes
|
||||||
if(temp2 != "") temp_line = temp_line + " " + temp2;
|
if(temp2 != "") temp_line = temp_line + " " + temp2;
|
||||||
|
|
||||||
std::string::size_type space = temp_line.find(" ");
|
std::string::size_type space = temp_line.find(" ");
|
||||||
if(space == std::string::npos) {
|
if(space == std::string::npos) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX"));
|
WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Copy the found property to a new string and erase from templine (mind the space)
|
//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);
|
std::string prop = temp_line.substr(space+1); temp_line.erase(space);
|
||||||
|
|
||||||
Section* sec = control->GetSection(temp_line.c_str());
|
Section* sec = control->GetSection(temp_line.c_str());
|
||||||
if(!sec) {
|
if(!sec) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str());
|
WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string val = sec->GetPropValue(prop.c_str());
|
std::string val = sec->GetPropValue(prop.c_str());
|
||||||
if(val == NO_SUCH_PROPERTY) {
|
if(val == NO_SUCH_PROPERTY) {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str());
|
WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WriteOut("%s",val.c_str());
|
WriteOut("%s",val.c_str());
|
||||||
first_shell->SetEnv("CONFIG",val.c_str());
|
first_shell->SetEnv("CONFIG",val.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Code for the configuration changes *
|
/* Code for the configuration changes *
|
||||||
* Official format: config -set "section property=value" *
|
* Official format: config -set "section property=value" *
|
||||||
* Accepted: without quotes and/or without -set and/or without section *
|
* Accepted: without quotes and/or without -set and/or without section *
|
||||||
* and/or the "=" replaced by a " " */
|
* and/or the "=" replaced by a " " */
|
||||||
|
|
||||||
if (cmd->FindString("-set",temp_line,true)) { //get all arguments
|
if (cmd->FindString("-set",temp_line,true)) { //get all arguments
|
||||||
std::string temp2 = "";
|
std::string temp2 = "";
|
||||||
cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes
|
cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes
|
||||||
if(temp2!="") temp_line = temp_line + " " + temp2;
|
if(temp2!="") temp_line = temp_line + " " + temp2;
|
||||||
} else if(!cmd->GetStringRemain(temp_line)) {//no set
|
} else if(!cmd->GetStringRemain(temp_line)) {//no set
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified
|
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
//Wanted input: n1 n2=n3
|
//Wanted input: n1 n2=n3
|
||||||
char copy[1024];
|
char copy[1024];
|
||||||
strcpy(copy,temp_line.c_str());
|
strcpy(copy,temp_line.c_str());
|
||||||
//seperate section from property
|
//seperate section from property
|
||||||
const char* temp = strchr(copy,' ');
|
const char* temp = strchr(copy,' ');
|
||||||
if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0;
|
if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0;
|
||||||
else {
|
else {
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE"));
|
WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//if n1 n2 n3 then replace last space with =
|
//if n1 n2 n3 then replace last space with =
|
||||||
const char* sign = strchr(temp,'=');
|
const char* sign = strchr(temp,'=');
|
||||||
if(!sign) {
|
if(!sign) {
|
||||||
sign = strchr(temp,' ');
|
sign = strchr(temp,' ');
|
||||||
if(sign) {
|
if(sign) {
|
||||||
copy[sign - copy] = '=';
|
copy[sign - copy] = '=';
|
||||||
} else {
|
} else {
|
||||||
//2 items specified (no space nor = between n2 and n3
|
//2 items specified (no space nor = between n2 and n3
|
||||||
//assume that they posted: property value
|
//assume that they posted: property value
|
||||||
//Try to determine the section.
|
//Try to determine the section.
|
||||||
Section* sec=control->GetSectionFromProperty(copy);
|
Section* sec=control->GetSectionFromProperty(copy);
|
||||||
if(!sec){
|
if(!sec){
|
||||||
if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore
|
if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore
|
||||||
WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy);
|
WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy);
|
||||||
return;
|
return;
|
||||||
} //Hack to allow config ems true
|
} //Hack to allow config ems true
|
||||||
char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp);
|
char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp);
|
||||||
sign = strchr(buffer,' ');
|
sign = strchr(buffer,' ');
|
||||||
if(sign) buffer[sign - buffer] = '=';
|
if(sign) buffer[sign - buffer] = '=';
|
||||||
strcpy(copy,sec->GetName());
|
strcpy(copy,sec->GetName());
|
||||||
temp = buffer;
|
temp = buffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input processed. Now the real job starts
|
/* Input processed. Now the real job starts
|
||||||
* copy contains the likely "sectionname"
|
* copy contains the likely "sectionname"
|
||||||
* temp contains "property=value"
|
* temp contains "property=value"
|
||||||
* the section is destroyed and a new input line is given to
|
* the section is destroyed and a new input line is given to
|
||||||
* the configuration parser. Then the section is restarted.
|
* the configuration parser. Then the section is restarted.
|
||||||
*/
|
*/
|
||||||
char* inputline = const_cast<char*>(temp);
|
char* inputline = const_cast<char*>(temp);
|
||||||
Section* sec = 0;
|
Section* sec = 0;
|
||||||
sec = control->GetSection(copy);
|
sec = control->GetSection(copy);
|
||||||
if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;}
|
if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;}
|
||||||
sec->ExecuteDestroy(false);
|
sec->ExecuteDestroy(false);
|
||||||
sec->HandleInputline(inputline);
|
sec->HandleInputline(inputline);
|
||||||
sec->ExecuteInit(false);
|
sec->ExecuteInit(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void CONFIG_ProgramStart(Program * * make) {
|
static void CONFIG_ProgramStart(Program * * make) {
|
||||||
*make=new CONFIG;
|
*make=new CONFIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PROGRAMS_Init(Section* /*sec*/) {
|
void PROGRAMS_Init(Section* /*sec*/) {
|
||||||
/* Setup a special callback to start virtual programs */
|
/* Setup a special callback to start virtual programs */
|
||||||
call_program=CALLBACK_Allocate();
|
call_program=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program");
|
CALLBACK_Setup(call_program,&PROGRAMS_Handler,CB_RETF,"internal program");
|
||||||
PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart);
|
PROGRAMS_MakeFile("CONFIG.COM",CONFIG_ProgramStart);
|
||||||
|
|
||||||
MSG_Add("PROGRAM_CONFIG_FILE_ERROR","Can't open file %s\n");
|
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_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_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_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_SECTION_ERROR","Section %s doesn't exist.\n");
|
||||||
MSG_Add("PROGRAM_CONFIG_PROPERTY_ERROR","No such section or property.\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_NO_PROPERTY","There is no property %s in section %s.\n");
|
||||||
MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n");
|
MSG_Add("PROGRAM_CONFIG_GET_SYNTAX","Correct syntax: config -get \"section property\".\n");
|
||||||
}
|
}
|
||||||
|
2006
src/misc/setup.cpp
2006
src/misc/setup.cpp
File diff suppressed because it is too large
Load Diff
@ -1,185 +1,185 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002-2009 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 $ */
|
/* $Id: support.cpp,v 1.37 2009-05-27 09:15:42 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
|
||||||
void upcase(std::string &str) {
|
void upcase(std::string &str) {
|
||||||
int (*tf)(int) = std::toupper;
|
int (*tf)(int) = std::toupper;
|
||||||
std::transform(str.begin(), str.end(), str.begin(), tf);
|
std::transform(str.begin(), str.end(), str.begin(), tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lowcase(std::string &str) {
|
void lowcase(std::string &str) {
|
||||||
int (*tf)(int) = std::tolower;
|
int (*tf)(int) = std::tolower;
|
||||||
std::transform(str.begin(), str.end(), str.begin(), tf);
|
std::transform(str.begin(), str.end(), str.begin(), tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Ripped some source from freedos for this one.
|
Ripped some source from freedos for this one.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* replaces all instances of character o with character c
|
* replaces all instances of character o with character c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
void strreplace(char * str,char o,char n) {
|
void strreplace(char * str,char o,char n) {
|
||||||
while (*str) {
|
while (*str) {
|
||||||
if (*str==o) *str=n;
|
if (*str==o) *str=n;
|
||||||
str++;
|
str++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char *ltrim(char *str) {
|
char *ltrim(char *str) {
|
||||||
while (*str && isspace(*reinterpret_cast<unsigned char*>(str))) str++;
|
while (*str && isspace(*reinterpret_cast<unsigned char*>(str))) str++;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *rtrim(char *str) {
|
char *rtrim(char *str) {
|
||||||
char *p;
|
char *p;
|
||||||
p = strchr(str, '\0');
|
p = strchr(str, '\0');
|
||||||
while (--p >= str && isspace(*reinterpret_cast<unsigned char*>(p))) {};
|
while (--p >= str && isspace(*reinterpret_cast<unsigned char*>(p))) {};
|
||||||
p[1] = '\0';
|
p[1] = '\0';
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *trim(char *str) {
|
char *trim(char *str) {
|
||||||
return ltrim(rtrim(str));
|
return ltrim(rtrim(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
char * upcase(char * str) {
|
char * upcase(char * str) {
|
||||||
for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast<unsigned char*>(idx));
|
for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast<unsigned char*>(idx));
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * lowcase(char * str) {
|
char * lowcase(char * str) {
|
||||||
for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast<unsigned char*>(idx));
|
for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast<unsigned char*>(idx));
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ScanCMDBool(char * cmd,char const * const check) {
|
bool ScanCMDBool(char * cmd,char const * const check) {
|
||||||
char * scan=cmd;size_t c_len=strlen(check);
|
char * scan=cmd;size_t c_len=strlen(check);
|
||||||
while ((scan=strchr(scan,'/'))) {
|
while ((scan=strchr(scan,'/'))) {
|
||||||
/* found a / now see behind it */
|
/* found a / now see behind it */
|
||||||
scan++;
|
scan++;
|
||||||
if (strncasecmp(scan,check,c_len)==0 && (scan[c_len]==' ' || scan[c_len]=='\t' || scan[c_len]=='/' || scan[c_len]==0)) {
|
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 */
|
/* Found a math now remove it from the string */
|
||||||
memmove(scan-1,scan+c_len,strlen(scan+c_len)+1);
|
memmove(scan-1,scan+c_len,strlen(scan+c_len)+1);
|
||||||
trim(scan-1);
|
trim(scan-1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This scans the command line for a remaining switch and reports it else returns 0*/
|
/* This scans the command line for a remaining switch and reports it else returns 0*/
|
||||||
char * ScanCMDRemain(char * cmd) {
|
char * ScanCMDRemain(char * cmd) {
|
||||||
char * scan,*found;;
|
char * scan,*found;;
|
||||||
if ((scan=found=strchr(cmd,'/'))) {
|
if ((scan=found=strchr(cmd,'/'))) {
|
||||||
while ( *scan && !isspace(*reinterpret_cast<unsigned char*>(scan)) ) scan++;
|
while ( *scan && !isspace(*reinterpret_cast<unsigned char*>(scan)) ) scan++;
|
||||||
*scan=0;
|
*scan=0;
|
||||||
return found;
|
return found;
|
||||||
} else return 0;
|
} else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * StripWord(char *&line) {
|
char * StripWord(char *&line) {
|
||||||
char * scan=line;
|
char * scan=line;
|
||||||
scan=ltrim(scan);
|
scan=ltrim(scan);
|
||||||
if (*scan=='"') {
|
if (*scan=='"') {
|
||||||
char * end_quote=strchr(scan+1,'"');
|
char * end_quote=strchr(scan+1,'"');
|
||||||
if (end_quote) {
|
if (end_quote) {
|
||||||
*end_quote=0;
|
*end_quote=0;
|
||||||
line=ltrim(++end_quote);
|
line=ltrim(++end_quote);
|
||||||
return (scan+1);
|
return (scan+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char * begin=scan;
|
char * begin=scan;
|
||||||
for (char c = *scan ;(c = *scan);scan++) {
|
for (char c = *scan ;(c = *scan);scan++) {
|
||||||
if (isspace(*reinterpret_cast<unsigned char*>(&c))) {
|
if (isspace(*reinterpret_cast<unsigned char*>(&c))) {
|
||||||
*scan++=0;
|
*scan++=0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line=scan;
|
line=scan;
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bits ConvDecWord(char * word) {
|
Bits ConvDecWord(char * word) {
|
||||||
bool negative=false;Bitu ret=0;
|
bool negative=false;Bitu ret=0;
|
||||||
if (*word=='-') {
|
if (*word=='-') {
|
||||||
negative=true;
|
negative=true;
|
||||||
word++;
|
word++;
|
||||||
}
|
}
|
||||||
while (char c=*word) {
|
while (char c=*word) {
|
||||||
ret*=10;
|
ret*=10;
|
||||||
ret+=c-'0';
|
ret+=c-'0';
|
||||||
word++;
|
word++;
|
||||||
}
|
}
|
||||||
if (negative) return 0-ret;
|
if (negative) return 0-ret;
|
||||||
else return ret;
|
else return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bits ConvHexWord(char * word) {
|
Bits ConvHexWord(char * word) {
|
||||||
Bitu ret=0;
|
Bitu ret=0;
|
||||||
while (char c=toupper(*reinterpret_cast<unsigned char*>(word))) {
|
while (char c=toupper(*reinterpret_cast<unsigned char*>(word))) {
|
||||||
ret*=16;
|
ret*=16;
|
||||||
if (c>='0' && c<='9') ret+=c-'0';
|
if (c>='0' && c<='9') ret+=c-'0';
|
||||||
else if (c>='A' && c<='F') ret+=10+(c-'A');
|
else if (c>='A' && c<='F') ret+=10+(c-'A');
|
||||||
word++;
|
word++;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
double ConvDblWord(char * word) {
|
double ConvDblWord(char * word) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95)
|
static char buf[1024]; //greater scope as else it doesn't always gets thrown right (linux/gcc2.95)
|
||||||
void E_Exit(const char * format,...) {
|
void E_Exit(const char * format,...) {
|
||||||
#if C_DEBUG && C_HEAVY_DEBUG
|
#if C_DEBUG && C_HEAVY_DEBUG
|
||||||
DEBUG_HeavyWriteLogInstruction();
|
DEBUG_HeavyWriteLogInstruction();
|
||||||
#endif
|
#endif
|
||||||
va_list msg;
|
va_list msg;
|
||||||
va_start(msg,format);
|
va_start(msg,format);
|
||||||
vsprintf(buf,format,msg);
|
vsprintf(buf,format,msg);
|
||||||
va_end(msg);
|
va_end(msg);
|
||||||
strcat(buf,"\n");
|
strcat(buf,"\n");
|
||||||
|
|
||||||
throw(buf);
|
throw(buf);
|
||||||
}
|
}
|
||||||
|
1346
src/shell/shell.cpp
1346
src/shell/shell.cpp
File diff suppressed because it is too large
Load Diff
@ -1,202 +1,202 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002-2009 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 $ */
|
/* $Id: shell_batch.cpp,v 1.36 2009-07-03 19:36:56 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
|
|
||||||
BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) {
|
BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * const cmd_line) {
|
||||||
location = 0;
|
location = 0;
|
||||||
prev=host->bf;
|
prev=host->bf;
|
||||||
echo=host->echo;
|
echo=host->echo;
|
||||||
shell=host;
|
shell=host;
|
||||||
char totalname[DOS_PATHLENGTH+4];
|
char totalname[DOS_PATHLENGTH+4];
|
||||||
DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation
|
DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation
|
||||||
cmd = new CommandLine(totalname,cmd_line);
|
cmd = new CommandLine(totalname,cmd_line);
|
||||||
filename = totalname;
|
filename = totalname;
|
||||||
|
|
||||||
//Test if file is openable
|
//Test if file is openable
|
||||||
if (!DOS_OpenFile(totalname,128,&file_handle)) {
|
if (!DOS_OpenFile(totalname,128,&file_handle)) {
|
||||||
//TODO Come up with something better
|
//TODO Come up with something better
|
||||||
E_Exit("SHELL:Can't open BatchFile %s",totalname);
|
E_Exit("SHELL:Can't open BatchFile %s",totalname);
|
||||||
}
|
}
|
||||||
DOS_CloseFile(file_handle);
|
DOS_CloseFile(file_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
BatchFile::~BatchFile() {
|
BatchFile::~BatchFile() {
|
||||||
delete cmd;
|
delete cmd;
|
||||||
shell->bf=prev;
|
shell->bf=prev;
|
||||||
shell->echo=echo;
|
shell->echo=echo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BatchFile::ReadLine(char * line) {
|
bool BatchFile::ReadLine(char * line) {
|
||||||
//Open the batchfile and seek to stored postion
|
//Open the batchfile and seek to stored postion
|
||||||
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
|
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
|
||||||
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str());
|
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str());
|
||||||
delete this;
|
delete this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET);
|
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_SET);
|
||||||
|
|
||||||
Bit8u c=0;Bit16u n=1;
|
Bit8u c=0;Bit16u n=1;
|
||||||
char temp[CMD_MAXLINE];
|
char temp[CMD_MAXLINE];
|
||||||
emptyline:
|
emptyline:
|
||||||
char * cmd_write=temp;
|
char * cmd_write=temp;
|
||||||
do {
|
do {
|
||||||
n=1;
|
n=1;
|
||||||
DOS_ReadFile(file_handle,&c,&n);
|
DOS_ReadFile(file_handle,&c,&n);
|
||||||
if (n>0) {
|
if (n>0) {
|
||||||
/* Why are we filtering this ?
|
/* Why are we filtering this ?
|
||||||
* Exclusion list: tab for batch files
|
* Exclusion list: tab for batch files
|
||||||
* escape for ansi
|
* escape for ansi
|
||||||
* backspace for alien odyssey */
|
* backspace for alien odyssey */
|
||||||
if (c>31 || c==0x1b || c=='\t' || c==8)
|
if (c>31 || c==0x1b || c=='\t' || c==8)
|
||||||
*cmd_write++=c;
|
*cmd_write++=c;
|
||||||
}
|
}
|
||||||
} while (c!='\n' && n);
|
} while (c!='\n' && n);
|
||||||
*cmd_write=0;
|
*cmd_write=0;
|
||||||
if (!n && cmd_write==temp) {
|
if (!n && cmd_write==temp) {
|
||||||
//Close file and delete bat file
|
//Close file and delete bat file
|
||||||
DOS_CloseFile(file_handle);
|
DOS_CloseFile(file_handle);
|
||||||
delete this;
|
delete this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!strlen(temp)) goto emptyline;
|
if (!strlen(temp)) goto emptyline;
|
||||||
if (temp[0]==':') goto emptyline;
|
if (temp[0]==':') goto emptyline;
|
||||||
|
|
||||||
/* Now parse the line read from the bat file for % stuff */
|
/* Now parse the line read from the bat file for % stuff */
|
||||||
cmd_write=line;
|
cmd_write=line;
|
||||||
char * cmd_read=temp;
|
char * cmd_read=temp;
|
||||||
char env_name[256];char * env_write;
|
char env_name[256];char * env_write;
|
||||||
while (*cmd_read) {
|
while (*cmd_read) {
|
||||||
env_write=env_name;
|
env_write=env_name;
|
||||||
if (*cmd_read=='%') {
|
if (*cmd_read=='%') {
|
||||||
cmd_read++;
|
cmd_read++;
|
||||||
if (cmd_read[0] == '%') {
|
if (cmd_read[0] == '%') {
|
||||||
cmd_read++;
|
cmd_read++;
|
||||||
*cmd_write++='%';
|
*cmd_write++='%';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cmd_read[0] == '0') { /* Handle %0 */
|
if (cmd_read[0] == '0') { /* Handle %0 */
|
||||||
const char *file_name = cmd->GetFileName();
|
const char *file_name = cmd->GetFileName();
|
||||||
cmd_read++;
|
cmd_read++;
|
||||||
strcpy(cmd_write,file_name);
|
strcpy(cmd_write,file_name);
|
||||||
cmd_write+=strlen(file_name);
|
cmd_write+=strlen(file_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
char next = cmd_read[0];
|
char next = cmd_read[0];
|
||||||
if(next > '0' && next <= '9') {
|
if(next > '0' && next <= '9') {
|
||||||
/* Handle %1 %2 .. %9 */
|
/* Handle %1 %2 .. %9 */
|
||||||
cmd_read++; //Progress reader
|
cmd_read++; //Progress reader
|
||||||
next -= '0';
|
next -= '0';
|
||||||
if (cmd->GetCount()<(unsigned int)next) continue;
|
if (cmd->GetCount()<(unsigned int)next) continue;
|
||||||
std::string word;
|
std::string word;
|
||||||
if (!cmd->FindCommand(next,word)) continue;
|
if (!cmd->FindCommand(next,word)) continue;
|
||||||
strcpy(cmd_write,word.c_str());
|
strcpy(cmd_write,word.c_str());
|
||||||
cmd_write+=strlen(word.c_str());
|
cmd_write+=strlen(word.c_str());
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
/* Not a command line number has to be an environment */
|
/* Not a command line number has to be an environment */
|
||||||
char * first=strchr(cmd_read,'%');
|
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. */
|
/* 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;}
|
if (!first) {*cmd_write++ = '%';continue;}
|
||||||
*first++ = 0;
|
*first++ = 0;
|
||||||
std::string env;
|
std::string env;
|
||||||
if (shell->GetEnvStr(cmd_read,env)) {
|
if (shell->GetEnvStr(cmd_read,env)) {
|
||||||
const char * equals=strchr(env.c_str(),'=');
|
const char * equals=strchr(env.c_str(),'=');
|
||||||
if (!equals) continue;
|
if (!equals) continue;
|
||||||
equals++;
|
equals++;
|
||||||
strcpy(cmd_write,equals);
|
strcpy(cmd_write,equals);
|
||||||
cmd_write+=strlen(equals);
|
cmd_write+=strlen(equals);
|
||||||
}
|
}
|
||||||
cmd_read=first;
|
cmd_read=first;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*cmd_write++=*cmd_read++;
|
*cmd_write++=*cmd_read++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*cmd_write=0;
|
*cmd_write=0;
|
||||||
//Store current location and close bat file
|
//Store current location and close bat file
|
||||||
this->location = 0;
|
this->location = 0;
|
||||||
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
|
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
|
||||||
DOS_CloseFile(file_handle);
|
DOS_CloseFile(file_handle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BatchFile::Goto(char * where) {
|
bool BatchFile::Goto(char * where) {
|
||||||
//Open bat file and search for the where string
|
//Open bat file and search for the where string
|
||||||
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
|
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
|
||||||
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str());
|
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str());
|
||||||
delete this;
|
delete this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char cmd_buffer[CMD_MAXLINE];
|
char cmd_buffer[CMD_MAXLINE];
|
||||||
char * cmd_write;
|
char * cmd_write;
|
||||||
|
|
||||||
/* Scan till we have a match or return false */
|
/* Scan till we have a match or return false */
|
||||||
Bit8u c;Bit16u n;
|
Bit8u c;Bit16u n;
|
||||||
again:
|
again:
|
||||||
cmd_write=cmd_buffer;
|
cmd_write=cmd_buffer;
|
||||||
do {
|
do {
|
||||||
n=1;
|
n=1;
|
||||||
DOS_ReadFile(file_handle,&c,&n);
|
DOS_ReadFile(file_handle,&c,&n);
|
||||||
if (n>0) {
|
if (n>0) {
|
||||||
if (c>31)
|
if (c>31)
|
||||||
*cmd_write++=c;
|
*cmd_write++=c;
|
||||||
}
|
}
|
||||||
} while (c!='\n' && n);
|
} while (c!='\n' && n);
|
||||||
*cmd_write++ = 0;
|
*cmd_write++ = 0;
|
||||||
char *nospace = trim(cmd_buffer);
|
char *nospace = trim(cmd_buffer);
|
||||||
if (nospace[0] == ':') {
|
if (nospace[0] == ':') {
|
||||||
nospace++; //Skip :
|
nospace++; //Skip :
|
||||||
//Strip spaces and = from it.
|
//Strip spaces and = from it.
|
||||||
while(*nospace && (isspace(*reinterpret_cast<unsigned char*>(nospace)) || (*nospace == '=')))
|
while(*nospace && (isspace(*reinterpret_cast<unsigned char*>(nospace)) || (*nospace == '=')))
|
||||||
nospace++;
|
nospace++;
|
||||||
|
|
||||||
//label is until space/=/eol
|
//label is until space/=/eol
|
||||||
char* const beginlabel = nospace;
|
char* const beginlabel = nospace;
|
||||||
while(*nospace && !isspace(*reinterpret_cast<unsigned char*>(nospace)) && (*nospace != '='))
|
while(*nospace && !isspace(*reinterpret_cast<unsigned char*>(nospace)) && (*nospace != '='))
|
||||||
nospace++;
|
nospace++;
|
||||||
|
|
||||||
*nospace = 0;
|
*nospace = 0;
|
||||||
if (strcasecmp(beginlabel,where)==0) {
|
if (strcasecmp(beginlabel,where)==0) {
|
||||||
//Found it! Store location and continue
|
//Found it! Store location and continue
|
||||||
this->location = 0;
|
this->location = 0;
|
||||||
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
|
DOS_SeekFile(file_handle,&(this->location),DOS_SEEK_CUR);
|
||||||
DOS_CloseFile(file_handle);
|
DOS_CloseFile(file_handle);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!n) {
|
if (!n) {
|
||||||
DOS_CloseFile(file_handle);
|
DOS_CloseFile(file_handle);
|
||||||
delete this;
|
delete this;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
goto again;
|
goto again;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BatchFile::Shift(void) {
|
void BatchFile::Shift(void) {
|
||||||
cmd->Shift(1);
|
cmd->Shift(1);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user