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
24typedef str identifier;
25
26mal_export int TYPE_identifier;
27mal_export str IDprelude(void *ret);
28mal_export ssize_t IDfromString(const char *src, size_t *len, identifier *retval, bool external);
29mal_export ssize_t IDtoString(str *retval, size_t *len, const char *handle, bool external);
30mal_export str IDentifier(identifier *retval, str *in);
31
32int TYPE_identifier;
33
34str 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 */
47ssize_t
48IDfromString(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 */
71ssize_t
72IDtoString(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 */
94str
95IDentifier(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