Board logo

标题: tincs让C语言在批处理中运行 [打印本页]

作者: happy886rr    时间: 2016-11-24 23:36     标题: 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解压即是

核心源码
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include <math.h>
  7. #include <unistd.h>
  8. #include <signal.h>
  9. #include <fcntl.h>
  10. #include <setjmp.h>
  11. #include <time.h>
  12. //清自行添加tcc库文件
  13. #include "libtcc.h"
  14. // 行号修正量
  15. int Amendment_LineNUM=0;
  16. //C脚本函数
  17. int RunCscript(char* RAMRead, const char* FunctionName, const char* CommandLine)
  18. {
  19. TCCState *S;
  20. int (*fun)(const char*);
  21. int ExitCode;
  22. unsigned long VL;
  23. S=tcc_new();
  24. if(!S){
  25. fprintf(stderr, "Error state\n");
  26. exit(1);
  27. }
  28. tcc_set_output_type(S, 0);
  29. if(tcc_compile_string(S, RAMRead)==-1){
  30. tcc_delete(S);
  31. fprintf(stderr, "Error compile\n");
  32. return -2;
  33. }
  34. tcc_add_symbol(S, "printf", (unsigned long)&printf);
  35. tcc_relocate(S);
  36. if(tcc_get_symbol(S, &VL, FunctionName)==-1){
  37. tcc_delete(S);
  38. fprintf(stderr, "Can't find the function name \"%s\"\n", FunctionName);
  39. exit(1);
  40. }
  41. fun=(void*)VL;
  42. ExitCode=fun(CommandLine);
  43. tcc_delete(S);
  44. exit(ExitCode);
  45. }
  46. //读取脚本
  47. int FileScript(const char* ScriptFile, const char* CommandLine, const char* FunctionName)
  48. {
  49. FILE* fp;
  50. if( (fp=fopen(ScriptFile, "rb"))==NULL ){
  51. fputs("Read script file error\n", stdout);
  52. exit(-1);
  53. }
  54. //流位参数
  55. long  ReadStart=0, ReadEnd=0;
  56. //行计数器
  57. int i=0;
  58. //行存放器
  59. char* LCache=(char*)tcc_malloc(4097*sizeof(char));
  60. //辅助行指针
  61. char* Line;
  62. while(!feof(fp)){
  63. memset(LCache, 0,  4096*sizeof(char));
  64. fgets(LCache, 4096, fp);
  65. //指针置换
  66. Line=LCache;
  67. //行计数器
  68. i++;
  69. //过滤行TAB缩进或前空格
  70. while(*Line=='\t'|| *Line==' '){Line++;}
  71. //过滤注释符
  72. if(Line[0]=='/' &&Line[1]=='/'){
  73. continue;
  74. }
  75. //开始符
  76. if(
  77. (Line[0]=='/') &&
  78. (Line[1]=='|') &&
  79. (Line[2]=='|') &&
  80. (Line[3]=='|')
  81. ){
  82. //获取起点流位
  83. ReadStart=ftell(fp);
  84. //提取行号修正量
  85. Amendment_LineNUM=i;
  86. //结束符
  87. }else if(
  88. (Line[0]=='|') &&
  89. (Line[1]=='|') &&
  90. (Line[2]=='|') &&
  91. (Line[3]=='/')
  92. ){
  93. break;
  94. }
  95. }
  96. //无法识别宏标签则退出
  97. if(ReadStart==0){exit(-2);}
  98. //计算结束位置
  99. ReadEnd=ftell(fp)-strlen(LCache);
  100. tcc_free(LCache);
  101. //脚本分离,读入内存
  102. char* RAMRead=(char*)tcc_malloc((ReadEnd-ReadStart+1)*sizeof(char));
  103. fseek(fp, ReadStart, SEEK_SET);
  104. fread(RAMRead, ReadEnd-ReadStart, 1, fp);
  105. fclose(fp);
  106. //RAMRead为空则退出
  107. if(RAMRead==NULL){
  108. fprintf(stderr, "Error script string!\n");
  109. exit(-3);
  110. }
  111. RAMRead[ReadEnd-ReadStart]='\0';
  112. RunCscript(RAMRead, FunctionName, CommandLine);
  113. tcc_free(RAMRead);
  114. return 0;
  115. }
  116. /*************MAIN主函数入口*************/
  117. int main(int argc, char** argv)
  118. {
  119. if(
  120. (argc      == 7                  ) &&
  121. (argv[1][0]=='-'                 ) &&
  122. (argv[1][1]=='s'||argv[1][1]=='S') &&
  123. (argv[3][0]=='-'                 ) &&
  124. (argv[3][1]=='f'||argv[3][1]=='F') &&
  125. (argv[5][0]=='-'                 ) &&
  126. (argv[5][1]=='v'||argv[5][1]=='V')
  127. ){
  128. char TCC_CUR_path[MAX_PATH]={0};
  129. GetModuleFileName(NULL,TCC_CUR_path,MAX_PATH);
  130. *(strrchr( TCC_CUR_path, '\\')+1) = 0;
  131. tcc_lib_path=TCC_CUR_path;
  132. FileScript(argv[2], argv[6], argv[4]);
  133. return 0;
  134. }
  135. //异常则抛出使用说明
  136. fputs(
  137. "THE PARSER OF C SCRIPT, VERSION 1.0\n"
  138. "TINCS.EXE\n"
  139. "COPYRIGHT@2016~2018 BY HAPPY\n"
  140. "-------------------------------------------------------------------------\n"
  141. "tincs -s [ScriptFile] -f [FunctionName] -v [Parameters]\n"
  142. "-------------------------------------------------------------------------\n"
  143. "      -h  Show help information\n"
  144. "      -s  Specify the script file\n"
  145. "      -f  Specifies the function name\n"
  146. "      -v  Specifies the parameters\n"
  147. "-------------------------------------------------------------------------\n"
  148. "2016/11/23\n"
  149. ,stdout
  150. );
  151. return -1;
  152. }
