p7zip/CPP/myWindows/mySplitCommandLine.cpp
2017-10-11 12:35:36 +02:00

218 lines
4.7 KiB
C++

#include "StdAfx.h"
#include "../Common/StringConvert.h"
#include "myPrivate.h"
#include "Windows/System.h"
#include "7zip/MyVersion.h"
#include "Common/StdOutStream.h"
#include "Common/IntToString.h"
#include "../C/CpuArch.h"
#ifdef ENV_HAVE_LOCALE
#include <locale.h>
#endif
#include <string.h> // memset
extern void my_windows_split_path(const AString &p_path, AString &dir , AString &base);
#if defined(MY_CPU_X86_OR_AMD64) && defined(_7ZIP_ASM)
static void PrintCpuChars(AString &s, UInt32 v)
{
for (int j = 0; j < 4; j++)
{
Byte b = (Byte)(v & 0xFF);
v >>= 8;
if (b == 0)
break;
s += (char)b;
}
}
static void x86cpuid_to_String(const Cx86cpuid &c, AString &s)
{
s.Empty();
UInt32 maxFunc2 = 0;
UInt32 t[3];
MyCPUID(0x80000000, &maxFunc2, &t[0], &t[1], &t[2]);
bool fullNameIsAvail = (maxFunc2 >= 0x80000004);
if (!fullNameIsAvail)
{
for (int i = 0; i < 3; i++)
PrintCpuChars(s, c.vendor[i]);
}
else
{
for (int i = 0; i < 3; i++)
{
UInt32 c[4] = { 0 };
MyCPUID(0x80000002 + i, &c[0], &c[1], &c[2], &c[3]);
for (int j = 0; j < 4; j++)
PrintCpuChars(s, c[j]);
}
}
s.Add_Space_if_NotEmpty();
{
char temp[32];
ConvertUInt32ToHex(c.ver, temp);
s += '(';
s += temp;
s += ')';
}
}
#endif
static void GetCpuName(AString &s)
{
s.Empty();
#ifdef MY_CPU_X86_OR_AMD64
{
#ifdef _7ZIP_ASM
Cx86cpuid cpuid;
if (x86cpuid_CheckAndRead(&cpuid))
{
x86cpuid_to_String(cpuid, s);
return;
}
#endif
#ifdef MY_CPU_AMD64
s = "x64";
#else
s = "x86";
#endif
}
#else
#ifdef MY_CPU_LE
s = "LE";
#elif defined(MY_CPU_BE)
s = "BE";
#else
#error ENDIANNESS
#endif
#endif
}
void mySplitCommandLine(int numArguments, char *arguments[],UStringVector &parts) {
{ // define P7ZIP_HOME_DIR
static char p7zip_home_dir[MAX_PATH];
AString dir,name;
my_windows_split_path(arguments[0],dir,name);
snprintf(p7zip_home_dir,sizeof(p7zip_home_dir),"P7ZIP_HOME_DIR=%s/",(const char *)dir);
p7zip_home_dir[sizeof(p7zip_home_dir)-1] = 0;
putenv(p7zip_home_dir);
}
#ifdef ENV_HAVE_LOCALE
// set the program's current locale from the user's environment variables
setlocale(LC_ALL,"");
// auto-detect which conversion p7zip should use
char *locale = setlocale(LC_CTYPE,0);
if (locale) {
size_t len = strlen(locale);
char *locale_upper = (char *)malloc(len+1);
if (locale_upper) {
strcpy(locale_upper,locale);
for(size_t i=0;i<len;i++)
locale_upper[i] = toupper(locale_upper[i] & 255);
if ( (strcmp(locale_upper,"") != 0)
&& (strcmp(locale_upper,"C") != 0)
&& (strcmp(locale_upper,"POSIX") != 0) ) {
global_use_utf16_conversion = 1;
}
free(locale_upper);
}
}
#elif defined(LOCALE_IS_UTF8)
global_use_utf16_conversion = 1; // assume LC_CTYPE="utf8"
#else
global_use_utf16_conversion = 0; // assume LC_CTYPE="C"
#endif
parts.Clear();
for(int ind=0;ind < numArguments; ind++) {
if ((ind <= 2) && (strcmp(arguments[ind],"-no-utf16") == 0)) {
global_use_utf16_conversion = 0;
} else if ((ind <= 2) && (strcmp(arguments[ind],"-utf16") == 0)) {
global_use_utf16_conversion = 1;
} else {
UString tmp = MultiByteToUnicodeString(arguments[ind]);
// tmp.Trim(); " " is a valid filename ...
if (!tmp.IsEmpty()) {
parts.Add(tmp);
}
// try to hide the password
{
char * arg = arguments[ind];
size_t len = strlen(arg);
if ( (len > 2) && (arg[0] == '-') && ( (arg[1]=='p') || (arg[1]=='P') ) )
{
memset(arg+2,'*',len-2);
}
}
}
}
}
const char *my_getlocale(void) {
#ifdef ENV_HAVE_LOCALE
const char* ret = setlocale(LC_CTYPE,0);
if (ret == 0)
ret ="C";
return ret;
#elif defined(LOCALE_IS_UTF8)
return "utf8";
#else
return "C";
#endif
}
void showP7zipInfo(CStdOutStream *so)
{
if (!so)
return;
AString cpu_name;
GetCpuName(cpu_name);
cpu_name.Trim();
int bits = int(sizeof(void *)) * 8;
*so << "p7zip Version " << P7ZIP_VERSION << " (locale=" << my_getlocale() <<",Utf16=";
if (global_use_utf16_conversion) *so << "on";
else *so << "off";
*so << ",HugeFiles=";
if (sizeof(off_t) >= 8) *so << "on,";
else *so << "off,";
*so << bits << " bits,";
int nbcpu = NWindows::NSystem::GetNumberOfProcessors();
if (nbcpu > 1) *so << nbcpu << " CPUs ";
else *so << nbcpu << " CPU ";
*so << cpu_name;
#ifdef _7ZIP_ASM
{
const char * txt =",ASM";
#ifdef MY_CPU_X86_OR_AMD64
if (CPU_Is_Aes_Supported()) { txt =",ASM,AES-NI"; }
#endif
*so << txt;
}
#endif
*so << ")\n\n";
}