本帖最后由 happy886rr 于 2016-11-25 00:13 编辑
TINCS.EXE
__________________________________________________________________________
一款采用TCCLIB库制作的C脚本解释器,体积不足60KB,但是能动态执行批处理中的
C语言源代码,且无需编译,无需主函数main(),任意函数随意呼,任意参数随意传。
该解释器无需库文件都可运行,当然如果没有库文件,很多函数需要自己去实现,如
果涉及到复杂的函数调用,建议将tcc或mingw的库文件include和lib文件夹拷贝至
tincs.exe的同目录。
约定:/|||为混编开始符,|||/为混编结束符;tincs将从/|||作为开始端执行脚本
__________________________________________________________________________
批处理C脚本解释器, 版本 1.0
使用:
tincs -s [脚本名] -f [函数名] -v [传入参数]
__________________________________________________________________________
选项:
-h 显示帮助
-s 指定脚本文件
-f 指定要调用的函数名
-v 指定传入参数
__________________________________________________________________________
示例:
执行批处理脚本自身,呼叫strlen函数计算字符串“你好”的长度
tincs -s "%~f0" -f strlen -v "你好"
__________________________________________________________________________
英译:
THE PARSER OF C SCRIPT, VERSION 1.0
TINCS.EXE
COPYRIGHT@2016~2018 BY HAPPY
-------------------------------------------------------------------------
tincs -s [ScriptFile] -f [FunctionName] -v [Parameters]
-------------------------------------------------------------------------
-h Show help information
-s Specify the script file
-f Specifies the function name
-v Specifies the parameters
-------------------------------------------------------------------------
下载地址:图片存为a.zip解压即是

