Skip to content

Commit

Permalink
feat: add support for preprocessor
Browse files Browse the repository at this point in the history
  • Loading branch information
Enter-tainer committed Apr 5, 2022
1 parent f679eec commit 253abdf
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "cxx2flow"
version = "0.5.5"
version = "0.5.6"
edition = "2018"
authors = ["mgt <[email protected]>"]
description = "Convert your C/C++ code to control flow chart"
Expand Down
90 changes: 90 additions & 0 deletions README-en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# cxx2flow

[简体中文](README.md) | [English](README-en.md)

Turn your C/C++ code into flowchart

## Demo

For more demo please refer to [GALLERY](gallery.md)

Two different styles:
| | |
|:-:|:-:|
| polyline | smooth |
|![ployline](assets/polyline.svg)|![curve](assets/curve.svg)|

```cpp
inline int read() { //快读
char c = getchar();
int x = 0, f = 1;
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}
```

### Error reporting

![error reporting](assets/error_reporting.png)

## Installation

### Compile from source

```bash
cargo install cxx2flow
```

### Prebuilt binary

It is recommended to download prebuilt binary from [Github Release](https://github.com/Enter-tainer/cxx2flow/releases).

## Usage

To compile the generated dot file, you need graphviz. You can also copy the output to online graphviz services such as http://magjac.com/graphviz-visual-editor/ .

```
cxx2flow 0.5.6
mgt <[email protected]>
Convert your C/C++ code to control flow chart
USAGE:
cxx2flow [OPTIONS] <INPUT> [FUNCTION]
ARGS:
<INPUT> Sets the input file. e.g. test.cpp
<FUNCTION> The function you want to convert. e.g. main [default: main]
OPTIONS:
-c, --curly Sets the style of the flow chart.
If specified, output flow chart will have curly connection line.
--cpp Use C preprocessor.
-h, --help Print help information
-o, --output <OUTPUT> Sets the output file.
If not specified, result will be directed to stdout.
e.g. graph.dot
-t, --tikz Use tikz backend.
-V, --version Print version information
Note that you need to manually compile the dot file using graphviz to get SVG or PNG files.
EXAMPLES:
cxx2flow test.cpp | dot -Tpng -o test.png
cxx2flow main.cpp my_custom_func | dot -Tsvg -o test.svg
Please give me star if this application helps you!
如果这个应用有帮助到你,请给我点一个 star!
https://github.com/Enter-tainer/cxx2flow
```

## Limitations

- The support of preprocessor is based on `cpp`, and is disabled by default. `--cpp` flag is needed to enable it. It will fail if `cpp` does not exist in `PATH`.
- Supported control flow keyword: while,for,if,break,continue,break,return,switch, goto, do-while。
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# cxx2flow

[简体中文](README.md) | [English](README-en.md)

将 C/C++ 代码转换为流程图

## 效果
Expand Down Expand Up @@ -51,7 +53,7 @@ cargo install cxx2flow
为了编译生成的 dot 文件,你需要安装 graphviz,并将其添加到 PATH 中。也可以将生成的结果复制进在线的 graphviz 服务中,如 http://magjac.com/graphviz-visual-editor/

```
cxx2flow 0.5.5
cxx2flow 0.5.6
mgt <[email protected]>
Convert your C/C++ code to control flow chart
Expand All @@ -65,6 +67,7 @@ ARGS:
OPTIONS:
-c, --curly Sets the style of the flow chart.
If specified, output flow chart will have curly connection line.
--cpp Use C preprocessor.
-h, --help Print help information
-o, --output <OUTPUT> Sets the output file.
If not specified, result will be directed to stdout.
Expand All @@ -85,5 +88,5 @@ https://github.com/Enter-tainer/cxx2flow

## 限制

- 不支持预处理器,如 include, ifdef, ifndef...
- 对于预处理器的支持基于 `cpp` ,默认关闭,需要使用 `--cpp` 参数手动启用。如果 `PATH` 中不存在 `cpp` 则会失败。
- 支持的控制流语句有:while,for,if,break,continue,break,return,switch, goto, do-while。
9 changes: 9 additions & 0 deletions assets/cpp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#define TEST

int main() {
#ifdef TEST
int a = 0;
#else
int a = 1;
#endif
}
34 changes: 32 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
use std::{
io::Write,
process::{self, Stdio},
};

use itertools::Itertools;
use once_cell::sync::Lazy;

use clap::Parser;
Expand Down Expand Up @@ -57,6 +63,9 @@ If specified, output flow chart will have curly connection line."
)]
curly: bool,

#[clap(long, help("Use C preprocessor."))]
cpp: bool,

#[clap(short, long, help("Use tikz backend."))]
tikz: bool,

Expand All @@ -70,11 +79,32 @@ If specified, output flow chart will have curly connection line."
function: String,
}


fn main() -> miette::Result<()> {
miette::set_panic_hook();
let args = Args::parse();
let content = std::fs::read(&args.input).into_diagnostic()?;
let content = if args.cpp {
let content = std::fs::read(&args.input).into_diagnostic()?;
let mut cpp = process::Command::new("cpp")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.into_diagnostic()?;
if let Some(mut child_stdin) = cpp.stdin.take() {
child_stdin.write_all(&content).into_diagnostic()?;
}
cpp.wait_with_output().into_diagnostic()?.stdout
} else {
std::fs::read(&args.input).into_diagnostic()?
};
let content = Itertools::intersperse(
String::from_utf8(content)
.unwrap()
.lines()
.filter(|x| !x.starts_with('#')),
"\n",
)
.collect::<String>()
.into_bytes();
let res = generate(
&content,
&args.input,
Expand Down

0 comments on commit 253abdf

Please sign in to comment.