Cthulhu  0.2.10
Cthulhu compiler collection
error.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: LGPL-3.0-only
2 
3 #include "os/core.h"
4 #include "os_common.h"
5 
6 #include "std/str.h"
7 #include "base/util.h"
8 
9 #include "core/macros.h"
10 #include "core/win32.h" // IWYU pragma: keep
11 
12 #define FORMAT_FLAGS (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS)
13 
15 CT_LOCAL os_error_t impl_last_error(void)
16 {
17  return (os_error_t)GetLastError();
18 }
19 
20 static DWORD format_inner(os_error_t error, char *buffer, size_t size)
21 {
22  return FormatMessageA(
23  /* dwFlags = */ FORMAT_FLAGS,
24  /* lpSource = */ NULL,
25  /* dwMessageId = */ (DWORD)error,
26  /* dwLanguageId = */ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
27  /* lpBuffer = */ buffer,
28  /* nSize = */ (DWORD)size,
29  /* Arguments = */ NULL);
30 }
31 
32 CT_LOCAL size_t impl_error_length(os_error_t error)
33 {
34  // TODO: is there a way of asking for the size of the buffer at all?
35  // this is what .NET core does, but its not clear if this is correct.
36  CT_UNUSED(error);
37  return 1024;
38 }
39 
40 CT_LOCAL size_t impl_error_string(os_error_t error, char *buffer, size_t size)
41 {
42  DWORD written = format_inner(error, buffer, size);
43 
44  if (written == 0)
45  {
46  return str_sprintf(buffer, size, "GetLastError: 0x%08lX", (DWORD)error);
47  }
48 
49  // replace every instance of \n\r\t with a single space
50  // if there are consecutive newlines or whitespace, replace them with a single space.
51  text_t text = text_make(buffer, written);
52  str_replace_inplace(&text, "\r\n\t", " ");
53 
54  // trim trailing whitespace and . characters
55  str_trim_back_inplace(&text, "\r\n\t .");
56 
57  return text.length;
58 }
CT_NODISCARD size_t size
Definition: scan.h:128
#define STA_DECL
sal2 annotation on function implementations to copy annotations from the declaration
CT_CONSTFN CT_BASE_API text_t text_make(STA_READS(length) char *text, size_t length)
create a new owning text array text must be a valid string at least length bytes long
#define CT_LOCAL
Definition: compiler.h:166
#define CT_UNUSED(x)
mark a variable as unused
Definition: macros.h:46
CT_STD_API void str_replace_inplace(INOUT_NOTNULL text_t *text, const char *search, const char *repl)
replace all instances of a substring in a string in place
CT_STD_API size_t str_sprintf(STA_WRITES(len) char *str, size_t len, STA_FORMAT_STRING const char *fmt,...)
format a string with printf-like syntax
CT_STD_API void str_trim_back_inplace(INOUT_NOTNULL text_t *text, const char *chars)
trim chars from the back of a string in place
CT_LOCAL size_t impl_error_length(os_error_t error)
Definition: error.c:21
STA_DECL CT_LOCAL os_error_t impl_last_error(void)
Definition: error.c:16
CT_LOCAL size_t impl_error_string(os_error_t error, char *buffer, size_t size)
Definition: error.c:27
a range of text
Definition: text.h:14
size_t length
the number of characters in the text
Definition: text.h:19
#define FORMAT_FLAGS
Definition: error.c:12