mirror of http://192.168.1.51:8099/gb/code_util
1766 lines
50 KiB
C++
1766 lines
50 KiB
C++
// scanner.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
|
|
//
|
|
|
|
#include <iostream>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <vector>
|
|
#include <algorithm>
|
|
#include <sys/shm.h>
|
|
#include <math.h>
|
|
|
|
#include "cmd.h"
|
|
#include "usb_manager.h"
|
|
|
|
#define CONST_E 2.7182818284590452353602874713527f
|
|
#define CONST_PI 3.1415926535897932384626433832795f
|
|
#define MM_PER_INCH 25.4f
|
|
#define IS_EQUAL(v, t) ((v - t) >= -.00001f && (v - t) <= .00001f)
|
|
|
|
namespace proc_util
|
|
{
|
|
static bool is_match(const char* str, const char* pattern)
|
|
{
|
|
std::vector<std::string> parts;
|
|
std::string all(pattern);
|
|
size_t pos = all.find("*");
|
|
|
|
while(pos != std::string::npos)
|
|
{
|
|
if(pos)
|
|
parts.push_back(all.substr(0, pos));
|
|
all.erase(0, pos + 1);
|
|
pos = all.find("*");
|
|
}
|
|
if(!all.empty())
|
|
parts.push_back(all);
|
|
|
|
for(pos = 0; pos < parts.size(); ++pos)
|
|
{
|
|
str = strstr(str, parts[pos].c_str());
|
|
if(!str)
|
|
break;
|
|
str += parts[pos].length();
|
|
}
|
|
|
|
return pos == parts.size();
|
|
}
|
|
static bool found_proc(uint64_t pid, const char* path, void* param)
|
|
{
|
|
struct
|
|
{
|
|
uint32_t cnt = 0;
|
|
std::string filter = "";
|
|
}*ptr;
|
|
*((void**)&ptr) = param;
|
|
|
|
if(ptr->filter.empty() || is_match(path, ptr->filter.c_str()))
|
|
printf("%d - %ld: %s\n", ++ptr->cnt, pid, path);
|
|
|
|
return true;
|
|
}
|
|
static bool found_modules(const char* path, bool is_dir, void* param)
|
|
{
|
|
uint32_t* cnt = (uint32_t*)param;
|
|
|
|
printf("%d - %s\n", ++cnt[0], path);
|
|
|
|
return true;
|
|
}
|
|
static bool found_modules_norepeat(const char* path, bool is_dir, void* param)
|
|
{
|
|
struct
|
|
{
|
|
uint32_t cnt;
|
|
std::vector<std::string> modules;
|
|
}*data = nullptr;
|
|
|
|
*(void**)&data = param;
|
|
|
|
if (std::find(data->modules.begin(), data->modules.end(), path) == data->modules.end())
|
|
{
|
|
printf("%d - %s\n", ++data->cnt, path);
|
|
data->modules.push_back(path);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
static bool on_found_thread(uint64_t tid, void* start_addr, void* param)
|
|
{
|
|
uint32_t* cnt = (uint32_t*)param;
|
|
|
|
printf("%d - %p(%u): starting at %p\n", ++cnt[0], tid, tid, start_addr);
|
|
|
|
return true;
|
|
}
|
|
static bool on_stack(uint64_t off, const char* module, void* param)
|
|
{
|
|
uint32_t* cnt = (uint32_t*)param;
|
|
|
|
printf("%d - %s + %p\n", ++cnt[0], module, off);
|
|
|
|
return true;
|
|
}
|
|
|
|
// -proc
|
|
static CONSOLE_ROUTINE(print_help)
|
|
{
|
|
printf("\
|
|
usage: enmo <pid> [-nrp]: to enumerate modules of process pid. -nrp is no repeating\n\
|
|
enpr [-filter *.so]: to enum all processes\n\
|
|
enth <pid>: to enumerate threads of process pid\n\
|
|
exit: to exit this APP\n\
|
|
q: quit process utility\n\
|
|
stck <pid> <tid>: to get thread(tid) calling stack of process pid\n\n\
|
|
");
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_module)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
uint64_t pid = sys_util::to_int(cmd->parameter(0));
|
|
bool nrp = cmd->count() >= 2 && strcmp(cmd->parameter(1), "-nrp") == 0;
|
|
|
|
if(nrp)
|
|
{
|
|
struct
|
|
{
|
|
uint32_t cnt = 0;
|
|
std::vector<std::string> modules;
|
|
}data;
|
|
|
|
sys_util::enum_modules(found_modules_norepeat, &data, pid);
|
|
}
|
|
else
|
|
{
|
|
uint32_t cnt = 0;
|
|
sys_util::enum_modules(found_modules, &cnt, pid);
|
|
}
|
|
}
|
|
else
|
|
printf(" enmo <pid> [-nrp]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_process)
|
|
{
|
|
struct
|
|
{
|
|
uint32_t cnt = 0;
|
|
std::string filter = "";
|
|
}para;
|
|
|
|
if(cmd->parameter("-filter"))
|
|
{
|
|
para.filter = cmd->parameter("-filter");
|
|
}
|
|
|
|
sys_util::enum_processes(found_proc, ¶);
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_thread)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
uint32_t cnt = 0;
|
|
|
|
sys_util::enum_threads(sys_util::to_int(cmd->parameter(0)), on_found_thread, &cnt);
|
|
}
|
|
else
|
|
printf(" enth <pid>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(get_stack)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
uint32_t cnt = 0;
|
|
|
|
sys_util::get_thread_callstack(sys_util::to_int(cmd->parameter(0)), sys_util::to_int(cmd->parameter(1)), on_stack, &cnt);
|
|
}
|
|
else
|
|
printf(" stck <pid> <tid>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(run_console)
|
|
{
|
|
quit_cmd quit = QUIT_CMD_NONE;
|
|
std::string pre_cmd = cmd->to_command_line();
|
|
console_dispatcher me;
|
|
|
|
me.add_command_routine("enmo", enum_module);
|
|
me.add_command_routine("enpr", enum_process);
|
|
me.add_command_routine("enth", enum_thread);
|
|
me.add_command_routine("stck", get_stack);
|
|
me.set_unhandled_routine(print_help);
|
|
quit = me.run("hgutil-proc", pre_cmd.c_str());
|
|
|
|
return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE;
|
|
}
|
|
}
|
|
namespace kernel_obj
|
|
{
|
|
// -kobj
|
|
static quit_cmd print_help(cmd_line* cmd, void* param)
|
|
{
|
|
printf("\
|
|
usage: enmsg: enumerate all shared memories\n\
|
|
ensem: enumerate all semaphores\n\
|
|
enshm: enumerate all shared memories\n\
|
|
rdshm <shm-key> [-size] [-f save-local-file]: read shared memory\n\
|
|
rmshm <shm-key>: remove shared-memory which defined by 'shm-key'\n\
|
|
exit: to exit this APP\n\
|
|
q: quit process utility\n\
|
|
\n\
|
|
");
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(read_shm)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
key_t k = (key_t)sys_util::to_int(cmd->parameter(0));
|
|
int shm = shmget(k, 0, 0600);
|
|
if(shm == -1)
|
|
{
|
|
printf(" Failed: shmget(%p, 0, 0600) = %d(%s)\n", k, errno, strerror(errno));
|
|
}
|
|
else
|
|
{
|
|
size_t size = sys_util::get_page_size();
|
|
FILE *dst = nullptr;
|
|
char *buf = nullptr;
|
|
std::string file("");
|
|
|
|
if(cmd->parameter("-size"))
|
|
size = sys_util::to_int(cmd->parameter("-size"));
|
|
if(cmd->parameter("-f"))
|
|
{
|
|
file = sys_util::to_abs_path(getenv("PWD"), cmd->parameter("-f"));
|
|
dst = fopen(file.c_str(), "wb");
|
|
if(!dst)
|
|
printf(" Failed to create target file(%s) = %d(%s)\n", file.c_str(), errno, strerror(errno));
|
|
else
|
|
printf(" Write down to file '%s'\n", file.c_str());
|
|
}
|
|
|
|
buf = (char*)shmat(shm, 0, 0);
|
|
if(buf == (char*)-1)
|
|
{
|
|
printf(" Failed to map shared memory(%p) = %d(%s)\n", k, errno, strerror(errno));
|
|
if(dst)
|
|
{
|
|
fclose(dst);
|
|
remove(file.c_str());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(dst)
|
|
{
|
|
size = fwrite(buf, 1, size, dst);
|
|
fclose(dst);
|
|
printf(" %u bytes saved into file '%s'\n", size, file.c_str());
|
|
}
|
|
else
|
|
console_dispatcher::print_sector((uint8_t*)buf, size);
|
|
shmdt(buf);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
printf(" rmshm <shared-memory-key>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(remove_shm)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
key_t k = (key_t)sys_util::to_int(cmd->parameter(0));
|
|
int shm = shmget(k, 0, 0600);
|
|
if(shm == -1)
|
|
{
|
|
printf("Failed: shmget(%p, 0, 0600) = %d(%s), try system command 'ipcs -M %s'\n", k, errno, strerror(errno), cmd->parameter(0));
|
|
}
|
|
else
|
|
{
|
|
struct shmid_ds ds = {0};
|
|
if(shmctl(shm, IPC_RMID, &ds))
|
|
{
|
|
printf("Failed: shmctl(%d, IPC_RMID, (shmid_ds*)%p) = %d(%s)\n", shm, &ds, k, errno, strerror(errno));
|
|
}
|
|
else
|
|
printf("Remove shared-memory(%p) success.\n", k);
|
|
}
|
|
}
|
|
else
|
|
printf(" rmshm <shared-memory-key>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_shm)
|
|
{
|
|
system("ipcs -m");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_sem)
|
|
{
|
|
system("ipcs -s");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(enum_msg)
|
|
{
|
|
system("ipcs -q");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(run_console)
|
|
{
|
|
quit_cmd quit = QUIT_CMD_NONE;
|
|
std::string pre_cmd = cmd->to_command_line();
|
|
console_dispatcher me;
|
|
|
|
me.add_command_routine("rmshm", remove_shm);
|
|
me.add_command_routine("rdshm", read_shm);
|
|
me.add_command_routine("enshm", enum_shm);
|
|
me.add_command_routine("enmsg", enum_msg);
|
|
me.add_command_routine("ensem", enum_sem);
|
|
me.set_unhandled_routine(print_help);
|
|
quit = me.run("hgutil-kobj", pre_cmd.c_str());
|
|
|
|
return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE;
|
|
}
|
|
}
|
|
namespace mem_util
|
|
{
|
|
// -mem
|
|
static uint32_t handle(int32_t argc, char** argv)
|
|
{
|
|
uint64_t total = 0, avail = 0;
|
|
uint32_t page = sys_util::get_page_size(),
|
|
err = sys_util::get_memory_info(&total, &avail);
|
|
char cpu[256] = {0};
|
|
|
|
sys_util::get_inf_file_data("/proc/cpuinfo", sizeof(cpu) - 1, "model name\t:%s %s %s %s @ %s", cpu, cpu + 50, cpu + 100, cpu + 150, cpu + 200);
|
|
printf("CPU model: %s %s %s %s @ %s\n", cpu, cpu + 50, cpu + 100, cpu + 150, cpu + 200);
|
|
if(err)
|
|
printf("get memory info failed: %d(%s)\n", err, strerror(err));
|
|
else
|
|
{
|
|
printf("Memory total: %s\n", sys_util::format_readable_bytes(total).c_str());
|
|
printf("Memory avail: %s\n", sys_util::format_readable_bytes(avail).c_str());
|
|
}
|
|
printf("Page size: %d\n", page);
|
|
|
|
return err;
|
|
}
|
|
|
|
static quit_cmd run_console(cmd_line* cmd, void* param)
|
|
{
|
|
quit_cmd quit = QUIT_CMD_NONE;
|
|
|
|
handle(0, nullptr);
|
|
|
|
return quit;
|
|
}
|
|
}
|
|
namespace parse_util
|
|
{
|
|
// we assume the console locale is in UTF-8 here ...
|
|
static CONSOLE_ROUTINE(print_help)
|
|
{
|
|
printf("\
|
|
usage: dbl <hex-str>: parse hex-string as double\n\
|
|
fdbl <decimal>: convert a decimal to inn-code double. command: fdbl -123.456\n\
|
|
fflt <decimal>: convert a decimal to inn-code float. command: fflt -123.456\n\
|
|
flt <hex-str>: parse hex-string as float\n\
|
|
fstr <string>: convert ansi-string to inn-code\n\
|
|
fuf8 <string>: convert utf8-string to inn-code\n\
|
|
funi <string>: convert unic-string to inn-code\n\
|
|
int <hex-str>: parse hex-string as integer\n\
|
|
str <hex-str>: parse hex-string as ansi-string\n\
|
|
unic <hex-str>: parse hex-string as unicode-16-string\n\
|
|
utf8 <hex-str>: parse hex-string as utf8-string\n\
|
|
exit: to exit this APP\n\
|
|
q: quit process utility\n\
|
|
");
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static std::string from_hex_str(const char* hex)
|
|
{
|
|
const char* h = hex, *t = nullptr;
|
|
uint64_t v = sys_util::from_hex_str(h, &t);
|
|
char buf[80] = {0};
|
|
int off = 0;
|
|
std::string in("");
|
|
|
|
while(t > h)
|
|
{
|
|
if((t - h) % 2)
|
|
v <<= 4;
|
|
off = 8;
|
|
for(int i = 0; i < (t - h + 1) / 2; ++i, v >>= 8)
|
|
buf[--off] = v & 0xff;
|
|
in += std::string(buf + off, 8 - off);
|
|
h = t;
|
|
v = sys_util::from_hex_str(h, &t);
|
|
}
|
|
in.append(8, '\0');
|
|
|
|
return std::move(in);
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(as_double)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: %f\n", *(double*)&val[0]);
|
|
}
|
|
else
|
|
printf(" dbl <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(from_double)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
double val = atof(cmd->parameter(0));
|
|
|
|
printf("Result: ");
|
|
for(int i = 0; i < sizeof(val); ++i)
|
|
printf("%02X", ((uint8_t*)&val)[i]);
|
|
printf("\n");
|
|
}
|
|
else
|
|
printf(" fdbl <decimal>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(from_float)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
float val = atof(cmd->parameter(0));
|
|
|
|
printf("Result: ");
|
|
for(int i = 0; i < sizeof(val); ++i)
|
|
printf("%02X", ((uint8_t*)&val)[i]);
|
|
printf("\n");
|
|
}
|
|
else
|
|
printf(" fflt <decimal>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(as_float)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: %f\n", *(float*)&val[0]);
|
|
}
|
|
else
|
|
printf(" flt <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(as_integer)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
if(val.length() - 8 <= 4)
|
|
{
|
|
int n = 0;
|
|
if(val.length() - 8 == 1)
|
|
n = (char)val[0];
|
|
else if(val.length() - 8 == 2)
|
|
n = *(short*)&val[0];
|
|
else
|
|
n = *(int*)&val[0];
|
|
printf("Result: %d(%u)\n", n, n);
|
|
}
|
|
else
|
|
printf("Result: %ld\n", *(uint64_t*)&val[0]);
|
|
}
|
|
else
|
|
printf(" int <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(as_ansi_str)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: '%s'\n", sys_util::transform_between_gbk_and_utf8(val.c_str(), true).c_str());
|
|
}
|
|
else
|
|
printf(" str <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(as_unicode)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: '%s'\n", sys_util::transform_between_utf16_and_utf8(val.c_str(), val.length(), true).c_str());
|
|
}
|
|
else
|
|
printf(" unic <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(as_utf8)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: '%s'\n", val.c_str());
|
|
}
|
|
else
|
|
printf(" utf8 <hex-string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(from_ansi)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
val = sys_util::transform_between_gbk_and_utf8(val.c_str(), false);
|
|
printf("Result: ");
|
|
for(int i = 0; i < val.length(); ++i)
|
|
printf("%02X", (uint8_t)val[i]);
|
|
printf("\n");
|
|
}
|
|
else
|
|
printf(" fstr <string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(from_utf8)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
printf("Result: ");
|
|
for(int i = 0; i < val.length(); ++i)
|
|
printf("%02X", (uint8_t)val[i]);
|
|
printf("\n");
|
|
}
|
|
else
|
|
printf(" fuf8 <string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(from_unicode)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
std::string val(from_hex_str(cmd->parameter(0)));
|
|
|
|
val = sys_util::transform_between_utf16_and_utf8(val.c_str(), val.length(), false);
|
|
printf("Result: ");
|
|
for(int i = 0; i < val.length(); ++i)
|
|
printf("%02X", (uint8_t)val[i]);
|
|
printf("\n");
|
|
}
|
|
else
|
|
printf(" funi <string>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(run_console)
|
|
{
|
|
quit_cmd quit = QUIT_CMD_NONE;
|
|
std::string pre_cmd = cmd->to_command_line();
|
|
console_dispatcher me;
|
|
|
|
me.add_command_routine("dbl", as_double);
|
|
me.add_command_routine("fdbl", from_double);
|
|
me.add_command_routine("fflt", from_float);
|
|
me.add_command_routine("flt", as_float);
|
|
me.add_command_routine("int", as_integer);
|
|
me.add_command_routine("str", as_ansi_str);
|
|
me.add_command_routine("unic", as_unicode);
|
|
me.add_command_routine("utf8", as_utf8);
|
|
me.add_command_routine("fstr", from_ansi);
|
|
me.add_command_routine("fuf8", from_utf8);
|
|
me.add_command_routine("funi", from_unicode);
|
|
me.set_unhandled_routine(print_help);
|
|
quit = me.run("hgutil-parse", pre_cmd.c_str());
|
|
|
|
return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE;
|
|
}
|
|
}
|
|
namespace calculator
|
|
{
|
|
static std::string format_readable_integer(uint64_t v, const char* fmt, int align = 4, const char* sep = " ", bool patch = true)
|
|
{
|
|
char buf[80] = {0};
|
|
std::string ret("");
|
|
|
|
if(strcmp(fmt, "%lb") == 0)
|
|
{
|
|
while(v)
|
|
{
|
|
ret.insert(0, v & 1 ? "1" : "0");
|
|
v >>= 1;
|
|
}
|
|
if(ret.empty())
|
|
ret = "0";
|
|
}
|
|
else
|
|
{
|
|
sprintf(buf, fmt, v);
|
|
ret = buf;
|
|
}
|
|
if(patch && (ret.length() % align))
|
|
{
|
|
std::string fill("");
|
|
|
|
fill.append(align, '0');
|
|
ret.insert(0, fill);
|
|
ret.erase(0, ret.length() % align);
|
|
}
|
|
for(int i = ret.length() - align; i > 0; i -= align)
|
|
ret.insert(i, sep);
|
|
|
|
return std::move(ret);
|
|
}
|
|
static bool is_valid_double(double v)
|
|
{
|
|
return isnan(v) == 0;
|
|
}
|
|
static double pick_decimal(const char*& dec, bool* ok)
|
|
{
|
|
double sign = 1.0f, radix = 1.0f, val = .0f, coef = 10.0f;
|
|
|
|
if(ok)
|
|
*ok = true;
|
|
if(*dec == '-')
|
|
{
|
|
sign = -1.0f;
|
|
dec++;
|
|
}
|
|
while(*dec)
|
|
{
|
|
if(*dec == '.')
|
|
{
|
|
if(radix < 1.0f)
|
|
{
|
|
if(ok)
|
|
*ok = false;
|
|
break;
|
|
}
|
|
radix = .1f;
|
|
coef = 1.0f;
|
|
}
|
|
else if(*dec == '-')
|
|
break;
|
|
else if(*dec >= '0' && *dec <= '9')
|
|
{
|
|
val *= coef;
|
|
val += (*dec - '0') * radix;
|
|
if(radix < 1.0f)
|
|
radix *= .1f;
|
|
}
|
|
else
|
|
break;
|
|
dec++;
|
|
}
|
|
|
|
if(!is_valid_double(val) && ok)
|
|
*ok = false;
|
|
|
|
return val * sign;
|
|
}
|
|
static double calc_exp(const char* exp, bool *ok = nullptr)
|
|
{
|
|
bool good = true;
|
|
double val = .0f, sign = 1.0f;
|
|
std::string sop("");
|
|
|
|
if(!ok)
|
|
ok = &good;
|
|
|
|
while(*exp)
|
|
{
|
|
double hi = .0f;
|
|
bool calc = false;
|
|
if(*exp == '(')
|
|
{
|
|
const char* end = sys_util::pick_simple_block(exp, ')');
|
|
if(!end)
|
|
{
|
|
*ok = false;
|
|
printf("Invalid expression: '%s'\n", exp);
|
|
break;
|
|
}
|
|
|
|
std::string sub(exp + 1, end - exp - 1);
|
|
|
|
sys_util::trim_left(sub);
|
|
sys_util::trim_right(sub);
|
|
hi = calc_exp(sub.c_str(), ok);
|
|
if(!ok[0])
|
|
break;
|
|
|
|
exp = end + 1;
|
|
calc = true;
|
|
}
|
|
else if(*exp == '-')
|
|
{
|
|
sign = -1.0f;
|
|
exp++;
|
|
}
|
|
else if(*exp == '.' || (*exp >= '0' && *exp <= '9'))
|
|
{
|
|
// number ...
|
|
hi = pick_decimal(exp, ok);
|
|
calc = true;
|
|
}
|
|
|
|
if(!ok[0])
|
|
{
|
|
printf("Invalid expression.\n");
|
|
break;
|
|
}
|
|
if(calc)
|
|
{
|
|
hi *= sign;
|
|
sign = 1.0f;
|
|
}
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(print_help)
|
|
{
|
|
printf("\
|
|
usage: acos <num>: perform arccos(num)\n\
|
|
add <num1> <num2> [... num_n]: perform num1 + num2 + ... + num_n\n\
|
|
asin <num>: perform arcsin(num)\n\
|
|
atan <num>: perform atan(num)\n\
|
|
cos <num>: perform cos(num)\n\
|
|
deg <num>: transform between degree and radian\n\
|
|
div <num1> <num2> [... num_n]: perform num1 / num2 / ... / num_n\n\
|
|
iam <num>: transfrom between millimeters and inches\n\
|
|
ln <num>: e ^ result = num\n\
|
|
log <num> [base = 10]: base ^ result = num\n\
|
|
mul <num1> <num2> [... num_n]: perform num1 * num2 * ... * num_n\n\
|
|
paper [paper-type <dpi>]: list all paper type, or calculate image size in with given paper and dpi\n\
|
|
pow <base> <exp>: calculate base^exp\n\
|
|
radix <integer>: print a interger into hex, decimal, oct and binary\n\
|
|
sin <num>: perform sin(num)\n\
|
|
sqrt <base> [exp]: perform base^(1/2), or base^(1/exp)\n\
|
|
sub <num1> <num2> [... num_n]: perform num1 - num2 - ... - num_n\n\
|
|
tan <num>: perform tan(num)\n\
|
|
exit: to exit this APP\n\
|
|
q: quit process utility\n\
|
|
");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(radix)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* end = nullptr;
|
|
uint64_t v(sys_util::to_int(cmd->parameter(0), &end));
|
|
|
|
if(end == cmd->parameter(0))
|
|
printf("Invalid interger: %s\n", cmd->parameter(0));
|
|
else
|
|
{
|
|
std::string bin(format_readable_integer(v, "%lX"));
|
|
|
|
printf("Hex: %s\n", bin.c_str());
|
|
|
|
bin = format_readable_integer(v, "%ld", 3, ",", false);
|
|
printf("Dec: %s\n", bin.c_str());
|
|
|
|
bin = format_readable_integer(v, "%lo", 3);
|
|
printf("Oct: %s\n", bin.c_str());
|
|
|
|
bin = format_readable_integer(v, "%lb");
|
|
printf("Bin: %s\n", bin.c_str());
|
|
}
|
|
}
|
|
else
|
|
printf(" radix <integer>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(calculate)
|
|
{
|
|
std::string exp(cmd->to_command_line());
|
|
double val = .0f;
|
|
bool ok = true;
|
|
|
|
sys_util::trim_left(exp);
|
|
sys_util::trim_right(exp);
|
|
val = calc_exp(exp.c_str(), &ok);
|
|
if(ok)
|
|
printf("Result: %f\n", val);
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(add)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* para = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(para, &ok), sum = .0f;
|
|
int ind = 0;
|
|
|
|
while(ok && *para == 0)
|
|
{
|
|
sum += v;
|
|
if(!is_valid_double(sum))
|
|
{
|
|
printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind));
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
if(ind + 1 >= cmd->count())
|
|
break;
|
|
para = cmd->parameter(++ind);
|
|
v = pick_decimal(para, &ok);
|
|
}
|
|
if(ok && *para == 0)
|
|
printf("Result: %f\n", sum);
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(ind));
|
|
}
|
|
else
|
|
printf(" add <num1> <num2> [...num_n]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(sub)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* para = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(para, &ok), sum = .0f;
|
|
int ind = 0;
|
|
|
|
while(ok && *para == 0)
|
|
{
|
|
if(ind == 0)
|
|
sum = v;
|
|
else
|
|
sum -= v;
|
|
if(!is_valid_double(sum))
|
|
{
|
|
printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind));
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
if(ind + 1 >= cmd->count())
|
|
break;
|
|
para = cmd->parameter(++ind);
|
|
v = pick_decimal(para, &ok);
|
|
}
|
|
if(ok && *para == 0)
|
|
printf("Result: %f\n", sum);
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(ind));
|
|
}
|
|
else
|
|
printf(" sub <num1> <num2> [...num_n]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(mul)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* para = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(para, &ok), sum = 1.0f;
|
|
int ind = 0;
|
|
|
|
while(ok && *para == 0)
|
|
{
|
|
sum *= v;
|
|
if(!is_valid_double(sum))
|
|
{
|
|
printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind));
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
if(ind + 1 >= cmd->count())
|
|
break;
|
|
para = cmd->parameter(++ind);
|
|
v = pick_decimal(para, &ok);
|
|
}
|
|
if(ok && *para == 0)
|
|
printf("Result: %f\n", sum);
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(ind));
|
|
}
|
|
else
|
|
printf(" add <num1> <num2> [...num_n]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(div)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* para = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(para, &ok), sum = .0f;
|
|
int ind = 0;
|
|
|
|
while(ok && *para == 0)
|
|
{
|
|
if(ind == 0)
|
|
sum = v;
|
|
else
|
|
sum /= v;
|
|
if(!is_valid_double(sum))
|
|
{
|
|
printf("Invalid result when calculate %d data: %s\n", ind + 1, cmd->parameter(ind));
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
if(ind + 1 >= cmd->count())
|
|
break;
|
|
para = cmd->parameter(++ind);
|
|
v = pick_decimal(para, &ok);
|
|
}
|
|
if(ok && *para == 0)
|
|
printf("Result: %f\n", sum);
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(ind));
|
|
}
|
|
else
|
|
printf(" sub <num1> <num2> [...num_n]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(inch_and_mm)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("%fmm = %finch\n", v, v / MM_PER_INCH);
|
|
printf("%finch = %fmm\n", v, v * MM_PER_INCH);
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" iam <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_log)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok), vb = 10.0f;
|
|
|
|
if(*oper == 0 && ok && v > .0f)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
oper = cmd->parameter(1);
|
|
vb = pick_decimal(oper, &ok);
|
|
if(*oper || !ok || vb <= .0f)
|
|
{
|
|
printf("Invalid number: %s\n", cmd->parameter(1));
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
}
|
|
printf("Result: %f\n", log(v) / log(vb));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" log <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_ln)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok && v > .0f)
|
|
{
|
|
printf("Result: %f\n", log(v) / log(CONST_E));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" log <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_degree)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("%f degree = %f radian\n", v, v / 180.0f * CONST_PI);
|
|
printf("%f radian = %f degree\n", v, v / CONST_PI * 180.0f);
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" deg <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_sin)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("Result in degree: %f\n", sin(v / 180.0f * CONST_PI));
|
|
printf("Result in radian: %f\n", sin(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" sin <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_cos)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("Result in degree: %f\n", cos(v / 180.0f * CONST_PI));
|
|
printf("Result in radian: %f\n", cos(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" cos <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_tan)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("Result in degree: %f\n", tan(v / 180.0f * CONST_PI));
|
|
printf("Result in radian: %f\n", tan(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" tan <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_asin)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f)
|
|
{
|
|
printf("Result in degree: %f\n", asin(v) / CONST_PI * 180.0f);
|
|
printf("Result in radian: %f\n", asin(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" asin <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_acos)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f)
|
|
{
|
|
printf("Result in degree: %f\n", acos(v) / CONST_PI * 180.0f);
|
|
printf("Result in radian: %f\n", acos(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" acos <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_atan)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok);
|
|
|
|
if(*oper == 0 && ok && v >= -1.0f && v <= 1.0f)
|
|
{
|
|
printf("Result in degree: %f\n", atan(v) / CONST_PI * 180.0f);
|
|
printf("Result in radian: %f\n", atan(v));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" atan <num>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(paper)
|
|
{
|
|
struct
|
|
{
|
|
std::string type;
|
|
float w;
|
|
float h;
|
|
}papers[] = {
|
|
{"A3", 297.0, 420.0},
|
|
{"A4", 210.0, 297.0},
|
|
{"A5", 148.0, 210.0},
|
|
{"A6", 105.0, 148.0},
|
|
{"B4", 257.0, 364.0},
|
|
{"B5", 182.0, 257.0},
|
|
{"JIS-B5", 176.0, 250.0},
|
|
{"B6", 125.0, 176.0}
|
|
};
|
|
if(cmd->count() == 0)
|
|
{
|
|
printf("Paper-type\tSize (mm)\n");
|
|
for(auto& v: papers)
|
|
printf(" %s %f * %f\n", v.type.c_str(), v.w, v.h);
|
|
}
|
|
else
|
|
{
|
|
bool help = true;
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* str = cmd->parameter(1);
|
|
bool ok = true;
|
|
double dpi = pick_decimal(str, &ok);
|
|
|
|
if(ok && *str == 0 && dpi > .0f)
|
|
{
|
|
for(auto& v: papers)
|
|
{
|
|
if(v.type == cmd->parameter(0))
|
|
{
|
|
double w = v.w / MM_PER_INCH * dpi + .999f,
|
|
h = v.h / MM_PER_INCH * dpi + .999f;
|
|
printf("Paper '%s' in DPI(%f) image size(pixel): %d * %d\n", v.type.c_str(), dpi, (int)w, (int)h);
|
|
help = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("Invalid DPI: %s\n", cmd->parameter(1));
|
|
help = false;
|
|
}
|
|
}
|
|
if(help)
|
|
{
|
|
printf(" paper [paper-type <dpi>]. paper type now support following:\n ");
|
|
for(auto& v: papers)
|
|
printf("%s ", v.type.c_str());
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_pow)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok), e = .0f;
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
oper = cmd->parameter(1);
|
|
e = pick_decimal(oper, &ok);
|
|
if(*oper == 0 && ok)
|
|
{
|
|
printf("Result: %f\n", pow(v, e));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(1));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" pow <base> <exp>\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(func_sqrt)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
const char* oper = cmd->parameter(0);
|
|
bool ok = true;
|
|
double v = pick_decimal(oper, &ok), e = .5f;
|
|
|
|
if(*oper == 0 && ok)
|
|
{
|
|
if(cmd->count() >= 2)
|
|
{
|
|
oper = cmd->parameter(1);
|
|
e = pick_decimal(oper, &ok);
|
|
if(*oper == 0 && ok && !IS_EQUAL(e, .0f))
|
|
{
|
|
e = 1.0f / e;
|
|
}
|
|
else
|
|
{
|
|
ok = false;
|
|
printf("Invalid number: %s\n", cmd->parameter(1));
|
|
}
|
|
}
|
|
if(ok)
|
|
printf("Result: %f\n", pow(v, e));
|
|
}
|
|
else
|
|
printf("Invalid number: %s\n", cmd->parameter(0));
|
|
}
|
|
else
|
|
printf(" sqrt <base> [exp]\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(run_console)
|
|
{
|
|
quit_cmd quit = QUIT_CMD_NONE;
|
|
std::string pre_cmd = cmd->to_command_line();
|
|
console_dispatcher me;
|
|
|
|
me.add_command_routine("add", add);
|
|
me.add_command_routine("sub", sub);
|
|
me.add_command_routine("mul", mul);
|
|
me.add_command_routine("div", div);
|
|
me.add_command_routine("iam", inch_and_mm);
|
|
me.add_command_routine("ln", func_ln);
|
|
me.add_command_routine("log", func_log);
|
|
me.add_command_routine("deg", func_degree);
|
|
me.add_command_routine("cos", func_cos);
|
|
me.add_command_routine("sin", func_sin);
|
|
me.add_command_routine("tan", func_tan);
|
|
me.add_command_routine("acos", func_acos);
|
|
me.add_command_routine("asin", func_asin);
|
|
me.add_command_routine("atan", func_atan);
|
|
me.add_command_routine("paper", paper);
|
|
me.add_command_routine("radix", radix);
|
|
me.add_command_routine("pow", func_pow);
|
|
me.add_command_routine("sqrt", func_sqrt);
|
|
me.set_unhandled_routine(print_help);
|
|
quit = me.run("hgutil-calc", pre_cmd.c_str());
|
|
|
|
return quit == QUIT_CMD_QUIT_ALL ? quit : QUIT_CMD_NONE;
|
|
}
|
|
|
|
}
|
|
|
|
namespace top
|
|
{
|
|
static CONSOLE_ROUTINE(print_help);
|
|
static CONSOLE_ROUTINE(clear_screen);
|
|
static CONSOLE_ROUTINE(quit_me);
|
|
static CONSOLE_ROUTINE(quit_all);
|
|
static CONSOLE_ROUTINE(system_call);
|
|
static CONSOLE_ROUTINE(recursive_file_oper);
|
|
static CONSOLE_ROUTINE(error_message);
|
|
};
|
|
|
|
namespace usb
|
|
{
|
|
struct {
|
|
int vid;
|
|
int pid;
|
|
}g_scanner[] = {
|
|
{0x31c9, 0x8200},
|
|
{0x31c9, 0x8420},
|
|
{0x31c9, 0x8429},
|
|
{0x31c9, 0x8520},
|
|
{0x31c9, 0x8529},
|
|
{0x31c9, 0x8620},
|
|
{0x31c9, 0x8629},
|
|
{0x31c9, 0x8730},
|
|
{0x31c9, 0x8739},
|
|
{0x2903, 0x1000},
|
|
{0x2903, 0x1002},
|
|
{0x2903, 0x7000},
|
|
{0x2903, 0x7002},
|
|
{0x2903, 0x7039},
|
|
{0x2903, 0x8000},
|
|
{0x2903, 0x9000},
|
|
{0x3308, 0x6006},
|
|
{0x3308, 0x6005},
|
|
{0x3308, 0x0238},
|
|
{0x3308, 0x0138},
|
|
{0X05DA, 0x9220},
|
|
{0x3072, 0x100},
|
|
{0x3072, 0x139},
|
|
{0x3072, 0x200},
|
|
{0x3072, 0x239},
|
|
{0x3072, 0x300},
|
|
{0x3072, 0x302},
|
|
{0x3072, 0x339},
|
|
{0x3072, 0x400},
|
|
{0x3072, 0x402},
|
|
{0x3072, 0x439},
|
|
{0x064B, 0x7823}
|
|
};
|
|
typedef struct _usb_device_que
|
|
{
|
|
int vid = 0;
|
|
int pid = 0;
|
|
libusb_device* device = nullptr;
|
|
usb_io* io = nullptr;
|
|
|
|
bool operator==(const libusb_device* dev)
|
|
{
|
|
return dev == device;
|
|
}
|
|
}USBDEVQ, *LPUSBDEVQ;
|
|
std::vector<USBDEVQ> devs_;
|
|
std::mutex dev_lock_;
|
|
|
|
void usb_event_function(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l
|
|
{
|
|
std::lock_guard<std::mutex> lock(dev_lock_);
|
|
std::vector<USBDEVQ>::iterator it = std::find(devs_.begin(), devs_.end(), device);
|
|
|
|
if (USB_EVENT_DEVICE_ARRIVED == ev)
|
|
{
|
|
if(it == devs_.end())
|
|
{
|
|
USBDEVQ dev;
|
|
dev.vid = vid;
|
|
dev.pid = pid;
|
|
dev.device = device;
|
|
devs_.push_back(dev);
|
|
}
|
|
else
|
|
{
|
|
it->vid = vid;
|
|
it->pid = pid;
|
|
}
|
|
}
|
|
else if (USB_EVENT_DEVICE_LEFT == ev)
|
|
{
|
|
if(it != devs_.end())
|
|
{
|
|
if(it->io)
|
|
it->io->release();
|
|
devs_.erase(it);
|
|
}
|
|
}
|
|
}
|
|
static bool is_scanner(int vid, int pid)
|
|
{
|
|
for(auto& v: g_scanner)
|
|
{
|
|
if(v.vid == vid && v.pid == pid)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
static void resolve(USBDEVQ& dev)
|
|
{
|
|
std::string msg("");
|
|
usb_io* io = nullptr;
|
|
int err = usb_manager::instance()->open(dev.device, &io, &msg);
|
|
|
|
if(err)
|
|
{
|
|
printf(" Open failed: %d - %s\n", dev.vid, dev.pid, err, msg.c_str());
|
|
printf(" To resolve this device, try RESTART it!\n\n");
|
|
if(io)
|
|
io->release();
|
|
|
|
return;
|
|
}
|
|
|
|
int size = 1024 * 1024,
|
|
len = size,
|
|
total = 0;
|
|
char *buf = new char[size];
|
|
|
|
io->set_timeout(100);
|
|
printf(" First: Clear bulk end-point ...");
|
|
while((err = io->read_bulk(buf, &len)) == 0)
|
|
{
|
|
total += len;
|
|
len = size;
|
|
}
|
|
printf(" %d byte(s) cleared with last error(%d).\n", total, err);
|
|
|
|
printf(" Second: Clear interrupt end-point ...");
|
|
total = 0;
|
|
len = size;
|
|
io->set_timeout(100);
|
|
while((err = io->read_interrupt(buf, &len)) == 0)
|
|
{
|
|
total += len;
|
|
len = size;
|
|
}
|
|
printf(" %d byte(s) cleared with last error(%d).\n", total, err == SCANNER_ERR_TIMEOUT ? 0 : err);
|
|
|
|
// try get SN:
|
|
printf(" Last: try get serial number ... ");
|
|
total = sizeof(len);
|
|
len = 0;
|
|
err = io->control_io(0x40, 0x64, 18, 0, &len, &total);
|
|
if(err == SCANNER_ERR_TIMEOUT)
|
|
{
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
err = io->control_io(0x40, 0x64, 18, 0, &len, &total);
|
|
}
|
|
if(err)
|
|
printf("write command failed: %d\n", err);
|
|
else
|
|
{
|
|
len = size;
|
|
err = io->read_bulk(buf, &len);
|
|
buf[len] = 0;
|
|
printf("%s (%d)\n", buf, err == SCANNER_ERR_TIMEOUT ? 0 : err);
|
|
}
|
|
delete[] buf;
|
|
printf("\n");
|
|
|
|
io->release();
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(print_help)
|
|
{
|
|
printf("\
|
|
usage: trouble: to resolve problem with HGs scanner\n\
|
|
lsusb: to print all USB devices\n\
|
|
exit: to exit this APP\n\
|
|
q: quit process utility\n\
|
|
");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(trouble)
|
|
{
|
|
std::lock_guard<std::mutex> lock(dev_lock_);
|
|
int cnt = 0;
|
|
for(auto& v : devs_)
|
|
{
|
|
if(!is_scanner(v.vid, v.pid))
|
|
continue;
|
|
|
|
printf(" %d: Resolve %04X:%04X ...\n", ++cnt, v.vid, v.pid);
|
|
resolve(v);
|
|
}
|
|
if(cnt == 0)
|
|
printf(" No scanner found!\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(list_usb)
|
|
{
|
|
std::lock_guard<std::mutex> lock(dev_lock_);
|
|
int cnt = 0;
|
|
|
|
for(auto& v : devs_)
|
|
printf(" %d: %04X:%04X\n", ++cnt, v.vid, v.pid);
|
|
if(cnt == 0)
|
|
printf(" No USB device found!\n");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(usb_tool)
|
|
{
|
|
usb_manager::instance()->register_hotplug(&usb_event_function, nullptr);
|
|
|
|
console_dispatcher me;
|
|
|
|
me.add_command_routine("trouble", &trouble);
|
|
me.add_command_routine("lsusb", &list_usb);
|
|
me.set_unhandled_routine(print_help);
|
|
|
|
quit_cmd ret = me.run("hgutil-usb");
|
|
|
|
return ret == QUIT_CMD_QUIT_ALL ? ret : QUIT_CMD_NONE;
|
|
}
|
|
}
|
|
|
|
int32_t main(int32_t argc, char *argv[])
|
|
{
|
|
// hgutil -proc
|
|
int err = 0;
|
|
|
|
console_dispatcher::add_supper_command_routine("clear", &top::clear_screen);
|
|
console_dispatcher::add_supper_command_routine("exit", &top::quit_all);
|
|
console_dispatcher::add_supper_command_routine("q", &top::quit_me);
|
|
console_dispatcher::add_supper_command_routine("sys", &top::system_call);
|
|
console_dispatcher::add_supper_command_routine("errm", &top::error_message);
|
|
|
|
console_dispatcher top;
|
|
|
|
top.add_command_routine("proc", proc_util::run_console);
|
|
top.add_command_routine("kobj", kernel_obj::run_console);
|
|
top.add_command_routine("mem", mem_util::run_console);
|
|
top.add_command_routine("parse", parse_util::run_console);
|
|
top.add_command_routine("calc", calculator::run_console);
|
|
top.add_command_routine("recf", top::recursive_file_oper);
|
|
top.add_command_routine("usb", usb::usb_tool);
|
|
top.set_unhandled_routine(top::print_help);
|
|
top.run("hgutil");
|
|
|
|
return 0;
|
|
}
|
|
|
|
namespace top
|
|
{
|
|
static CONSOLE_ROUTINE(print_help)
|
|
{
|
|
printf("\
|
|
usage: calc: calculator utility\n\
|
|
clear: clear screen\n\
|
|
errm: <err-no> print error message of 'err-no'\n\
|
|
kobj: named kernel objects(shared memory, event...) utility\n\
|
|
mem: memory utility\n\
|
|
parse: parse inner-code as readable target\n\
|
|
proc: process utilities\n\
|
|
recf: recursive execute system command on files\n\
|
|
usb : usb utilities\n\
|
|
q: exit\n\
|
|
sys: invoke system command\n\n\
|
|
");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(clear_screen)
|
|
{
|
|
system("clear");
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
static CONSOLE_ROUTINE(quit_me)
|
|
{
|
|
return QUIT_CMD_QUIT_ME;
|
|
}
|
|
static CONSOLE_ROUTINE(quit_all)
|
|
{
|
|
return QUIT_CMD_QUIT_ALL;
|
|
}
|
|
static CONSOLE_ROUTINE(system_call)
|
|
{
|
|
std::string cmdl(cmd->to_command_line());
|
|
|
|
system(cmdl.c_str());
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
bool is_wildcard_match(const char* str, const char* pattern, int str_len, int patt_len)
|
|
{
|
|
int str_ind = 0, pattern_ind = 0, star = -1, m = 0;
|
|
|
|
if (str_len == -1)
|
|
str_len = strlen(str);
|
|
if (patt_len == -1)
|
|
patt_len = strlen(pattern);
|
|
while (str_ind < str_len)
|
|
{
|
|
if (pattern_ind < patt_len && (str[str_ind] == pattern[pattern_ind] || pattern[pattern_ind] == '?'))
|
|
{
|
|
str_ind++;
|
|
pattern_ind++;
|
|
}
|
|
else if (pattern_ind < patt_len && pattern[pattern_ind] == '*')
|
|
{
|
|
star = pattern_ind++;
|
|
m = str_ind;
|
|
}
|
|
else if (star != -1)
|
|
{
|
|
pattern_ind = star + 1;
|
|
str_ind = ++m;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
while (pattern_ind < patt_len && pattern[pattern_ind] == '*')
|
|
pattern_ind++;
|
|
|
|
return pattern_ind == patt_len;
|
|
}
|
|
static bool is_match(const char* val, const char* pattern)
|
|
{
|
|
if(strstr(pattern, "*"))
|
|
{
|
|
return is_wildcard_match(val, pattern, strlen(val), strlen(pattern));
|
|
}
|
|
else
|
|
{
|
|
return strcmp(val, pattern) == 0;
|
|
}
|
|
}
|
|
static bool on_file_found(const char* path, bool is_dir, void* param)
|
|
{
|
|
if(is_dir)
|
|
return true;
|
|
struct
|
|
{
|
|
std::string pattern;
|
|
std::string syscmd;
|
|
}*para = nullptr;
|
|
const char* name = strrchr(path, '/');
|
|
|
|
if(name++ == nullptr)
|
|
name = path;
|
|
*((void**)¶) = param;
|
|
if(is_match(name, para->pattern.c_str()))
|
|
{
|
|
std::string cmd(para->syscmd), file(path);
|
|
size_t pos = cmd.find("%s");
|
|
|
|
if(file.find(" ") != std::string::npos)
|
|
{
|
|
file += "\"";
|
|
file.insert(0, "\"");
|
|
}
|
|
cmd.replace(pos, 2, file);
|
|
printf(" %s = %d\n", cmd.c_str(), system(cmd.c_str()));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
static CONSOLE_ROUTINE(recursive_file_oper)
|
|
{
|
|
// recf <path /home> <file Makefile or *.sh> <sys-command chmod 777 %s - '%s' is the file>
|
|
bool help = true;
|
|
|
|
if(cmd->count() > 3)
|
|
{
|
|
std::string path(cmd->parameter(0)),
|
|
file(cmd->parameter(1)),
|
|
syscmd("");
|
|
struct
|
|
{
|
|
std::string pattern;
|
|
std::string syscmd;
|
|
}para;
|
|
|
|
|
|
cmd->remove(0);
|
|
cmd->remove(0);
|
|
para.syscmd = cmd->to_command_line();
|
|
para.pattern = std::move(file);
|
|
help = para.syscmd.find("%s") == std::string::npos;
|
|
|
|
if(!help)
|
|
sys_util::enum_files(path.c_str(), on_file_found, ¶);
|
|
}
|
|
if(help)
|
|
{
|
|
printf(" recf <path /home> <file Makefile or *.sh> <sys-command chmod 777 %%s - '%%s' is the file>\n");
|
|
}
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
|
|
static CONSOLE_ROUTINE(error_message)
|
|
{
|
|
if(cmd->count())
|
|
{
|
|
printf(" error %d: %s\n", atoi(cmd->parameter(0)), strerror(atoi(cmd->parameter(0))));
|
|
}
|
|
else
|
|
{
|
|
printf(" errm <err-no>\n");
|
|
}
|
|
|
|
return QUIT_CMD_NONE;
|
|
}
|
|
};
|
|
|