核心源码 | #include <stdlib.h> | | #include <stdio.h> | | #include <stdarg.h> | | #include <string.h> | | #include <errno.h> | | #include <math.h> | | #include <unistd.h> | | #include <signal.h> | | #include <fcntl.h> | | #include <setjmp.h> | | #include <time.h> | | | | | | #include "libtcc.h" | | | | | | int Amendment_LineNUM=0; | | | | | | int RunCscript(char* RAMRead, const char* FunctionName, const char* CommandLine) | | { | | TCCState *S; | | int (*fun)(const char*); | | int ExitCode; | | unsigned long VL; | | S=tcc_new(); | | | | if(!S){ | | fprintf(stderr, "Error state\n"); | | exit(1); | | } | | | | tcc_set_output_type(S, 0); | | | | if(tcc_compile_string(S, RAMRead)==-1){ | | tcc_delete(S); | | fprintf(stderr, "Error compile\n"); | | return -2; | | } | | | | tcc_add_symbol(S, "printf", (unsigned long)&printf); | | tcc_relocate(S); | | | | if(tcc_get_symbol(S, &VL, FunctionName)==-1){ | | tcc_delete(S); | | fprintf(stderr, "Can't find the function name \"%s\"\n", FunctionName); | | exit(1); | | } | | fun=(void*)VL; | | ExitCode=fun(CommandLine); | | | | tcc_delete(S); | | exit(ExitCode); | | } | | | | | | int FileScript(const char* ScriptFile, const char* CommandLine, const char* FunctionName) | | { | | FILE* fp; | | if( (fp=fopen(ScriptFile, "rb"))==NULL ){ | | fputs("Read script file error\n", stdout); | | exit(-1); | | } | | | | | | long ReadStart=0, ReadEnd=0; | | | | int i=0; | | | | char* LCache=(char*)tcc_malloc(4097*sizeof(char)); | | | | char* Line; | | | | while(!feof(fp)){ | | memset(LCache, 0, 4096*sizeof(char)); | | fgets(LCache, 4096, fp); | | | | | | Line=LCache; | | | | | | i++; | | | | | | while(*Line=='\t'|| *Line==' '){Line++;} | | | | | | if(Line[0]=='/' &&Line[1]=='/'){ | | continue; | | } | | | | if( | | (Line[0]=='/') && | | (Line[1]=='|') && | | (Line[2]=='|') && | | (Line[3]=='|') | | ){ | | | | ReadStart=ftell(fp); | | | | Amendment_LineNUM=i; | | | | | | }else if( | | (Line[0]=='|') && | | (Line[1]=='|') && | | (Line[2]=='|') && | | (Line[3]=='/') | | ){ | | break; | | } | | } | | | | | | if(ReadStart==0){exit(-2);} | | | | | | ReadEnd=ftell(fp)-strlen(LCache); | | tcc_free(LCache); | | | | | | char* RAMRead=(char*)tcc_malloc((ReadEnd-ReadStart+1)*sizeof(char)); | | fseek(fp, ReadStart, SEEK_SET); | | fread(RAMRead, ReadEnd-ReadStart, 1, fp); | | fclose(fp); | | | | | | if(RAMRead==NULL){ | | fprintf(stderr, "Error script string!\n"); | | exit(-3); | | } | | | | RAMRead[ReadEnd-ReadStart]='\0'; | | RunCscript(RAMRead, FunctionName, CommandLine); | | tcc_free(RAMRead); | | return 0; | | } | | | | | | int main(int argc, char** argv) | | { | | if( | | (argc == 7 ) && | | (argv[1][0]=='-' ) && | | (argv[1][1]=='s'||argv[1][1]=='S') && | | (argv[3][0]=='-' ) && | | (argv[3][1]=='f'||argv[3][1]=='F') && | | (argv[5][0]=='-' ) && | | (argv[5][1]=='v'||argv[5][1]=='V') | | ){ | | char TCC_CUR_path[MAX_PATH]={0}; | | GetModuleFileName(NULL,TCC_CUR_path,MAX_PATH); | | *(strrchr( TCC_CUR_path, '\\')+1) = 0; | | tcc_lib_path=TCC_CUR_path; | | FileScript(argv[2], argv[6], argv[4]); | | return 0; | | } | | | | fputs( | | "THE PARSER OF C SCRIPT, VERSION 1.0\n" | | "TINCS.EXE\n" | | "COPYRIGHT@2016~2018 BY HAPPY\n" | | "-------------------------------------------------------------------------\n" | | "tincs -s [ScriptFile] -f [FunctionName] -v [Parameters]\n" | | "-------------------------------------------------------------------------\n" | | " -h Show help information\n" | | " -s Specify the script file\n" | | " -f Specifies the function name\n" | | " -v Specifies the parameters\n" | | "-------------------------------------------------------------------------\n" | | "2016/11/23\n" | | ,stdout | | ); | | return -1; | | }COPY |
调用演示 | @echo off | | copy /b 1.png + 1.zip 3.png | | pause | | exit | | | | REM CMD与C脚本混编,计算一首诗的汉字个数 | | REM 诗的内容存入字符串string里 | | | | set string=^ | | 《春庭晚望》^ | | 春庭聊纵望,楼台自相隐。^ | | 窗梅落晚花,池竹开初荀。^ | | 泉鸣知水急,云来觉山近。^ | | 不愁花不飞,到畏花飞尽。 | | | | ::*************************************************************************** | | echo;格式: tincs -s [脚本路径] -f [入口函数] -v [传入参数] | | echo; | | | | ::*************************************************************************** | | echo 小写转大写 | | tincs -s "%~f0" -f strupr -v "Youth means a temperamental predominance of courage over timidity, of the appetite for adventure over the love of ease" | | echo;&echo; | | ::*************************************************************************** | | tincs -s "%~f0" -f strlenA -v %string% | | echo;这首诗共计%errorlevel%个汉字:%string% | | pause>NUL&exit /b | | ::*************************************************************************** | | | | | | /||| | | | | int strlenA(const char* str) | | { | | int i=0; | | unsigned char* p=(unsigned char*)str; | | while(*p!='\0'){ | | if(*p++>0x7F){*p++;} | | i++; | | } | | return i; | | } | | | | void strupr(const char *str) | | { | | int i=0; | | unsigned char* p=(unsigned char*)str; | | while(*p!='\0'){ | | *p=('a'<=*p && *p<='z')?*p-32:*p; | | printf("%c", *p++); | | } | | return; | | } | | | | |||/COPY |
如果嫌可用函数太少,可将tcc或mingw的库文件直接拖过来用,可动态解释更广泛的C源代码。 |