1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | /* |
10 | * @f identifier |
11 | * @a Fabian Groffen, Martin Kersten |
12 | * @+ Identifier Wrapper |
13 | * The identifier atom is a shallow wrapper that contains an object's id. |
14 | * Due to it being wrapped by this atom, methods can distinguish |
15 | * it from a normal string. |
16 | * The variable of this time can be further extended with properties |
17 | * to further qualify the identifier referenced. |
18 | * |
19 | */ |
20 | #include "monetdb_config.h" |
21 | #include "mal.h" |
22 | #include "mal_exception.h" |
23 | |
24 | typedef str identifier; |
25 | |
26 | mal_export int TYPE_identifier; |
27 | mal_export str IDprelude(void *ret); |
28 | mal_export ssize_t IDfromString(const char *src, size_t *len, identifier *retval, bool external); |
29 | mal_export ssize_t IDtoString(str *retval, size_t *len, const char *handle, bool external); |
30 | mal_export str IDentifier(identifier *retval, str *in); |
31 | |
32 | int TYPE_identifier; |
33 | |
34 | str IDprelude(void *ret) |
35 | { |
36 | (void) ret; |
37 | TYPE_identifier = ATOMindex("identifier" ); |
38 | return MAL_SUCCEED; |
39 | } |
40 | |
41 | /** |
42 | * Creates a new identifier from the given string (stupid string copy). |
43 | * Warning: GDK function, does NOT pass a string by reference, and wants |
44 | * a pointer to a pointer for the retval! |
45 | * Returns the number of chars read |
46 | */ |
47 | ssize_t |
48 | IDfromString(const char *src, size_t *len, identifier *retval, bool external) |
49 | { |
50 | size_t l = strlen(src) + 1; |
51 | if (*retval == NULL || *len < l) { |
52 | GDKfree(*retval); |
53 | *retval = GDKmalloc(l); |
54 | if (*retval == NULL) |
55 | return -1; |
56 | *len = l; |
57 | } |
58 | if (external && strncmp(src, "nil" , 3) == 0) { |
59 | memcpy(*retval, str_nil, 2); |
60 | return 3; |
61 | } |
62 | memcpy(*retval, src, l); |
63 | return (ssize_t) l - 1; |
64 | } |
65 | |
66 | /** |
67 | * Returns the string representation of the given identifier. |
68 | * Warning: GDK function |
69 | * Returns the length of the string |
70 | */ |
71 | ssize_t |
72 | IDtoString(str *retval, size_t *len, const char *handle, bool external) |
73 | { |
74 | size_t hl = strlen(handle) + 1; |
75 | if (external && strcmp(handle, str_nil) == 0) |
76 | hl = 4; |
77 | if (*len < hl || *retval == NULL) { |
78 | GDKfree(*retval); |
79 | *retval = GDKmalloc(hl); |
80 | if (*retval == NULL) |
81 | return -1; |
82 | *len = hl; |
83 | } |
84 | if (external && strcmp(handle, str_nil) == 0) |
85 | strcpy(*retval, "nil" ); |
86 | else |
87 | memcpy(*retval, handle, hl); |
88 | return (ssize_t) hl - 1; |
89 | } |
90 | /** |
91 | * Returns an identifier, parsed from a string. The fromStr function is used |
92 | * to parse the string. |
93 | */ |
94 | str |
95 | IDentifier(identifier *retval, str *in) |
96 | { |
97 | size_t len = 0; |
98 | |
99 | if (IDfromString(*in, &len, retval, false) < 0) |
100 | throw(PARSE, "identifier.identifier" , "Error while parsing %s" , *in); |
101 | |
102 | return (MAL_SUCCEED); |
103 | } |
104 | |