|
| 1 | +/* |
| 2 | ++----------------------------------------------------------------------+ |
| 3 | + | Zend Engine | |
| 4 | + +----------------------------------------------------------------------+ |
| 5 | + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | |
| 6 | + +----------------------------------------------------------------------+ |
| 7 | + | This source file is subject to version 2.00 of the Zend license, | |
| 8 | + | that is bundled with this package in the file LICENSE, and is | |
| 9 | + | available through the world-wide-web at the following url: | |
| 10 | + | http://www.zend.com/license/2_00.txt. | |
| 11 | + | If you did not receive a copy of the Zend license and are unable to | |
| 12 | + | obtain it through the world-wide-web, please send a note to | |
| 13 | + | [email protected] so we can mail you a copy immediately. | |
| 14 | + +----------------------------------------------------------------------+ |
| 15 | + | Authors: Rob Landers <[email protected]> | |
| 16 | + | | |
| 17 | + +----------------------------------------------------------------------+ |
| 18 | +*/ |
| 19 | + |
| 20 | +#include "zend_namespaces.h" |
| 21 | +#include "zend_API.h" |
| 22 | +#include "zend_hash.h" |
| 23 | + |
| 24 | +zend_class_entry *create_namespace(zend_string *name) { |
| 25 | + zend_class_entry *ns = pemalloc(sizeof(zend_class_entry *), 0); |
| 26 | + zend_initialize_class_data(ns, 1); |
| 27 | + ns->type = ZEND_NAMESPACE_CLASS; |
| 28 | + ns->ce_flags |= ZEND_ACC_UNINSTANTIABLE; |
| 29 | + ns->name = zend_string_copy(name); |
| 30 | + |
| 31 | + return ns; |
| 32 | +} |
| 33 | + |
| 34 | +static zend_class_entry *insert_namespace(const zend_string *name) { |
| 35 | + zend_class_entry *parent_ns = EG(global_namespace); |
| 36 | + zend_class_entry *ns = parent_ns; |
| 37 | + const char *start = ZSTR_VAL(name); |
| 38 | + const char *end = start + ZSTR_LEN(name); |
| 39 | + const char *pos = start; |
| 40 | + size_t len = 0; |
| 41 | + |
| 42 | + while (pos <= end) { |
| 43 | + if (pos == end || *pos == '\\') { |
| 44 | + len = pos - start; |
| 45 | + zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 0); |
| 46 | + |
| 47 | + ns = zend_hash_find_ptr(EG(namespaces), needle); |
| 48 | + |
| 49 | + if (!ns) { |
| 50 | + zend_string *interned_name = zend_new_interned_string(needle); |
| 51 | + ns = create_namespace(interned_name); |
| 52 | + ns->lexical_scope = parent_ns; |
| 53 | + zend_hash_add_ptr(EG(namespaces), interned_name, ns); |
| 54 | + } |
| 55 | + zend_string_release(needle); |
| 56 | + |
| 57 | + parent_ns = ns; |
| 58 | + } |
| 59 | + pos ++; |
| 60 | + } |
| 61 | + |
| 62 | + return ns; |
| 63 | +} |
| 64 | + |
| 65 | +zend_class_entry *zend_resolve_namespace(zend_string *name) { |
| 66 | + if (EG(global_namespace) == NULL) { |
| 67 | + EG(global_namespace) = create_namespace(zend_empty_string); |
| 68 | + EG(global_namespace)->lexical_scope = NULL; |
| 69 | + zend_hash_init(EG(namespaces), 8, NULL, ZEND_CLASS_DTOR, 0); |
| 70 | + zend_hash_add_ptr(EG(namespaces), zend_empty_string, EG(global_namespace)); |
| 71 | + } |
| 72 | + |
| 73 | + if (name == NULL || ZSTR_LEN(name) == 0) { |
| 74 | + return EG(global_namespace); |
| 75 | + } |
| 76 | + |
| 77 | + zend_string *lc_name = zend_string_tolower(name); |
| 78 | + zend_class_entry *ns = zend_hash_find_ptr(EG(namespaces), lc_name); |
| 79 | + |
| 80 | + if (!ns) { |
| 81 | + ns = insert_namespace(lc_name); |
| 82 | + } |
| 83 | + |
| 84 | + zend_string_release(lc_name); |
| 85 | + |
| 86 | + return ns; |
| 87 | +} |
| 88 | + |
| 89 | +zend_class_entry *zend_lookup_namespace(zend_string *name) { |
| 90 | + zend_string *lc_name = zend_string_tolower(name); |
| 91 | + zend_class_entry *ns = zend_hash_find_ptr(EG(namespaces), lc_name); |
| 92 | + zend_string_release(lc_name); |
| 93 | + |
| 94 | + return ns; |
| 95 | +} |
0 commit comments