用php写了一个统计Lua脚本行数的工具

2024-04-19 15:32
文章标签 工具 统计 php 脚本 lua 行数

本文主要是介绍用php写了一个统计Lua脚本行数的工具,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在quick-cocos2d-x的打包编译Lua的php文件里面加入统计Lua脚本行数的功能

关键代码就这么一行,在windows上面用find函数

list($line,$file,$size) = explode(" ",shell_exec("find /V \"\" /C ".$path));

在linux上面直接由wc 函数可以返回文本行数的貌似。。替换一下就可以了。

<?php
define('DS', DIRECTORY_SEPARATOR);
define('LUAJIT', false);
class LuaPackager
{
private $packageName    = '';
private $rootdir        = '';
private $rootdirLength  = 0;
private $files          = array();
private $modules        = array();
private $excludes       = array();
private $totalLine 		= 0;
function __construct($config)
{
$this->rootdir       = realpath($config['srcdir']);
$this->rootdirLength = strlen($this->rootdir) + 1;
$this->packageName   = trim($config['packageName'], '.');
$this->excludes      = $config['excludes'];
$this->totalLine     = 0;
if (!empty($this->packageName))
{
$this->packageName = $this->packageName . '.';
}
}
function dumpZip($outputFileBasename)
{
$this->files = array();
$this->modules = array();
print("compile script files\n");
$this->compile();
if (empty($this->files))
{
printf("error.\nERROR: not found script files in %s\n", $this->rootdir);
return;
}
$zipFilename = $outputFileBasename . '.zip';
$zip = new ZipArchive();
if ($zip->open($zipFilename, ZIPARCHIVE::OVERWRITE | ZIPARCHIVE::CM_STORE))
{
printf("create ZIP bundle file: %s\n", $zipFilename);
foreach ($this->modules as $module)
{
$zip->addFromString($module['moduleName'], $module['bytes']);
}
$zip->close();
printf("done.\n\n");
}
printf("\n============================================: %d Lines  ",$this->totalLine);
print <<<EOT
### HOW TO USE ###
1. Add code to your lua script:
CCLuaLoadChunksFromZip("${zipFilename}")
EOT;
}
function dump($outputFileBasename)
{
$this->files = array();
$this->modules = array();
print("compile script files\n");
$this->compile();
if (empty($this->files))
{
printf("error.\nERROR: not found script files in %s\n", $this->rootdir);
return;
}
$headerFilename = $outputFileBasename . '.h';
printf("create C header file: %s\n", $headerFilename);
file_put_contents($headerFilename, $this->renderHeaderFile($outputFileBasename));
$sourceFilename = $outputFileBasename . '.c';
printf("create C source file: %s\n", $sourceFilename);
file_put_contents($sourceFilename, $this->renderSourceFile($outputFileBasename));
printf("\n============================================: %d Lines  ",$this->totalLine);
printf("done.\n\n");
$outputFileBasename = basename($outputFileBasename);
print <<<EOT
### HOW TO USE ###
1. Add code to AppDelegate.cpp:
extern "C" {
#include "${outputFileBasename}.h"
}
2. Add code to AppDelegate::applicationDidFinishLaunching()
CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
luaopen_${outputFileBasename}(pEngine->getLuaState());
pEngine->executeString("require(\"main\")");
EOT;
}
private function compile()
{
if (file_exists($this->rootdir) && is_dir($this->rootdir))
{
$this->files = $this->getFiles($this->rootdir);
}
foreach ($this->files as $path)
{
$filename = substr($path, $this->rootdirLength);
$fi = pathinfo($filename);
if ($fi['extension'] != 'lua') continue;
$basename = ltrim($fi['dirname'] . DS . $fi['filename'], '/\\.');
$moduleName = $this->packageName . str_replace(DS, '.', $basename);
$found = false;
foreach ($this->excludes as $k => $v)
{
if (substr($moduleName, 0, strlen($v)) == $v)
{
$found = true;
break;
}
}
if ($found) continue;
printf('  compile module: %s...', $moduleName);
$bytes = $this->compileFile($path);
if ($bytes == false)
{
print("error.\n");
}
else
{
print("ok.\n");
$bytesName = 'lua_m_' . strtolower(str_replace('.', '_', $moduleName));
$this->modules[] = array(
'moduleName'    => $moduleName,
'bytesName'     => $bytesName,
'functionName'  => 'luaopen_' . $bytesName,
'basename'      => $basename,
'bytes'         => $bytes,
);
}
}
}
private function getFiles($dir)
{
$files = array();
$dir = rtrim($dir, "/\\") . DS;
$dh = opendir($dir);
if ($dh == false) { return $files; }
while (($file = readdir($dh)) !== false)
{
if ($file{0} == '.') { continue; }
$path = $dir . $file;
if (is_dir($path))
{
$files = array_merge($files, $this->getFiles($path));
}
elseif (is_file($path))
{
$files[] = $path;
}
}
closedir($dh);
return $files;
}
private function getFileLine($path)
{
$size = 0;
if (file_exists($path))
{	
list($line,$file,$size) = explode(" ",shell_exec("find /V \"\" /C ".$path));
}
return $size;
}
private function compileFile($path)
{
$line = $this->getFileLine($path);
$this->totalLine = $this->totalLine + $line;
printf("\n============================================: %d Lines  ",$this->totalLine);
$tmpfile = $path . '.bytes';
if (file_exists($tmpfile)) unlink($tmpfile);
if (LUAJIT)
{
$command = sprintf('luajit -b -s "%s" "%s"', $path, $tmpfile);
}
else
{
$command = sprintf('luac -o "%s" "%s"', $tmpfile, $path);
}
passthru($command);
if (!file_exists($tmpfile)) return false;
$bytes = file_get_contents($tmpfile);
unlink($tmpfile);
return $bytes;
}
private function renderHeaderFile($outputFileBasename)
{
$headerSign = '__LUA_MODULES_' . strtoupper(md5(time())) . '_H_';
$outputFileBasename = basename($outputFileBasename);
$contents = array();
$contents[] = <<<EOT
/* ${outputFileBasename}.h */
#ifndef ${headerSign}
#define ${headerSign}
#if __cplusplus
extern "C" {
#endif
#include "lua.h"
void luaopen_${outputFileBasename}(lua_State* L);
#if __cplusplus
}
#endif
EOT;
$contents[] = '/*';
foreach ($this->modules as $module)
{
// $contents[] = sprintf('/* %s, %s.lua */', $module['moduleName'], $module['basename']);
$contents[] = sprintf('int %s(lua_State* L);', $module['functionName']);
}
$contents[] = '*/';
$contents[] = <<<EOT
#endif /* ${headerSign} */
EOT;
return implode("\n", $contents);
}
private function renderSourceFile($outputFileBasename)
{
$outputFileBasename = basename($outputFileBasename);
$contents = array();
$contents[] = <<<EOT
/* ${outputFileBasename}.c */
#include "lua.h"
#include "lauxlib.h"
#include "${outputFileBasename}.h"
EOT;
foreach ($this->modules as $module)
{
$contents[] = sprintf('/* %s, %s.lua */', $module['moduleName'], $module['basename']);
$contents[] = sprintf('static const unsigned char %s[] = {', $module['bytesName']);
// $contents[] = $this->encodeBytes($module['bytes']);
$contents[] = $this->encodeBytesFast($module['bytes']);
$contents[] = '};';
$contents[] = '';
}
$contents[] = '';
foreach ($this->modules as $module)
{
$functionName = $module['functionName'];
$bytesName    = $module['bytesName'];
$basename     = $module['basename'];
$contents[] = <<<EOT
int ${functionName}(lua_State *L) {
int arg = lua_gettop(L);
luaL_loadbuffer(L,
(const char*)${bytesName},
sizeof(${bytesName}),
"${basename}.lua");
lua_insert(L,1);
lua_call(L,arg,1);
return 1;
}
EOT;
}
$contents[] = '';
$contents[] = "static luaL_Reg ${outputFileBasename}_modules[] = {";
foreach ($this->modules as $module)
{
$contents[] = sprintf('    {"%s", %s},',
$module["moduleName"],
$module["functionName"]);
}
$contents[] = <<<EOT
{NULL, NULL}
};
void luaopen_${outputFileBasename}(lua_State* L)
{
luaL_Reg* lib = ${outputFileBasename}_modules;
for (; lib->func; lib++)
{
lua_getglobal(L, "package");
lua_getfield(L, -1, "preload");
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
lua_pop(L, 2);
}
}
EOT;
return implode("\n", $contents);
}
private function encodeBytes($bytes)
{
$len      = strlen($bytes);
$contents = array();
$offset   = 0;
$buffer   = array();
while ($offset < $len)
{
$buffer[] = ord(substr($bytes, $offset, 1));
if (count($buffer) == 16)
{
$contents[] = $this->encodeBytesBlock($buffer);
$buffer = array();
}
$offset++;
}
if (!empty($buffer))
{
$contents[] = $this->encodeBytesBlock($buffer);
}
return implode("\n", $contents);
}
private function encodeBytesFast($bytes)
{
$len = strlen($bytes);
$output = array();
for ($i = 0; $i < $len; $i++)
{
$output[] = sprintf('%d,', ord($bytes{$i}));
}
return implode('', $output);
}
private function encodeBytesBlock($buffer)
{
$output = array();
$len = count($buffer);
for ($i = 0; $i < $len; $i++)
{
$output[] = sprintf('%d,', $buffer[$i]);
}
return implode('', $output);
}
}
function help()
{
echo <<<EOT
usage: php package_scripts.php [options] dirname output_filename
options:
--bundle make bundle file
-p prefix package name
-x exclude packages, eg: -x framework.server, framework.tests
EOT;
}
if ($argc < 3)
{
help();
exit(1);
}
array_shift($argv);
$config = array(
'packageName'        => '',
'excludes'           => array(),
'srcdir'             => '',
'outputFileBasename' => '',
'zip'                => false,
);
do
{
if ($argv[0] == '-p')
{
$config['packageName'] = $argv[1];
array_shift($argv);
}
else if ($argv[0] == '-x')
{
$excludes = explode(',', $argv[1]);
foreach ($excludes as $k => $v)
{
$v = trim($v);
if (empty($v))
{
unset($excludes[$k]);
}
else
{
$excludes[$k] = $v;
}
}
$config['excludes'] = $excludes;
array_shift($argv);
}
else if ($argv[0] == '-zip')
{
$config['zip'] = true;
}
else if ($config['srcdir'] == '')
{
$config['srcdir'] = $argv[0];
}
else
{
$config['outputFileBasename'] = $argv[0];
}
array_shift($argv);
} while (count($argv) > 0);
$packager = new LuaPackager($config);
if ($config['zip'])
{
$packager->dumpZip($config['outputFileBasename']);
}
else
{
$packager->dump($config['outputFileBasename']);
}


 

