1 /*************************************************
2 * Exim - an Internet mail transport agent *
3 *************************************************/
5 /* Copyright (c) University of Cambridge 1995 - 2017 */
6 /* See the file NOTICE for conditions of use and distribution. */
8 /* Functions for handling macros */
14 # define store_get(nbytes) malloc((size_t)(nbytes))
15 #define string_copyn(s, len) strndup(CS(s), (len))
18 /*************************************************
19 * Deal with an assignment to a macro *
20 *************************************************/
22 /* We have a new definition; add to the collection.
23 Items are numbered so we can avoid recursion in expansions.
26 name Name of the macro. Will be copied.
27 val Expansion result for the macro. Will be copied.
31 macro_create(const uschar * name, const uschar * val, BOOL command_line)
33 int namelen = Ustrlen(name);
34 macro_item * m = store_get(sizeof(macro_item) + namelen);
36 /* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
38 m->command_line = command_line;
40 m->replen = Ustrlen(val);
41 m->m_number = m_number++;
42 memset(&m->tnode, 0, sizeof(tree_node));
43 /* Use memcpy here not Ustrcpy to avoid spurious compiler-inserted check
44 when building with fortify-source. We know there is room for the copy into
45 this dummy for a variable-size array because of the way we did the memory
47 memcpy(m->tnode.name, name, namelen+1);
48 m->tnode.data.ptr = string_copyn(val, m->replen);
49 (void) tree_insertnode(&tree_macros, &m->tnode);
55 /* Search for a macro, with an exact match on the name.
56 Return the node, or NULL for not-found.
58 Arguments: name key to search for
62 macro_search(const uschar * name)
66 t = tree_search(tree_macros, name);
67 return tnode_to_mitem(t);
71 /* Search for a macro with a (possibly improper) leading substring
72 matching the given name. Return the node, or NULL for not-found.
74 Arguments: name key to search on
78 macro_search_prefix(const uschar * s)
83 for (t = tree_macros; t; t = c < 0 ? t->left : t->right)
84 if ((c = Ustrncmp(s, t->name, tnode_to_mitem(t)->namelen)) == 0)
85 return tnode_to_mitem(t);
90 /* Search for the macro with the largest possible leading substring
91 matching the given name. */
94 macro_search_largest_prefix(const uschar * s)
100 if ((found = macro_search_prefix(s)))
102 /* There could be a node with a larger substring also matching the
103 name. If so it must be in the right subtree; either the right child
104 or (if that sorts after the name) in the left subtree of the right child. */
106 child = found->tnode.right;
108 if ((c = Ustrncmp(s, child->name, tnode_to_mitem(child)->namelen)) == 0)
110 found = tnode_to_mitem(child);
111 child = found->tnode.right;
113 else if (c < 0 && (child = child->left))
124 macro_print(uschar * name, uschar * val, void * ctx)
126 BOOL names_only = (BOOL)(long)ctx;
128 printf("%s\n", CS name);
130 printf("%s=%s\n", CS name, CS val);