#include <QCoreApplication>#include <QCommandLineOption>#include <QCommandLineParser>#include <QDebug>#include <QTimer>#include <QFile>#include <QDir>#include <QTextCodec>typedef struct{quint32 row;quint32 type;QString templateFile;}Command;QString loadTemplate(QString path);QString toUnicodeString(QByteArray &array);QString toUnicodeString(QByteArray &array, QString &codec);QByteArray encodeForName(QString code, QString unicodeStr);/*** 函数功能: initCLO* 输入参数: -* 返 回 值: QMap<选项, 值>* 说 明: -*/QList<QCommandLineOption> initCLO(){QList<QCommandLineOption> oList;// 添加命令选项QCommandLineOption optType("t");optType.setValueName("type");optType.setDescription("注释类型,function or src or header");oList.append( optType );QCommandLineOption optRow("r");optRow.setValueName("row");optRow.setDescription("函数定义所在行(从0开始递增)");oList.append( optRow );QCommandLineOption optTemplate("p");optTemplate.setValueName("template");optTemplate.setDescription("注释模板文件");oList.append( optTemplate );return oList;}/*** 函数功能: getOptionSet* 输入参数: [parser] 命令选项解析器* 返 回 值: Command* 说 明: -*/Command getOptionSet( QCommandLineParser &parser ){// QStringList options = parser.optionNames();// QMap<QString, QStringList> cmd; // QMap<name, values>Command cmd;if( parser.isSet("t") ){QString type = parser.value("t");cmd.type = 0;if( type == "function" ){cmd.type = 1;}else if( type == "src" ){cmd.type = 2;}else if( type == "header" ){cmd.type = 3;}}if( parser.isSet("r") ){cmd.row = parser.value("r").toInt();}if( parser.isSet("p") ){cmd.templateFile = parser.value("p");}return cmd;}/*** 函数功能: 插入函数注释* 输入参数: [file] 源文件 [row] 光标所在行 [templateStr] 模板字符串(已正常转换成unicode编码)* 返 回 值: -* 说 明: -*/void insertFunctionComments( QFile *file, quint32 row, QString templateStr ){// row是在源编码格式下的行数,所以需要使用源编码格式处理// 检测源文件编码格式QByteArray rawData = file->readAll();QString encode;toUnicodeString( rawData, encode );// 跳转到光标所在行file->seek(0);quint32 lineNum = 0;while( lineNum++ < row ){file->readLine();}qint32 fpos = 0;do{// 向下搜索非空行if( file->atEnd() ){break;}fpos = file->pos();QByteArray data = file->readLine();data = data.simplified();if( data.isEmpty() ){continue;}// 对非空白行应用正则表达式,提取函数名和参数(需要先转换成unicode编码格式)QString str = toUnicodeString( data );QRegExp regExp( "(.*)\\b([_a-zA-Z]\\w*\\b)\\s*\\((.*)\\)");qint32 pos = regExp.indexIn(str);if( pos >= 0 ){QString name = regExp.cap(2);// 函数名QString args = regExp.cap(3);QString args_;qDebug()<<regExp.capturedTexts();file->seek(fpos);// 提取参数,并且添加"[]"if( args.simplified() == "void" ){args = "-";}else{QString var;args = args.simplified();if( args.endsWith("...") ){var="[...] ";}regExp.setPattern( "[_a-zA-Z]\\w*\\s+\\**([_a-zA-Z]\\w*)\\s*" );pos = 0;while( ( pos=regExp.indexIn(args,pos)) != -1 ){pos +=regExp.matchedLength();args_.append( QString("[%1] ").arg(regExp.cap(1)));}if( !var.isEmpty() ){args_.append(var);}}// 替换模板 // @todo:替换data,time,author等变量if(templateStr.isEmpty()){templateStr = "/**\r\n"" * 函数功能: ${function}\r\n"" * 输入参数: ${args}\r\n"" * 返 回 值: -\r\n"" * 说 明: -\r\n"" */\r\n";}templateStr.replace("${function}", name);templateStr.replace("${args}", args_);// 将模板转换成源数据的编码格式,并插入到源数据中QByteArray insert = encodeForName(encode, templateStr);qDebug().noquote()<<"add comments\r\n"<<insert;if( !insert.isEmpty() ){rawData.insert( fpos, insert );}// 覆盖源文件file->seek(0);file->write( rawData );}break;}while(1);qDebug()<<"finish";}int main(int argc, char *argv[]){QCoreApplication a(argc, argv);a.setApplicationVersion("v0.1");a.setApplicationName("comments");QCommandLineParser cmdParser;cmdParser.setApplicationDescription("Add comments for function/file");cmdParser.addHelpOption();cmdParser.addVersionOption();cmdParser.addPositionalArgument("file", "the file to open");QList<QCommandLineOption> optionList = initCLO();cmdParser.addOptions(optionList);// 解析应用进程的参数if( argc == 1 ) {cmdParser.showVersion();cmdParser.showHelp();return 0;}else{cmdParser.process( a );Command cmd = getOptionSet(cmdParser);if( cmdParser.positionalArguments().isEmpty() ){cmdParser.showHelp();return 0;}QString file = cmdParser.positionalArguments().at(0);QFile txtFile(file);if( txtFile.open(QIODevice::ReadWrite) ){// 加载模板QString temp = loadTemplate(cmd.templateFile);// 插入注释switch(cmd.type){case 1:insertFunctionComments( &txtFile, cmd.row , temp );break;case 2:break;case 3:break;default:cmdParser.showHelp();return 0;break;}txtFile.close();}}a.exit(0);return 0;}/*** 函数功能: 将unicode字符串按名字编码* 输入参数: [code] 编码格式的名字 [unicodeStr] unicode字符串* 返 回 值: -* 说 明: 将unicodeStr 按照code编码格式转化编码*/QByteArray encodeForName(QString code, QString unicodeStr){QTextCodec *codec = QTextCodec::codecForName(code.toLatin1());QTextEncoder *encoder = new QTextEncoder( codec );QByteArray array = encoder->fromUnicode( unicodeStr );if( encoder->hasFailure() ){return QByteArray();}else{if( code == "UTF-8" ){return array.mid(3); // 使用fromUnicode 转换UTF-8是带有BOM的数据}else{return array;}}}/*** 函数功能: 转换成unicode格式的QString字符串* 输入参数: [array] 未知编码的源数据* 返 回 值: [encode] 源数据的编码格式 [QString]转换之后的字符串* 说 明: -*/QString toUnicodeString(QByteArray &array, QString &encode){// ConverterState.invalidChars 实测invalidChars为非unicode的字符数,不能用于判断编码类型QString str;QString tmp;QTextCodec *codec = QTextCodec::codecForName("UTF-8");QTextDecoder *decoder = new QTextDecoder(codec );tmp = decoder->toUnicode( array );if( !decoder->hasFailure()){str = tmp;encode.clear();encode.append("UTF-8");// qDebug()<<"UTF-8";}delete decoder;decoder = NULL;codec = QTextCodec::codecForName("GB18030");decoder = new QTextDecoder(codec );tmp = decoder->toUnicode( array );if( !decoder->hasFailure()){// qDebug()<<"GB18030";str = tmp;encode.clear();encode.append("GB18030");}delete decoder;return str;}/*** 函数功能: 转换成unicode格式的QString字符串* 输入参数: [array] 未知编码的源数据* 返 回 值: [QString]转换之后的字符串* 说 明: -*/QString toUnicodeString(QByteArray &array){// ConverterState.invalidChars 实测invalidChars为非unicode的字符数,不能用于判断编码类型QString str;QString tmp;QTextCodec *codec = QTextCodec::codecForName("UTF-8");QTextDecoder *decoder = new QTextDecoder(codec );tmp = decoder->toUnicode( array );if( !decoder->hasFailure()){str = tmp;// qDebug()<<"UTF-8";}delete decoder;decoder = NULL;codec = QTextCodec::codecForName("GB18030");decoder = new QTextDecoder(codec );tmp = decoder->toUnicode( array );if( !decoder->hasFailure()){// qDebug()<<"GB18030";str = tmp;}delete decoder;return str;}/*** 函数功能: 加载注释模板数据* 输入参数: [path] 带后缀的模板文件的路劲* 返 回 值: -* 说 明: -*/QString loadTemplate(QString path){QFile file(path);if(file.open( QIODevice::ReadOnly )){QByteArray array = file.readAll();file.close();return toUnicodeString( array );}else{return QString();}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。