ACAV f0ba4b7c9529
Abstract Syntax Tree (AST) visualization tool for C, C++, and Objective-C
Loading...
Searching...
No Matches
ProcessOutputUtils.h
Go to the documentation of this file.
1/*$!{
2* Aurora Clang AST Viewer (ACAV)
3*
4* Copyright (c) 2026 Min Liu
5* Copyright (c) 2026 Michael David Adams
6*
7* SPDX-License-Identifier: GPL-2.0-or-later
8*
9* This program is free software; you can redistribute it and/or modify
10* it under the terms of the GNU General Public License as published by
11* the Free Software Foundation; either version 2 of the License, or
12* (at your option) any later version.
13*
14* This program is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17* GNU General Public License for more details.
18*
19* You should have received a copy of the GNU General Public License along
20* with this program; if not, see <https://www.gnu.org/licenses/>.
21}$!*/
22
25#pragma once
26
27#include "core/LogEntry.h"
28#include "core/ProcessLogParser.h"
29#include <QDateTime>
30#include <QHash>
31#include <QProcess>
32#include <functional>
33
34namespace acav {
35
36using LogEmitter = std::function<void(const LogEntry &)>;
37
38inline void emitParsedOutput(QString &buffer, const QString &chunk,
39 const QString &source, bool isStdErr,
40 const LogEmitter &emitLog) {
41 const QVector<LogEntry> entries =
42 parseProcessOutput(buffer, chunk, source, isStdErr);
43 for (const LogEntry &entry : entries) {
44 emitLog(entry);
45 }
46}
47
48inline void emitParsedOutput(QHash<QProcess *, QString> &buffers,
49 QProcess *process, const QString &chunk,
50 const QString &source, bool isStdErr,
51 const LogEmitter &emitLog) {
52 if (!process) {
53 return;
54 }
55 QString &buffer = buffers[process];
56 emitParsedOutput(buffer, chunk, source, isStdErr, emitLog);
57}
58
59inline void drainProcessOutput(QProcess *process, QString &stdoutBuffer,
60 QString &stderrBuffer, const QString &source,
61 const LogEmitter &emitLog) {
62 if (!process) {
63 return;
64 }
65
66 const QString stdoutChunk =
67 QString::fromUtf8(process->readAllStandardOutput());
68 const QString stderrChunk =
69 QString::fromUtf8(process->readAllStandardError());
70
71 emitParsedOutput(stdoutBuffer, stdoutChunk, source, false, emitLog);
72 emitParsedOutput(stderrBuffer, stderrChunk, source, true, emitLog);
73 if (!stdoutBuffer.isEmpty()) {
74 emitParsedOutput(stdoutBuffer, "\n", source, false, emitLog);
75 }
76 if (!stderrBuffer.isEmpty()) {
77 emitParsedOutput(stderrBuffer, "\n", source, true, emitLog);
78 }
79}
80
81inline void drainProcessOutput(QProcess *process, QString &stdoutBuffer,
82 QString &stderrBuffer, const QString &source,
83 const LogEmitter &emitLog,
84 QString *stdoutCapture,
85 QString *stderrCapture) {
86 if (!process) {
87 return;
88 }
89
90 const QString stdoutChunk =
91 QString::fromUtf8(process->readAllStandardOutput());
92 const QString stderrChunk =
93 QString::fromUtf8(process->readAllStandardError());
94 if (stdoutCapture) {
95 stdoutCapture->append(stdoutChunk);
96 }
97 if (stderrCapture) {
98 stderrCapture->append(stderrChunk);
99 }
100
101 emitParsedOutput(stdoutBuffer, stdoutChunk, source, false, emitLog);
102 emitParsedOutput(stderrBuffer, stderrChunk, source, true, emitLog);
103 if (!stdoutBuffer.isEmpty()) {
104 emitParsedOutput(stdoutBuffer, "\n", source, false, emitLog);
105 }
106 if (!stderrBuffer.isEmpty()) {
107 emitParsedOutput(stderrBuffer, "\n", source, true, emitLog);
108 }
109}
110
111inline void drainProcessOutput(QProcess *process,
112 QHash<QProcess *, QString> &stdoutBuffers,
113 QHash<QProcess *, QString> &stderrBuffers,
114 const QString &source,
115 const LogEmitter &emitLog) {
116 if (!process) {
117 return;
118 }
119 QString &stdoutBuffer = stdoutBuffers[process];
120 QString &stderrBuffer = stderrBuffers[process];
121 drainProcessOutput(process, stdoutBuffer, stderrBuffer, source, emitLog);
122}
123
124inline void drainProcessOutput(QProcess *process,
125 QHash<QProcess *, QString> &stdoutBuffers,
126 QHash<QProcess *, QString> &stderrBuffers,
127 const QString &source,
128 const LogEmitter &emitLog,
129 QString *stdoutCapture,
130 QString *stderrCapture) {
131 if (!process) {
132 return;
133 }
134 QString &stdoutBuffer = stdoutBuffers[process];
135 QString &stderrBuffer = stderrBuffers[process];
136 drainProcessOutput(process, stdoutBuffer, stderrBuffer, source, emitLog,
137 stdoutCapture, stderrCapture);
138}
139
140inline void emitErrorLog(const QString &source, const QString &message,
141 const LogEmitter &emitLog) {
142 LogEntry entry;
143 entry.level = LogLevel::Error;
144 entry.source = source;
145 entry.message = message;
146 entry.timestamp = QDateTime::currentDateTime();
147 emitLog(entry);
148}
149
150} // namespace acav