/* +----------------------------------------------------------------------+ | Hidef | +----------------------------------------------------------------------+ | Copyright (c) 2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Gopal Vijayaraghavan | +----------------------------------------------------------------------+ */ /* $Id: hidef.c,v 1.4 2007/02/25 21:57:24 pajoye Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "php.h" #include "php_ini.h" #include "php_scandir.h" #include "zend_globals.h" #include "ext/standard/info.h" #include "SAPI.h" #include "hidef.h" /* {{{ hidef globals * * true globals, no need for thread safety here */ static HashTable hidef_constants_table; /* }}} */ /* {{{ hidef_functions[] * * Every user visible function must have an entry in hidef_functions[]. */ zend_function_entry hidef_functions[] = { {NULL, NULL, NULL} /* Must be the last line in hidef_functions[] */ }; /* }}} */ /* {{{ hidef_module_entry */ zend_module_entry hidef_module_entry = { STANDARD_MODULE_HEADER, "hidef", hidef_functions, PHP_MINIT(hidef), PHP_MSHUTDOWN(hidef), NULL, NULL, PHP_MINFO(hidef), #if ZEND_MODULE_API_NO >= 20010901 "0.1.0", #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_HIDEF ZEND_GET_MODULE(hidef) #endif /* {{{ struct hidef_ini_parser_ctxt */ typedef struct _hidef_ini_parser_ctxt { int module_number; const char * filename; } hidef_ini_parser_ctxt; /* }}} */ /* {{{ hidef_zval_free */ static void hidef_zval_free(void *p) { zval * zv = (zval*) p; if(zv->type == IS_STRING) { free(Z_STRVAL_P(zv)); } } /* }}} */ /* {{{ hidef_ini_parser_cb */ static void hidef_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg) { char *p; char *key = Z_STRVAL_P(arg1); int type = IS_STRING; zval value; zend_constant c; hidef_ini_parser_ctxt * ctxt = (hidef_ini_parser_ctxt*)arg; TSRMLS_FETCH(); c.flags = CONST_CS | CONST_PERSISTENT; #ifdef CONST_CT_SUBST c.flags |= CONST_CT_SUBST; #endif c.module_number = ctxt->module_number; switch (callback_type) { case ZEND_INI_PARSER_ENTRY: { if(!arg2) { return; } if(strncmp(key, "int ", strlen("int ")) == 0) { type = IS_LONG; } else if(strncmp(key, "str ", strlen("str ")) == 0) { type = IS_STRING; } else if(strncmp(key, "float ", strlen("float ")) == 0) { type = IS_DOUBLE; } else if(strncmp(key, "bool ", strlen("bool ")) == 0) { type = IS_BOOL; } else { /* TODO: error */ return; } p = strrchr(key, ' '); if((p == NULL) || strlen(p) == 1) { /* TODO: error handling */ return; } p += 1; /* skip ' '*/ value = *arg2; zval_copy_ctor(&value); switch(type) { case IS_LONG: { convert_to_long(&value); } break; case IS_DOUBLE: { convert_to_double(&value); } break; case IS_BOOL: { convert_to_boolean(&value); } break; case IS_STRING: { convert_to_string(&value); } break; } /* TODO: check conversion results */ c.value = value; if(type == IS_STRING) { /* TODO: this leaks memory */ c.value.value.str.val = zend_strndup(Z_STRVAL_P(&c.value), Z_STRLEN_P(&c.value)); } c.name = zend_strndup(p, strlen(p)); c.name_len = strlen(p)+1; if(zend_register_constant(&c TSRMLS_CC) == FAILURE) { fprintf(stderr, "Constant '%s' redefined in %s line %d\n", p, ctxt->filename, zend_ini_scanner_get_lineno(TSRMLS_C) - 1); } zend_hash_add(&hidef_constants_table, c.name, c.name_len, &c.value, sizeof(c.value), NULL); zval_dtor(&value); } break; #ifdef ZEND_INI_PARSER_POP_ENTRY case ZEND_INI_PARSER_POP_ENTRY: { /* do nothing here, I suppose */ } break; #endif case ZEND_INI_PARSER_SECTION: { /* ignore sectioning */ } break; default: assert(0); } } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(hidef) { char ini_path[MAXPATHLEN]={0,}; char ini_file[MAXPATHLEN]={0,}; int ndir, i; char *p = NULL; struct stat sb; zend_file_handle fh = {0,}; struct dirent **namelist = NULL; hidef_ini_parser_ctxt ctxt = {0,}; ctxt.module_number = module_number; zend_hash_init(&hidef_constants_table, 32, NULL, hidef_zval_free, 1); if (!sapi_module.php_ini_ignore && strlen(PHP_CONFIG_FILE_SCAN_DIR)) { snprintf(ini_path, MAXPATHLEN, "%s%c%s", PHP_CONFIG_FILE_SCAN_DIR, DEFAULT_SLASH, "hidef"); if ((ndir = php_scandir(ini_path, &namelist, 0, php_alphasort)) > 0) { for (i = 0; i < ndir; i++) { /* check for a .ini extension */ if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) { free(namelist[i]); continue; } snprintf(ini_file, MAXPATHLEN, "%s%c%s", ini_path, DEFAULT_SLASH, namelist[i]->d_name); if (VCWD_STAT(ini_file, &sb) == 0 && S_ISREG(sb.st_mode)) { if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) { fh.filename = ini_file; ctxt.filename = ini_file; fh.type = ZEND_HANDLE_FP; zend_parse_ini_file(&fh, 1, hidef_ini_parser_cb, &ctxt); } } free(namelist[i]); } free(namelist); } } return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION * */ PHP_MSHUTDOWN_FUNCTION(hidef) { zend_hash_destroy(&hidef_constants_table); return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(hidef) { char ini_path[MAXPATHLEN]={0,}; HashPosition pos; zend_constant *val; int module_number = zend_module->module_number; php_info_print_table_start(); if (!sapi_module.php_ini_ignore && strlen(PHP_CONFIG_FILE_SCAN_DIR)) { snprintf(ini_path, MAXPATHLEN, "%s%c%s", PHP_CONFIG_FILE_SCAN_DIR, DEFAULT_SLASH, "hidef"); } else { php_info_print_table_row(2, "hidef support", "disabled"); php_info_print_table_end(); return; } php_info_print_table_row(2, "hidef support", "enabled"); php_info_print_table_row(2, "ini search path", ini_path); #ifdef CONST_CT_SUBST php_info_print_table_row(2, "substitution mode", "compile time"); #else php_info_print_table_row(2, "substitution mode", "runtime"); #endif php_info_print_table_end(); php_info_print_table_start(); php_info_print_table_header(2, "Constant", "Value"); zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos); while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) { if (val->module_number == module_number) { zval const_val = {0,}; const_val = val->value; zval_copy_ctor(&const_val); convert_to_string(&const_val); php_info_print_table_row(2, val->name, Z_STRVAL_P(&const_val)); zval_dtor(&const_val); } zend_hash_move_forward_ex(EG(zend_constants), &pos); } php_info_print_table_end(); } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */