aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker.sln20
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.cpp673
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj90
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.filters36
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.user11
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/ReadMe.txt40
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.cpp8
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.h15
-rw-r--r--experimental/LightSymbolsUtil/Callstacker/Callstacker/targetver.h8
-rw-r--r--experimental/LightSymbolsUtil/lightsymbols/helper.h65
-rw-r--r--experimental/LightSymbolsUtil/lightsymbols/lightsymbols.cc169
-rw-r--r--experimental/LightSymbolsUtil/lightsymbols/lightsymbols.h50
12 files changed, 1185 insertions, 0 deletions
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker.sln b/experimental/LightSymbolsUtil/Callstacker/Callstacker.sln
new file mode 100644
index 0000000000..3be208ddc4
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Callstacker", "Callstacker\Callstacker.vcxproj", "{A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}.Debug|Win32.Build.0 = Debug|Win32
+ {A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}.Release|Win32.ActiveCfg = Release|Win32
+ {A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.cpp b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.cpp
new file mode 100644
index 0000000000..150a1dff2b
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.cpp
@@ -0,0 +1,673 @@
+// Callstacker.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+
+#include <string>
+#include <map>
+#include <vector>
+
+using namespace std;
+
+// can't delete, only add files repository!
+class SkSourceDb {
+public:
+ SkSourceDb(const char* szBaseSrcPath, const char* szLightSymbolsDbFile) {
+ this->baseSrcPath = szBaseSrcPath;
+ this->lightSymbolsDbFile = szLightSymbolsDbFile;
+ nextId = 1;
+ }
+
+ const string& getBaseSrcPath() const {
+ return baseSrcPath;
+ }
+
+ string GetStoredFilename(const string& filename) {
+ string base = filename.substr(0, baseSrcPath.length());
+ if (base != baseSrcPath) {
+ return "";
+ }
+
+ string relative = filename.substr(baseSrcPath.length());
+ char tmp[10000];
+ strcpy(tmp, relative.c_str()); // insecure
+ char* sz = tmp;
+ while (*sz) {
+ if (*sz == '\\') *sz = '/';
+ sz++;
+ }
+ sz = tmp;
+ if (*sz == '/') sz++;
+
+ return string(sz);
+ }
+
+ int obtainFileId(const string& filename) {
+ string stored = GetStoredFilename(filename);
+ if (stored.empty()) {
+ return -1;
+ }
+
+ if (filenames.find(stored) == filenames.end()) {
+ int id = nextId;
+ nextId++;
+ filenames[stored] = id;
+ return id;
+ } else {
+ return filenames[stored];
+ }
+ }
+
+ static void Load(char* szFileName, SkSourceDb** ret, const char* whereToSave, const char* szBaseSrcPath) {
+ char szLine[10000];
+ FILE* file = fopen(szFileName, "rt");
+ if (file == NULL) {
+ *ret = NULL;
+ return;
+ }
+
+ const char* trimed;
+ SkSourceDb* db = new SkSourceDb(szBaseSrcPath, whereToSave == NULL ? szFileName : whereToSave);
+
+ map<int, string> ids;
+ int id;
+ while (true) {
+ id = -1;
+ if (fscanf(file, "%i", &id) == 0) break;
+ if (id == -1) break;
+ *szLine = '\0';
+ fgets(szLine, 10000, file);
+ trimed = trim(szLine);
+
+ if (id < 0 || ids[id] != "") {
+ printf("fatal error: duplicate value for id = %i, existing = \"%s\", new = \"%s\"\n", id, ids[id].c_str(), trimed);
+ exit(-1);
+ }
+
+ if (trimed == NULL || *trimed == '\0') {
+ printf("fatal error: no valuefor id = %i\n", id);
+ exit(-1);
+ }
+
+ if (db->filenames.find(trimed) != db->filenames.end()) {
+ printf("fatal error: duplicate id for same file: file = %s, existing id = %i, new id = %i\n", trimed, db->filenames[trimed], id);
+// exit(-1);
+ }
+
+ string value = trimed;
+ ids[id] = value;
+ db->filenames[value] = id;
+ if (db->nextId <= id) {
+ db->nextId = id + 1;
+ }
+ }
+
+ *ret = db;
+ }
+
+ // dumb comit, smarter: use append
+ void commit() {
+ save(lightSymbolsDbFile.c_str());
+ }
+
+private:
+
+ static const char* trim(char* sz) {
+ if (sz == NULL) return NULL;
+
+ while (*sz == ' ' || *sz == '\t' || *sz == '\r' || *sz == '\n' || *sz == ',')
+ sz++;
+
+ if (*sz == '\0') return sz;
+
+ int len = strlen(sz);
+ char* start = sz;
+ sz = sz + (len - 1);
+
+ while (sz >= start && (*sz == ' ' || *sz == '\t' || *sz == '\r' || *sz == '\n' || *sz == ',')) {
+ *sz = '\0';
+ sz--;
+ }
+
+ return start;
+ }
+
+ void save(const char* szFilename) {
+ char szLine[10000];
+ FILE* file = fopen(szFilename, "wt");
+
+ map<string, int>::const_iterator itr;
+
+ for(itr = filenames.begin(); itr != filenames.end(); ++itr){
+ fprintf(file, "%i, %s\n", (*itr).second, (*itr).first.c_str());
+ }
+ fclose(file);
+ }
+
+ string baseSrcPath;
+ string lightSymbolsDbFile;
+ map<string, int> filenames;
+ int nextId;
+};
+
+SkSourceDb* source_db = NULL;
+
+bool endsWith(const char* who, const char* what) {
+ int a = strlen(who);
+ int b = strlen(what);
+ return stricmp(who + a - b, what) == 0; // insecure
+}
+
+bool sourceFile(const char* szFileName) {
+ return endsWith(szFileName, ".h") || endsWith(szFileName, ".c") || endsWith(szFileName, ".cpp") || endsWith(szFileName, ".cc");
+}
+
+// "
+// //
+// /*
+class CppState {
+public:
+
+ CppState() : line(1), inComment(false), inLineComment(false), inDoubleQuote(false), inSingleQuote(false), isEscaping(false), commentEnding(false), commentMightBeStarting(false) {
+ }
+
+ void apply(int ch) {
+ if (ch == '\n') {
+ line++;
+ if (inLineComment) inLineComment = false;
+ }
+
+ if (inLineComment) {
+ return;
+ }
+
+ if (commentMightBeStarting) {
+ commentMightBeStarting = false;
+ if (ch == '*') {
+ inComment = true;
+ } else if (ch == '/') {
+ inLineComment = true;
+ } else {
+ add('/');//previously we has / but was not pushed on tokens
+ newToken();//
+ }
+ }
+
+ if (inSingleQuote) {
+ if (isEscaping)
+ isEscaping = false;
+ else if (ch == '\\')
+ isEscaping = true;
+ else if (ch == '\'') {
+ inSingleQuote = false;
+ newToken();
+ pushToken("__SINGLE_QUOTE__");
+ newToken();
+ }
+
+ return;
+ } else if (inDoubleQuote) {
+ if (isEscaping)
+ isEscaping = false;
+ else if (ch == '\\')
+ isEscaping = true;
+ else if (ch == '\"') {
+ inDoubleQuote = false;
+ newToken();
+ pushToken("__DOUBLE_QUOTE__");
+ newToken();
+ }
+
+ return;
+ } else if (inComment) {
+ if (ch == '*') {
+ commentEnding = true;
+ } else if (ch == '/') {
+ inComment = false;
+ commentEnding = false;
+ } else {
+ commentEnding = false;
+ }
+
+ return;
+ }
+
+ switch (ch) {
+ case '\'':
+ newToken();
+ inSingleQuote = true;
+ return;
+
+ case '\"':
+ newToken();
+ inDoubleQuote = true;
+ return;
+
+ case '/':
+ newToken();
+ commentMightBeStarting = true;
+ return;
+ }
+
+ if (isspace(ch)) {
+ newToken();
+ } else if (tokenDelimiter(ch)) {
+ newToken();
+ if (isSingleCharToken(ch)) {
+ add(ch);
+ newToken();
+ }
+ } else if (isTokenable(ch)) {
+ add(ch);
+ } else {
+ printf("undexpected ... %c", (char)ch);
+ }
+ }
+
+ bool enteredFunction() {
+ if (inComment || inLineComment || inDoubleQuote || inSingleQuote || commentMightBeStarting) {
+ return false;
+ }
+
+ if (tokens.size() == 0) {
+ return false;
+ }
+
+ if (tokens[tokens.size() - 1] != "{") {
+ return false;
+ }
+
+ int i = tokens.size() - 2;
+
+ bool foundCloseBraket = false;
+ int innerBrakets = 0;
+ bool foundOpenBraket = false;
+ int iName = -1;
+
+ while (i >= 0) {
+ string t_i = tokens[i]; // debugging sucks!
+
+ if (!foundCloseBraket && (tokens[i] == "enum"
+ || tokens[i] == "struct"
+ || tokens[i] == "class"
+ || tokens[i] == "namespace"
+ || tokens[i] == "public"
+ || tokens[i] == "private"
+ || tokens[i] == "protected"
+ || tokens[i] == "__asm"
+ || tokens[i] == "catch"
+ || tokens[i] == "__except"
+ )) {
+ return false;
+ }
+
+ if (tokens[i] == ")") {
+ if (foundCloseBraket)
+ innerBrakets++;
+ else if (i >= 3 && tokens[i - 1] == "." && tokens[i - 2] == "." && tokens[i - 3] == ".") {
+ i -= 3;
+ }
+ foundCloseBraket = true;
+ } else if (tokens[i] == "(" && innerBrakets > 0) {
+ innerBrakets--;
+ } else if (tokens[i] == "(" && innerBrakets == 0) {
+ foundOpenBraket = true;
+ i--; if ( i < 0) return false;
+ string name = tokens[i];
+ iName = i;
+
+ if (name == "if" || name == "while" || name == "switch"|| name == "for") {
+ return false;
+ }
+
+ if (!CouldBeFunctionName(name)) return false;
+ if (i >= 6 && tokens[i - 1] == ":" && tokens[i - 2] == ":" && CouldBeClassnName(tokens[i - 3]) && tokens[i - 4] == ":" && tokens[i - 5] == ":" && CouldBeClassnName(tokens[i - 6])) {
+ name = tokens[i - 6] + "::" + tokens[i - 3] + "::" + name;
+ iName = i - 6;
+ if (i >= 7 && (tokens[i - 7] == ":" || tokens[i-7] == ",")) {
+ i -= 7 + 1;
+ name = "";
+ foundCloseBraket = false;
+ foundOpenBraket = false;
+ innerBrakets = 0;
+ continue;
+ }
+ }
+ else if (i >= 3 && tokens[i - 1] == ":" && tokens[i - 2] == ":" && CouldBeClassnName(tokens[i - 3])) {
+ name = tokens[i - 3] + "::" + name;
+ iName = i - 3;
+ if (i >= 4 && (tokens[i - 4] == ":" || tokens[i-4] == ",")) {
+ i -= 4 + 1;
+ name = "";
+ foundCloseBraket = false;
+ foundOpenBraket = false;
+ innerBrakets = 0;
+ continue;
+ }
+ }
+ else if (i >= 1 && (tokens[i - 1] == ":" || tokens[i-1] == ",")) {
+ i -= 1 + 1;
+ name = "";
+ foundCloseBraket = false;
+ foundOpenBraket = false;
+ innerBrakets = 0;
+ continue;
+ }
+
+ if (name == "") {
+ return false;
+ }
+
+ if (iName >= 2 && tokens[iName - 2] == "#" && tokens[iName - 1] == "define") {
+ return false;
+ }
+
+ if (iName >= 1 && (tokens[i - 1] == "enum"
+ || tokens[i - 1] == "struct"
+ || tokens[i - 1] == "class"
+ || tokens[i - 1] == "namespace"
+ || tokens[i - 1] == "public"
+ || tokens[i - 1] == "private"
+ || tokens[i - 1] == "protected"
+ || tokens[i - 1] == "__asm"
+ || tokens[i - 1] == "if"
+ || tokens[i - 1] == "while"
+ || tokens[i - 1] == "for"
+ || tokens[i - 1] == "switch"
+ || tokens[i - 1] == "!"
+ )) {
+ return false;
+ }
+
+ int k = 10;
+ i = iName - 2;
+ bool isInline = false;// heuristic for inline functions
+ while (k > 0 && i >= 0) {
+ if (tokens[i] == "inline") {
+ isInline = true;
+ break;
+ }
+ if (tokens[i] == ";" || tokens[i] == "{" || tokens[i] == "}") {
+ break;
+ }
+ i--;
+ k--;
+ }
+
+ if (isInline) return false; //do not trace inline functions
+
+ lastFunctionName = name;
+ return true;
+ } else {
+ if (!foundCloseBraket) {
+ if (!IgnorableFunctionModifier(tokens[i])) {
+ return false;
+ }
+ } else {
+ if (!IgnorableFunctionParameter(tokens[i])) {
+ return false;
+ }
+ }
+ }
+
+ i--;
+ }
+
+ return false;
+ }
+
+ const char* functionName() {
+ return lastFunctionName.c_str();
+ }
+
+ int lineNumber() {
+ return line;
+ }
+
+private:
+
+ bool CouldBeFunctionName(const string& str) {
+ if (str.empty()) return false;
+ if (!isalpha(str[0]) && str[0] != '_' && str[0] != '~' && str[0] != ':') return false;
+ for (int i = 1; i < str.length(); i++) {
+ if (!isalpha(str[i]) && !isdigit(str[i]) && str[i] != '_' && str[i] != ':') return false;
+ }
+
+ return true;
+ }
+
+ bool isNumber(const string& str) {
+ if (str.empty()) return false;
+ for (int i = 0; i < str.length(); i++) {
+ if (!isdigit(str[i]) && str[i] != '.' && str[i] != 'x' && str[i] != 'X' && str[i] != 'e' && str[i] != 'E') return false;
+ }
+
+ return true;
+ }
+
+
+ bool isOperator(const string& str) {
+ if (str.empty()) return false;
+ for (int i = 1; i < str.length(); i++) {
+ switch (str[i]) {
+ case '<':
+ case '>':
+ case '=':
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '(':
+ case ')':
+ case '[':
+ case ']':
+ case '!':
+ case '|':
+ case '&':
+ case '^':
+ case '%':
+ break;
+ default:
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool CouldBeClassnName(const string& str) {
+ return CouldBeFunctionName(str);
+ }
+
+ bool IgnorableFunctionModifier(const string& str) {
+ return str.empty() || CouldBeFunctionName(str);
+ }
+
+ bool IgnorableFunctionParameter(const string& str) {
+ if (str.empty()) return true;
+ if (CouldBeFunctionName(str)) return true;
+ if (str == ",") return true;
+ if (str == "*") return true;
+ if (str == "=") return true;
+ if (str == "&") return true;
+ if (str == "<") return true;
+ if (str == ">") return true;
+ if (str == ":") return true;
+ if (str == "=") return true;
+ if (isNumber(str)) return true;
+ if (str == "]") return true;
+ if (str == "[") return true;
+
+ if (str == ";") return false;
+
+ return false;
+ }
+
+
+ bool tokenDelimiter(int ch) {
+ if (isspace(ch)) return true;
+ if (isdigit(ch)) return false;
+ if (isalpha(ch)) return false;
+ if (ch == '_') return false;
+ return true;
+ }
+
+ bool isTokenable(int ch) {
+ if (isdigit(ch)) return true;
+ if (isalpha(ch)) return true;
+ if (ch == '_') return true;
+ return false;
+ }
+
+ bool isSingleCharToken(int ch) {
+ if (isspace(ch)) return false;
+ if (isdigit(ch)) return false;
+ if (isalpha(ch)) return false;
+ if (ch == '_') return false;
+ return true;
+ }
+
+ void add(char ch) {
+ token += ch;
+ }
+
+ void pushToken(const char* sz) {
+ newToken();
+ token = sz;
+ newToken();
+ }
+
+ void newToken() {
+ if (token.empty()) return;
+
+ if (tokens.size() > 0) {
+ string last = tokens[tokens.size() -1];
+ if (last == "operator") {
+ if (isOperator(op + token)) {
+ op += token;
+ token = "";
+ return;
+ } else if (op != "" && isOperator(op)) {
+ tokens[tokens.size() -1] = last + op;
+ op = "";
+ return;
+ } else if (isOperator(token)) {
+ op = token;
+ token = "";
+ return;
+ } else {
+ // compile error?
+ op = "";
+ }
+ } else if (last == "~") {
+ tokens[tokens.size() -1] = last + token;
+ token = "";
+ return;
+ }
+ }
+
+ tokens.push_back(token);
+ token = "";
+ }
+
+ int line;
+ vector<string> tokens;
+ string token;
+ string lastFunctionName;
+
+ bool inComment;
+ bool inLineComment;
+ bool inDoubleQuote;
+ bool inSingleQuote;
+ bool isEscaping;
+ bool commentEnding;
+ bool commentMightBeStarting;
+
+ string op;
+};
+
+char output[100000000];
+char* now;
+
+
+void emit(char ch) {
+ *now = ch;
+ now++;
+}
+
+void emit(const char* szCode, const char* szFunctionName, int fileId, int line) {
+ sprintf(now, szCode, szFunctionName, fileId, line);
+ while (*now) {
+ now++;
+ }
+}
+
+void runFile(const char* szFileNameInput, const char* szFileNameOutput, const char* szInclude) {
+ printf("%s\n", szFileNameInput);
+
+
+ if (!sourceFile(szFileNameInput))
+ return;
+
+ now = output;
+ int fileId = source_db->obtainFileId(szFileNameInput);
+ FILE* file = fopen(szFileNameInput, "rt");
+ int ch;
+ CppState state;
+ while (true) {
+ int ch = getc(file);
+ if (ch == -1)
+ break;
+ state.apply(ch);
+ emit(ch);
+ if (ch == '{' && state.enteredFunction()) { // {
+ emit("LS_TRACE(\"%s\", %i, %i);", state.functionName(), fileId, state.lineNumber()); // light symbol traces, create a macro to define it
+ }
+ }
+ fclose(file);
+
+ file = fopen(szFileNameOutput, "wt");
+ // TODO: input parameter
+ fprintf(file, "#include \"%s\"\n", szInclude);
+ fwrite(output, 1, now - output, file);
+ fclose(file);
+ //source_db->commit();
+}
+
+// to create the list file:
+// dir *.cpp;*.h;*.cc /s /b
+void runAll(char* szFileHolder, const char* szInclude) {
+ FILE* file = fopen(szFileHolder, "rt");
+ if (file == NULL) {
+ return;
+ }
+
+ while (true) {
+ char szFileName[10000] = "";
+ fgets(szFileName, 10000, file);
+ char* end = szFileName + strlen(szFileName) - 1;
+ while (end > szFileName && (*end == '\n' || *end == '\r' || *end == ' ' || *end == '\t')) {
+ *end = 0;
+ end--;
+ }
+ if (strlen(szFileName) == 0)
+ break;
+
+ runFile(szFileName, szFileName, szInclude);
+ }
+ fclose(file);
+ source_db->commit();
+}
+
+int _tmain(int argc, char* argv[])
+{
+ // base path, include, list.txt, lightSymbolFile, [lightSymbolsOut]
+ SkSourceDb::Load(argv[4], &source_db, argc == 5 ? argv[4] : argv[5], argv[1]);
+ if (source_db == NULL) {
+ source_db = new SkSourceDb(argv[1], argv[4]);
+ }
+
+ runAll(argv[3], argv[2]); // e.g. foo\\src\\lightsymbols\\lightsymbols.h");
+
+ return 0;
+} \ No newline at end of file
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj
new file mode 100644
index 0000000000..61411c4ec6
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A0E72F45-561E-4B28-B9B2-6C9E9F6BA8BA}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>Callstacker</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h" />
+ <ClInclude Include="targetver.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="Callstacker.cpp" />
+ <ClCompile Include="stdafx.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.filters b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.filters
new file mode 100644
index 0000000000..b7e939c14a
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.filters
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="stdafx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="targetver.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="stdafx.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Callstacker.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.user b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.user
new file mode 100644
index 0000000000..797bf6a30f
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/Callstacker.vcxproj.user
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LocalDebuggerCommandArguments>D:\edisonn\chromium1_new\ D:\edisonn\chromium1_new\all.txt D:\edisonn\chromium1_new\lightsymbols.txt</LocalDebuggerCommandArguments>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LocalDebuggerCommandArguments>D:\edisonn\chromium1_new\ D:\edisonn\chromium1_new\all.txt D:\edisonn\chromium1_new\lightsymbols.txt</LocalDebuggerCommandArguments>
+ <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
+ </PropertyGroup>
+</Project> \ No newline at end of file
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/ReadMe.txt b/experimental/LightSymbolsUtil/Callstacker/Callstacker/ReadMe.txt
new file mode 100644
index 0000000000..8f597bf979
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/ReadMe.txt
@@ -0,0 +1,40 @@
+========================================================================
+ CONSOLE APPLICATION : Callstacker Project Overview
+========================================================================
+
+AppWizard has created this Callstacker application for you.
+
+This file contains a summary of what you will find in each of the files that
+make up your Callstacker application.
+
+
+Callstacker.vcxproj
+ This is the main project file for VC++ projects generated using an Application Wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+Callstacker.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+Callstacker.cpp
+ This is the main application source file.
+
+/////////////////////////////////////////////////////////////////////////////
+Other standard files:
+
+StdAfx.h, StdAfx.cpp
+ These files are used to build a precompiled header (PCH) file
+ named Callstacker.pch and a precompiled types file named StdAfx.obj.
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.cpp b/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.cpp
new file mode 100644
index 0000000000..30465b021c
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// Callstacker.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.h b/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.h
new file mode 100644
index 0000000000..47a0d0252b
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/stdafx.h
@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/experimental/LightSymbolsUtil/Callstacker/Callstacker/targetver.h b/experimental/LightSymbolsUtil/Callstacker/Callstacker/targetver.h
new file mode 100644
index 0000000000..90e767bfce
--- /dev/null
+++ b/experimental/LightSymbolsUtil/Callstacker/Callstacker/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include <SDKDDKVer.h>
diff --git a/experimental/LightSymbolsUtil/lightsymbols/helper.h b/experimental/LightSymbolsUtil/lightsymbols/helper.h
new file mode 100644
index 0000000000..29258675cc
--- /dev/null
+++ b/experimental/LightSymbolsUtil/lightsymbols/helper.h
@@ -0,0 +1,65 @@
+#include <stdlib.h>
+#define CANVAS_PATH "CANVAS_PATH"
+
+class SkFile {
+ FILE* file;
+ bool busted;
+ char* sz;
+ mutable int i;
+
+public:
+ SkFile(unsigned long id) {
+ file = NULL;
+ busted = false;
+ sz = new char[100000];
+ set(id);
+ i = 100;
+ }
+
+ ~SkFile() {
+ delete sz;
+ if (file) {
+ fclose(file);
+ }
+ }
+
+ void set(unsigned long id) {
+ if (busted) {
+ return;
+ }
+
+ if (file == NULL) {
+ char sz[10000];
+ sprintf(sz, "%s\\%ul.callstacks.txt", getenv(CANVAS_PATH), id);
+ file = fopen(sz, "a");
+ if (file == NULL) {
+ busted = true;
+ }
+ fprintf(file, "\n\n\nNEW SESSION, just coliding ids ... should generate a new file ideally ... \n\n\n");
+ }
+ }
+
+ void appendLine(const char* sz) const {
+ if (busted) {
+ return;
+ }
+
+ fprintf(file, "%s\n", sz);
+ }
+
+ void dump(bool flush = false) const {
+ if (busted) {
+ return;
+ }
+
+ LightSymbol::GetCallStack(sz, 100000, " >- ");
+ appendLine(sz);
+
+ i--;
+
+ if (i < 0 || flush) {
+ i = 100;
+ fflush(file);
+ }
+ }
+};
diff --git a/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.cc b/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.cc
new file mode 100644
index 0000000000..230faf587f
--- /dev/null
+++ b/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.cc
@@ -0,0 +1,169 @@
+#include "lightsymbols.h"
+
+LightSymbol::PLightSymbol LightSymbol::lsFrames[1000];
+HANDLE LightSymbol::handleFrames[1000];
+SZ* LightSymbol::fileNames;
+bool LightSymbol::busted = false;
+
+
+LightSymbol::LightSymbol(const char* sym, int fileId, int lineNumber) {
+ while (busted) {
+ busted = busted;
+ }
+ this->sym = sym;
+ this->fileId = fileId;
+ this->lineNumber = lineNumber;
+
+ LightSymbol** container = getThreadFrameContainer();
+
+ parentFrame = *container;
+ *container = this; // shortcut for get+set current frame
+}
+
+LightSymbol::~LightSymbol() {
+
+// assert if (GetCurrentFrame() != this) {
+
+ SetCurrentFrame(parentFrame);
+}
+
+bool LightSymbol::GetCallStack(char* sz, int len, const char* separator) {
+ LightSymbol* ls = GetCurrentFrame();
+ if (ls == 0) {
+ return false;
+ } else {
+ return ls->GetCallStackCore(sz, len, separator);
+ }
+}
+
+LightSymbol** LightSymbol::getThreadFrameContainer() {
+ //pthread_t t = pthread_self();
+ HANDLE h = (HANDLE)GetCurrentThreadId(); // f, keep handle so I don't have to recompie tyhe whole app; update toi DWORD one I really need changes in header file
+ int i = 0;
+ while (handleFrames[i] != h && handleFrames[i] != NULL && i < 1000 - 1) {
+ i++;
+ }
+ if (handleFrames[i] == h) {
+ return &lsFrames[i];
+ }
+ handleFrames[i] = h;
+ return &lsFrames[i];
+}
+
+bool LightSymbol::GetCallStackCore(char* sz, int len, const char* separator) const {
+ if (busted) {
+ return false;
+ }
+ if (fileNames == NULL) { // f multithreading synchr
+ FILE* log = fopen("d:\\edisonn\\log.txt", "wt");
+
+ if (log) { fprintf(log, "build\n");fflush(log); }
+
+ char szLine[10000];
+ FILE* file = fopen(getenv(LIGHT_SYMBOLS_FILE), "rt");
+ if (file == NULL) {
+ busted = true;
+ return false;
+ }
+
+ const char* trimed;
+
+ // count number of lines
+ int id;
+ int entries = 0;
+ while (true) {
+ id = -1;
+ if (fscanf(file, "%i", &id) == 0) break;
+ if (id == -1) break;
+ if (entries <= id + 1) {
+ entries = id + 1;
+ }
+ *szLine = '\0';
+ fgets(szLine, 10000, file);
+ trimed = trim(szLine);
+ }
+
+ fclose(file);
+ file = fopen(getenv(LIGHT_SYMBOLS_FILE), "rt");
+ if (file == NULL) {
+ busted = true;
+ return false; // f this
+ }
+
+ if (log) { fprintf(log, "entries: %i\n", entries);fflush(log); }
+
+ SZ* __fileNames = new SZ[entries];
+
+ while (true) {
+ id = -1;
+ if (fscanf(file, "%i", &id) == 0) break;
+ if (id == -1) break;
+ *szLine = '\0';
+ fgets(szLine, 10000, file);
+ trimed = trim(szLine);
+
+ if (log) { fprintf(log, "%i, %s", id, trimed); }
+
+ // ass u me the file is correct
+
+ __fileNames[id] = new char[strlen(trimed) + 1];
+ if (log) { fprintf(log, " - ");fflush(log); }
+ strcpy(__fileNames[id], trimed);
+ if (log) { fprintf(log, " _ \n");fflush(log); }
+ }
+ fclose(file);
+ fileNames = __fileNames;
+ if (log) { fclose(log); }
+ }
+
+ const LightSymbol* ls = this;
+ char* szOut = sz;
+ // f security
+ while (ls != NULL && len > 1000) {
+ sprintf(szOut, "%s, %s:%i%s", ls->sym, fileNames[ls->fileId], ls->lineNumber, separator);
+ while (*szOut && len > 0) {
+ szOut++;
+ len--;
+ }
+ ls = ls->parentFrame;
+ }
+
+ int more = 0;
+ while (ls != NULL) {
+ ls = ls->parentFrame;
+ }
+
+ if (more > 0) {
+ sprintf(szOut, " ... %i more frames. allocate more memory!", more);
+ }
+
+ return true;
+}
+
+LightSymbol* LightSymbol::GetCurrentFrame() {
+ return *getThreadFrameContainer();
+}
+
+void LightSymbol::SetCurrentFrame(LightSymbol* ls) {
+ *getThreadFrameContainer() = ls;
+}
+
+const char* LightSymbol::trim(char* sz) {
+ if (sz == NULL) return NULL;
+
+ while (*sz == ' ' || *sz == '\t' || *sz == '\r' || *sz == '\n' || *sz == ',')
+ sz++;
+
+ if (*sz == '\0') return sz;
+
+ int len = strlen(sz);
+ char* start = sz;
+ sz = sz + (len - 1);
+
+ while (sz >= start && (*sz == ' ' || *sz == '\t' || *sz == '\r' || *sz == '\n' || *sz == ',')) {
+ *sz = '\0';
+ sz--;
+ }
+
+ return start;
+}
diff --git a/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.h b/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.h
new file mode 100644
index 0000000000..1dc6e85049
--- /dev/null
+++ b/experimental/LightSymbolsUtil/lightsymbols/lightsymbols.h
@@ -0,0 +1,50 @@
+#ifndef __LIGHT_SYMBOLS__
+#define __LIGHT_SYMBOLS__
+#define LS_TRACE(functionName,fileId,lineNumber) LightSymbol __lstr(functionName,fileId,lineNumber);
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+//#include <pthread.h>
+#include <Windows.h>
+
+typedef char* SZ;
+
+#define LIGHT_SYMBOLS_FILE "LIGHT_SYMBOLS_FILE"
+
+class LightSymbol {
+ const char* sym;
+ int fileId;
+ int lineNumber;
+
+ LightSymbol* parentFrame;
+
+ typedef LightSymbol* PLightSymbol;
+
+ static PLightSymbol lsFrames[1000];
+ static HANDLE handleFrames[1000];
+ static SZ* fileNames;
+ static bool busted;
+
+public:
+ LightSymbol(const char* sym, int fileId, int lineNumber);
+
+ ~LightSymbol();
+
+ static bool GetCallStack(char* sz, int len, const char* separator);
+
+private:
+
+ static LightSymbol** getThreadFrameContainer();
+
+ bool GetCallStackCore(char* sz, int len, const char* separator) const ;
+
+ static LightSymbol* GetCurrentFrame() ;
+
+ static void SetCurrentFrame(LightSymbol* ls) ;
+
+ static const char* trim(char* sz) ;
+};
+
+#endif \ No newline at end of file