找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 13237|回复: 7

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

[复制链接]
发表于 2016-11-24 23:36:43 | 显示全部楼层 |阅读模式
本帖最后由 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.        
  37.         if(tcc_get_symbol(S, &VL, FunctionName)==-1){
  38.                 tcc_delete(S);
  39.                 fprintf(stderr, "Can't find the function name "%s"\n", FunctionName);
  40.                 exit(1);       
  41.         }
  42.         fun=(void*)VL;
  43.         ExitCode=fun(CommandLine);
  44.        
  45.         tcc_delete(S);
  46.         exit(ExitCode);
  47. }

  48. //读取脚本
  49. int FileScript(const char* ScriptFile, const char* CommandLine, const char* FunctionName)
  50. {
  51.         FILE* fp;
  52.         if( (fp=fopen(ScriptFile, "rb"))==NULL ){
  53.                 fputs("Read script file error\n", stdout);
  54.                 exit(-1);
  55.         }
  56.        
  57.         //流位参数
  58.         long  ReadStart=0, ReadEnd=0;
  59.         //行计数器
  60.         int i=0;
  61.         //行存放器
  62.         char* LCache=(char*)tcc_malloc(4097*sizeof(char));
  63.         //辅助行指针
  64.         char* Line;

  65.         while(!feof(fp)){
  66.                 memset(LCache, 0,  4096*sizeof(char));
  67.                 fgets(LCache, 4096, fp);

  68.                 //指针置换
  69.                 Line=LCache;

  70.                 //行计数器
  71.                 i++;

  72.                 //过滤行TAB缩进或前空格
  73.                 while(*Line=='\t'|| *Line==' '){Line++;}

  74.                 //过滤注释符
  75.                 if(Line[0]=='/' &&Line[1]=='/'){
  76.                         continue;
  77.                 }
  78.                 //开始符
  79.                 if(
  80.                         (Line[0]=='/') &&
  81.                         (Line[1]=='|') &&
  82.                         (Line[2]=='|') &&
  83.                         (Line[3]=='|')
  84.                 ){
  85.                         //获取起点流位
  86.                         ReadStart=ftell(fp);
  87.                         //提取行号修正量
  88.                         Amendment_LineNUM=i;

  89.                 //结束符               
  90.                 }else if(
  91.                         (Line[0]=='|') &&
  92.                         (Line[1]=='|') &&
  93.                         (Line[2]=='|') &&
  94.                         (Line[3]=='/')
  95.                 ){
  96.                         break;
  97.                 }
  98.         }

  99.         //无法识别宏标签则退出
  100.         if(ReadStart==0){exit(-2);}
  101.        
  102.         //计算结束位置
  103.         ReadEnd=ftell(fp)-strlen(LCache);
  104.         tcc_free(LCache);
  105.        
  106.         //脚本分离,读入内存
  107.         char* RAMRead=(char*)tcc_malloc((ReadEnd-ReadStart+1)*sizeof(char));
  108.         fseek(fp, ReadStart, SEEK_SET);
  109.         fread(RAMRead, ReadEnd-ReadStart, 1, fp);
  110.         fclose(fp);
  111.        
  112.         //RAMRead为空则退出
  113.         if(RAMRead==NULL){
  114.                 fprintf(stderr, "Error script string!\n");
  115.                 exit(-3);
  116.         }

  117.         RAMRead[ReadEnd-ReadStart]='\0';
  118.         RunCscript(RAMRead, FunctionName, CommandLine);
  119.         tcc_free(RAMRead);
  120.         return 0;
  121. }

  122. /*************MAIN主函数入口*************/
  123. int main(int argc, char** argv)
  124. {
  125.         if(
  126.                 (argc      == 7                  ) &&
  127.                 (argv[1][0]=='-'                 ) &&
  128.                 (argv[1][1]=='s'||argv[1][1]=='S') &&
  129.                 (argv[3][0]=='-'                 ) &&
  130.                 (argv[3][1]=='f'||argv[3][1]=='F') &&
  131.                 (argv[5][0]=='-'                 ) &&
  132.                 (argv[5][1]=='v'||argv[5][1]=='V')
  133.         ){       
  134.                 char TCC_CUR_path[MAX_PATH]={0};
  135.                 GetModuleFileName(NULL,TCC_CUR_path,MAX_PATH);
  136.                 *(strrchr( TCC_CUR_path, '\\')+1) = 0;
  137.                 tcc_lib_path=TCC_CUR_path;
  138.                 FileScript(argv[2], argv[6], argv[4]);
  139.                 return 0;
  140.         }
  141.         //异常则抛出使用说明
  142.         fputs(
  143.                 "THE PARSER OF C SCRIPT, VERSION 1.0\n"
  144.                 "TINCS.EXE\n"
  145.                 "COPYRIGHT@2016~2018 BY HAPPY\n"
  146.                 "-------------------------------------------------------------------------\n"
  147.                 "tincs -s [ScriptFile] -f [FunctionName] -v [Parameters]\n"
  148.                 "-------------------------------------------------------------------------\n"
  149.                 "      -h  Show help information\n"
  150.                 "      -s  Specify the script file\n"
  151.                 "      -f  Specifies the function name\n"
  152.                 "      -v  Specifies the parameters\n"
  153.                 "-------------------------------------------------------------------------\n"
  154.                 "2016/11/23\n"
  155.                 ,stdout
  156.         );
  157.         return -1;
  158. }
复制代码
调用演示
  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源代码。

评分

参与人数 2技术 +2 收起 理由
老刘1号 + 1 6x
yu2n + 1 不明觉厉

查看全部评分

发表于 2016-11-25 04:39:23 | 显示全部楼层
虽然不会C,但知道这又是一个很牛的开始
发表于 2016-11-25 09:21:34 | 显示全部楼层
批处理可以更强大了 这样是me
 楼主| 发表于 2016-11-25 09:38:06 | 显示全部楼层
本帖最后由 happy886rr 于 2016-11-25 09:39 编辑

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

用批处理制作带音乐的动感相册,将会是分分钟的事。几行批文就实现。这个第三方我还在编写中,马上完成。
发表于 2016-11-25 13:39:09 | 显示全部楼层
作品好多。进步好快。
 楼主| 发表于 2016-11-25 16:29:55 | 显示全部楼层
回复 5# codegay
多谢兄的夸奖,我才学会结构体怎么用,学会指针是啥了。
发表于 2016-11-25 21:02:40 | 显示全部楼层
下载地址:图片存为a.zip解压即是

7-Zip 表示根本不认识你家的 .zip ,这明明是 .rar 。
 楼主| 发表于 2016-11-25 22:51:43 | 显示全部楼层
回复 7# yu2n
哈哈,7z是lzma,默认它没有WinRAR的兼容头,偏移量不对,7z可作为#解压。一般WinRAR是主流,支持这种copy /b的解压。7z注重压缩算法,lz77变种算法。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 23:52 , Processed in 0.013485 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表