feat: wcsc

This commit is contained in:
msojocs 2023-08-03 22:27:25 +08:00
parent ca9bdccdf5
commit 6cd8743b4c
15 changed files with 181465 additions and 52 deletions

View File

@ -65,5 +65,12 @@
},
"cmake.configureSettings": {
"CMAKE_TOOLCHAIN_FILE": "/root/vcpkg/scripts/buildsystems/vcpkg.cmake"
}
},
"clangd.arguments": [
"-log=verbose",
"-pretty",
"--background-index",
//"--query-driver=/bin/arm-buildroot-linux-gnueabihf-g++", //for cross compile usage
"--compile-commands-dir=${workspaceFolder}/build/"
]
}

View File

@ -44,11 +44,19 @@ add_executable(wcc
src/wxml/compiler.cpp
src/wxml/dom_lib/str_cache.cpp
src/wxml/dom_lib/wxml_dom.cpp
src/utils/json.cpp
src/utils/string_utils.cpp
src/utils/file.cpp
)
add_executable(wcsc
src/wcsc.cpp
src/wcsc/usage.cpp
src/wxss/css_tree_lib/parser.cpp
src/wxss/common.cpp
src/wxss/x_compiler.cpp
src/utils/json.cpp
src/utils/string_utils.cpp
src/utils/file.cpp
)
add_executable(
resolve_path

View File

@ -1,5 +1,5 @@
#ifndef __MAIN_H__
#define __MAIN_H__
#ifndef __WCC_H__
#define __WCC_H__
#include <iostream>
#include <map>

101
src/include/wxss.h Normal file
View File

@ -0,0 +1,101 @@
#ifndef __WXSS_H__
#define __WXSS_H__
#include <iostream>
#include <string>
#include <map>
#include <memory>
#include <vector>
namespace WXSS
{
std::string RemoveQuote(std::string const&);
int NewLintAndParseCSSList(std::map<std::string,std::string> const&, std::vector<std::string> &, std::string&, std::string&, int, bool, std::string const&, std::string const&);
int LintAndParseCSSList(std::map<std::string,std::string> const&, std::string&, std::string&, std::string&, int, bool, bool, bool, std::string const&);
void LintAndParseCSS(std::string const&, std::string const&, std::string&, std::string&, bool, bool, bool, bool, std::string const&);
class Token
{
private:
/* data */
public:
Token(/* args */);
~Token();
std::string GetLiteral(void);
};
namespace CSSTreeLib
{
class CSSSyntaxTree
{
private:
/* data */
public:
std::string offset_0;
WXSS::Token offset_24;
std::vector<std::shared_ptr<CSSSyntaxTree>> offset_120;
std::shared_ptr<std::string> offset_140;
CSSSyntaxTree(/* args */);
~CSSSyntaxTree();
void GetHostRule(std::string &);
void Print2Stream(int, std::stringstream &);
void RenderCode(std::string &,bool);
};
class LexicalChecker
{
private:
/* data */
public:
LexicalChecker(/* args */);
~LexicalChecker();
void Init();
void Traval(std::shared_ptr<WXSS::CSSTreeLib::CSSSyntaxTree> &);
void GetInstance(void);
};
class Parser
{
private:
/* data */
public:
Parser(/* args */);
~Parser();
int Parse(std::string const&, std::string const&, std::string&, std::string const&);
};
} // namespace CSSTreeLib
class XCompiler
{
private:
/* data */
public:
int offset_0 = 0;
int offset_4 = 0;
std::string offset_8;
std::map<std::string, std::shared_ptr<WXSS::CSSTreeLib::CSSSyntaxTree>> offset_32;
std::map<std::string, std::vector<std::string>> offset_56;
std::map<std::string, int> offset_136;
XCompiler(/* args */);
XCompiler(std::map<std::string, std::string> const&, bool, std::string const&);
~XCompiler();
void DealRPX(std::string &, std::stringstream &);
void GetHostRule(std::string &);
void ShowTree(std::string &);
void GetCompiled(std::string const&, std::string&);
void GetJSCompiled(std::string const&, std::string&);
void GetWellFormattedJSCompiled(std::string const&, std::string&);
void GenExpr(std::shared_ptr<WXSS::CSSTreeLib::CSSSyntaxTree>, std::stringstream &, std::string &);
int GetPageCss(std::string const&, std::string&, uint);
void MarkImported(std::string const&);
int GetCommHead(std::vector<std::string> &, std::string&, bool, std::string const&);
};
} // namespace WXSS
#endif

50
src/utils/json.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <iostream>
#include <map>
#include <iomanip>
#include <sstream>
std::string EscapeToJsonString(std::string const& a2)
{
std::stringstream ret;
for (int i = 0; i < a2.length(); i++)
{
char cur = a2[i];
if (cur == '\\' || cur == '"' || cur <= 0x1Fu)
{
ret << "\\u";
ret << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(cur);
}
else
{
ret << cur;
}
}
return ret.str();
}
std::string DictToJsonString(std::map<std::string, std::string> const& a2)
{
std::stringstream ret;
ret << "{";
bool isFirst = true;
for(auto kv: a2)
{
if (!isFirst)
{
ret << ",";
}
ret << "\"";
// key
ret << EscapeToJsonString(kv.first);
ret << "\":";
ret << "\"";
// value
ret << EscapeToJsonString(kv.second);
ret << "\"";
isFirst = false;
}
ret << "}";
return ret.str();
}

View File

@ -8,7 +8,7 @@
#include "include/usage.h"
#include "include/string_utils.h"
#include "include/wxml.h"
#include "include/wcc.h"
#include "include/json.h"
using namespace std;
@ -507,49 +507,3 @@ int main(int argc, const char **argv)
return 0;
}
std::string DictToJsonString(std::map<std::string, std::string> const& a2)
{
std::stringstream ret;
ret << "{";
bool isFirst = true;
for(auto kv: a2)
{
if (!isFirst)
{
ret << ",";
}
ret << "\"";
// key
ret << EscapeToJsonString(kv.first);
ret << "\":";
ret << "\"";
// value
ret << EscapeToJsonString(kv.second);
ret << "\"";
isFirst = false;
}
ret << "}";
return ret.str();
}
std::string EscapeToJsonString(std::string const& a2)
{
stringstream ret;
for (int i = 0; i < a2.length(); i++)
{
char cur = a2[i];
if (cur == '\\' || cur == '"' || cur <= 0x1Fu)
{
ret << "\\u";
ret << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(cur);
}
else
{
ret << cur;
}
}
return ret.str();
}

