Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
PluginErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Common/ResultErrorFormatter.h"
6#include "PluginError.h"
7
8namespace SC
9{
10namespace detail
11{
12inline bool appendPluginErrorDetail(ResultErrorFormatter& formatter, PluginErrorDetail detail)
13{
14 switch (detail)
15 {
16 case PluginErrorDetail::None: return true;
17 case PluginErrorDetail::PathAssign: formatter.append("assign path"); break;
18 case PluginErrorDetail::PathAppend: formatter.append("append path"); break;
19 case PluginErrorDetail::MetadataName: formatter.append("parse metadata name"); break;
20 case PluginErrorDetail::MetadataVersion: formatter.append("parse metadata version"); break;
21 case PluginErrorDetail::MetadataDescription: formatter.append("parse metadata description"); break;
22 case PluginErrorDetail::MetadataCategory: formatter.append("parse metadata category"); break;
23 case PluginErrorDetail::MetadataDependency: formatter.append("parse metadata dependency"); break;
24 case PluginErrorDetail::MetadataBuildOption: formatter.append("parse metadata build option"); break;
25 case PluginErrorDetail::ScannerDefinitionStorage: formatter.append("store scanner definition"); break;
26 case PluginErrorDetail::ScannerCandidatePath: formatter.append("build scanner candidate path"); break;
27 case PluginErrorDetail::ScannerCandidateFile: formatter.append("store scanner candidate file"); break;
28 case PluginErrorDetail::IteratorAssignDirectory: formatter.append("assign directory path"); break;
29 case PluginErrorDetail::IteratorBuildSearchPath: formatter.append("build directory search path"); break;
30 case PluginErrorDetail::IteratorBuildEntryPath: formatter.append("build directory entry path"); break;
31 case PluginErrorDetail::CompilerFindConfiguration: formatter.append("find compiler configuration"); break;
32 case PluginErrorDetail::CompilerBuildArguments: formatter.append("build compiler arguments"); break;
33 case PluginErrorDetail::CompilerWriteArguments: formatter.append("write compiler arguments"); break;
34 case PluginErrorDetail::CompilerBuildObjectPath: formatter.append("build object path"); break;
35 case PluginErrorDetail::LinkerBuildArguments: formatter.append("build linker arguments"); break;
36 case PluginErrorDetail::LinkerWriteArguments: formatter.append("write linker arguments"); break;
37 case PluginErrorDetail::LinkerBuildOutputPath: formatter.append("build dynamic library path"); break;
38 case PluginErrorDetail::SysrootFindVersion: formatter.append("find sysroot version"); break;
39 case PluginErrorDetail::SysrootBuildIncludePath: formatter.append("build sysroot include path"); break;
40 case PluginErrorDetail::SysrootBuildLibraryPath: formatter.append("build sysroot library path"); break;
41 case PluginErrorDetail::RegistryUnloadList: formatter.append("build registry unload list"); break;
42 case PluginErrorDetail::RegistryStoreDefinition: formatter.append("store registry definition"); break;
43 case PluginErrorDetail::RegistryFindPlugin: formatter.append("find registry plugin"); break;
44 case PluginErrorDetail::WindowsFileCreate: formatter.append("Windows create file"); break;
45 case PluginErrorDetail::WindowsFileGetSize: formatter.append("Windows get file size"); break;
46 case PluginErrorDetail::WindowsFileRead: formatter.append("Windows read file"); break;
47 case PluginErrorDetail::WindowsFileDelete: formatter.append("Windows delete file"); break;
48 case PluginErrorDetail::PosixFileOpen: formatter.append("POSIX open file"); break;
49 case PluginErrorDetail::PosixFileStat: formatter.append("POSIX get file size"); break;
50 case PluginErrorDetail::PosixFileRead: formatter.append("POSIX read file"); break;
51 case PluginErrorDetail::PosixFileRemove: formatter.append("POSIX remove file"); break;
52 case PluginErrorDetail::WindowsDirectoryFindFirst: formatter.append("Windows find first directory entry"); break;
53 case PluginErrorDetail::WindowsDirectoryFindNext: formatter.append("Windows find next directory entry"); break;
54 case PluginErrorDetail::PosixDirectoryOpen: formatter.append("POSIX open directory"); break;
55 case PluginErrorDetail::PosixDirectoryRead: formatter.append("POSIX read directory"); break;
56 case PluginErrorDetail::WindowsDynamicLibraryLoad: formatter.append("Windows load dynamic library"); break;
57 case PluginErrorDetail::WindowsDynamicLibraryClose: formatter.append("Windows close dynamic library"); break;
58 case PluginErrorDetail::WindowsDynamicLibraryGetSymbol:
59 formatter.append("Windows get dynamic library symbol");
60 break;
61 case PluginErrorDetail::PosixDynamicLibraryLoad: formatter.append("POSIX load dynamic library"); break;
62 case PluginErrorDetail::PosixDynamicLibraryClose: formatter.append("POSIX close dynamic library"); break;
63 case PluginErrorDetail::PosixDynamicLibraryGetSymbol: formatter.append("POSIX get dynamic library symbol"); break;
64 case PluginErrorDetail::WindowsSymbolNameConversion: formatter.append("Windows convert symbol name"); break;
65 case PluginErrorDetail::PosixSymbolNameAssign: formatter.append("POSIX assign symbol name"); break;
66 case PluginErrorDetail::WindowsDebuggerUnlock: formatter.append("Windows unlock debugger file"); break;
67 case PluginErrorDetail::WindowsDebuggerDelete: formatter.append("Windows delete debugger file"); break;
68 default: return false;
69 }
70 return true;
71}
72
73inline bool appendPluginError(ResultErrorFormatter& formatter, PluginError error)
74{
75 switch (error)
76 {
77 case PluginError::PathNotNullTerminated: formatter.append("Path is not null terminated"); break;
78 case PluginError::UnsupportedPathEncoding: formatter.append("Path encoding is not supported"); break;
79 case PluginError::InvalidDefinition: formatter.append("Plugin definition is invalid"); break;
80 case PluginError::DynamicLibraryOperationUnsupported:
81 formatter.append("Dynamic library operation is unsupported");
82 break;
83 case PluginError::PathCapacityExceeded: formatter.append("Path capacity exceeded"); break;
84 case PluginError::DefinitionCapacityExceeded: formatter.append("Plugin definition capacity exceeded"); break;
85 case PluginError::ScannerCapacityExceeded: formatter.append("Plugin scanner capacity exceeded"); break;
86 case PluginError::RegistryCapacityExceeded: formatter.append("Plugin registry capacity exceeded"); break;
87 case PluginError::CompilerConfigurationCapacityExceeded:
88 formatter.append("Compiler configuration capacity exceeded");
89 break;
90 case PluginError::SysrootCapacityExceeded: formatter.append("Sysroot capacity exceeded"); break;
91 case PluginError::ArgumentCapacityExceeded: formatter.append("Argument capacity exceeded"); break;
92 case PluginError::FileOpenFailed: formatter.append("Failed to open file"); break;
93 case PluginError::FileSizeQueryFailed: formatter.append("Failed to query file size"); break;
94 case PluginError::FileBufferCapacityExceeded: formatter.append("File buffer capacity exceeded"); break;
95 case PluginError::FileReadFailed: formatter.append("Failed to read file"); break;
96 case PluginError::FileReadIncomplete: formatter.append("File read incomplete"); break;
97 case PluginError::FileRemoveFailed: formatter.append("Failed to remove file"); break;
98 case PluginError::DirectoryOpenFailed: formatter.append("Failed to open directory"); break;
99 case PluginError::DirectoryReadFailed: formatter.append("Failed to read directory"); break;
100 case PluginError::CompilerNotFound: formatter.append("Compiler not found"); break;
101 case PluginError::SysrootNotFound: formatter.append("Sysroot not found"); break;
102 case PluginError::CompilerEnvironmentReadFailed: formatter.append("Failed to read compiler environment"); break;
103 case PluginError::CompilerExitedWithFailure: formatter.append("Compiler exited unsuccessfully"); break;
104 case PluginError::LinkerExitedWithFailure: formatter.append("Linker exited unsuccessfully"); break;
105 case PluginError::DynamicLibraryAlreadyLoaded: formatter.append("Dynamic library is already loaded"); break;
106 case PluginError::DynamicLibraryLoadFailed: formatter.append("Failed to load dynamic library"); break;
107 case PluginError::DynamicLibraryCloseFailed: formatter.append("Failed to close dynamic library"); break;
108 case PluginError::DynamicLibraryNotLoaded: formatter.append("Dynamic library is not loaded"); break;
109 case PluginError::SymbolNameConversionFailed: formatter.append("Failed to convert symbol name"); break;
110 case PluginError::SymbolNameCapacityExceeded: formatter.append("Symbol name capacity exceeded"); break;
111 case PluginError::SymbolNotFound: formatter.append("Symbol not found"); break;
112 case PluginError::InitializationEntryPointNotFound:
113 formatter.append("Plugin initialization entry point not found");
114 break;
115 case PluginError::CloseEntryPointNotFound: formatter.append("Plugin close entry point not found"); break;
116 case PluginError::PluginNotFound: formatter.append("Plugin not found"); break;
117 case PluginError::PluginInitializationFailed: formatter.append("Plugin initialization failed"); break;
118 case PluginError::PluginShutdownFailed: formatter.append("Plugin shutdown failed"); break;
119 case PluginError::DebuggerUnlockFailed: formatter.append("Failed to unlock debugger file"); break;
120 case PluginError::ReloadUnsupported: formatter.append("Plugin reload is unsupported by this runtime"); break;
121 default: return false;
122 }
123 return true;
124}
125
126inline ResultErrorFormat formatPluginErrorWithContext(PluginError error, PluginErrorDetail detail,
127 PluginErrorContextKind contextKind, PluginErrorContext context,
128 Span<char> output)
129{
130 ResultErrorFormatter formatter(output);
131 if (not appendPluginError(formatter, error))
132 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
133 if (detail != PluginErrorDetail::None)
134 {
135 formatter.append(" (detail: ");
136 if (not appendPluginErrorDetail(formatter, detail))
137 return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
138 formatter.append(")");
139 }
140 switch (contextKind)
141 {
142 case PluginErrorContextKind::None: break;
143 case PluginErrorContextKind::NativeError:
144 formatter.append(" (native error: ");
145 formatter.append(static_cast<uint64_t>(context.nativeError));
146 formatter.append(")");
147 break;
148 case PluginErrorContextKind::ExitCode:
149 formatter.append(" (exit code: ");
150 if (context.exitCode < 0)
151 {
152 formatter.append("-");
153 formatter.append(static_cast<uint64_t>(-static_cast<int64_t>(context.exitCode)));
154 }
155 else
156 formatter.append(static_cast<uint64_t>(context.exitCode));
157 formatter.append(")");
158 break;
159 case PluginErrorContextKind::RequiredBytes:
160 formatter.append(" (required capacity: ");
161 formatter.append(static_cast<uint64_t>(context.requiredBytes));
162 formatter.append(" bytes)");
163 break;
164 case PluginErrorContextKind::RequiredElements:
165 formatter.append(" (required capacity: ");
166 formatter.append(static_cast<uint64_t>(context.requiredElements));
167 formatter.append(" elements)");
168 break;
169 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
170 }
171 return formatter.finish();
172}
173} // namespace detail
174
175inline ResultErrorFormat formatPluginError(PluginError error, Span<char> output)
176{
177 return detail::formatPluginErrorWithContext(error, PluginErrorDetail::None, PluginErrorContextKind::None, {},
178 output);
179}
180
181inline ResultErrorFormat formatPluginError(Result result, Span<char> output)
182{
183 if (result)
184 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
185 if (result.category() != PluginResultCategory)
186 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
187 return formatPluginError(static_cast<PluginError>(result.errorValue()), output);
188}
189
190inline ResultErrorFormat formatPluginError(ResultPlugin result, Span<char> output)
191{
192 if (result)
193 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
194 if (result.result.category() != PluginResultCategory)
195 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
196 return detail::formatPluginErrorWithContext(static_cast<PluginError>(result.result.errorValue()), result.detail,
197 result.contextKind, result.context, output);
198}
199} // namespace SC
PluginErrorContextKind
Kind of the scalar diagnostic context stored in ResultPlugin.
Definition PluginError.h:112
PluginErrorDetail
Stable operation or backend stage retained for a Plugin failure.
Definition PluginError.h:57
PluginError
Stable portable failures returned by the Plugin library.
Definition PluginError.h:14