1 Star 0 Fork 0

Ging/comments

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
main.cpp 9.91 KB
一键复制 编辑 原始数据 按行查看 历史
Ging 提交于 2024-12-05 21:12 +08:00 . v0.1.0 初步完成函数注释功能
#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();
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/Ging_H/comments.git
git@gitee.com:Ging_H/comments.git
Ging_H
comments
comments
main

搜索帮助