View File

@ -1,6 +1,284 @@
#include <iostream>
#include <vector>
#include <map>
#include "./include/usage.h"
#include "include/file.h"
#include "include/wxss.h"
#include "include/wxml.h"
#include "include/json.h"
int main(int argc, char **argv) {
int main(int argc, const char **argv) {
// main - 0
if (argc <= 1)
{
return usage(argc, argv);
}
// main - 5
std::string configPath = "";
std::vector<std::string> v69;
for (int i = 1; i < argc; i++)
{
bool isUseConfigFile = false;
std::string configPath = "--config-path";
if (!configPath.compare(argv[i]))
{
isUseConfigFile = true;
}
if (isUseConfigFile)
{
i++;
configPath = argv[i];
}
else
{
v69.emplace_back(argv[i]);
}
}
// main - 10
if (configPath.length() > 0)
{
// 使用配置文件
std::string configData = "";
readFile(configPath.data(), configData);
while (configData.length() > 0) {
std::string v104;
v104 = getNextArg(configData, "\n");
v69.emplace_back(v104);
}
}
// main - 15
bool v56 = false;
std::vector<std::string> v66;
std::string v75, v83;
int v29 = 0;
bool v30 = false;
bool v31 = false;
bool v32 = false;
bool v34 = false;
bool v35 = false;
bool v36 = false;
bool v37 = false;
std::string fileName;
std::string v76;
for (int i = 0; i < v69.size(); i++) {
std::string cur = v69[i];
if (cur[0] != '-')
{
if (!v56)
{
v66.emplace_back(v69[i]);
continue;
}
v75 = i;
v56 = false;
continue;
}
switch(cur[1])
{
case 'o':
{
if (v69.size() > i + 1)
{
i++;
fileName = v69[i];
v56 = false;
continue;
}
}
break;
case 's':
{
if (cur[2] == 't')
{
v56 = false;
v34 = true;
continue;
}
if (cur[2] == 'd')
{
if (v69.size() > i + 1)
{
i++;
v56 = false;
v83 = v69[i + 1];
v35 = true;
continue;
}
}
else if (v69.size() > i + 1)
{
v56 = false;
i++;
v32 = true;
continue;
}
}
break;
case 'l':
if (cur[2] == 'c')
{
v56 = false;
continue;
}
if (cur[2] == 'l')
{
v36 = true;
v56 = false;
continue;
}
break;
case 'd':
if (cur[2] == 'b')
{
v56 = false;
v37 = true;
continue;
}
break;
case 'j':
if (cur[2] == 's')
{
v56 = false;
v31 = true;
continue;
}
break;
case 'c':
if (cur[2] == 'p')
{
v56 = true;
continue;
}
break;
default:
if (cur[1] == 'p' && cur[2] == 'c')
{
v30 = true;
v29 = atoi(v69[i + 1].data());
i++;
v56 = false;
continue;
}
break;
}
v56 = false;
if (!v69[i].compare("--subpackage") && v69.size() > i)
{
std::string v101 = "";
v101.reserve();
v101.append("./", 2);
v101.append(v69[i + 1]);
// TODO... 待检验
v76 = v101;
}
}
// main - 20
if (v66.begin() == v66.end() && !v32 && !v35)
{
return usage(argc, argv);
}
FILE * f = stdout;
if (fileName.length())
{
f = fopen(fileName.data(), "w");
}
std::map<std::string, std::string> v77;
if (!v35)
{
for (int j=0; j < v66.size(); j++)
{
std::string fileContent;
if (readFile(v66[j].data(), fileContent))
{
fprintf(stderr, "%s not found\n", v66[j].data());
return 1;
}
v77[v66[j]] = fileContent;
}
}
// main - 25
std::string v88, v90;
std::vector<std::string> v72;
if (!v30)
{
if (!v36)
{
int v25;
v25 = WXSS::LintAndParseCSSList(v77, v66[0], v88, v90, 0, v31, v37, v34, v75);
if (v25)
{
fprintf(stderr, "ERR: %s\nerror file count: %d\n", v90.data(), 0);
return 1;
}
return 0;
}
LABEL_102:
std::string v96;
std::string v94;
WXSS::XCompiler lt(v77, v37, v75);
// lt.offset_136.erase()
// lt.offset_136.erase()
v96.assign(lt.offset_8);
std::map<std::string, std::string> v92;
if (!lt.offset_4)
{
int ret = lt.GetCommHead(v72, v94, true, v76);
if (ret)
{
fprintf(stderr, "ERR: GetCommHead ret %d", ret);
}
for (int i = 0; i < v72.size(); i++)
{
std::string v98;
std::string cur = v72[i];
std::string v101 = WXML::Rewrite::ToStringCode(cur);
int ret = lt.GetPageCss(v101, v98, 0);
if (ret)
{
fprintf(stderr, "INFO: GetPageCss fail ret %d", ret);
}
v92.emplace(cur, v98);
}
std::stringstream v104;
v104 << "{\"common\":\"";
v104 << EscapeToJsonString(v94);
v104 << "\",\"pageWxss\":";
v104 << DictToJsonString(v92);
v104 << "}";
std::string v101 = v104.str();
}
fprintf(stderr, "ERR: wxss GetCompiledResult: %s, error file count: %d, ret %d", v96.data(), lt.offset_4, lt.offset_0);
return 1;
}
// main - 30
for (int i = 0; i < v29; i++)
{
v72.push_back(v66[i]);
}
// main - 35
// main - 40
if (v36)
{
goto LABEL_102;
}
int v25 = WXSS::NewLintAndParseCSSList(v77, v72, v88, v90, 0, v37, v75, v76);
if (v25)
{
fprintf(stderr, "ERR: %s\nerror file count: %d\n", v90.data(), 0);
return 1;
}
fprintf(f, "%s", v88.data());
fclose(f);
// main - 45
return 0;
}

21
src/wcsc/usage.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <iostream>
//----- (00401726) --------------------------------------------------------
int usage(int argc, const char **argv)
{
printf("*** WeChat Stylesheet Compiler, Version %s ***\n", "v0.4me_20190328_db");
printf(
"Usage: %s [-lc] [-o OUTPUT] [-s <NAME OF FILE>] [-st] [-js] [-db] [-cp <CLASS PREFIX>] [-pc <FILE COUNT>] <[-sd <SOU"
"RCE DIRECTLY>] | <root_css_file..> [import_css_files..]>\n",
*argv);
printf(" -lc: need to lint the css\n");
printf(" -sd: 'someclass { font-size: 18px }'\n");
printf(" -s: read from stdin\n");
printf(" -o: output destination (default stdout)\n");
printf(" -st: print tree\n");
printf(" -db: add debug attr\n");
printf(" -js: js formate output\n");
printf(" -cp: add class prefix\n");
printf(" -pc: page wxss files count\n");
return 0;
}

15
src/wxss/common.cpp Normal file
View File

@ -0,0 +1,15 @@
#include "../include/wxss.h"
namespace WXSS
{
std::string RemoveQuote(std::string const&)
{
throw "not implement";
}
int LintAndParseCSSList(std::map<std::string,std::string> const&, std::string&, std::string&, std::string&, int, bool, bool, bool, std::string const&)
{
throw "not implement";
}
}

View File

@ -0,0 +1,16 @@
#include "../../include/wxss.h"
namespace WXSS
{
namespace CSSTreeLib
{
CSSSyntaxTree::CSSSyntaxTree(/* args */)
{
}
CSSSyntaxTree::~CSSSyntaxTree()
{
}
}
} // namespace WXSS

View File

@ -0,0 +1,13 @@
#include "../../include/wxss.h"
namespace WXSS
{
namespace CSSTreeLib
{
void LexicalChecker::GetInstance(/* args */)
{
}
}
} // namespace WXSS

View File

@ -0,0 +1,22 @@
#include "../../include/wxss.h"
namespace WXSS
{
namespace CSSTreeLib
{
Parser::Parser(/* args */)
{
}
Parser::~Parser()
{
}
int Parser::Parse(std::string const&, std::string const&, std::string&, std::string const&)
{
throw "not implement";
}
}
} // namespace WXSS

13
src/wxss/token.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "../include/wxss.h"
namespace WXSS
{
Token::Token(/* args */)
{
}
Token::~Token()
{
}
}

144
src/wxss/x_compiler.cpp Normal file
View File

@ -0,0 +1,144 @@
#include "../include/wxss.h"
#include "../include/wxa.h"
namespace WXSS
{
XCompiler::XCompiler(/* args */)
{
}
XCompiler::XCompiler(std::map<std::string, std::string> const& a2, bool a3, std::string const& a4)
{
std::map<std::string, int> _v64;
if (a3)
{
// GetInstance
}
else
{
// GetInstance
}
this->offset_0 = 0;
this->offset_4 = 0;
std::string v55;
for (auto i = a2.begin(); i != a2.end(); i++)
{
WXSS::CSSTreeLib::Parser v29;
std::string v61;
std::string v77;
int v47 = v29.Parse(i->second, i->first, v61, a4);
if (v47)
{
this->offset_4++;
v55 += v61 + "\n";
this->offset_0 = v47;
}
else
{
std::shared_ptr<WXSS::CSSTreeLib::CSSSyntaxTree> v57(new WXSS::CSSTreeLib::CSSSyntaxTree());
WXSS::CSSTreeLib::LexicalChecker v31;
v31.Traval(v57);
std::string v42;
for (int j = 0; j < v57->offset_120.size(); j++)
{
auto cur = v57->offset_120[j];
if (cur->offset_0 == "DIRECTIVE")
{
auto v8 = cur->offset_120;
v42 = i->first;
if (v8.size() > 1 && v8[0]->offset_0 == "@import")
{
std::string lit = v8[1]->offset_24.GetLiteral();
std::string v64 = WXSS::RemoveQuote(lit);
std::string v70;
if (v64[0] == '/')
{
std::string v74 = "." + v64;
if (a2.end() != a2.find(v74))
{
v70.assign(v74);
}
v74 += ".wxss";
if (a2.end() != a2.find(v74))
{
v70.assign(v74);
}
}
if (!v70.length())
{
MMBizWxaAppComm::PathCombine(i->first, v64, v70);
}
if (a2.find(v70) == a2.end())
{
v70 += ".wxss";
}
if (a2.find(v70) == a2.end())
{
v55 += "path `" + v64 + "` not found from `" + i->first + "`.\n";
this->offset_4++;
this->offset_0 = 3;
}
else
{
auto v34 = this->offset_56;
std::vector<std::string> v10 = v34[i->first];
v10.push_back(v70);
std::shared_ptr<std::string> v33(new std::string());
v33->assign(v70);
cur->offset_140 = v33;
}
}
}
}
std::string v74 = v42;
std::shared_ptr<WXSS::CSSTreeLib::CSSSyntaxTree> v75(new WXSS::CSSTreeLib::CSSSyntaxTree());
// this->offset_32.
// todo...
}
}
// end for
// XCompiler - 5
if (!this->offset_0)
{
for (auto j = a2.begin(); j != a2.end(); j++)
{
_v64[j->first] = 0;
}
for (auto k = a2.begin(); k != a2.end(); k++)
{
std::string v32 = k->first;
}
// XCompiler - 5 - 0
while (true)
{
while (true)
{
/* code */
break;
}
break;
}
// XCompiler - 5 - 5
if (a2.size() != 0) // todo...
{
v55 += "I don't know what will happen if a snake eats its tail, but a file can not import itself.";
this->offset_0 = 4;
this->offset_4++;
}
}
}
XCompiler::~XCompiler()
{
}
} // namespace WXSS

180771
test/wcsc.disassembly.cpp Normal file

File diff suppressed because it is too large Load Diff