返回列表 发帖

tincs让C语言在批处理中运行

本帖最后由 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>
//清自行添加tcc库文件
#include "libtcc.h"
// 行号修正量
int Amendment_LineNUM=0;
//C脚本函数
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++;
//过滤行TAB缩进或前空格
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);
//RAMRead为空则退出
if(RAMRead==NULL){
fprintf(stderr, "Error script string!\n");
exit(-3);
}
RAMRead[ReadEnd-ReadStart]='\0';
RunCscript(RAMRead, FunctionName, CommandLine);
tcc_free(RAMRead);
return 0;
}
/*************MAIN主函数入口*************/
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源代码。
2

评分人数

虽然不会C,但知道这又是一个很牛的开始

TOP

批处理可以更强大了 这样是me

TOP

本帖最后由 happy886rr 于 2016-11-25 09:39 编辑

回复 3# ads350668398
这只是开始,之后我将再发个贴,让你看到批处理如何实现网页中的图片翻转,拉伸旋转等js特效,基本70%的网页js特效都能在批处理黑黑的控制台下实现。完全颠覆你对批处理的认识。

用批处理制作带音乐的动感相册,将会是分分钟的事。几行批文就实现。这个第三方我还在编写中,马上完成。

TOP

作品好多。进步好快。
去学去写去用才有进步。安装python3代码存为xx.py 双击运行或右键用IDLE打开按F5运行

TOP

回复 5# codegay
多谢兄的夸奖,我才学会结构体怎么用,学会指针是啥了。

TOP

下载地址:图片存为a.zip解压即是

7-Zip 表示根本不认识你家的 .zip ,这明明是 .rar 。
『千江有水千江月』千江有水,月映千江;万里无云,万里青天。    http://yu2n.qiniudn.com/

TOP

回复 7# yu2n
哈哈,7z是lzma,默认它没有WinRAR的兼容头,偏移量不对,7z可作为#解压。一般WinRAR是主流,支持这种copy /b的解压。7z注重压缩算法,lz77变种算法。

TOP

返回列表