diff --git a/README.html b/README.html deleted file mode 100644 index 49c9aa5..0000000 --- a/README.html +++ /dev/null @@ -1,627 +0,0 @@ - - - - -README - - -

宏替换工具

这是一个为编程语言加入define宏定义的工具,用于实现对不同版本、不同平台进行区分,实现原理是利用宏注释不需要的代码,该工具理论上适用于任何编程语言。

使用方式

1.在代码中加入宏注释

2.在代码所在目录运行findtool工具,并定义宏:WINDOWS

这个命令可直接在本项目上操作来查看效果

在编译时若没有此宏,会将define与endif之间的内容进行/**/注释,若有宏,则进行解除注释。

宏内定义的内容不要使用多行注释

命令使用

-define 定义宏
-exdir 排除文件夹
-h 查看帮助

不足与限制

  1. 在#define与#endif之间不要使用多行注释/**/,yaml文件中#define与#endif之间不要使用#注释
  2. #与define之间不能出现空格
  3. 代码替换不会备份,若担心代码丢失请先备份代码

//默认排除文件夹:
bin build .git .svn debug release

打赏作者

打赏留言备注项目名+您的名字,您将出现在影子项目的赞助列表~ -https://afdian.net/@fengdeyingzi

- - \ No newline at end of file diff --git a/bin/definetool.dart b/bin/definetool.dart index 7f60653..e294a18 100644 --- a/bin/definetool.dart +++ b/bin/definetool.dart @@ -1,4 +1,4 @@ -import 'util/defineutil.dart'; +import 'util/DefineTool.dart'; /* 宏定义替换工具 @@ -7,9 +7,8 @@ import 'util/defineutil.dart'; */ void main(List arguments) { // #ifdef WEB -/* print('Hello web!');*/ // #else - print("Hello windows"); +/* print("Hello windows");*/ // #endif print("宏定义替换工具"); @@ -35,13 +34,7 @@ void main(List arguments) { isDefine = false; exDirList = []; } else if (item == "-h") { - print(""" --define 定义宏 --exdir 排除文件夹 --h 查看帮助 - -示例:definetool -define WINDOWS - """); + printHelp(); return; } else { if (isDefine) { @@ -52,6 +45,24 @@ void main(List arguments) { } } } - DefineUtil util = DefineUtil(dir, exdir: exDirList, defines: defineList); + DefineTool util = DefineTool(); + if(exDirList!=null) + util.exdirList = exDirList; + if(defineList!=null) + util.setDefines(defineList); + else{ + printHelp(); + return; + } util.start(); } + +void printHelp() { + print(""" +-define 定义宏 +-exdir 排除文件夹 +-h 查看帮助 + +示例:definetool -define WINDOWS + """); +} \ No newline at end of file diff --git a/bin/util/CodeParse.dart b/bin/util/CodeParse.dart new file mode 100644 index 0000000..96652aa --- /dev/null +++ b/bin/util/CodeParse.dart @@ -0,0 +1,516 @@ + + +class CodeParseUtil { + String code=""; + List list_keyWordItems=[]; + + CodeParseUtil() { + list_keyWordItems = []; + } + +//分析代码 + void parseCode(String code) { + this.code = code; + int type = 0; + int uptype = 0; + int start = 0; + int end = code.length; + StringBuffer builder_cur = StringBuffer(); + StringBuffer builder_type = StringBuffer(); + int leve = 0; + bool isR = false; + for (int i = 0; i < code.length; i++) { + String c = code[i]; + if(uptype!=type){ + builder_type.write("\x1B[32m"+type.toString()+"\x1B[0m"); + uptype = type; + } + builder_type.write("\x1B[35m"+c+"\x1B[0m"); + + switch (type) { + case 0: + if(c == '\r'){ + isR = true; + } + else if (c == '\n') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + if(isR){ + item.word = "\r\n"; + isR = false; + } + item.type = KeyWordType.TYPE_LINE; + list_keyWordItems.add(item); + } else if (c == '/') { + builder_cur.write(c); + type = 2; + } else if (c == '\"') { + builder_cur.write(c); + type = 5; + } else if (c == '\'') { + builder_cur.write(c); + type = 6; + } + else if (isOperators(c)) { + KeyWordItem item = KeyWordItem(); + item.word = c; + item.leve = leve; + item.type = KeyWordType.TYPE_CHAR; + list_keyWordItems.add(item); + } else if (isNumber(c)) { + builder_cur.write(c); + type = 1; + } else if (isLetter(c)) { + builder_cur.write(c); + type = 3; + } else { + KeyWordItem item = KeyWordItem(); + if (c == '{'){ + leve++; + } + else if (c == '}'){ + leve--; + } + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + list_keyWordItems.add(item); + } + break; + case 1: //数字 + if (isNumber(c)) { + builder_cur.write(c); + } else { + KeyWordItem item2 = KeyWordItem(); + item2.leve = leve; + item2.word = builder_cur.toString(); + builder_cur.clear(); + item2.type = KeyWordType.TYPE_FINAL; + list_keyWordItems.add(item2); + + if (isOperators(c)) { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + list_keyWordItems.add(item); + } else if (c == '\r' || c == '\n') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_LINE; + type = 0; + list_keyWordItems.add(item); + } else if (c == ';') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + type = 0; + list_keyWordItems.add(item); + } else { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + type = 0; + list_keyWordItems.add(item); + } + } + + break; + case 2: //注释 + if (c == '*') { + builder_cur.write(c); + type = 11; + } else if (c == '/') { + builder_cur.write(c); + type = 10; + } else { + builder_cur.write(c); + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = builder_cur.toString(); + builder_cur.clear(); + item.type = KeyWordType.TYPE_CHAR; + list_keyWordItems.add(item); + type = 0; + } + break; + case 3: //字母 + if (isLetter(c)) { + builder_cur.write(c); + } else { + KeyWordItem item2 = KeyWordItem(); + item2.leve = leve; + item2.word = builder_cur.toString(); + builder_cur.clear(); + item2.type = KeyWordType.TYPE_VAR; + list_keyWordItems.add(item2); + if (isOperators(c)) { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + list_keyWordItems.add(item); + type = 0; + } else if (c == '\r' || c == '\n') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_LINE; + type = 0; + list_keyWordItems.add(item); + } else if (c == ';') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + type = 0; + list_keyWordItems.add(item); + } else if(c == '\"'){ + builder_cur.write(c); + type = 5; + } + else { + if(c == '{'){ + leve++; + }else if(c == '}'){ + leve--; + } + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = c; + item.type = KeyWordType.TYPE_CHAR; + type = 0; + list_keyWordItems.add(item); + } + } + + break; + case 5: //双引号 + if (c == '\\') { + builder_cur.write(c); + //跳过一个字符解析 + type = 7; + } else if (c == '\"') { + builder_cur.write(c); + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.type = KeyWordType.TYPE_STRING; + item.word = builder_cur.toString(); + list_keyWordItems.add(item); + builder_cur.clear(); + type = 0; + } else { + builder_cur.write(c); + } + break; + case 6: //单引号 + if (c == '\\') { + builder_cur.write(c); + //跳过一个字符解析 + type = 8; + } else if (c == '\'') { + builder_cur.write(c); + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.type = KeyWordType.TYPE_STRING; + item.word = builder_cur.toString(); + list_keyWordItems.add(item); + builder_cur.clear(); + type = 0; + } else { + builder_cur.write(c); + } + break; + case 7: + builder_cur.write(c); + type = 5; + break; + case 8: + builder_cur.write(c); + type = 6; + break; + case 10: //解析单行注释 + if (c == '\n') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = builder_cur.toString(); + builder_cur.clear(); + item.type = KeyWordType.TYPE_ANNOTATION; + list_keyWordItems.add(item); + type = 0; + addLine(c); + } else if (c == '\r') { + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.word = builder_cur.toString(); + builder_cur.clear(); + item.type = KeyWordType.TYPE_ANNOTATION; + list_keyWordItems.add(item); + type = 0; + addLine(c); + } else { + builder_cur.write(c); + } + break; + case 11: //多行注释 + + if (c == '/') { + if (builder_cur.length > 2 && builder_cur.toString()[builder_cur.length - 1] == '*') { + builder_cur.write(c); + type = 0; + KeyWordItem item = KeyWordItem(); + item.word = builder_cur.toString(); + builder_cur.clear(); + item.type = KeyWordType.TYPE_BLOCK_ANNOTATION; + list_keyWordItems.add(item); + } else { + builder_cur.write(c); + } + } else { + builder_cur.write(c); + } + break; + } + + + } + if(builder_cur.length>0){ + KeyWordItem item = KeyWordItem(); + item.leve = leve; + item.type = KeyWordType.TYPE_STRING; + item.word = builder_cur.toString(); + list_keyWordItems.add(item); + builder_cur.clear(); + } + // print("测试:" + builder_type.toString()); + + // print("解析完成:" + list_keyWordItems.toString()); + } + + @override + String toString() { + StringBuffer builder = StringBuffer(); + for (int i = 0; i < list_keyWordItems.length; i++) { + KeyWordItem item = list_keyWordItems[i]; + builder.write(item.word); + } + return builder.toString(); + } + + + String toStringColor() { + /* + print('\x1B[31mThis is a red text\x1B[0m'); + print('\x1B[32mThis is a green text\x1B[0m'); + print('\x1B[33mThis is a yellow text\x1B[0m'); + print('\x1B[34mThis is a blue text\x1B[0m'); + print('\x1B[35mThis is a magenta text\x1B[0m'); + print('\x1B[36mThis is a cyan text\x1B[0m'); + print('\x1B[1mThis is a bold text\x1B[0m'); + */ + StringBuffer builder = StringBuffer(); + for (int i = 0; i < list_keyWordItems.length; i++) { + KeyWordItem item = list_keyWordItems[i]; + if(item.word=="\r\n"){ + builder.write("换行符"+"\n"); + } + // if(item.word == "\r" || item.word=="\n"){ + // builder.write("换行"); + // } + if(item.type == KeyWordType.TYPE_ANNOTATION){ + builder.write("\x1B[32m${item.word}\x1B[0m"); + }else if(item.type == KeyWordType.TYPE_VAR){ + builder.write("\x1B[34m${item.word}\x1B[0m"); + }else if(item.type == KeyWordType.TYPE_FINAL){ + builder.write("\x1B[32m${item.word}\x1B[0m"); + }else if(item.type == KeyWordType.TYPE_FUNCTION){ + builder.write("\x1B[31m${item.word}\x1B[0m"); + }else if(item.type == KeyWordType.TYPE_CHAR || item.type == KeyWordType.TYPE_STRING){ + builder.write("\x1B[35m${item.word}\x1B[0m"); + } + else{ + builder.write(item.word); + } + // builder.write("--"+item.type.toString()); + + } + return builder.toString(); + } + +//去除代码中的注释 + void clearAnnotation() { + for (int i = list_keyWordItems.length - 1; i >= 0; i--) { + KeyWordItem item = list_keyWordItems[i]; + if (item.type == KeyWordType.TYPE_ANNOTATION) { + list_keyWordItems.removeAt(i); + } + } + // print("解析完成:" + list_keyWordItems.toString()); + } + + void mixUp(Map mixParams) { + mixParams.forEach((key, value) { + for (int i = 0; i < list_keyWordItems.length; i++) { + KeyWordItem item = list_keyWordItems[i]; + if (item.word == key && + (item.type == KeyWordType.TYPE_FUNCTION || + item.type == KeyWordType.TYPE_VAR)) { + item.word = value; + } + } + }); + } + + void addLog(String formatStr) { + String name = "Name"; + int index = 0; + int leve = 0; + bool hasIF = false; //在分号后是否有if语句 + for (int i = 0; i < list_keyWordItems.length; i++) { + KeyWordItem item = list_keyWordItems[i]; + if (item.word == "if") { + hasIF = true; + } else if (item.type == KeyWordType.TYPE_FUNCTION || + item.type == KeyWordType.TYPE_VAR) { + name = item.word; + } + if (item.word == "{") { + leve++; + } else if (item.word == "}") { + leve++; + } else if (item.type == KeyWordType.TYPE_LINE) {} + if (item.word == ";" && leve > 0) { + KeyWordItem logitem = KeyWordItem(); + logitem.type = KeyWordType.TYPE_FUNCTION; + String str = "$formatStr"; + str = str.replaceFirst("{tag}", "LogTag"); + str = str.replaceFirst("{index}", "$index"); + str = str.replaceFirst("{name}", name); + logitem.word = str; + i++; + if (!hasIF) { + list_keyWordItems.insert(i, logitem); + } else { + // print("换行 "); + } + + index++; + hasIF = false; + } + } + } + + void clearLog(String formatStr) { + String name = "Name"; + int index = 0; + int leve = 0; + bool hasIF = false; //在分号后是否有if语句 + for (int i = 0; i < list_keyWordItems.length; i++) { + KeyWordItem item = list_keyWordItems[i]; + if (item.word == "if") { + hasIF = true; + } else if (item.type == KeyWordType.TYPE_FUNCTION || + item.type == KeyWordType.TYPE_VAR) { + name = item.word; + } + if (item.word == "{") { + leve++; + } else if (item.word == "}") { + leve++; + } else if (item.type == KeyWordType.TYPE_LINE) {} + + if (item.word == ";" && leve > 0) { + KeyWordItem logitem = KeyWordItem(); + logitem.type = KeyWordType.TYPE_FUNCTION; + String str = "$formatStr"; + str = str.replaceFirst("{tag}", "LogTag"); + str = str.replaceFirst("{index}", "$index"); + str = str.replaceFirst("{name}", name); + logitem.word = str; + i++; + if (!hasIF) { + list_keyWordItems.insert(i, logitem); + } else { + // print("换行 "); + } + + index++; + hasIF = false; + } + } + } + + void addChar(String c) { + KeyWordItem item = KeyWordItem(); + item.type = KeyWordType.TYPE_CHAR; + item.word = c; + list_keyWordItems.add(item); + } + void addLine(String c){ + KeyWordItem item = KeyWordItem(); + item.type = KeyWordType.TYPE_LINE; + item.word = c; + list_keyWordItems.add(item); + } + + bool isNumber(String c) { + if (c.compareTo('0') >= 0 && c.compareTo('9') <= 0) { + return true; + } + return false; + } + + bool isLetter(String c) { + if ((c.compareTo('a') >= 0 && c.compareTo('z') <= 0) || + (c.compareTo('A') >= 0 && c.compareTo('Z') <= 0) || c == '_') { + return true; + } + return false; + } + + bool isOperators(String c) { + if (c == '+' || + c == '-' || + c == '<' || + c == '>' || + c == '=' || + c == '*' || + c == '/' || + c == '^' || + c == '|' || + c == '&' || + c == '\$' || + c == '#' || + c == '%' || + c == '@' || + c == '!' || + c == '?' || + c == ':') { + return true; + } + return false; + } +} + +enum KeyWordType { + TYPE_VAR, //字母 变量(没有区分变量类型和变量名,没有判断关键字,需要后期处理) + TYPE_FINAL, //常量 + TYPE_FUNCTION, //方法 + TYPE_CHAR, //字符(没有区分运算符和字符串) + TYPE_STRING, //字符串 + TYPE_ANNOTATION, //单行注释 + TYPE_BLOCK_ANNOTATION, //块注释 + TYPE_LINE, //换行符 +} + +class KeyWordItem { + KeyWordType type; + String word; + int leve=0; + + KeyWordItem({this.type = KeyWordType.TYPE_CHAR, this.word = ""}); +} \ No newline at end of file diff --git a/bin/util/DefineTool.dart b/bin/util/DefineTool.dart new file mode 100644 index 0000000..431419e --- /dev/null +++ b/bin/util/DefineTool.dart @@ -0,0 +1,307 @@ +import 'dart:convert'; +import 'dart:io'; +import '../util/CodeParse.dart'; +import '../util/FileUtil.dart'; +/* +利用代码解析实现宏定义工具 +实现思路是解析注释里面的#ifdef #ifndef #else #endif +然后根据define的值来生成新代码 +*/ + +class DefineTool { + //忽略列表 + List exdirList = ["bin", "build", ".git", ".svn", "debug", "release"]; + //要开启的宏 + List definesList = []; + //扫描文件类型 + List fileNameList = [".dart", ".yaml", ".yml", ".podspec", ".java", ".kt", ".go",".rs",".js",".ts",".php",".cs",".swift",".py"]; + //扫描后的文件列表 + List codeList = []; + + //设置宏 + void setDefines(List defines){ + definesList = defines; + } + + void start(){ + //获取当前路径 + String path = Directory.current.path; + //获取需要定义的文件列表 + _doFileListDir(path); + //遍历代码进行解析,并生成新代码 + for(int i=0;i data = FileUtil.readData(file.path); + String code = utf8.decode(data); + String newCode = defineCode(code); + // + File filebak = File(file.path+".bak"); + if(!filebak.existsSync()){ + filebak.createSync(); + } + if(data.isNotEmpty){ + filebak.writeAsBytesSync(data); + } + file.writeAsStringSync(newCode); + } + } + + //获取需要定义的文件列表 + void _doFileListDir(String path) { + Directory dir = Directory(path); + List listFile = dir.listSync(); + //循环扫描需要转换的代码 + for (int i = 0; i < listFile.length; i++) { + var file = listFile[i]; + FileStat stat = file.statSync(); + if (stat.type == FileSystemEntityType.directory) { + _doFileListDir(file.path); + } else if (stat.type == FileSystemEntityType.file) { + var endName = FileUtil.getEndName(file.path); + if (fileNameList.contains(endName)) { + List data = FileUtil.readData(file.path); + String code = utf8.decode(data); + if(code.contains("#ifdef") || code.contains("#else") || code.contains("#endif") || code.contains("#ifndef")){ + codeList.add(File(file.path)); + } + } + } + } + //当前状态 + int defineState = 0; //0表示未定义 1表示ifdef 2表示ifndef + //遍历代码进行解析,并生成新代码 + for(int i=0;i data = FileUtil.readData(file.path); + String code = utf8.decode(data); + + + } + } + //寻找下一行的KeyWordItem + KeyWordItem? getNextLineWordItem(CodeParseUtil parseUtil, KeyWordItem item) { + int index = parseUtil.list_keyWordItems.indexOf(item); + index += 1; + bool isNextLine = false; + for (; index < parseUtil.list_keyWordItems.length; index++) { + KeyWordItem keyWordItem = parseUtil.list_keyWordItems[index]; + KeyWordItem? nextItem = null; + if(index= 0; index--) { + // print("index "+index.toString()+" "+parseUtil.list_keyWordItems[index].type.toString()+" "+parseUtil.list_keyWordItems[index].word); + KeyWordItem keyWordItem = parseUtil.list_keyWordItems[index]; + if(isNextLine){ + return keyWordItem; + } + + if (keyWordItem.type == KeyWordType.TYPE_LINE && keyWordItem.word.contains("/*")) { + return keyWordItem; + } + else if(keyWordItem.word.contains("*/")){ + return keyWordItem; + } + else if(keyWordItem.type == KeyWordType.TYPE_LINE){ + isNextLine = true; + } + } + return null; + } + + //解析代码并生成新代码 + String defineCode(String codeText){ + //当前状态 + int defineState = 0; //0表示未定义 1表示ifdef 2表示ifndef + //是否包含 + bool isContains = false; + //是否加注释 + bool isAddAnnotation = false; + //是否去除注释 + + bool isRemoveAnnotation = false; + + CodeParseUtil parseUtil = CodeParseUtil(); + parseUtil.parseCode(codeText); + // print(parseUtil.toStringColor()); + for(int i=0;i dlist = keyWordItem.word.split(" "); + // print("dlist "+dlist.toString()); + if(dlist.length>1){ + for(int n=0;n ndlist = keyWordItem.word.split(" "); + if(ndlist.length>1){ + for(int n=0;n exdirList = ["bin", "build", ".git", ".svn", "debug", "release"]; List definesList = []; //要开启的宏 @@ -15,6 +16,7 @@ class DefineUtil { List define = "#ifdef".codeUnits; List endif = "#endif".codeUnits; + List ifndef = "#ifndef".codeUnits; String dirpath = ""; //初始化