/*
+----------------------------------------------------------------------+
| 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 <gopalv@php.net> |
+----------------------------------------------------------------------+
*/
/* $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
*/
syntax highlighted by Code2HTML, v. 0.9.1