这篇关于用php写了一个统计Lua脚本行数的工具的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/917937

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java调用Python脚本实现HelloWorld的示例详解

《Java调用Python脚本实现HelloWorld的示例详解》作为程序员,我们经常会遇到需要在Java项目中调用Python脚本的场景,下面我们来看看如何从基础到进阶,一步步实现Java与Pyth... 目录一、环境准备二、基础调用:使用 Runtime.exec()2.1 实现步骤2.2 代码解析三、

Python脚本轻松实现检测麦克风功能

《Python脚本轻松实现检测麦克风功能》在进行音频处理或开发需要使用麦克风的应用程序时,确保麦克风功能正常是非常重要的,本文将介绍一个简单的Python脚本,能够帮助我们检测本地麦克风的功能,需要的... 目录轻松检测麦克风功能脚本介绍一、python环境准备二、代码解析三、使用方法四、知识扩展轻松检测麦

IDEA与MyEclipse代码量统计方式

《IDEA与MyEclipse代码量统计方式》文章介绍在项目中不安装第三方工具统计代码行数的方法,分别说明MyEclipse通过正则搜索(排除空行和注释)及IDEA使用Statistic插件或调整搜索... 目录项目场景MyEclipse代码量统计IDEA代码量统计总结项目场景在项目中,有时候我们需要统计

MySQL慢查询工具的使用小结

《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

基于Python实现进阶版PDF合并/拆分工具

《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD