1- import { ReplOutput } from "../interface" ;
1+ import {
2+ Diagnostic ,
3+ DiagnosticFrame ,
4+ DiagnosticSeverity ,
5+ ReplOutput ,
6+ } from "../interface" ;
27import { compileAndRun , CompilerInfo , SelectedCompiler } from "./api" ;
38
49import _stacktrace_cpp from "./cpp/_stacktrace.cpp?raw" ;
510
11+ const GCC_DIAG_REGEX =
12+ / ^ (?: .* \/ ) ? ( [ ^ : \n ] + ) : ( \d + ) : (?: ( \d + ) : ) ? \s * ( f a t a l e r r o r | e r r o r | w a r n i n g | n o t e ) : \s * ( .* ) $ / ;
13+ const LD_DIAG_REGEX =
14+ / ^ (?: (?: \/ u s r \/ b i n \/ l d : \s + ) ? (?: .* \/ ) ? ( [ ^ : \n ] + ) ) : ( \d + ) : (?: \( [ ^ ) ] + \) : ) ? \s * ( u n d e f i n e d r e f e r e n c e t o .* ) $ / ;
15+
616export function selectCppCompiler (
717 compilerList : CompilerInfo [ ]
818) : SelectedCompiler {
@@ -73,8 +83,8 @@ export function selectCppCompiler(
7383 }
7484
7585 // その他オプション
76- options . compilerOptionsRaw . push ( "-g" ) ;
77- commandline . push ( "-g" ) ;
86+ options . compilerOptionsRaw . push ( "-g" , "-no-pie" ) ;
87+ commandline . push ( "-g" , "-no-pie" ) ;
7888
7989 options . getCommandlineStr = ( filenames : string [ ] ) => {
8090 return [ ...commandline , ...filenames , "&&" , "./a.out" ] . join ( " " ) ;
@@ -87,13 +97,14 @@ export async function cppRunFiles(
8797 options : SelectedCompiler ,
8898 files : Record < string , string | undefined > ,
8999 filenames : string [ ] ,
90- onOutput : ( output : ReplOutput ) => void
100+ onOutput : ( output : ReplOutput ) => void ,
101+ onDiagnostic ?: ( diagnostic : Diagnostic ) => void
91102) : Promise < void > {
92- // Constants for stack trace processing
93- const WANDBOX_PATH = "/home/wandbox" ;
94-
95103 // Track state for processing stack traces
96104 let inStackTrace = false ;
105+ let signal = "" ;
106+ let exceptionMessage = "" ;
107+ const runtimeFrames : DiagnosticFrame [ ] = [ ] ;
97108
98109 await compileAndRun (
99110 {
@@ -108,14 +119,90 @@ export async function cppRunFiles(
108119 ( event ) => {
109120 const { ndjsonType, output } = event ;
110121
122+ // Parse compiler messages for diagnostics
123+ if ( ndjsonType === "CompilerMessageE" ) {
124+ const gccMatch = GCC_DIAG_REGEX . exec ( output . message ) ;
125+ if ( gccMatch ) {
126+ const rawFilename = gccMatch [ 1 ] . replace ( / ^ \. \/ / , "" ) ;
127+ if (
128+ rawFilename !== "_stacktrace.cpp" &&
129+ ! rawFilename . startsWith ( "<" ) &&
130+ ! rawFilename . includes ( "/include/" )
131+ ) {
132+ const lineNum = parseInt ( gccMatch [ 2 ] , 10 ) ;
133+ const colNum = gccMatch [ 3 ] ? parseInt ( gccMatch [ 3 ] , 10 ) : undefined ;
134+ const sev = gccMatch [ 4 ] ;
135+ const msg = gccMatch [ 5 ] ;
136+
137+ let severity : DiagnosticSeverity = "error" ;
138+ if ( sev === "warning" ) severity = "warning" ;
139+ else if ( sev === "note" ) severity = "info" ;
140+
141+ onDiagnostic ?.( {
142+ frames : [
143+ {
144+ filename : rawFilename ,
145+ startLineNumber : lineNum ,
146+ startColumn : colNum ,
147+ } ,
148+ ] ,
149+ message : msg ,
150+ severity,
151+ } ) ;
152+ }
153+ } else {
154+ const ldMatch = LD_DIAG_REGEX . exec ( output . message ) ;
155+ if ( ldMatch ) {
156+ const rawFilename = ldMatch [ 1 ] . replace ( / ^ \. \/ / , "" ) ;
157+ if (
158+ rawFilename !== "_stacktrace.cpp" &&
159+ ! rawFilename . startsWith ( "<" ) &&
160+ ! rawFilename . includes ( "/include/" )
161+ ) {
162+ const lineNum = parseInt ( ldMatch [ 2 ] , 10 ) ;
163+ const msg = ldMatch [ 3 ] ;
164+ onDiagnostic ?.( {
165+ frames : [
166+ {
167+ filename : rawFilename ,
168+ startLineNumber : lineNum ,
169+ } ,
170+ ] ,
171+ message : msg ,
172+ severity : "error" ,
173+ } ) ;
174+ }
175+ }
176+ }
177+ }
178+
179+ // Check for exception / terminate message in stderr
180+ if ( ndjsonType === "StdErr" ) {
181+ if ( output . message . includes ( "what():" ) ) {
182+ const idx = output . message . indexOf ( "what():" ) ;
183+ exceptionMessage = output . message . slice ( idx + 7 ) . trim ( ) ;
184+ } else if (
185+ output . message . includes ( "terminate called after throwing an instance of" )
186+ ) {
187+ const m =
188+ / t e r m i n a t e c a l l e d a f t e r t h r o w i n g a n i n s t a n c e o f ' ( [ ^ ' ] + ) ' / . exec (
189+ output . message
190+ ) ;
191+ if ( m && ! exceptionMessage ) {
192+ exceptionMessage = m [ 1 ] ;
193+ }
194+ }
195+ }
196+
111197 // Check for signal marker in stderr
112198 if (
113199 ndjsonType === "StdErr" &&
114200 output . message . startsWith ( "#!my_code_signal:" )
115201 ) {
202+ signal = output . message . slice ( 17 ) . trim ( ) ;
116203 onOutput ( {
117204 type : "error" ,
118- message : output . message . slice ( 17 ) ,
205+ message : signal ,
119206 } ) ;
120207 return ;
121208 }
@@ -135,12 +222,28 @@ export async function cppRunFiles(
135222
136223 // Process stack trace lines
137224 if ( inStackTrace && ndjsonType === "StdErr" ) {
138- // Filter to show only user source code
139- if ( output . message . includes ( WANDBOX_PATH ) ) {
140- onOutput ( {
141- type : "trace" ,
142- message : output . message . replace ( `${ WANDBOX_PATH } /` , "" ) ,
143- } ) ;
225+ const m = / \s a t \s + (?: .* \/ ) ? ( [ ^ : \s ] + ) : ( \d + ) / . exec ( output . message ) ;
226+ if (
227+ m &&
228+ ! output . message . includes ( "/boost/" ) &&
229+ ! output . message . includes ( "/include/" ) &&
230+ ! output . message . includes ( "/opt/wandbox/" )
231+ ) {
232+ const filename = m [ 1 ] . replace ( / ^ \. \/ / , "" ) ;
233+ if ( filename !== "_stacktrace.cpp" ) {
234+ const cleanedMessage = output . message . replace (
235+ / \s + a t \s + .* \/ ( [ ^ \/ ] + : \d + .* ) $ / ,
236+ " at $1"
237+ ) ;
238+ onOutput ( {
239+ type : "trace" ,
240+ message : cleanedMessage ,
241+ } ) ;
242+ runtimeFrames . push ( {
243+ filename,
244+ startLineNumber : parseInt ( m [ 2 ] , 10 ) ,
245+ } ) ;
246+ }
144247 }
145248 return ;
146249 }
@@ -149,4 +252,13 @@ export async function cppRunFiles(
149252 onOutput ( output ) ;
150253 }
151254 ) ;
255+
256+ if ( runtimeFrames . length > 0 ) {
257+ const message = exceptionMessage || signal || "Runtime error" ;
258+ onDiagnostic ?.( {
259+ frames : runtimeFrames ,
260+ message,
261+ severity : "error" ,
262+ } ) ;
263+ }
152264}
0 commit comments