diff --git a/.idea/misc.xml b/.idea/misc.xml
index 36970fa..ac2c845 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -4,7 +4,7 @@
-
+
\ No newline at end of file
diff --git a/src/main/CTests/test.c b/src/main/CTests/test.c
index 25d0302..5df7da4 100644
--- a/src/main/CTests/test.c
+++ b/src/main/CTests/test.c
@@ -14,5 +14,7 @@ short munis(int a,int b){
int l = a;
int f = b;
int k = l - f;
- return k;
+ int h = add(l,f);
+ int p = k / h;
+ return p;
}
\ No newline at end of file
diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt
index 3b43ee0..9300f77 100644
--- a/src/main/kotlin/Main.kt
+++ b/src/main/kotlin/Main.kt
@@ -167,7 +167,7 @@ fun App() {
getInvokeTraceTreeString("main",sf,relations)
ttGraph = generateGraph(relations)
- ivGraph = sf.functions.getInvokeGraph("main")
+ ivGraph = sf.functions.getInvokeGraph()
showResult.value = true
}
diff --git a/src/main/kotlin/core/CFunction.kt b/src/main/kotlin/core/CFunction.kt
index 823ca5f..cf2ff8c 100644
--- a/src/main/kotlin/core/CFunction.kt
+++ b/src/main/kotlin/core/CFunction.kt
@@ -130,7 +130,7 @@ fun List.find(name: String): CFunction? {
* List.getInvokeTree
* @param List: 要求包含所有函数以查找
* @param name: 从哪个函数开始查找
- * @return 特制的 TraceTree
+ * @return 特制的 TraceTree funcName -> tracetree[], 包含的是调用者的参数
*/
fun List.getInvokeTree(name: String): Map> {
// 先找到开始的函数
@@ -154,10 +154,13 @@ fun List.getInvokeTree(name: String): Map> {
if (function != null) {
val info = InvokeInfo(name, args)
val tt = function.getTraceTree(info)
- invokeTrees.addAll(tt)
+ // 过滤 trace tree
+ invokeTrees.addAll(tt.filter { it.name.startsWith(name) })
}
if (funcName != "") {
- resultMap[funcName] = invokeTrees
+ val newTree = invokeTrees.toList()
+ resultMap[funcName] = newTree // 因为之后要清空
+ invokeTrees.clear()
args.clear()
funcName = ""
}
diff --git a/src/main/kotlin/core/GraphvizHelper.kt b/src/main/kotlin/core/GraphvizHelper.kt
index 8197cb4..409664d 100644
--- a/src/main/kotlin/core/GraphvizHelper.kt
+++ b/src/main/kotlin/core/GraphvizHelper.kt
@@ -7,22 +7,23 @@ fun generateGraph(relations: Map>, crossLabelPaths: List<
sb.append("digraph G {\n")
for ((label, edges) in relations) {
- sb.append(" subgraph cluster_$label {\n")
- sb.append(" label = \"$label\";\n")
+ sb.append("subgraph cluster_$label {")
+ sb.append("label = \"$label\";")
val uniquePaths = mutableSetOf()
for (relation in edges) {
uniquePaths.add("${relation.from} -> ${relation.to}")
- sb.append("${relation.from}$label[label=${relation.from}];\n${relation.to}$label[label=${relation.to}];\n")
- sb.append("${relation.from}$label -> ${relation.to}$label;\n")
+ sb.append("${relation.from}$label[label=${relation.from}];${relation.to}$label[label=${relation.to}];")
+ sb.append("${relation.from}$label -> ${relation.to}$label;")
}
- sb.append(" }\n")
+ sb.append("}\n")
}
if (crossLabelPaths != null) {
// 处理跨函数
+ val hashes = mutableListOf() // 去重, 重复是因为一个参数可以有多个影响其他变量的路线,但一起显示太奇怪了
for (path in crossLabelPaths) {
val parts = path.split(":")
if (parts.size == 3) {
@@ -31,13 +32,18 @@ fun generateGraph(relations: Map>, crossLabelPaths: List<
val fromNode = subPath[0] // 这里就是z
val toNode = subPath[1] // 下一个就是
// from 到 to 用虚线
- sb.append(" $fromNode${parts[1]} -> $toNode${parts[0]} [style=dashed];\n")
+ val str = "$fromNode${parts[1]} -> $toNode${parts[0]} [style=dashed];"
+ val hash = str.hashCode()
+ if (hash !in hashes){ // 不重复
+ sb.append(str)
+ hashes.add(hash)
+ }
}
}
}
}
- sb.append("}\n")
+ sb.append("\n}")
return sb.toString()
}
@@ -63,14 +69,13 @@ fun parseRelation(funcName: String, parse: String): Map>{
)
}
-fun List.getInvokeGraph(funcName: String): String {
+fun List.getInvokeGraph(): String {
val relations = mutableMapOf>()
- val func = this.find(funcName) ?: return ""
-
+ val crossLabelPaths = StringBuilder()
this.forEach {
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
+ crossLabelPaths.append(this.getInvokeTree(it.name).getFuncRepr(it.name))
+ crossLabelPaths.append('\n')
}
-
- val crossLabelPaths = this.getInvokeTree(func.name).getFuncRepr(func.name)
- return generateGraph(relations,crossLabelPaths.split('\n')) + "\n"
+ return generateGraph(relations,crossLabelPaths.split('\n').filter { it.isNotEmpty() })
}
\ No newline at end of file
diff --git a/src/main/kotlin/core/SourceFile.kt b/src/main/kotlin/core/SourceFile.kt
index debc35b..7702eb5 100644
--- a/src/main/kotlin/core/SourceFile.kt
+++ b/src/main/kotlin/core/SourceFile.kt
@@ -6,8 +6,6 @@ import java.io.File
import core.CLanguage.Companion.OPERATION.*
import core.CLanguage.Companion.declarationRegex
import core.CLanguage.Companion.types
-import utils.getDefineList
-import utils.getUseList
class SourceFile {
companion object {
@@ -156,18 +154,12 @@ fun main() {
val funcs = sourceFile.parseFunction()
val relations = mutableMapOf>()
funcs.forEach {
- println("${it.name}(${it.params}) -> ${it.returnType} {\n${it.content}\n} ")
- it.cParser.sentenceList.forEach{ s->
- println("${s.left},${s.right},${s.type}")
- }
- println(it.getTraceTree().getStringRepr())
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
}
- println(funcs.getInvokeTree("main").getFuncRepr("main"))
+ for (function in funcs) {
+ println(funcs.getInvokeTree(function.name).getFuncRepr(function.name))
+ }
println(generateGraph(relations))
- println(funcs.getInvokeGraph("main"))
-
- println(getDefineList(sourceFile.getDef()))
- println(getUseList(sourceFile.getUse()))
+ println(funcs.getInvokeGraph())
}
\ No newline at end of file
diff --git a/src/main/kotlin/core/TraceTree.kt b/src/main/kotlin/core/TraceTree.kt
index bd7b337..d8ccf4f 100644
--- a/src/main/kotlin/core/TraceTree.kt
+++ b/src/main/kotlin/core/TraceTree.kt
@@ -49,15 +49,13 @@ fun List.getStringRepr(): String {
fun Map>.getFuncRepr(func: String): String {
val result = StringBuilder()
- var fName = ""
this.forEach { (name, list) ->
- fName = name
val listRepr = list.getStringRepr()
- result.append(listRepr.split('\n').filter { it.startsWith(func) }.joinToString("\n"))
+ for (line in listRepr.lines()) {
+ if (line.startsWith(func)){ // main:x-> 这样的
+ result.append("$name:$line\n")
+ }
+ }
}
- val fixedResult = StringBuilder()
- result.lines().forEach { line ->
- fixedResult.append("$fName:$line\n")
- }
- return fixedResult.toString()
+ return result.toString().trim()
}
\ No newline at end of file
diff --git a/src/main/kotlin/utils/OpenBrowser.kt b/src/main/kotlin/utils/OpenBrowser.kt
index 57aa370..ecd17ea 100644
--- a/src/main/kotlin/utils/OpenBrowser.kt
+++ b/src/main/kotlin/utils/OpenBrowser.kt
@@ -1,6 +1,10 @@
package utils
import java.awt.Desktop
+import java.awt.Toolkit
+import java.awt.datatransfer.StringSelection
+import java.io.File
+import java.io.IOException
import java.net.URI
import java.util.*
@@ -10,7 +14,20 @@ fun openBrowser(uri: URI) {
when {
Desktop.isDesktopSupported() && desktop.isSupported(Desktop.Action.BROWSE) -> desktop.browse(uri)
"mac" in osName -> Runtime.getRuntime().exec("open $uri")
- "nix" in osName || "nux" in osName -> Runtime.getRuntime().exec("xdg-open $uri")
+ "nix" in osName || "nux" in osName -> {
+ try {
+ Runtime.getRuntime().exec("xdg-open $uri")
+ }catch (_: IOException){
+ // xdg-open 不存在
+ if (File("/run/current-system/sw/bin/xdg-open").exists()){ // nixos
+ Runtime.getRuntime().exec("/run/current-system/sw/bin/xdg-open $uri")
+ }else{
+ val clipboard = Toolkit.getDefaultToolkit().systemClipboard
+ val content = StringSelection(uri.toString())
+ clipboard.setContents(content, null)
+ }
+ }
+ }
else -> desktop.browse(uri)
}
}