Cthulhu  0.2.10
Cthulhu compiler collection
scan.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-3.0-only
2 
3 #include "ctu/scan.h"
4 #include "arena/arena.h"
5 #include "ctu/ast.h"
6 
7 #include "scan/node.h"
8 
9 #include "cthulhu/broker/scan.h"
10 #include "cthulhu/events/events.h"
11 #include "std/str.h"
12 
13 #include <gmp.h>
14 
15 void ctu_parse_digit(scan_t *scan, where_t where, ctu_integer_t *integer, const char *str, int len, size_t base)
16 {
17  // TODO: this chain could be better
18  if (str_endswithn(str, len, "ul"))
19  {
20  len -= 2;
21  integer->digit = eDigitLong;
22  integer->sign = eSignUnsigned;
23  }
24  else if (str_endswithn(str, len, "uz"))
25  {
26  len -= 2;
27  integer->digit = eDigitSize;
28  integer->sign = eSignUnsigned;
29  }
30  else if (str_endswithn(str, len, "l"))
31  {
32  len--;
33  integer->digit = eDigitLong;
34  integer->sign = eSignSigned;
35  }
36  else if (str_endswithn(str, len, "u"))
37  {
38  len--;
39  integer->digit = eDigitInt;
40  integer->sign = eSignUnsigned;
41  }
42  else
43  {
44  integer->digit = eDigitInt;
45  integer->sign = eSignSigned;
46  }
47 
48  // TODO: i should maybe submit a patch to gmp to support a length argument
49  arena_t *arena = ctx_get_arena(scan);
50  char *copy = arena_strndup(str, len, arena);
51  int ret = mpz_init_set_str(integer->value, copy, (int)base);
52  arena_free(copy, len + 1, arena); // TODO: this +1 is a bit weird
53 
54  if (ret == -1)
55  {
56  const node_t *node = node_new(scan, where);
57  logger_t *logger = ctx_get_logger(scan);
58  msg_notify(logger, &kEvent_InvalidIntegerLiteral, node, "failed to parse base %zu digit '%s'", base, str);
59  }
60 }
61 
62 void ctuerror(where_t *where, void *state, scan_t *scan, const char *msg)
63 {
64  ctx_error(where, state, scan, msg);
65 }
CT_BROKER_API void ctx_error(const where_t *where, const void *state, const scan_t *scan, const char *msg)
Definition: context.c:59
CT_BROKER_API logger_t * ctx_get_logger(const scan_t *scan)
Definition: context.c:14
CT_BROKER_API arena_t * ctx_get_arena(const scan_t *scan)
Definition: context.c:20
CT_NODISCARD CT_SCAN_API node_t * node_new(const scan_t *scan, where_t where)
create a new node on the heap
Definition: node.c:40
CT_NODISCARD CT_ARENA_API char * arena_strndup(STA_READS(len) const char *str, size_t len, arena_t *arena)
allocate a copy of a string with a maximum length from a custom allocator
CT_ARENA_API void arena_free(STA_RELEASE void *ptr, size_t size, arena_t *arena)
release memory from a custom allocator
CT_NOTIFY_API event_builder_t msg_notify(INOUT_NOTNULL logger_t *logs, const diagnostic_t *diagnostic, const node_t *node, STA_FORMAT_STRING const char *fmt,...)
notify the logger of a new message
CT_NODISCARD CT_PUREFN CT_STD_API bool str_endswithn(STA_READS(len) const char *str, size_t len, const char *suffix)
check if a string ends with a substring
void ctu_parse_digit(scan_t *scan, where_t where, ctu_integer_t *integer, const char *str, int len, size_t base)
Definition: scan.c:15
void ctuerror(where_t *where, void *state, scan_t *scan, const char *msg)
Definition: scan.c:62
an allocator object
Definition: arena.h:86
digit_t digit
Definition: ast.h:17
sign_t sign
Definition: ast.h:18
mpz_t value
Definition: ast.h:16
a logging sink
Definition: notify.c:14
a position in a source file
Definition: node.h:23
a source file scanner
Definition: scan.h:24
a location inside a scanner locations are inclusive and 0-based
Definition: where.h:23