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 Ustrcpy(m->tnode.name, name);
44 m->tnode.data.ptr = string_copyn(val, m->replen);
45 (void) tree_insertnode(&tree_macros, &m->tnode);
51 /* Search for a macro, with an exact match on the name.
52 Return the node, or NULL for not-found.
54 Arguments: name key to search for
58 macro_search(const uschar * name)
62 t = tree_search(tree_macros, name);
63 return tnode_to_mitem(t);
67 /* Search for a macro with a (possibly improper) leading substring
68 matching the given name. Return the node, or NULL for not-found.
70 Arguments: name key to search on
74 macro_search_prefix(const uschar * s)
79 for (t = tree_macros; t; t = c < 0 ? t->left : t->right)
80 if ((c = Ustrncmp(s, t->name, tnode_to_mitem(t)->namelen)) == 0)
81 return tnode_to_mitem(t);
86 /* Search for the macro with the largest possible leading substring
87 matching the given name. */
90 macro_search_largest_prefix(const uschar * s)
96 if ((found = macro_search_prefix(s)))
98 /* There could be a node with a larger substring also matching the
99 name. If so it must be in the right subtree; either the right child
100 or (if that sorts after the name) in the left subtree of the right child. */
102 child = found->tnode.right;
104 if ((c = Ustrncmp(s, child->name, tnode_to_mitem(child)->namelen)) == 0)
106 found = tnode_to_mitem(child);
107 child = found->tnode.right;
109 else if (c < 0 && (child = child->left))
120 macro_print(uschar * name, uschar * val, void * ctx)
122 BOOL names_only = (BOOL)(long)ctx;
124 printf("%s\n", CS name);
126 printf("%s=%s\n", CS name, CS val);