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