复制代码
调用演示
  1. @echo off
  2. copy /b 1.png + 1.zip 3.png
  3. pause
  4. exit
  5. REM CMD与C脚本混编,计算一首诗的汉字个数
  6. REM 诗的内容存入字符串string里
  7. set string=^
  8. 《春庭晚望》^
  9. 春庭聊纵望,楼台自相隐。^
  10. 窗梅落晚花,池竹开初荀。^
  11. 泉鸣知水急,云来觉山近。^
  12. 不愁花不飞,到畏花飞尽。
  13. ::***************************************************************************
  14. echo;格式: tincs -s [脚本路径] -f [入口函数] -v [传入参数]
  15. echo;
  16. ::***************************************************************************
  17. echo 小写转大写
  18. 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"
  19. echo;&echo;
  20. ::***************************************************************************
  21. tincs -s "%~f0" -f strlenA -v  %string%
  22. echo;这首诗共计%errorlevel%个汉字:%string%
  23. pause>NUL&exit /b
  24. ::***************************************************************************
  25. /|||
  26. int strlenA(const char* str)
  27. {
  28. int i=0;
  29. unsigned char* p=(unsigned char*)str;
  30. while(*p!='\0'){
  31. if(*p++>0x7F){*p++;}
  32. i++;
  33. }
  34. return i;
  35. }
  36. void strupr(const char *str)
  37. {
  38. int i=0;
  39. unsigned char* p=(unsigned char*)str;
  40. while(*p!='\0'){
  41. *p=('a'<=*p && *p<='z')?*p-32:*p;
  42. printf("%c", *p++);
  43. }
  44. return;
  45. }
  46. |||/
复制代码
如果嫌可用函数太少,可将tcc或mingw的库文件直接拖过来用,可动态解释更广泛的C源代码。
作者: zhangzsky    时间: 2016-11-25 04:39

虽然不会C,但知道这又是一个很牛的开始
作者: ads350668398    时间: 2016-11-25 09:21

批处理可以更强大了 这样是me
作者: happy886rr    时间: 2016-11-25 09:38

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

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

用批处理制作带音乐的动感相册,将会是分分钟的事。几行批文就实现。这个第三方我还在编写中,马上完成。
作者: codegay    时间: 2016-11-25 13:39

作品好多。进步好快。
作者: happy886rr    时间: 2016-11-25 16:29

回复 5# codegay
多谢兄的夸奖,我才学会结构体怎么用,学会指针是啥了。
作者: yu2n    时间: 2016-11-25 21:02

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

7-Zip 表示根本不认识你家的 .zip ,这明明是 .rar 。
作者: happy886rr    时间: 2016-11-25 22:51

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




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2