com php/gtk-src: Segfault bug on win32 and windows build system: main/phpg_gvalue.c win32/config.w32.in win 32/confutils.js
| From: | Elizabeth Marie Smith | Date: | Wed, 15 Aug 2012 01:40:50 +0000 |
| Subject: | com php/gtk-src: Segfault bug on win32 and windows build system: main/phpg_gvalue.c win32/config.w32.in win 32/confutils.js | ||
| Groups: | php.gtk.cvs | ||
| Request: | Send a blank email to php-gtk-cvs+get-4856@lists.php.net to get a copy of this message | ||
Commit: b9901ae6000b45d2883122fcbc13dcfba6cbf61c
Author: Elizabeth M Smith <auroraeosrose@gmail.com> Tue, 14 Aug 2012 21:40:26 -0400
Parents: 4cda109cf9fbc3498df709a0cf009da93919439e
Branches: master
Link: http://git.php.net/?p=php/gtk-src.git;a=commitdiff;h=b9901ae6000b45d2883122fcbc13dcfba6cbf61c
Log:
Segfault bug on win32 and windows build system
issue with the zend destructor using type and getting confused when
there was no type - only showed up on release builds on win32 (grrr
stupid thing) - also fixed the compiler detection and flags. This
probably breaks things for older then 2008 compilers, really don't care
Changed paths:
M main/phpg_gvalue.c
M win32/config.w32.in
M win32/confutils.js
diff --git a/main/phpg_gvalue.c b/main/phpg_gvalue.c index 94c9969..b47cab3 100644 --- a/main/phpg_gvalue.c +++ b/main/phpg_gvalue.c @@ -1,554 +1,555 @@ -/* - * PHP-GTK - The PHP language bindings for GTK+ - * - * Copyright (C) 2001-2008 Andrei Zmievski <andrei@php.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "php_gtk.h" - -#if HAVE_PHP_GTK - -/* - * GValue related functions - */ - - -/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */ -PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, zend_bool do_utf8 TSRMLS_DC) -{ - assert(value != NULL); - - switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { - case G_TYPE_INVALID: - case G_TYPE_NONE: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_NULL(*value); - break; - - case G_TYPE_CHAR: - { - gchar val = g_value_get_char(gval); - MAKE_ZVAL_IF_NULL(*value); - ZVAL_STRINGL(*value, (char *)&val, 1, 1); - } - break; - - case G_TYPE_UCHAR: - { - guchar val = g_value_get_uchar(gval); - MAKE_ZVAL_IF_NULL(*value); - ZVAL_STRINGL(*value, (char *)&val, 1, 1); - } - break; - - case G_TYPE_BOOLEAN: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_BOOL(*value, g_value_get_boolean(gval)); - break; - - case G_TYPE_INT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_int(gval)); - break; - - case G_TYPE_LONG: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_long(gval)); - break; - - case G_TYPE_UINT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_uint(gval)); - break; - - case G_TYPE_ULONG: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_ulong(gval)); - break; - - case G_TYPE_FLOAT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_DOUBLE(*value, (double)g_value_get_float(gval)); - break; - - case G_TYPE_DOUBLE: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_DOUBLE(*value, (double)g_value_get_double(gval)); - break; - - case G_TYPE_ENUM: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_enum(gval)); - break; - - case G_TYPE_FLAGS: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_flags(gval)); - break; - - case G_TYPE_STRING: - { - gchar *cp = NULL; - gsize cp_len = 0; - zend_bool free_cp = 0; - const gchar *str = g_value_get_string(gval); - - MAKE_ZVAL_IF_NULL(*value); - if (str != NULL) { - if (do_utf8) { - cp = phpg_from_utf8(str, strlen(str), &cp_len, &free_cp TSRMLS_CC); - if (cp) { - str = cp; - } else { - php_error(E_WARNING, "Could not convert string from UTF-8"); - } - } - ZVAL_STRING(*value, (char *)str, 1); - if (free_cp) { - g_free(cp); - } - } else - ZVAL_NULL(*value); - } - break; - - case G_TYPE_PARAM: - phpg_paramspec_new(value, g_value_get_param(gval) TSRMLS_CC); - break; - - case G_TYPE_OBJECT: - phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); - break; - - case G_TYPE_INTERFACE: - if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) { - phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); - } else { - php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); - MAKE_STD_ZVAL(*value); - ZVAL_NULL(*value); - return FAILURE; - } - break; - - case G_TYPE_POINTER: - phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC); - break; - - case G_TYPE_BOXED: - { - phpg_gboxed_marshal_t *gbm; - - if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { - zval *object = (zval *) g_value_dup_boxed(gval); - MAKE_ZVAL_IF_NULL(*value); - if (object) { - REPLACE_ZVAL_VALUE(value, object, 1); - zval_ptr_dtor(&object); - return SUCCESS; - } else { - ZVAL_NULL(*value); - return FAILURE; - } - } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) { - int i; - zval *item; - int value_count; - - GValueArray *array = (GValueArray *) g_value_get_boxed(gval); - MAKE_ZVAL_IF_NULL(*value); - array_init(*value); - value_count = array->n_values; - - for (i = 0; i < value_count; i++) { - MAKE_STD_ZVAL(item); - phpg_gvalue_to_zval(array->values + i, &item, copy_boxed, TRUE TSRMLS_CC); - add_next_index_zval(*value, item); - } - } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { - MAKE_STD_ZVAL(*value); - return gbm->to_zval(gval, value TSRMLS_CC); - } else { - if (copy_boxed) { - phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC); - } else { - phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC); - } - } - break; - } - - default: - php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); - MAKE_STD_ZVAL(*value); - ZVAL_NULL(*value); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */ -PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval **value, zend_bool do_utf8 TSRMLS_DC) -{ - switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { - /* - * For whatever reason, we should apparently respect that the gval may be of these - * types and they do not need a value. - */ - case G_TYPE_INVALID: - case G_TYPE_NONE: - break; - - case G_TYPE_BOOLEAN: - convert_to_boolean_ex(value); - g_value_set_boolean(gval, (gboolean)Z_BVAL_PP(value)); - break; - - case G_TYPE_CHAR: - convert_to_string_ex(value); - g_value_set_char(gval, Z_STRVAL_PP(value)[0]); - break; - - case G_TYPE_UCHAR: - convert_to_string_ex(value); - g_value_set_uchar(gval, (guchar)Z_STRVAL_PP(value)[0]); - break; - - case G_TYPE_INT: - convert_to_long_ex(value); - g_value_set_int(gval, (gint)Z_LVAL_PP(value)); - break; - - case G_TYPE_UINT: - convert_to_long_ex(value); - g_value_set_uint(gval, (guint)Z_LVAL_PP(value)); - break; - - case G_TYPE_LONG: - convert_to_long_ex(value); - g_value_set_long(gval, (glong)Z_LVAL_PP(value)); - break; - - case G_TYPE_ULONG: - convert_to_long_ex(value); - g_value_set_ulong(gval, (gulong)Z_LVAL_PP(value)); - break; - - case G_TYPE_FLOAT: - convert_to_double_ex(value); - g_value_set_float(gval, (gfloat)Z_DVAL_PP(value)); - break; - - case G_TYPE_DOUBLE: - convert_to_double_ex(value); - g_value_set_double(gval, Z_DVAL_PP(value)); - break; - - case G_TYPE_ENUM: - { - gint val = 0; - if (phpg_gvalue_get_enum(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { - return FAILURE; - } - g_value_set_enum(gval, val); - break; - } - - case G_TYPE_FLAGS: - { - gint val = 0; - if (phpg_gvalue_get_flags(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { - return FAILURE; - } - g_value_set_flags(gval, val); - break; - } - - case G_TYPE_STRING: - { - gchar *utf8 = NULL; - gsize utf8_len = 0; - zend_bool free_utf8 = 0; - gchar *str; - - convert_to_string_ex(value); - str = Z_STRVAL_PP(value); - if (do_utf8) { - utf8 = phpg_to_utf8(Z_STRVAL_PP(value), Z_STRLEN_PP(value), &utf8_len, &free_utf8 TSRMLS_CC); - if (utf8) { - str = utf8; - } else { - php_error(E_WARNING, "Could not convert string to UTF-8"); - } - } - g_value_set_string(gval, str); - if (free_utf8) { - g_free(utf8); - } - break; - } - - case G_TYPE_POINTER: - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_pointer(gval, NULL); - } else if (Z_TYPE_PP(value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gpointer_ce TSRMLS_CC) - && G_VALUE_HOLDS(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->gtype)) { - g_value_set_pointer(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->pointer); - } else { - return FAILURE; - } - break; - - case G_TYPE_BOXED: - { - phpg_gboxed_marshal_t *gbm; - - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_boxed(gval, NULL); - /* - * We should be safe just setting the zval here, since G_TYPE_PHP_VALUE is - * supposed to take any zval type. - */ - } else if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { - g_value_set_boxed(gval, *value); - } else if (Z_TYPE_PP(value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gboxed_ce TSRMLS_CC) - && G_VALUE_HOLDS(gval, ((phpg_gboxed_t*)PHPG_GET(*value))->gtype)) { - g_value_set_boxed(gval, PHPG_GBOXED(*value)); - } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { - return gbm->from_zval(*value, gval TSRMLS_CC); - } else - return FAILURE; - break; - } - - case G_TYPE_PARAM: - if (php_gtk_check_class(*value, gparamspec_ce)) { - g_value_set_param(gval, PHPG_GPARAMSPEC(*value)); - } else { - return FAILURE; - } - break; - - case G_TYPE_OBJECT: - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_object(gval, NULL); - } else if (Z_TYPE_P(*value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gobject_ce TSRMLS_CC) - && G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { - g_value_set_object(gval, PHPG_GOBJECT(*value)); - } else - return FAILURE; - break; - - case G_TYPE_INTERFACE: - if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT) && - Z_TYPE_PP(value) == IS_OBJECT && - G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { - g_value_set_object(gval, PHPG_GOBJECT(*value)); - } else { - php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); - return FAILURE; - } - break; - - default: - php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); - return FAILURE; - - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_param_gvalue_to_zval() */ -PHP_GTK_API int phpg_param_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, const GParamSpec *pspec TSRMLS_DC) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - /* TODO */ - return FAILURE; - } else { - return phpg_gvalue_to_zval(gval, value, copy_boxed, TRUE TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_param_gvalue_from_zval() */ -PHP_GTK_API int phpg_param_gvalue_from_zval(GValue *gval, zval **value, const GParamSpec *pspec TSRMLS_DC) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - /* TODO */ - return FAILURE; - } else { - return phpg_gvalue_from_zval(gval, value, TRUE TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalues_to_array() */ -PHP_GTK_API zval *phpg_gvalues_to_array(const GValue *values, uint n_values) -{ - zval *hash; - zval *item = NULL; - int i; - int value_count; - - MAKE_STD_ZVAL(hash); - array_init(hash); - value_count = n_values; - - for (i = 0; i < value_count; i++) { - //item = phpg_gvalue_to_zval(&values[i], FALSE); - if (!item) { - MAKE_STD_ZVAL(item); - ZVAL_NULL(item); - } - zend_hash_next_index_insert(Z_ARRVAL_P(hash), &item, sizeof(zval *), NULL); - } - - return hash; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_get_enum() */ -PHP_GTK_API int phpg_gvalue_get_enum(GType enum_type, zval *enum_val, gint *result) -{ - if (result == NULL) - return FAILURE; - - if (enum_val == NULL) { - *result = 0; - } else if (Z_TYPE_P(enum_val) == IS_LONG) { - *result = Z_LVAL_P(enum_val); - } else if (Z_TYPE_P(enum_val) == IS_STRING) { - GEnumClass *eclass = NULL; - GEnumValue *info = NULL; - - if (enum_type != G_TYPE_NONE) { - eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of enum"); - return FAILURE; - } - - info = g_enum_get_value_by_name(eclass, Z_STRVAL_P(enum_val)); - - if (info == NULL) { - info = g_enum_get_value_by_nick(eclass, Z_STRVAL_P(enum_val)); - } - g_type_class_unref(eclass); - - if (info != NULL) { - *result = info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to enum", Z_STRVAL_P(enum_val)); - return FAILURE; - } - } else { - php_error(E_WARNING, "PHP-GTK internal error: enums must be strings or integers"); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_get_flags() */ -PHP_GTK_API int phpg_gvalue_get_flags(GType flags_type, zval *flags_val, gint *result) -{ - GFlagsClass *fclass = NULL; - GFlagsValue *info = NULL; - - if (result == NULL) - return FAILURE; - - if (flags_val == NULL) { - *result = 0; - } else if (Z_TYPE_P(flags_val) == IS_LONG) { - *result = Z_LVAL_P(flags_val); - } else if (Z_TYPE_P(flags_val) == IS_STRING) { - if (flags_type != G_TYPE_NONE) { - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); - return FAILURE; - } - - info = g_flags_get_value_by_name(fclass, Z_STRVAL_P(flags_val)); - if (info == NULL) { - info = g_flags_get_value_by_nick(fclass, Z_STRVAL_P(flags_val)); - } - g_type_class_unref(fclass); - - if (info != NULL) { - *result = info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_P(flags_val)); - return FAILURE; - } - } else if (Z_TYPE_P(flags_val) == IS_ARRAY) { - zval **flag; - - *result = 0; - if (flags_type != G_TYPE_NONE) { - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); - return FAILURE; - } - - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(flags_val)); - zend_hash_get_current_data(Z_ARRVAL_P(flags_val), (void **)&flag) == SUCCESS; - zend_hash_move_forward(Z_ARRVAL_P(flags_val))) { - - if (Z_TYPE_PP(flag) == IS_LONG) { - *result |= Z_LVAL_PP(flag); - } else if (Z_TYPE_PP(flag) == IS_STRING) { - info = g_flags_get_value_by_name(fclass, Z_STRVAL_PP(flag)); - if (info == NULL) { - info = g_flags_get_value_by_nick(fclass, Z_STRVAL_PP(flag)); - } - if (info != NULL) { - *result |= info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_PP(flag)); - g_type_class_unref(fclass); - return FAILURE; - } - } else { - php_error(E_WARNING, "PHP-GTK flag arrays can contain only integers or strings"); - g_type_class_unref(fclass); - return 0; - } - } - g_type_class_unref(fclass); - } else { - php_error(E_WARNING, "PHP-GTK flags must be strings, integers, or arrays of strings or integers"); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -#endif - -/* vim: set fdm=marker et : */ +/* + * PHP-GTK - The PHP language bindings for GTK+ + * + * Copyright (C) 2001-2008 Andrei Zmievski <andrei@php.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "php_gtk.h" + +#if HAVE_PHP_GTK + +/* + * GValue related functions + */ + + +/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */ +PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, zend_bool do_utf8 TSRMLS_DC) +{ + assert(value != NULL); + + switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { + case G_TYPE_INVALID: + case G_TYPE_NONE: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_NULL(*value); + break; + + case G_TYPE_CHAR: + { + gchar val = g_value_get_char(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_STRINGL(*value, (char *)&val, 1, 1); + } + break; + + case G_TYPE_UCHAR: + { + guchar val = g_value_get_uchar(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_STRINGL(*value, (char *)&val, 1, 1); + } + break; + + case G_TYPE_BOOLEAN: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_BOOL(*value, g_value_get_boolean(gval)); + break; + + case G_TYPE_INT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_int(gval)); + break; + + case G_TYPE_LONG: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_long(gval)); + break; + + case G_TYPE_UINT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_uint(gval)); + break; + + case G_TYPE_ULONG: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_ulong(gval)); + break; + + case G_TYPE_FLOAT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_DOUBLE(*value, (double)g_value_get_float(gval)); + break; + + case G_TYPE_DOUBLE: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_DOUBLE(*value, (double)g_value_get_double(gval)); + break; + + case G_TYPE_ENUM: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_enum(gval)); + break; + + case G_TYPE_FLAGS: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_flags(gval)); + break; + + case G_TYPE_STRING: + { + gchar *cp = NULL; + gsize cp_len = 0; + zend_bool free_cp = 0; + const gchar *str = g_value_get_string(gval); + + MAKE_ZVAL_IF_NULL(*value); + if (str != NULL) { + if (do_utf8) { + cp = phpg_from_utf8(str, strlen(str), &cp_len, &free_cp TSRMLS_CC); + if (cp) { + str = cp; + } else { + php_error(E_WARNING, "Could not convert string from UTF-8"); + } + } + ZVAL_STRING(*value, (char *)str, 1); + if (free_cp) { + g_free(cp); + } + } else + ZVAL_NULL(*value); + } + break; + + case G_TYPE_PARAM: + phpg_paramspec_new(value, g_value_get_param(gval) TSRMLS_CC); + break; + + case G_TYPE_OBJECT: + phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); + break; + + case G_TYPE_INTERFACE: + if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) { + phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); + } else { + php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); + MAKE_STD_ZVAL(*value); + ZVAL_NULL(*value); + return FAILURE; + } + break; + + case G_TYPE_POINTER: + phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC); + break; + + case G_TYPE_BOXED: + { + phpg_gboxed_marshal_t *gbm; + + if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { + zval *object = (zval *) g_value_dup_boxed(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_NULL(*value); + if (object) { + REPLACE_ZVAL_VALUE(value, object, 1); + zval_ptr_dtor(&object); + return SUCCESS; + } else { + ZVAL_NULL(*value); + return FAILURE; + } + } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) { + int i; + zval *item; + int value_count; + + GValueArray *array = (GValueArray *) g_value_get_boxed(gval); + MAKE_ZVAL_IF_NULL(*value); + array_init(*value); + value_count = array->n_values; + + for (i = 0; i < value_count; i++) { + MAKE_STD_ZVAL(item); + phpg_gvalue_to_zval(array->values + i, &item, copy_boxed, TRUE TSRMLS_CC); + add_next_index_zval(*value, item); + } + } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { + MAKE_STD_ZVAL(*value); + return gbm->to_zval(gval, value TSRMLS_CC); + } else { + if (copy_boxed) { + phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC); + } else { + phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC); + } + } + break; + } + + default: + php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); + MAKE_STD_ZVAL(*value); + ZVAL_NULL(*value); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */ +PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval **value, zend_bool do_utf8 TSRMLS_DC) +{ + switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { + /* + * For whatever reason, we should apparently respect that the gval may be of these + * types and they do not need a value. + */ + case G_TYPE_INVALID: + case G_TYPE_NONE: + break; + + case G_TYPE_BOOLEAN: + convert_to_boolean_ex(value); + g_value_set_boolean(gval, (gboolean)Z_BVAL_PP(value)); + break; + + case G_TYPE_CHAR: + convert_to_string_ex(value); + g_value_set_char(gval, Z_STRVAL_PP(value)[0]); + break; + + case G_TYPE_UCHAR: + convert_to_string_ex(value); + g_value_set_uchar(gval, (guchar)Z_STRVAL_PP(value)[0]); + break; + + case G_TYPE_INT: + convert_to_long_ex(value); + g_value_set_int(gval, (gint)Z_LVAL_PP(value)); + break; + + case G_TYPE_UINT: + convert_to_long_ex(value); + g_value_set_uint(gval, (guint)Z_LVAL_PP(value)); + break; + + case G_TYPE_LONG: + convert_to_long_ex(value); + g_value_set_long(gval, (glong)Z_LVAL_PP(value)); + break; + + case G_TYPE_ULONG: + convert_to_long_ex(value); + g_value_set_ulong(gval, (gulong)Z_LVAL_PP(value)); + break; + + case G_TYPE_FLOAT: + convert_to_double_ex(value); + g_value_set_float(gval, (gfloat)Z_DVAL_PP(value)); + break; + + case G_TYPE_DOUBLE: + convert_to_double_ex(value); + g_value_set_double(gval, Z_DVAL_PP(value)); + break; + + case G_TYPE_ENUM: + { + gint val = 0; + if (phpg_gvalue_get_enum(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { + return FAILURE; + } + g_value_set_enum(gval, val); + break; + } + + case G_TYPE_FLAGS: + { + gint val = 0; + if (phpg_gvalue_get_flags(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { + return FAILURE; + } + g_value_set_flags(gval, val); + break; + } + + case G_TYPE_STRING: + { + gchar *utf8 = NULL; + gsize utf8_len = 0; + zend_bool free_utf8 = 0; + gchar *str; + + convert_to_string_ex(value); + str = Z_STRVAL_PP(value); + if (do_utf8) { + utf8 = phpg_to_utf8(Z_STRVAL_PP(value), Z_STRLEN_PP(value), &utf8_len, &free_utf8 TSRMLS_CC); + if (utf8) { + str = utf8; + } else { + php_error(E_WARNING, "Could not convert string to UTF-8"); + } + } + g_value_set_string(gval, str); + if (free_utf8) { + g_free(utf8); + } + break; + } + + case G_TYPE_POINTER: + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_pointer(gval, NULL); + } else if (Z_TYPE_PP(value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gpointer_ce TSRMLS_CC) + && G_VALUE_HOLDS(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->gtype)) { + g_value_set_pointer(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->pointer); + } else { + return FAILURE; + } + break; + + case G_TYPE_BOXED: + { + phpg_gboxed_marshal_t *gbm; + + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_boxed(gval, NULL); + /* + * We should be safe just setting the zval here, since G_TYPE_PHP_VALUE is + * supposed to take any zval type. + */ + } else if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { + g_value_set_boxed(gval, *value); + } else if (Z_TYPE_PP(value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gboxed_ce TSRMLS_CC) + && G_VALUE_HOLDS(gval, ((phpg_gboxed_t*)PHPG_GET(*value))->gtype)) { + g_value_set_boxed(gval, PHPG_GBOXED(*value)); + } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { + return gbm->from_zval(*value, gval TSRMLS_CC); + } else + return FAILURE; + break; + } + + case G_TYPE_PARAM: + if (php_gtk_check_class(*value, gparamspec_ce)) { + g_value_set_param(gval, PHPG_GPARAMSPEC(*value)); + } else { + return FAILURE; + } + break; + + case G_TYPE_OBJECT: + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_object(gval, NULL); + } else if (Z_TYPE_P(*value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gobject_ce TSRMLS_CC) + && G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { + g_value_set_object(gval, PHPG_GOBJECT(*value)); + } else + return FAILURE; + break; + + case G_TYPE_INTERFACE: + if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT) && + Z_TYPE_PP(value) == IS_OBJECT && + G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { + g_value_set_object(gval, PHPG_GOBJECT(*value)); + } else { + php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); + return FAILURE; + } + break; + + default: + php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); + return FAILURE; + + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_param_gvalue_to_zval() */ +PHP_GTK_API int phpg_param_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, const GParamSpec *pspec TSRMLS_DC) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + /* TODO */ + return FAILURE; + } else { + return phpg_gvalue_to_zval(gval, value, copy_boxed, TRUE TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_param_gvalue_from_zval() */ +PHP_GTK_API int phpg_param_gvalue_from_zval(GValue *gval, zval **value, const GParamSpec *pspec TSRMLS_DC) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + /* TODO */ + return FAILURE; + } else { + return phpg_gvalue_from_zval(gval, value, TRUE TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalues_to_array() */ +PHP_GTK_API zval *phpg_gvalues_to_array(const GValue *values, uint n_values) +{ + zval *hash; + zval *item = NULL; + int i; + int value_count; + + MAKE_STD_ZVAL(hash); + array_init(hash); + value_count = n_values; + + for (i = 0; i < value_count; i++) { + //item = phpg_gvalue_to_zval(&values[i], FALSE); + if (!item) { + MAKE_STD_ZVAL(item); + ZVAL_NULL(item); + } + zend_hash_next_index_insert(Z_ARRVAL_P(hash), &item, sizeof(zval *), NULL); + } + + return hash; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_get_enum() */ +PHP_GTK_API int phpg_gvalue_get_enum(GType enum_type, zval *enum_val, gint *result) +{ + if (result == NULL) + return FAILURE; + + if (enum_val == NULL) { + *result = 0; + } else if (Z_TYPE_P(enum_val) == IS_LONG) { + *result = Z_LVAL_P(enum_val); + } else if (Z_TYPE_P(enum_val) == IS_STRING) { + GEnumClass *eclass = NULL; + GEnumValue *info = NULL; + + if (enum_type != G_TYPE_NONE) { + eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of enum"); + return FAILURE; + } + + info = g_enum_get_value_by_name(eclass, Z_STRVAL_P(enum_val)); + + if (info == NULL) { + info = g_enum_get_value_by_nick(eclass, Z_STRVAL_P(enum_val)); + } + g_type_class_unref(eclass); + + if (info != NULL) { + *result = info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to enum", Z_STRVAL_P(enum_val)); + return FAILURE; + } + } else { + php_error(E_WARNING, "PHP-GTK internal error: enums must be strings or integers"); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_get_flags() */ +PHP_GTK_API int phpg_gvalue_get_flags(GType flags_type, zval *flags_val, gint *result) +{ + GFlagsClass *fclass = NULL; + GFlagsValue *info = NULL; + + if (result == NULL) + return FAILURE; + + if (flags_val == NULL) { + *result = 0; + } else if (Z_TYPE_P(flags_val) == IS_LONG) { + *result = Z_LVAL_P(flags_val); + } else if (Z_TYPE_P(flags_val) == IS_STRING) { + if (flags_type != G_TYPE_NONE) { + fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); + return FAILURE; + } + + info = g_flags_get_value_by_name(fclass, Z_STRVAL_P(flags_val)); + if (info == NULL) { + info = g_flags_get_value_by_nick(fclass, Z_STRVAL_P(flags_val)); + } + g_type_class_unref(fclass); + + if (info != NULL) { + *result = info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_P(flags_val)); + return FAILURE; + } + } else if (Z_TYPE_P(flags_val) == IS_ARRAY) { + zval **flag; + + *result = 0; + if (flags_type != G_TYPE_NONE) { + fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); + return FAILURE; + } + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(flags_val)); + zend_hash_get_current_data(Z_ARRVAL_P(flags_val), (void **)&flag) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(flags_val))) { + + if (Z_TYPE_PP(flag) == IS_LONG) { + *result |= Z_LVAL_PP(flag); + } else if (Z_TYPE_PP(flag) == IS_STRING) { + info = g_flags_get_value_by_name(fclass, Z_STRVAL_PP(flag)); + if (info == NULL) { + info = g_flags_get_value_by_nick(fclass, Z_STRVAL_PP(flag)); + } + if (info != NULL) { + *result |= info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_PP(flag)); + g_type_class_unref(fclass); + return FAILURE; + } + } else { + php_error(E_WARNING, "PHP-GTK flag arrays can contain only integers or strings"); + g_type_class_unref(fclass); + return 0; + } + } + g_type_class_unref(fclass); + } else { + php_error(E_WARNING, "PHP-GTK flags must be strings, integers, or arrays of strings or integers"); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +#endif + +/* vim: set fdm=marker et : */ diff --git a/win32/config.w32.in b/win32/config.w32.in index 88e295e..fafa61e 100644 --- a/win32/config.w32.in +++ b/win32/config.w32.in @@ -1,157 +1,162 @@ -// vim:ft=javascript -// $Id$ -// "Master" config file; think of it as a configure.in equivalent. - -// MSVC version table -var MSVCVERS = []; -MSVCVERS[1200] = 'MSVC6 (Visual C++ 6.0)'; -MSVCVERS[1300] = 'MSVC7 (Visual C++ 2002)'; -MSVCVERS[1310] = 'MSVC7.1 (Visual C++ 2003)'; -MSVCVERS[1400] = 'MSVC8 (Visual C++ 2005)'; -MSVCVERS[1500] = 'MSVC9 (Visual C++ 2008)'; -MSVCVERS[1600] = 'MSVC10 (Visual C++ 2010)'; - -STDOUT.WriteBlankLines(1); - -CL = PATH_PROG('cl'); - -// avoid picking up midnight commander from cygwin -PATH_PROG('mc', WshShell.Environment("Process").Item("PATH")); -PATH_PROG('rc', WshShell.Environment("Process").Item("PATH")); - -/* cygwin ships with 'link.exe'. Avoid searching the cygwin path for this, as we want the MS linker */ -PATH_PROG('link', WshShell.Environment("Process").Item("PATH"), "LD"); -PATH_PROG('nmake'); - -// check for grep and sed! -if (!PATH_PROG('grep', WshShell.Environment("Process").Item("PATH")) || - !PATH_PROG('sed', WshShell.Environment("Process").Item("PATH"))) { - ERROR("grep and sed are required"); -} - -// we don't want to define LIB, as that will override the default library path set in that env var -PATH_PROG('lib', null, 'MAKE_LIB'); -PATH_PROG('php'); - -STDOUT.WriteBlankLines(1); - -if (CL) { - var VCVERS = probe_msvc_compiler_version(CL); - - if (typeof(MSVCVERS[VCVERS]) == undefined) { - // Lets just bail out if we dont know the MSVC version - ERROR("MS C++ compiler is required -- unable to detect version"); - } else { - STDOUT.WriteLine("Detected compiler version: " + MSVCVERS[VCVERS]); - } -} else { - ERROR("MS C++ compiler is required"); -} - -STDOUT.WriteBlankLines(1); - -ARG_WITH('php-build', 'Path to where you extracted http://www.php.net/extra/win32build.zip. Assumes that it is a sibling of this source dir (..\\php_build) if not specified', 'no'); -ARG_WITH('cygwin', 'Path to cygwin utilities on your system', '\\cygwin'); -ARG_ENABLE('gd', 'Php has static gd', 'no'); -ARG_ENABLE('zts', 'Disable thread safety', 'yes'); - -// stick objects somewhere outside of the source tree -ARG_ENABLE('object-out-dir', 'Alternative location for binary objects during build', ''); -if (PHP_GTK_OBJECT_OUT_DIR.length) { - if (!FSO.FolderExists(PHP_GTK_OBJECT_OUT_DIR)) { - ERROR('Your chosen output directory ' + PHP_GTK_OBJECT_OUT_DIR + ' does not exist'); - } - PHP_GTK_OBJECT_OUT_DIR += '\\'; -} - -ARG_ENABLE('debug', 'Compile with debugging symbols', "no"); -ARG_ENABLE('debug-pack', 'Release binaries with external debug symbols (--enable-debug must not be specified)', 'no'); -if (PHP_GTK_DEBUG == "yes" && PHP_GTK_DEBUG_PACK == "yes") { - ERROR("Use of both --enable-debug and --enable-debug-pack not allowed."); -} - -// Compile directory -if (PHP_GTK_DEBUG == "yes" && PHP_GTK_ZTS == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug_TS"); - DEFINE("PHP_LIB", "php5ts_debug.lib"); - PHP_LIB = "php5ts_debug.lib"; -} else if (PHP_GTK_DEBUG == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug"); - DEFINE("PHP_LIB", "php5_debug.lib"); - PHP_LIB = "php5_debug.lib"; -} else if (PHP_GTK_ZTS == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release_TS"); - DEFINE("PHP_LIB", "php5ts.lib"); - PHP_LIB = "php5ts.lib"; -} else { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release"); - DEFINE("PHP_LIB", "php5.lib"); - PHP_LIB = "php5.lib"; -} -if (PHP_GTK_PHP_BUILD == 'no') { - if (FSO.FolderExists("..\\php_gtk_build")) { - PHP_GTK_PHP_BUILD = "..\\php_gtk_build"; - } else if (FSO.FolderExists("..\\php_build")) { - PHP_GTK_PHP_BUILD = "..\\php_build"; - } else if (FSO.FolderExists("..\\win32build")) { - PHP_GTK_PHP_BUILD = "..\\win32build"; - } else if (FSO.FolderExists("..\\php-win32-dev\\php_build")) { - PHP_GTK_PHP_BUILD = "..\\php-win32-dev\\php_build"; - } -} - -var php_usual_include_suspects = PHP_GTK_PHP_BUILD; -var php_usual_lib_suspects = PHP_GTK_PHP_BUILD; - -ARG_IS('all', 'Configure all available extensions', 'no'); - -DEFINE("PHPGTKDLL", "php_gtk2.dll"); -DEFINE("PHPGTKLIB", "php_gtk2.lib"); -get_version_numbers(); -/* pick up the version from gtk/gtkversion.h */ -get_gtk_libversion(); - -// General link flags -DEFINE("LDFLAGS", "/nologo"); -// General DLL link flags -DEFINE("DLL_LDFLAGS", "/dll /machine:I386"); -// PHP-GTK DLL link flags -DEFINE("LDFLAGS_PHP_GTK", "$(DLL_LDFLAGS)"); - -// General libs -DEFINE("LIBS", "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib"); - -if (PHP_GTK_DEBUG == "yes") { - DEFINE("CFLAGS", "/nologo /LDd /MDd /Gm /ZI /GZ /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=1 /D PHP_WIN32 /D WIN32 /D _DEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); - ADD_FLAG("LDFLAGS", "/debug"); - -} else { - DEFINE("CFLAGS", "/nologo /MD /W3 /GX /O2 /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=0 /D PHP_WIN32 /D WIN32 /D NDEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); - // Generate external debug files when --enable-debug-pack is specified - if (PHP_GTK_DEBUG_PACK == "yes") { - ADD_FLAG("CFLAGS", "/Zi"); - ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); - } -} - -if (PHP_GTK_ZTS == "yes") { - ADD_FLAG("CFLAGS", "/D ZTS=1"); - } - -if (VCVERS < 1400) { - // Enable automatic precompiled headers - ADD_FLAG('CFLAGS', '/YX /c'); -} else { - // fun stuff: MS deprecated ANSI stdio and similar functions - disable warnings - // GS hardens the binary against buffer overruns - ADD_FLAG('CFLAGS', '/GS /wd4996 '); -} - -if (PHP_GTK_GD == "yes") { - ADD_FLAG('CFLAGS', '/D HAVE_GD_BUNDLED=1'); -} - -probe_basic_headers(); - -ADD_SOURCES("main", "php_gtk.c php_gtk_ext.w32.c php_gtk_util.c phpg_closure.c phpg_exceptions.c phpg_gboxed.c phpg_gobject.c phpg_gpointer.c phpg_gtype.c phpg_gvalue.c phpg_atom.c phpg_support.c phpg_paramspec.c", "php-gtk"); - +// vim:ft=javascript +// $Id$ +// "Master" config file; think of it as a configure.in equivalent. + +// MSVC version table +var MSVCVERS = []; +MSVCVERS[1200] = 'MSVC6 (Visual C++ 6.0)'; +MSVCVERS[1300] = 'MSVC7 (Visual C++ 2002)'; +MSVCVERS[1310] = 'MSVC7.1 (Visual C++ 2003)'; +MSVCVERS[1400] = 'MSVC8 (Visual C++ 2005)'; +MSVCVERS[1500] = 'MSVC9 (Visual C++ 2008)'; +MSVCVERS[1600] = 'MSVC10 (Visual C++ 2010)'; + +STDOUT.WriteBlankLines(1); + +CL = PATH_PROG('cl'); + +// avoid picking up midnight commander from cygwin +PATH_PROG('mc', WshShell.Environment("Process").Item("PATH")); +PATH_PROG('rc', WshShell.Environment("Process").Item("PATH")); + +/* cygwin ships with 'link.exe'. Avoid searching the cygwin path for this, as we want the MS linker */ +PATH_PROG('link', WshShell.Environment("Process").Item("PATH"), "LD"); +PATH_PROG('nmake'); + +// check for grep and sed! +if (!PATH_PROG('grep', WshShell.Environment("Process").Item("PATH")) || + !PATH_PROG('sed', WshShell.Environment("Process").Item("PATH"))) { + ERROR("grep and sed are required"); +} + +// we don't want to define LIB, as that will override the default library path set in that env var +PATH_PROG('lib', null, 'MAKE_LIB'); +PATH_PROG('php'); + +if (!PATH_PROG('php', WshShell.Environment("Process").Item("PATH"))) { + ERROR("php is required"); +} + +STDOUT.WriteBlankLines(1); + +if (CL) { + var VCVERS = probe_msvc_compiler_version(CL); + STDOUT.WriteLine("Detected compiler version: " + VCVERS); + + if (typeof(MSVCVERS[VCVERS]) == undefined) { + // Lets just bail out if we dont know the MSVC version + ERROR("MS C++ compiler is required -- unable to detect version"); + } else { + STDOUT.WriteLine("Detected compiler version: " + MSVCVERS[VCVERS]); + } +} else { + ERROR("MS C++ compiler is required"); +} + +STDOUT.WriteBlankLines(1); + +ARG_WITH('php-build', 'Path to where you extracted http://www.php.net/extra/win32build.zip. Assumes that it is a sibling of this source dir (..\\php_build) if not specified', 'no'); +ARG_WITH('cygwin', 'Path to cygwin utilities on your system', '\\cygwin'); +ARG_ENABLE('gd', 'Php has static gd', 'no'); +ARG_ENABLE('zts', 'Disable thread safety', 'yes'); + +// stick objects somewhere outside of the source tree +ARG_ENABLE('object-out-dir', 'Alternative location for binary objects during build', ''); +if (PHP_GTK_OBJECT_OUT_DIR.length) { + if (!FSO.FolderExists(PHP_GTK_OBJECT_OUT_DIR)) { + ERROR('Your chosen output directory ' + PHP_GTK_OBJECT_OUT_DIR + ' does not exist'); + } + PHP_GTK_OBJECT_OUT_DIR += '\\'; +} + +ARG_ENABLE('debug', 'Compile with debugging symbols', "no"); +ARG_ENABLE('debug-pack', 'Release binaries with external debug symbols (--enable-debug must not be specified)', 'no'); +if (PHP_GTK_DEBUG == "yes" && PHP_GTK_DEBUG_PACK == "yes") { + ERROR("Use of both --enable-debug and --enable-debug-pack not allowed."); +} + +// Compile directory +if (PHP_GTK_DEBUG == "yes" && PHP_GTK_ZTS == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug_TS"); + DEFINE("PHP_LIB", "php5ts_debug.lib"); + PHP_LIB = "php5ts_debug.lib"; +} else if (PHP_GTK_DEBUG == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug"); + DEFINE("PHP_LIB", "php5_debug.lib"); + PHP_LIB = "php5_debug.lib"; +} else if (PHP_GTK_ZTS == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release_TS"); + DEFINE("PHP_LIB", "php5ts.lib"); + PHP_LIB = "php5ts.lib"; +} else { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release"); + DEFINE("PHP_LIB", "php5.lib"); + PHP_LIB = "php5.lib"; +} +if (PHP_GTK_PHP_BUILD == 'no') { + if (FSO.FolderExists("..\\php_gtk_build")) { + PHP_GTK_PHP_BUILD = "..\\php_gtk_build"; + } else if (FSO.FolderExists("..\\php_build")) { + PHP_GTK_PHP_BUILD = "..\\php_build"; + } else if (FSO.FolderExists("..\\win32build")) { + PHP_GTK_PHP_BUILD = "..\\win32build"; + } else if (FSO.FolderExists("..\\php-win32-dev\\php_build")) { + PHP_GTK_PHP_BUILD = "..\\php-win32-dev\\php_build"; + } +} + +var php_usual_include_suspects = PHP_GTK_PHP_BUILD; +var php_usual_lib_suspects = PHP_GTK_PHP_BUILD; + +ARG_IS('all', 'Configure all available extensions', 'no'); + +DEFINE("PHPGTKDLL", "php_gtk2.dll"); +DEFINE("PHPGTKLIB", "php_gtk2.lib"); +get_version_numbers(); +/* pick up the version from gtk/gtkversion.h */ +get_gtk_libversion(); + +// General link flags +DEFINE("LDFLAGS", "/nologo"); +// General DLL link flags +DEFINE("DLL_LDFLAGS", "/dll /machine:I386"); +// PHP-GTK DLL link flags +DEFINE("LDFLAGS_PHP_GTK", "$(DLL_LDFLAGS)"); + +// General libs +DEFINE("LIBS", "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib"); + +if (PHP_GTK_DEBUG == "yes") { + DEFINE("CFLAGS", "/nologo /LDd /MDd /Gm /ZI /GZ /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=1 /D PHP_WIN32 /D WIN32 /D _DEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); + ADD_FLAG("LDFLAGS", "/debug"); + +} else { + DEFINE("CFLAGS", "/nologo /MD /W3 /EHsc /Ox /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=0 /D PHP_WIN32 /D WIN32 /D NDEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); + // Generate external debug files when --enable-debug-pack is specified + if (PHP_GTK_DEBUG_PACK == "yes") { + ADD_FLAG("CFLAGS", "/Zi"); + ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); + } +} + +if (PHP_GTK_ZTS == "yes") { + ADD_FLAG("CFLAGS", "/D ZTS=1"); + } + +if (VCVERS < 1400) { + // Enable automatic precompiled headers + ADD_FLAG('CFLAGS', '/YX /c'); +} else { + // fun stuff: MS deprecated ANSI stdio and similar functions - disable warnings + // GS hardens the binary against buffer overruns + ADD_FLAG('CFLAGS', '/GS /wd4996 '); +} + +if (PHP_GTK_GD == "yes") { + ADD_FLAG('CFLAGS', '/D HAVE_GD_BUNDLED=1'); +} + +probe_basic_headers(); + +ADD_SOURCES("main", "php_gtk.c php_gtk_ext.w32.c php_gtk_util.c phpg_closure.c phpg_exceptions.c phpg_gboxed.c phpg_gobject.c phpg_gpointer.c phpg_gtype.c phpg_gvalue.c phpg_atom.c phpg_support.c phpg_paramspec.c", "php-gtk"); + diff --git a/win32/confutils.js b/win32/confutils.js index a19cf7f..5ce08e9 100644 --- a/win32/confutils.js +++ b/win32/confutils.js @@ -1,1263 +1,1263 @@ -// Utils for configure script -/* - +----------------------------------------------------------------------+ - | PHP-GTK Version 2 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2005 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 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_0.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. | - +----------------------------------------------------------------------+ - | Author: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ -*/ - -// $Id: confutils.js,v 1.24 2008-08-01 14:34:43 auroraeosrose Exp $ - -/* set vars */ -var STDOUT = WScript.StdOut; -var STDERR = WScript.StdErr; -var WshShell = WScript.CreateObject("WScript.Shell"); -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var MFO = null; -var MFE = null; -var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); -var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); - -if (PROGRAM_FILES == null) { - PROGRAM_FILES = "C:\\Program Files"; -} - -var CWD = WshShell.CurrentDirectory; - -if (typeof(CWD) == "undefined") { - CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("buildconf.bat")); -} - -configure_args = new Array(); -configure_subst = WScript.CreateObject("Scripting.Dictionary"); - -configure_hdr = WScript.CreateObject("Scripting.Dictionary"); -build_dirs = new Array(); -make_builds = new Array(); - -extension_include_code = ""; -extension_module_ptrs = ""; - -/* functions */ - -function get_gtk_libversion() -{ - var env, i, vin, major, minor; - var found = false; - - found = CHECK_HEADER("gtk/gtkversion.h"); - - if (found) { - STDOUT.WriteLine(" <in default path>"); - vin = file_get_contents(found + "\\gtk\\gtkversion.h"); - - regex = new RegExp("GTK_MAJOR_VERSION\\s+\\(([0-9]+)\\)"); - regex.exec(vin); - major = RegExp.$1; - if (major < 2) - major = 2; - - regex = new RegExp("GTK_MINOR_VERSION\\s+\\(([0-9]+)\\)"); - regex.exec(vin); - minor = RegExp.$1; - if (minor < 6) - minor = 6; - - if (major >= 2 && minor >=8) { - ENABLE_CAIRO = 1; - } else { - ENABLE_CAIRO = 0; - } - PHP_GTK_LIBVERSION = major + '.' + minor; - } else { - STDOUT.WriteLine(" <not found>"); - PHP_GTK_LIBVERSION = '2.6'; - } - - STDOUT.Write("Library definitions for " + PHP_GTK_LIBVERSION + " will be used"); - STDERR.WriteBlankLines(1); -} - -function generate_source() { - - if (!FSO.FileExists("ext\\gtk+\\complete.txt")) { - if (!FSO.FileExists("win32\\temp.bat")) { - STDERR.WriteLine("Run buildconf first - the source file generator is missing"); - WScript.Quit(10); - } else { - var temp = FSO.OpenTextFile("win32\\temp.bat", 8); - temp.WriteLine("@echo off > source_complete.txt"); - temp.Close(); - WshShell.Run("win32\\temp", 0); - } - } - return; -} - -function check_generation() { - - if (!FSO.FileExists("source_complete.txt")) { - STDOUT.WriteLine("Waiting for source files to generate..."); - WScript.Sleep(3500); - check_generation(); - } - return; -} - -function get_version_numbers() { - - /* pick up the version from main/php_gtk.h */ - var vin = file_get_contents("main\\php_gtk.h"); - var version, version_strings, major, minor, details, release = "", extra = ""; - - if (vin.match(new RegExp("PHP_GTK_VERSION \"([^\"]+)\""))) { - version = RegExp.$1; - version_strings = version.split("."); - - major = version_strings[0]; - minor = version_strings[1]; - details = version_strings[2]; - - for (i = 0; i < details.length; i++) { - if(!isNaN(details.charAt(i))) { - release = release + details.charAt(i); - } else { - extra = details.substring(i); - break; - } - } - } - - var vfile = FSO.CreateTextFile("main/php_gtk_version.h", true); - vfile.WriteLine("/* This file is automatically generated during win32 configuration */"); - vfile.WriteLine("/* Edit php_gtk.h to change the version number */"); - vfile.WriteLine("#define PHP_GTK_MAJOR_VERSION " + major); - vfile.WriteLine("#define PHP_GTK_MINOR_VERSION " + minor); - vfile.WriteLine("#define PHP_GTK_RELEASE_VERSION " + release); - if (PHP_GTK_DEBUG == "yes") { - vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + " (DEBUG)\""); - } else { - vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + "\""); - } - - DEFINE('PHP_GTK_VERSION_STRING', version); -} - -function condense_path(path) { - - path = FSO.GetAbsolutePathName(path); - - if (path.substr(0, CWD.length).toLowerCase() - == CWD.toLowerCase() && - (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { - return path.substr(CWD.length + 1); - } - - var a = CWD.split("\\"); - var b = path.split("\\"); - var i, j; - - for (i = 0; i < b.length; i++) { - if (a[i].toLowerCase() == b[i].toLowerCase()) - continue; - if (i > 0) { - /* first difference found */ - path = ""; - for (j = 0; j < a.length - i; j++) { - path += "..\\"; - } - for (j = i; j < b.length; j++) { - path += b[j]; - if (j < b.length - 1) - path += "\\"; - } - return path; - } - /* on a different drive */ - break; - } - - return path; -} - -function ConfigureArg(type, optname, helptext, defval) { - - var opptype = ""; - - if (type) { - - opptype = type == "enable" ? "disable" : "without"; - - if (defval == "yes" || defval == "yes,shared") { - this.arg = "--" + opptype + "-" + optname; - this.imparg = "--" + type + "-" + optname; - } else { - this.arg = "--" + type + "-" + optname; - this.imparg = "--" + opptype + "-" + optname; - } - } else { - this.arg = "--" + optname; - } - - this.optname = optname; - this.helptext = helptext; - this.defval = defval; - this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); - this.seen = false; - this.argval = defval; -} - -function analyze_arg(argval) { - - var ret = new Array(); - - if (argval == "shared") { - argval = "yes"; - } else if (argval == null) { - /* nothing */ - } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { - argval = arg_match[1]; - } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { - argval = arg_match[1]; - } - - ret[0] = argval; - return ret; -} - -function conf_process_args() { - - var i, j; - var configure_help_mode = false; - var analyzed = false; - var nice = "cscript /nologo configure.js "; - - args = WScript.Arguments; - - for (i = 0; i < args.length; i++) { - arg = args(i); - nice += ' "' + arg + '"'; - if (arg == "--help") { - configure_help_mode = true; - break; - } - - // If it is --foo=bar, split on the equals sign - arg = arg.split("=", 2); - argname = arg[0]; - if (arg.length > 1) { - argval = arg[1]; - } else { - argval = null; - } - - // Find the arg - found = false; - for (j = 0; j < configure_args.length; j++) { - if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { - found = true; - - arg = configure_args[j]; - arg.seen = true; - - analyzed = analyze_arg(argval); - argval = analyzed[0]; - - if (argname == arg.imparg) { - /* we matched the implicit, or default arg */ - if (argval == null) { - argval = arg.defval; - } - } else { - /* we matched the non-default arg */ - if (argval == null) { - argval = arg.defval == "no" ? "yes" : "no"; - } - } - - arg.argval = argval; - eval("PHP_GTK_" + arg.symval + " = argval;"); - break; - } - } - if (!found) { - STDERR.WriteLine("Unknown option " + argname); - STDERR.WriteLine("Please try configure.js --help for a list of valid options"); - WScript.Quit(2); - } - } - - if (configure_help_mode) { - - STDOUT.WriteBlankLines(1); - - // Measure width to pretty-print the output - max_width = 0; - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.arg.length > max_width) { - max_width = arg.arg.length; - } - } - - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - - n = max_width - arg.arg.length; - pad = " "; - for (j = 0; j < n; j++) { - pad += " "; - } - STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); - } - WScript.Quit(1); - } - - // Now set any defaults we might have missed out earlier - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.seen) - continue; - analyzed = analyze_arg(arg.defval); - argval = analyzed[0]; - - eval("PHP_GTK_" + arg.symval + " = argval;"); - } - - MFO = FSO.CreateTextFile("Makefile.objects", true); - MFE = FSO.CreateTextFile("Makefile.extensions", true); - - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Saving configure options to configure.bat"); - var nicefile = FSO.CreateTextFile("configure.bat", true); - nicefile.WriteLine(nice); - nicefile.Close(); - - AC_DEFINE('CONFIGURE_COMMAND', nice); -} - -function find_pattern_in_path(pattern, path) { - - if (path == null) { - return false; - } - - var dirs = path.split(';'); - var i; - var items; - - for (i = 0; i < dirs.length; i++) { - items = glob(dirs[i] + "\\" + pattern); - if (items) { - return condense_path(items[0]); - } - } - return false; -} - -function ARG_IS(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("", optname, helptext, defval); -} - -function ARG_WITH(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); -} - -function ARG_ENABLE(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); -} - -function DEFINE(name, value) { - - if (configure_subst.Exists(name)) { - configure_subst.Remove(name); - } - configure_subst.Add(name, value); -} - -function AC_DEFINE(name, value, comment, quote) { - - if (quote == null) { - quote = true; - } - if (quote && typeof(value) == "string") { - value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; - } else if (value.length == 0) { - value = '""'; - } - var item = new Array(value, comment); - if (configure_hdr.Exists(name)) { - var orig_item = configure_hdr.Item(name); - STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + item[0]); - } else { - configure_hdr.Add(name, item); - } -} - -function PATH_PROG(progname, additional_paths, symbol) { - - var exe; - var place; - var cyg_path = PHP_GTK_CYGWIN + "\\bin;" + PHP_GTK_CYGWIN + "\\usr\\local\\bin"; - - exe = progname + ".exe"; - - if (additional_paths == null) { - additional_paths = cyg_path; - } else { - additional_paths += ";" + cyg_path; - } - - place = search_paths(exe, additional_paths, "PATH"); - - if (place == true) { - place = exe; - } else if (place != false) { - - if (place.lastIndexOf("\\") != place.length - 1) { - place += "\\"; - } - - place = place + exe; - - if (place.indexOf(" ")) { - place = '"' + place + '"'; - } - } - - if (place) { - if (symbol == null) { - symbol = progname.toUpperCase(); - } - DEFINE(symbol, place); - } - return place; -} - -function CHECK_LIB(libnames, target, path_to_check, common_name) { - - STDOUT.Write("Checking for " + libnames + " ... "); - - if (common_name == null && target != null) { - common_name = target; - } - - if (path_to_check == null) { - path_to_check = ""; - } - - // if they specified a common name for the package that contains - // the library, tag some useful defaults on to the end of the - // path to be searched - if (common_name != null) { - path_to_check += ";..\\" + common_name + "*"; - } - - // Determine target for build flags - if (target == null) { - target = ""; - } else { - target = "_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); - } - - // Expand path to include general dirs - path_to_check += ";" + php_usual_lib_suspects; - - // It is common practice to put libs under one of these dir names - var subdirs = new Array(PHP_GTK_DEBUG == "yes" ? "Debug" : "Release", "lib", "libs", "libexec"); - - // libnames can be ; separated list of accepted library names - libnames = libnames.split(';'); - - var i, j, k, libname; - var location = false; - var path = path_to_check.split(';'); - - for (i = 0; i < libnames.length; i++) { - libname = libnames[i]; - - for (k = 0; k < path.length; k++) { - location = glob(path[k] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - for (j = 0; j < subdirs.length; j++) { - location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - } - if (location) - break; - } - - if (location) { - location = condense_path(location); - var libdir = FSO.GetParentFolderName(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine( location); - - return location; - } - - // Check in their standard lib path - location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); - - if (location) { - location = condense_path(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine(" <in LIB path> " + libname); - return location; - } - } - - ERROR(" " + libname + " not found - aborting configure process"); - - return false; -} - -function CHECK_HEADER(header_name, path_to_check) { - if (!path_to_check) { - path_to_check = php_usual_include_suspects; - } - - var path = search_paths(header_name, path_to_check, "INCLUDE"); - - if (!path) { - ERROR(" " + header_name + " not found - aborting configure process"); - } - - return path; -} - -// use this for version checking -function GREP_HEADER(header_name, regex, path_to_check) { - - var c = false; - - if (FSO.FileExists(path_to_check + "\\" + header_name)) { - c = file_get_contents(path_to_check + "\\" + header_name); - } - - if (!c) { - /* look in the include path */ - - var p = search_paths(header_name, path_to_check, "INCLUDE"); - - if (typeof(p) == "string") { - c = file_get_contents(p); - } - - if (!c) { - return false; - } - } - - if (typeof(regex) == "string") { - regex = new RegExp(regex); - } - - if (c.match(regex)) { - /* caller can now use RegExp.$1 etc. to get at patterns */ - return true; - } - return false; -} - -function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) { - - var dir_part_to_add = ""; - - if (use_env == null) { - use_env = true; - } - - // if true, add the dir part of the header_name to the include path - if (add_dir_part == null) { - add_dir_part = false; - } else if (add_dir_part) { - var basename = FSO.GetFileName(header_name); - dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); - } - - if (path_to_check == null) { - path_to_check = php_usual_include_suspects; - } else { - path_to_check += ";" + php_usual_include_suspects; - } - - var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); - var have = 0; - var sym; - - if (typeof(p) == "string") { - ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); - } - - have = p ? 1 : 0 - - sym = header_name.toUpperCase(); - sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); - - if (typeof(add_to_flag_only) == undefined && - flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { - add_to_flag_only = true; - } - - if (typeof(add_to_flag_only) != "undefined") { - ADD_FLAG(flag_name, "/D HAVE_" + sym + "=" + have); - } else { - AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); - } - - return p; -} - -function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) { - - var dllflags = ""; - var dep_libs = ""; - var EXT = extname.toUpperCase().replace(new RegExp("-", "g"), "_"); - var extname_for_printing; - var res_var = ""; - var file; - - if (cflags == null) { - cflags = ""; - } - - if (typeof(obj_dir) == "undefined") { - - extname_for_printing = configure_module_dirname; - - } else { - - extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; - } - - STDOUT.WriteLine("Enabling extension " + extname_for_printing); - - if (extname == 'php-gtk') { - cflags = "/D COMPILE_DL_" + EXT + "2 /D " + EXT + "_EXPORTS=1" + cflags; - file = MFO; - } else { - cflags = "/D PHP_GTK_COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1" + cflags; - file = MFE; - } - - file.WriteBlankLines(1); - file.WriteLine("# objects for EXT " + extname); - file.WriteBlankLines(1); - - ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); - - file.WriteBlankLines(1); - - // PHP-GTK and its extensions are always built as shared for now - - if (dllname == null) { - if (extname == 'php-gtk') { - dllname = "php_gtk2.dll"; - resname = generate_version_info_resource(dllname, configure_module_dirname); - res_var = " $(PHPGTKDLL_RES)"; - } else { - cflags = "/D GTK_SHARED=1 " + cflags; - dllname = "php_gtk_" + extname + "2.dll"; - dllflags = " $(DLL_LDFLAGS)"; - dep_libs = " $(BUILD_DIR)\\$(PHPGTKLIB) $(LIBS_PHP_GTK)"; - } - } - var libname = dllname.substring(0, dllname.length - 4) + ".lib"; - var ld = "@$(LD)"; - - ADD_FLAG("EXT_TARGETS", "$(BUILD_DIR)\\" + dllname); - make_builds[make_builds.length] = extname + ": $(BUILD_DIR)\\" + dllname; - - file.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(" + EXT + "_GLOBAL_OBJS)" + res_var); - file.WriteLine("\t" + ld + " /out:$(BUILD_DIR)\\" + dllname + " $(LDFLAGS_" + EXT + ")" + dllflags + " $(LDFLAGS) $(" + EXT + "_GLOBAL_OBJS) $(LIBS_" + EXT + ")" + dep_libs + " $(LIBS)" + res_var); - - file.WriteBlankLines(1); - file.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); - file.WriteLine("\t@echo EXT " + extname + " build complete"); - file.WriteBlankLines(1); - - ADD_FLAG("CFLAGS_" + EXT, cflags); -} - -function ADD_SOURCES(dir, file_list, target, obj_dir) { - - var i; - var tv; - var src, obj, sym, flags; - var core_cflags = ""; - var file; - - sym = target.toUpperCase().replace(new RegExp("-", "g"), "_") + "_GLOBAL_OBJS"; - flags = "CFLAGS_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); - - if (configure_subst.Exists(sym)) { - tv = configure_subst.Item(sym); - } else { - tv = ""; - } - - if (target != "php-gtk") { - file = MFE; - core_cflags = "$(CFLAGS_PHP_GTK) "; - } else { - file = MFO; - } - - file_list = file_list.split(new RegExp("\\s+")); - file_list.sort(); - - var re = new RegExp("\.[a-z0-9A-Z\-]+$"); - - dir = dir.replace(new RegExp("/", "g"), "\\"); - var objs_line = ""; - var srcs_line = ""; - - var sub_build = "$(BUILD_DIR)\\"; - - /* if module dir is not a child of the main source dir, - * we need to tweak it; we should have detected such a - * case in condense_path and rewritten the path to - * be relative. - * This probably breaks for non-sibling dirs */ - if (obj_dir == null) { - var build_dir = dir.replace(new RegExp("^..\\\\"), ""); - } else { - var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); - } - - var mangle_dir = build_dir.replace(new RegExp("[\\\\/.+-]", "g"), "_"); - - /* kill trailing underscores */ - if (mangle_dir.substring(mangle_dir.length - 1) == "_") { - mangle_dir = mangle_dir.substring(0, mangle_dir.length - 1); - } - - var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); - - var dirs = build_dir.split("\\"); - var i, d = ""; - for (i = 0; i < dirs.length; i++) { - d += dirs[i]; - build_dirs[build_dirs.length] = d; - d += "\\"; - } - sub_build += d; - - DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build); - - for (i in file_list) { - src = file_list[i]; - obj = src.replace(re, ".obj"); - tv += " " + sub_build + obj; - - file.WriteLine(sub_build + obj + ": " + dir + "\\" + src); - file.WriteLine("\t@$(CC) $(" + flags + ") " + core_cflags + "$(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); - } - - DEFINE(sym, tv); -} - -function ADD_FLAG(name, flags, target) { - - if (target != null) { - name = target.toUpperCase() + "_" + name; - } - if (configure_subst.Exists(name)) { - var curr_flags = configure_subst.Item(name); - - if (curr_flags.indexOf(flags) >= 0) { - return; - } - - flags = flags + " " + curr_flags; - configure_subst.Remove(name); - } - configure_subst.Add(name, flags); -} - -function get_define(name) { - - return configure_subst.Item(name); -} - -function ERROR(msg) { - - STDERR.WriteBlankLines(2); - STDERR.WriteLine("ERROR: " + msg); - WScript.Quit(3); -} - -function WARNING(msg) { - - STDERR.WriteLine("WARNING: " + msg); - STDERR.WriteBlankLines(1); -} - -/* Searches a set of paths for a file; returns the dir in which the file was found, true if it -was found in the default env path, or false if it was not found at all. env_name is the optional -name of an env var specifying the default path to search */ -function search_paths(thing_to_find, explicit_path, env_name) { - - var i, found = false, place = false, file, env; - - STDOUT.Write("Checking for " + thing_to_find + " ... "); - - if (thing_to_find.length < 6) { - STDOUT.Write(" "); - } - - thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); - - if (explicit_path != null) { - if (typeof(explicit_path) == "string") { - explicit_path = explicit_path.split(";"); - } - - for (i = 0; i < explicit_path.length; i++) { - file = glob(explicit_path[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = file[0]; - place = place.substr(0, place.length - thing_to_find.length - 1); - break; - } - } - } - - if (!found && env_name != null) { - env = WshShell.Environment("Process").Item(env_name); - env = env.split(";"); - for (i = 0; i < env.length; i++) { - file = glob(env[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = true; - break; - } - } - } - - if (found && place == true) { - STDOUT.WriteLine(" <in default path>"); - place = file[0]; - place = place.substr(0, place.length - thing_to_find.length - 1); - } else if (found) { - STDOUT.WriteLine(" " + place); - } else { - STDOUT.WriteLine(" <not found>"); - } - return place; -} - -function word_wrap_and_indent(indent, text, line_suffix, indent_char) { - - if (text == null) { - return ""; - } - - var words = text.split(new RegExp("\\s+", "g")); - var i = 0; - var ret_text = ""; - var this_line = ""; - var t; - var space = ""; - var lines = 0; - - if (line_suffix == null) { - line_suffix = ""; - } - - if (indent_char == null) { - indent_char = " "; - } - - for (i = 0; i < indent; i++) { - space += indent_char; - } - - for (i = 0; i < words.length; i++) { - if (this_line.length) { - t = this_line + " " + words[i]; - } else { - t = words[i]; - } - - if (t.length + indent > 78) { - if (lines++) { - ret_text += space; - } - ret_text += this_line + line_suffix + "\r\n"; - this_line = ""; - } - - if (this_line.length) { - this_line += " " + words[i]; - } else { - this_line = words[i]; - } - } - - if (this_line.length) { - if (lines) - ret_text += space; - ret_text += this_line; - } - - return ret_text; -} - -function file_get_contents(filename) { - - var f, c; - - try { - f = FSO.OpenTextFile(filename, 1); - c = f.ReadAll(); - f.Close(); - return c; - } catch (e) { - STDOUT.WriteLine("Problem reading " + filename); - return false; - } -} - -function generate_files() { - - var i, dir, bd, last; - - generate_source(); - - STDOUT.WriteLine("Generating source files - this may take a few seconds"); - WScript.Sleep(3500); - check_generation(); - - // Check to see if we have additional objects to add - var sources = file_get_contents("sources.temp"); - configure_module_dirname = condense_path("ext\\gtk+\\"); - EXTENSION("php-gtk", php_gtk_files + sources, true); - - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Creating build dirs..."); - dir = get_define("BUILD_DIR"); - build_dirs.sort(); - last = null; - - if (!FSO.FolderExists(dir)) { - FSO.CreateFolder(dir); - } - - for (i = 0; i < build_dirs.length; i++) { - bd = FSO.BuildPath(dir, build_dirs[i]); - if (bd == last) { - continue; - } - last = bd; - ADD_FLAG("BUILD_DIRS_SUB", bd); - if (!FSO.FolderExists(bd)) { - FSO.CreateFolder(bd); - } - } - - generate_makefile(); - - STDOUT.WriteLine("Done."); - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Type 'nmake' to build all targets, or 'nmake php-gtk' to build PHP-GTK alone"); - STDOUT.WriteLine("* Configured PHP-GTK extensions can be built individually at a later stage *"); -} - -function generate_makefile() { - - MFE.WriteLine(""); // To avoid error if MFE will be complete - MFE.Close(); // Makefile.extensions is now complete - MFO.Close(); // Makefile.objects is now complete - var MF = FSO.CreateTextFile("Makefile", true); - STDOUT.WriteLine("Generating Makefile"); - - MF.WriteLine("# Generated by configure.js"); - MF.WriteBlankLines(1); - - /* spit out variable definitions */ - var keys = (new VBArray(configure_subst.Keys())).toArray(); - var i; - - for (i in keys) { - /* The trailing space is needed to prevent the trailing backslash that is part of - the build dir flags (CFLAGS_BD_XXX) from being seen as a line continuation character */ - MF.WriteLine(keys[i] + "=" + configure_subst.Item(keys[i]) + " "); - } - - MF.WriteBlankLines(1); - MF.WriteLine("all: $(EXT_TARGETS)"); - - for (i = make_builds.length; i >= 0; i--) { - if (i == make_builds.length) { - MF.WriteLine("!IF EXIST($(BUILD_DIR)\\$(PHPGTKLIB))"); - } - MF.WriteLine(make_builds[i]); - } - - if (make_builds.length > 1) { - MF.WriteLine("!ELSE"); - MF.WriteLine("!MESSAGE Note: $(PHPGTKLIB) must be created before PHP-GTK extensions can be built"); - } - - MF.WriteLine("!ENDIF"); - MF.WriteLine("build_dirs: $(BUILD_DIR) $(BUILD_DIRS_SUB)"); - MF.WriteBlankLines(1); - - TF = FSO.OpenTextFile("Makefile.objects", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - TF = FSO.OpenTextFile("Makefile.extensions", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - MF.Close(); - - FSO.DeleteFile("Makefile.objects"); - FSO.DeleteFile("Makefile.extensions"); -} - -function copy_and_subst(srcname, destname, subst_array) { - - if (!FSO.FileExists(srcname)) { - srcname = configure_module_dirname + "\\" + srcname; - destname = configure_module_dirname + "\\" + destname; - } - - var content = file_get_contents(srcname); - var i; - - for (i = 0; i < subst_array.length; i+=2) { - var re = subst_array[i]; - var rep = subst_array[i+1]; - - content = content.replace(re, rep); - } - - var f = FSO.CreateTextFile(destname, true); - f.Write(content); - f.Close(); -} - -// glob using simple filename wildcards; returns an array of matches found in the filesystem -function glob(path_pattern) { - - var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); - var p; - var base = ""; - var is_pat_re = /\*/; - - if (FSO.FileExists(path_pattern)) { - return new Array(path_pattern); - } - - // first, build as much as possible that doesn't have a pattern - for (p = 0; p < path_parts.length; p++) { - if (path_parts[p].match(is_pat_re)) - break; - if (p) - base += "\\"; - base += path_parts[p]; - } - - return _inner_glob(base, p, path_parts); -} - -function _inner_glob(base, p, parts) { - - var pat = parts[p]; - var full_name = base + "\\" + pat; - var re = null; - var items = null; - - if (p == parts.length) { - return false; - } - - if (FSO.FileExists(full_name)) { - if (p < parts.length - 1) { - // we didn't reach the full extent of the pattern - return false; - } - return new Array(full_name); - } - - if (FSO.FolderExists(full_name) && p == parts.length - 1) { - // we have reached the end of the pattern; no need to recurse - return new Array(full_name); - } - - // Convert the pattern into a regexp - re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); - - items = new Array(); - - if (!FSO.FolderExists(base)) { - return false; - } - - var folder = FSO.GetFolder(base); - var fc = null; - var subitems = null; - var item_name = null; - var j; - - fc = new Enumerator(folder.SubFolders); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - - if (item_name.match(re)) { - // got a match; if we are at the end of the pattern, just add these - // things to the items array - if (p == parts.length - 1) { - items[items.length] = fc.item(); - } else { - // we should recurse and do more matches - subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); - if (subitems) { - for (j = 0; j < subitems.length; j++) { - items[items.length] = subitems[j]; - } - } - } - } - } - - // if we are at the end of the pattern, we should match files too - if (p == parts.length - 1) { - fc = new Enumerator(folder.Files); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - if (item_name.match(re)) { - items[items.length] = fc.item(); - } - } - } - - if (items.length == 0) - return false; - - return items; -} - -/* Emits rule to generate version info for an extension. -Returns the name of the .res file that will be generated */ -function generate_version_info_resource(makefiletarget, creditspath) { - - // makefiletarget is php-gtk.dll - // creditspath is ext\gtk+ - - var resname = makefiletarget + ".res"; - var res_desc = "PHP-GTK Script Interpreter"; - var res_prod_name = "PHP-GTK"; - var credits; - var thanks = "Thanks to Andrei Zmievski"; - var logo = ""; - - if (FSO.FileExists(creditspath + '/CREDITS')) { - credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); - res_desc = credits.ReadLine(); - try { - thanks = credits.ReadLine(); - } catch (e) { - thanks = null; - } - if (thanks == null) { - thanks = ""; - } else { - thanks = "Thanks to " + thanks; - } - credits.Close(); - } - - MFO.WriteLine("PHPGTKDLL_RES=$(BUILD_DIR)\\$(PHPGTKDLL).res"); - MFO.WriteBlankLines(1); - - if (makefiletarget.match(new RegExp("\\.exe$"))) { - logo = " /D WANT_LOGO"; - } - - MFO.WriteLine("$(PHPGTKDLL_RES): win32\\template.rc"); - MFO.WriteLine("\t$(RC) /fo $(PHPGTKDLL_RES)" + logo + ' /D FILE_DESCRIPTION="\\"' + res_desc + '\\"" /D FILE_NAME="\\"$(PHPGTKDLL)\\"" /D PRODUCT_NAME="\\"' + res_prod_name + '\\"" /D THANKS_GUYS="\\"' + thanks + '\\"" win32\\template.rc'); - MFO.WriteBlankLines(1); - - return resname; -} - -/* execute a command and return the output as a string */ -function execute(command_line) { - var e = WshShell.Exec(command_line); - var ret = ""; - - ret = e.StdOut.ReadAll(); - - return ret; -} - -// Which version of the compiler do we have? +// Utils for configure script +/* + +----------------------------------------------------------------------+ + | PHP-GTK Version 2 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2005 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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. | + +----------------------------------------------------------------------+ + | Author: Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +// $Id: confutils.js,v 1.24 2008-08-01 14:34:43 auroraeosrose Exp $ + +/* set vars */ +var STDOUT = WScript.StdOut; +var STDERR = WScript.StdErr; +var WshShell = WScript.CreateObject("WScript.Shell"); +var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var MFO = null; +var MFE = null; +var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); +var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); + +if (PROGRAM_FILES == null) { + PROGRAM_FILES = "C:\\Program Files"; +} + +var CWD = WshShell.CurrentDirectory; + +if (typeof(CWD) == "undefined") { + CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("buildconf.bat")); +} + +configure_args = new Array(); +configure_subst = WScript.CreateObject("Scripting.Dictionary"); + +configure_hdr = WScript.CreateObject("Scripting.Dictionary"); +build_dirs = new Array(); +make_builds = new Array(); + +extension_include_code = ""; +extension_module_ptrs = ""; + +/* functions */ + +function get_gtk_libversion() +{ + var env, i, vin, major, minor; + var found = false; + + found = CHECK_HEADER("gtk/gtkversion.h"); + + if (found) { + STDOUT.WriteLine(" <in default path>"); + vin = file_get_contents(found + "\\gtk\\gtkversion.h"); + + regex = new RegExp("GTK_MAJOR_VERSION\\s+\\(([0-9]+)\\)"); + regex.exec(vin); + major = RegExp.$1; + if (major < 2) + major = 2; + + regex = new RegExp("GTK_MINOR_VERSION\\s+\\(([0-9]+)\\)"); + regex.exec(vin); + minor = RegExp.$1; + if (minor < 6) + minor = 6; + + if (major >= 2 && minor >=8) { + ENABLE_CAIRO = 1; + } else { + ENABLE_CAIRO = 0; + } + PHP_GTK_LIBVERSION = major + '.' + minor; + } else { + STDOUT.WriteLine(" <not found>"); + PHP_GTK_LIBVERSION = '2.6'; + } + + STDOUT.Write("Library definitions for " + PHP_GTK_LIBVERSION + " will be used"); + STDERR.WriteBlankLines(1); +} + +function generate_source() { + + if (!FSO.FileExists("ext\\gtk+\\complete.txt")) { + if (!FSO.FileExists("win32\\temp.bat")) { + STDERR.WriteLine("Run buildconf first - the source file generator is missing"); + WScript.Quit(10); + } else { + var temp = FSO.OpenTextFile("win32\\temp.bat", 8); + temp.WriteLine("@echo off > source_complete.txt"); + temp.Close(); + WshShell.Run("win32\\temp", 0); + } + } + return; +} + +function check_generation() { + + if (!FSO.FileExists("source_complete.txt")) { + STDOUT.WriteLine("Waiting for source files to generate..."); + WScript.Sleep(3500); + check_generation(); + } + return; +} + +function get_version_numbers() { + + /* pick up the version from main/php_gtk.h */ + var vin = file_get_contents("main\\php_gtk.h"); + var version, version_strings, major, minor, details, release = "", extra = ""; + + if (vin.match(new RegExp("PHP_GTK_VERSION \"([^\"]+)\""))) { + version = RegExp.$1; + version_strings = version.split("."); + + major = version_strings[0]; + minor = version_strings[1]; + details = version_strings[2]; + + for (i = 0; i < details.length; i++) { + if(!isNaN(details.charAt(i))) { + release = release + details.charAt(i); + } else { + extra = details.substring(i); + break; + } + } + } + + var vfile = FSO.CreateTextFile("main/php_gtk_version.h", true); + vfile.WriteLine("/* This file is automatically generated during win32 configuration */"); + vfile.WriteLine("/* Edit php_gtk.h to change the version number */"); + vfile.WriteLine("#define PHP_GTK_MAJOR_VERSION " + major); + vfile.WriteLine("#define PHP_GTK_MINOR_VERSION " + minor); + vfile.WriteLine("#define PHP_GTK_RELEASE_VERSION " + release); + if (PHP_GTK_DEBUG == "yes") { + vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + " (DEBUG)\""); + } else { + vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + "\""); + } + + DEFINE('PHP_GTK_VERSION_STRING', version); +} + +function condense_path(path) { + + path = FSO.GetAbsolutePathName(path); + + if (path.substr(0, CWD.length).toLowerCase() + == CWD.toLowerCase() && + (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { + return path.substr(CWD.length + 1); + } + + var a = CWD.split("\\"); + var b = path.split("\\"); + var i, j; + + for (i = 0; i < b.length; i++) { + if (a[i].toLowerCase() == b[i].toLowerCase()) + continue; + if (i > 0) { + /* first difference found */ + path = ""; + for (j = 0; j < a.length - i; j++) { + path += "..\\"; + } + for (j = i; j < b.length; j++) { + path += b[j]; + if (j < b.length - 1) + path += "\\"; + } + return path; + } + /* on a different drive */ + break; + } + + return path; +} + +function ConfigureArg(type, optname, helptext, defval) { + + var opptype = ""; + + if (type) { + + opptype = type == "enable" ? "disable" : "without"; + + if (defval == "yes" || defval == "yes,shared") { + this.arg = "--" + opptype + "-" + optname; + this.imparg = "--" + type + "-" + optname; + } else { + this.arg = "--" + type + "-" + optname; + this.imparg = "--" + opptype + "-" + optname; + } + } else { + this.arg = "--" + optname; + } + + this.optname = optname; + this.helptext = helptext; + this.defval = defval; + this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); + this.seen = false; + this.argval = defval; +} + +function analyze_arg(argval) { + + var ret = new Array(); + + if (argval == "shared") { + argval = "yes"; + } else if (argval == null) { + /* nothing */ + } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { + argval = arg_match[1]; + } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { + argval = arg_match[1]; + } + + ret[0] = argval; + return ret; +} + +function conf_process_args() { + + var i, j; + var configure_help_mode = false; + var analyzed = false; + var nice = "cscript /nologo configure.js "; + + args = WScript.Arguments; + + for (i = 0; i < args.length; i++) { + arg = args(i); + nice += ' "' + arg + '"'; + if (arg == "--help") { + configure_help_mode = true; + break; + } + + // If it is --foo=bar, split on the equals sign + arg = arg.split("=", 2); + argname = arg[0]; + if (arg.length > 1) { + argval = arg[1]; + } else { + argval = null; + } + + // Find the arg + found = false; + for (j = 0; j < configure_args.length; j++) { + if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { + found = true; + + arg = configure_args[j]; + arg.seen = true; + + analyzed = analyze_arg(argval); + argval = analyzed[0]; + + if (argname == arg.imparg) { + /* we matched the implicit, or default arg */ + if (argval == null) { + argval = arg.defval; + } + } else { + /* we matched the non-default arg */ + if (argval == null) { + argval = arg.defval == "no" ? "yes" : "no"; + } + } + + arg.argval = argval; + eval("PHP_GTK_" + arg.symval + " = argval;"); + break; + } + } + if (!found) { + STDERR.WriteLine("Unknown option " + argname); + STDERR.WriteLine("Please try configure.js --help for a list of valid options"); + WScript.Quit(2); + } + } + + if (configure_help_mode) { + + STDOUT.WriteBlankLines(1); + + // Measure width to pretty-print the output + max_width = 0; + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.arg.length > max_width) { + max_width = arg.arg.length; + } + } + + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + + n = max_width - arg.arg.length; + pad = " "; + for (j = 0; j < n; j++) { + pad += " "; + } + STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); + } + WScript.Quit(1); + } + + // Now set any defaults we might have missed out earlier + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.seen) + continue; + analyzed = analyze_arg(arg.defval); + argval = analyzed[0]; + + eval("PHP_GTK_" + arg.symval + " = argval;"); + } + + MFO = FSO.CreateTextFile("Makefile.objects", true); + MFE = FSO.CreateTextFile("Makefile.extensions", true); + + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Saving configure options to configure.bat"); + var nicefile = FSO.CreateTextFile("configure.bat", true); + nicefile.WriteLine(nice); + nicefile.Close(); + + AC_DEFINE('CONFIGURE_COMMAND', nice); +} + +function find_pattern_in_path(pattern, path) { + + if (path == null) { + return false; + } + + var dirs = path.split(';'); + var i; + var items; + + for (i = 0; i < dirs.length; i++) { + items = glob(dirs[i] + "\\" + pattern); + if (items) { + return condense_path(items[0]); + } + } + return false; +} + +function ARG_IS(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("", optname, helptext, defval); +} + +function ARG_WITH(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); +} + +function ARG_ENABLE(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); +} + +function DEFINE(name, value) { + + if (configure_subst.Exists(name)) { + configure_subst.Remove(name); + } + configure_subst.Add(name, value); +} + +function AC_DEFINE(name, value, comment, quote) { + + if (quote == null) { + quote = true; + } + if (quote && typeof(value) == "string") { + value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; + } else if (value.length == 0) { + value = '""'; + } + var item = new Array(value, comment); + if (configure_hdr.Exists(name)) { + var orig_item = configure_hdr.Item(name); + STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + item[0]); + } else { + configure_hdr.Add(name, item); + } +} + +function PATH_PROG(progname, additional_paths, symbol) { + + var exe; + var place; + var cyg_path = PHP_GTK_CYGWIN + "\\bin;" + PHP_GTK_CYGWIN + "\\usr\\local\\bin"; + + exe = progname + ".exe"; + + if (additional_paths == null) { + additional_paths = cyg_path; + } else { + additional_paths += ";" + cyg_path; + } + + place = search_paths(exe, additional_paths, "PATH"); + + if (place == true) { + place = exe; + } else if (place != false) { + + if (place.lastIndexOf("\\") != place.length - 1) { + place += "\\"; + } + + place = place + exe; + + if (place.indexOf(" ")) { + place = '"' + place + '"'; + } + } + + if (place) { + if (symbol == null) { + symbol = progname.toUpperCase(); + } + DEFINE(symbol, place); + } + return place; +} + +function CHECK_LIB(libnames, target, path_to_check, common_name) { + + STDOUT.Write("Checking for " + libnames + " ... "); + + if (common_name == null && target != null) { + common_name = target; + } + + if (path_to_check == null) { + path_to_check = ""; + } + + // if they specified a common name for the package that contains + // the library, tag some useful defaults on to the end of the + // path to be searched + if (common_name != null) { + path_to_check += ";..\\" + common_name + "*"; + } + + // Determine target for build flags + if (target == null) { + target = ""; + } else { + target = "_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); + } + + // Expand path to include general dirs + path_to_check += ";" + php_usual_lib_suspects; + + // It is common practice to put libs under one of these dir names + var subdirs = new Array(PHP_GTK_DEBUG == "yes" ? "Debug" : "Release", "lib", "libs", "libexec"); + + // libnames can be ; separated list of accepted library names + libnames = libnames.split(';'); + + var i, j, k, libname; + var location = false; + var path = path_to_check.split(';'); + + for (i = 0; i < libnames.length; i++) { + libname = libnames[i]; + + for (k = 0; k < path.length; k++) { + location = glob(path[k] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + for (j = 0; j < subdirs.length; j++) { + location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + } + if (location) + break; + } + + if (location) { + location = condense_path(location); + var libdir = FSO.GetParentFolderName(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine( location); + + return location; + } + + // Check in their standard lib path + location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); + + if (location) { + location = condense_path(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine(" <in LIB path> " + libname); + return location; + } + } + + ERROR(" " + libname + " not found - aborting configure process"); + + return false; +} + +function CHECK_HEADER(header_name, path_to_check) { + if (!path_to_check) { + path_to_check = php_usual_include_suspects; + } + + var path = search_paths(header_name, path_to_check, "INCLUDE"); + + if (!path) { + ERROR(" " + header_name + " not found - aborting configure process"); + } + + return path; +} + +// use this for version checking +function GREP_HEADER(header_name, regex, path_to_check) { + + var c = false; + + if (FSO.FileExists(path_to_check + "\\" + header_name)) { + c = file_get_contents(path_to_check + "\\" + header_name); + } + + if (!c) { + /* look in the include path */ + + var p = search_paths(header_name, path_to_check, "INCLUDE"); + + if (typeof(p) == "string") { + c = file_get_contents(p); + } + + if (!c) { + return false; + } + } + + if (typeof(regex) == "string") { + regex = new RegExp(regex); + } + + if (c.match(regex)) { + /* caller can now use RegExp.$1 etc. to get at patterns */ + return true; + } + return false; +} + +function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) { + + var dir_part_to_add = ""; + + if (use_env == null) { + use_env = true; + } + + // if true, add the dir part of the header_name to the include path + if (add_dir_part == null) { + add_dir_part = false; + } else if (add_dir_part) { + var basename = FSO.GetFileName(header_name); + dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); + } + + if (path_to_check == null) { + path_to_check = php_usual_include_suspects; + } else { + path_to_check += ";" + php_usual_include_suspects; + } + + var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); + var have = 0; + var sym; + + if (typeof(p) == "string") { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } + + have = p ? 1 : 0 + + sym = header_name.toUpperCase(); + sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); + + if (typeof(add_to_flag_only) == undefined && + flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { + add_to_flag_only = true; + } + + if (typeof(add_to_flag_only) != "undefined") { + ADD_FLAG(flag_name, "/D HAVE_" + sym + "=" + have); + } else { + AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); + } + + return p; +} + +function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) { + + var dllflags = ""; + var dep_libs = ""; + var EXT = extname.toUpperCase().replace(new RegExp("-", "g"), "_"); + var extname_for_printing; + var res_var = ""; + var file; + + if (cflags == null) { + cflags = ""; + } + + if (typeof(obj_dir) == "undefined") { + + extname_for_printing = configure_module_dirname; + + } else { + + extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; + } + + STDOUT.WriteLine("Enabling extension " + extname_for_printing); + + if (extname == 'php-gtk') { + cflags = "/D COMPILE_DL_" + EXT + "2 /D " + EXT + "_EXPORTS=1" + cflags; + file = MFO; + } else { + cflags = "/D PHP_GTK_COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1" + cflags; + file = MFE; + } + + file.WriteBlankLines(1); + file.WriteLine("# objects for EXT " + extname); + file.WriteBlankLines(1); + + ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); + + file.WriteBlankLines(1); + + // PHP-GTK and its extensions are always built as shared for now + + if (dllname == null) { + if (extname == 'php-gtk') { + dllname = "php_gtk2.dll"; + resname = generate_version_info_resource(dllname, configure_module_dirname); + res_var = " $(PHPGTKDLL_RES)"; + } else { + cflags = "/D GTK_SHARED=1 " + cflags; + dllname = "php_gtk_" + extname + "2.dll"; + dllflags = " $(DLL_LDFLAGS)"; + dep_libs = " $(BUILD_DIR)\\$(PHPGTKLIB) $(LIBS_PHP_GTK)"; + } + } + var libname = dllname.substring(0, dllname.length - 4) + ".lib"; + var ld = "@$(LD)"; + + ADD_FLAG("EXT_TARGETS", "$(BUILD_DIR)\\" + dllname); + make_builds[make_builds.length] = extname + ": $(BUILD_DIR)\\" + dllname; + + file.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(" + EXT + "_GLOBAL_OBJS)" + res_var); + file.WriteLine("\t" + ld + " /out:$(BUILD_DIR)\\" + dllname + " $(LDFLAGS_" + EXT + ")" + dllflags + " $(LDFLAGS) $(" + EXT + "_GLOBAL_OBJS) $(LIBS_" + EXT + ")" + dep_libs + " $(LIBS)" + res_var); + + file.WriteBlankLines(1); + file.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); + file.WriteLine("\t@echo EXT " + extname + " build complete"); + file.WriteBlankLines(1); + + ADD_FLAG("CFLAGS_" + EXT, cflags); +} + +function ADD_SOURCES(dir, file_list, target, obj_dir) { + + var i; + var tv; + var src, obj, sym, flags; + var core_cflags = ""; + var file; + + sym = target.toUpperCase().replace(new RegExp("-", "g"), "_") + "_GLOBAL_OBJS"; + flags = "CFLAGS_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); + + if (configure_subst.Exists(sym)) { + tv = configure_subst.Item(sym); + } else { + tv = ""; + } + + if (target != "php-gtk") { + file = MFE; + core_cflags = "$(CFLAGS_PHP_GTK) "; + } else { + file = MFO; + } + + file_list = file_list.split(new RegExp("\\s+")); + file_list.sort(); + + var re = new RegExp("\.[a-z0-9A-Z\-]+$"); + + dir = dir.replace(new RegExp("/", "g"), "\\"); + var objs_line = ""; + var srcs_line = ""; + + var sub_build = "$(BUILD_DIR)\\"; + + /* if module dir is not a child of the main source dir, + * we need to tweak it; we should have detected such a + * case in condense_path and rewritten the path to + * be relative. + * This probably breaks for non-sibling dirs */ + if (obj_dir == null) { + var build_dir = dir.replace(new RegExp("^..\\\\"), ""); + } else { + var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); + } + + var mangle_dir = build_dir.replace(new RegExp("[\\\\/.+-]", "g"), "_"); + + /* kill trailing underscores */ + if (mangle_dir.substring(mangle_dir.length - 1) == "_") { + mangle_dir = mangle_dir.substring(0, mangle_dir.length - 1); + } + + var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); + + var dirs = build_dir.split("\\"); + var i, d = ""; + for (i = 0; i < dirs.length; i++) { + d += dirs[i]; + build_dirs[build_dirs.length] = d; + d += "\\"; + } + sub_build += d; + + DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build); + + for (i in file_list) { + src = file_list[i]; + obj = src.replace(re, ".obj"); + tv += " " + sub_build + obj; + + file.WriteLine(sub_build + obj + ": " + dir + "\\" + src); + file.WriteLine("\t@$(CC) $(" + flags + ") " + core_cflags + "$(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); + } + + DEFINE(sym, tv); +} + +function ADD_FLAG(name, flags, target) { + + if (target != null) { + name = target.toUpperCase() + "_" + name; + } + if (configure_subst.Exists(name)) { + var curr_flags = configure_subst.Item(name); + + if (curr_flags.indexOf(flags) >= 0) { + return; + } + + flags = flags + " " + curr_flags; + configure_subst.Remove(name); + } + configure_subst.Add(name, flags); +} + +function get_define(name) { + + return configure_subst.Item(name); +} + +function ERROR(msg) { + + STDERR.WriteBlankLines(2); + STDERR.WriteLine("ERROR: " + msg); + WScript.Quit(3); +} + +function WARNING(msg) { + + STDERR.WriteLine("WARNING: " + msg); + STDERR.WriteBlankLines(1); +} + +/* Searches a set of paths for a file; returns the dir in which the file was found, true if it +was found in the default env path, or false if it was not found at all. env_name is the optional +name of an env var specifying the default path to search */ +function search_paths(thing_to_find, explicit_path, env_name) { + + var i, found = false, place = false, file, env; + + STDOUT.Write("Checking for " + thing_to_find + " ... "); + + if (thing_to_find.length < 6) { + STDOUT.Write(" "); + } + + thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); + + if (explicit_path != null) { + if (typeof(explicit_path) == "string") { + explicit_path = explicit_path.split(";"); + } + + for (i = 0; i < explicit_path.length; i++) { + file = glob(explicit_path[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = file[0]; + place = place.substr(0, place.length - thing_to_find.length - 1); + break; + } + } + } + + if (!found && env_name != null) { + env = WshShell.Environment("Process").Item(env_name); + env = env.split(";"); + for (i = 0; i < env.length; i++) { + file = glob(env[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = true; + break; + } + } + } + + if (found && place == true) { + STDOUT.WriteLine(" <in default path>"); + place = file[0]; + place = place.substr(0, place.length - thing_to_find.length - 1); + } else if (found) { + STDOUT.WriteLine(" " + place); + } else { + STDOUT.WriteLine(" <not found>"); + } + return place; +} + +function word_wrap_and_indent(indent, text, line_suffix, indent_char) { + + if (text == null) { + return ""; + } + + var words = text.split(new RegExp("\\s+", "g")); + var i = 0; + var ret_text = ""; + var this_line = ""; + var t; + var space = ""; + var lines = 0; + + if (line_suffix == null) { + line_suffix = ""; + } + + if (indent_char == null) { + indent_char = " "; + } + + for (i = 0; i < indent; i++) { + space += indent_char; + } + + for (i = 0; i < words.length; i++) { + if (this_line.length) { + t = this_line + " " + words[i]; + } else { + t = words[i]; + } + + if (t.length + indent > 78) { + if (lines++) { + ret_text += space; + } + ret_text += this_line + line_suffix + "\r\n"; + this_line = ""; + } + + if (this_line.length) { + this_line += " " + words[i]; + } else { + this_line = words[i]; + } + } + + if (this_line.length) { + if (lines) + ret_text += space; + ret_text += this_line; + } + + return ret_text; +} + +function file_get_contents(filename) { + + var f, c; + + try { + f = FSO.OpenTextFile(filename, 1); + c = f.ReadAll(); + f.Close(); + return c; + } catch (e) { + STDOUT.WriteLine("Problem reading " + filename); + return false; + } +} + +function generate_files() { + + var i, dir, bd, last; + + generate_source(); + + STDOUT.WriteLine("Generating source files - this may take a few seconds"); + WScript.Sleep(3500); + check_generation(); + + // Check to see if we have additional objects to add + var sources = file_get_contents("sources.temp"); + configure_module_dirname = condense_path("ext\\gtk+\\"); + EXTENSION("php-gtk", php_gtk_files + sources, true); + + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Creating build dirs..."); + dir = get_define("BUILD_DIR"); + build_dirs.sort(); + last = null; + + if (!FSO.FolderExists(dir)) { + FSO.CreateFolder(dir); + } + + for (i = 0; i < build_dirs.length; i++) { + bd = FSO.BuildPath(dir, build_dirs[i]); + if (bd == last) { + continue; + } + last = bd; + ADD_FLAG("BUILD_DIRS_SUB", bd); + if (!FSO.FolderExists(bd)) { + FSO.CreateFolder(bd); + } + } + + generate_makefile(); + + STDOUT.WriteLine("Done."); + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Type 'nmake' to build all targets, or 'nmake php-gtk' to build PHP-GTK alone"); + STDOUT.WriteLine("* Configured PHP-GTK extensions can be built individually at a later stage *"); +} + +function generate_makefile() { + + MFE.WriteLine(""); // To avoid error if MFE will be complete + MFE.Close(); // Makefile.extensions is now complete + MFO.Close(); // Makefile.objects is now complete + var MF = FSO.CreateTextFile("Makefile", true); + STDOUT.WriteLine("Generating Makefile"); + + MF.WriteLine("# Generated by configure.js"); + MF.WriteBlankLines(1); + + /* spit out variable definitions */ + var keys = (new VBArray(configure_subst.Keys())).toArray(); + var i; + + for (i in keys) { + /* The trailing space is needed to prevent the trailing backslash that is part of + the build dir flags (CFLAGS_BD_XXX) from being seen as a line continuation character */ + MF.WriteLine(keys[i] + "=" + configure_subst.Item(keys[i]) + " "); + } + + MF.WriteBlankLines(1); + MF.WriteLine("all: $(EXT_TARGETS)"); + + for (i = make_builds.length; i >= 0; i--) { + if (i == make_builds.length) { + MF.WriteLine("!IF EXIST($(BUILD_DIR)\\$(PHPGTKLIB))"); + } + MF.WriteLine(make_builds[i]); + } + + if (make_builds.length > 1) { + MF.WriteLine("!ELSE"); + MF.WriteLine("!MESSAGE Note: $(PHPGTKLIB) must be created before PHP-GTK extensions can be built"); + } + + MF.WriteLine("!ENDIF"); + MF.WriteLine("build_dirs: $(BUILD_DIR) $(BUILD_DIRS_SUB)"); + MF.WriteBlankLines(1); + + TF = FSO.OpenTextFile("Makefile.objects", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + TF = FSO.OpenTextFile("Makefile.extensions", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + MF.Close(); + + FSO.DeleteFile("Makefile.objects"); + FSO.DeleteFile("Makefile.extensions"); +} + +function copy_and_subst(srcname, destname, subst_array) { + + if (!FSO.FileExists(srcname)) { + srcname = configure_module_dirname + "\\" + srcname; + destname = configure_module_dirname + "\\" + destname; + } + + var content = file_get_contents(srcname); + var i; + + for (i = 0; i < subst_array.length; i+=2) { + var re = subst_array[i]; + var rep = subst_array[i+1]; + + content = content.replace(re, rep); + } + + var f = FSO.CreateTextFile(destname, true); + f.Write(content); + f.Close(); +} + +// glob using simple filename wildcards; returns an array of matches found in the filesystem +function glob(path_pattern) { + + var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); + var p; + var base = ""; + var is_pat_re = /\*/; + + if (FSO.FileExists(path_pattern)) { + return new Array(path_pattern); + } + + // first, build as much as possible that doesn't have a pattern + for (p = 0; p < path_parts.length; p++) { + if (path_parts[p].match(is_pat_re)) + break; + if (p) + base += "\\"; + base += path_parts[p]; + } + + return _inner_glob(base, p, path_parts); +} + +function _inner_glob(base, p, parts) { + + var pat = parts[p]; + var full_name = base + "\\" + pat; + var re = null; + var items = null; + + if (p == parts.length) { + return false; + } + + if (FSO.FileExists(full_name)) { + if (p < parts.length - 1) { + // we didn't reach the full extent of the pattern + return false; + } + return new Array(full_name); + } + + if (FSO.FolderExists(full_name) && p == parts.length - 1) { + // we have reached the end of the pattern; no need to recurse + return new Array(full_name); + } + + // Convert the pattern into a regexp + re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); + + items = new Array(); + + if (!FSO.FolderExists(base)) { + return false; + } + + var folder = FSO.GetFolder(base); + var fc = null; + var subitems = null; + var item_name = null; + var j; + + fc = new Enumerator(folder.SubFolders); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + + if (item_name.match(re)) { + // got a match; if we are at the end of the pattern, just add these + // things to the items array + if (p == parts.length - 1) { + items[items.length] = fc.item(); + } else { + // we should recurse and do more matches + subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); + if (subitems) { + for (j = 0; j < subitems.length; j++) { + items[items.length] = subitems[j]; + } + } + } + } + } + + // if we are at the end of the pattern, we should match files too + if (p == parts.length - 1) { + fc = new Enumerator(folder.Files); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + if (item_name.match(re)) { + items[items.length] = fc.item(); + } + } + } + + if (items.length == 0) + return false; + + return items; +} + +/* Emits rule to generate version info for an extension. +Returns the name of the .res file that will be generated */ +function generate_version_info_resource(makefiletarget, creditspath) { + + // makefiletarget is php-gtk.dll + // creditspath is ext\gtk+ + + var resname = makefiletarget + ".res"; + var res_desc = "PHP-GTK Script Interpreter"; + var res_prod_name = "PHP-GTK"; + var credits; + var thanks = "Thanks to Andrei Zmievski"; + var logo = ""; + + if (FSO.FileExists(creditspath + '/CREDITS')) { + credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); + res_desc = credits.ReadLine(); + try { + thanks = credits.ReadLine(); + } catch (e) { + thanks = null; + } + if (thanks == null) { + thanks = ""; + } else { + thanks = "Thanks to " + thanks; + } + credits.Close(); + } + + MFO.WriteLine("PHPGTKDLL_RES=$(BUILD_DIR)\\$(PHPGTKDLL).res"); + MFO.WriteBlankLines(1); + + if (makefiletarget.match(new RegExp("\\.exe$"))) { + logo = " /D WANT_LOGO"; + } + + MFO.WriteLine("$(PHPGTKDLL_RES): win32\\template.rc"); + MFO.WriteLine("\t$(RC) /fo $(PHPGTKDLL_RES)" + logo + ' /D FILE_DESCRIPTION="\\"' + res_desc + '\\"" /D FILE_NAME="\\"$(PHPGTKDLL)\\"" /D PRODUCT_NAME="\\"' + res_prod_name + '\\"" /D THANKS_GUYS="\\"' + thanks + '\\"" win32\\template.rc'); + MFO.WriteBlankLines(1); + + return resname; +} + +/* execute a command and return the output as a string */ +function execute(command_line) { + var e = WshShell.Exec(command_line); + var ret = ""; + + ret = e.StdOut.ReadAll(); + + return ret; +} + +// Which version of the compiler do we have? function probe_msvc_compiler_version(CL) { - var command = 'cmd /c ""' + CL + '" -v"'; - var version = execute(command + '" 2>&1"'); + var command = 'cmd /c ' + CL + ' -v'; + var version = execute(command + ' 2>&1'); if (version.match(/(\d+\.\d+)/)) { return RegExp.$1.split(".").join(""); } - - return 0; -} - -// Poke around for some headers -function probe_basic_headers() -{ - var p; - - // hack to catch common location of libs - if (typeof(p) == "string") { - p = p.replace(new RegExp("include$"), "lib"); - ADD_FLAG("LDFLAGS", '/libpath:"' + p + '" '); - php_usual_lib_suspects += ";" + p; - } - - // Make sure that tsrm, main and ZEND get added to the includes - var php_dir = CHECK_HEADER('Zend/zend.h'); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\TSRM" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\main" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\Zend" '); -} - -/* non-functions */ - -if (!FSO.FileExists("buildconf.bat")) { - STDERR.WriteLine("Must be run from the root of the PHP-GTK source"); - WScript.Quit(10); -} + + return 0; +} + +// Poke around for some headers +function probe_basic_headers() +{ + var p; + + // hack to catch common location of libs + if (typeof(p) == "string") { + p = p.replace(new RegExp("include$"), "lib"); + ADD_FLAG("LDFLAGS", '/libpath:"' + p + '" '); + php_usual_lib_suspects += ";" + p; + } + + // Make sure that tsrm, main and ZEND get added to the includes + var php_dir = CHECK_HEADER('Zend/zend.h'); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\TSRM" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\main" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\Zend" '); +} + +/* non-functions */ + +if (!FSO.FileExists("buildconf.bat")) { + STDERR.WriteLine("Must be run from the root of the PHP-GTK source"); + WScript.Quit(10); +}
diff --git a/main/phpg_gvalue.c b/main/phpg_gvalue.c index 94c9969..b47cab3 100644 --- a/main/phpg_gvalue.c +++ b/main/phpg_gvalue.c @@ -1,554 +1,555 @@ -/* - * PHP-GTK - The PHP language bindings for GTK+ - * - * Copyright (C) 2001-2008 Andrei Zmievski <andrei@php.net> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "php_gtk.h" - -#if HAVE_PHP_GTK - -/* - * GValue related functions - */ - - -/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */ -PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, zend_bool do_utf8 TSRMLS_DC) -{ - assert(value != NULL); - - switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { - case G_TYPE_INVALID: - case G_TYPE_NONE: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_NULL(*value); - break; - - case G_TYPE_CHAR: - { - gchar val = g_value_get_char(gval); - MAKE_ZVAL_IF_NULL(*value); - ZVAL_STRINGL(*value, (char *)&val, 1, 1); - } - break; - - case G_TYPE_UCHAR: - { - guchar val = g_value_get_uchar(gval); - MAKE_ZVAL_IF_NULL(*value); - ZVAL_STRINGL(*value, (char *)&val, 1, 1); - } - break; - - case G_TYPE_BOOLEAN: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_BOOL(*value, g_value_get_boolean(gval)); - break; - - case G_TYPE_INT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_int(gval)); - break; - - case G_TYPE_LONG: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_long(gval)); - break; - - case G_TYPE_UINT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_uint(gval)); - break; - - case G_TYPE_ULONG: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_ulong(gval)); - break; - - case G_TYPE_FLOAT: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_DOUBLE(*value, (double)g_value_get_float(gval)); - break; - - case G_TYPE_DOUBLE: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_DOUBLE(*value, (double)g_value_get_double(gval)); - break; - - case G_TYPE_ENUM: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_enum(gval)); - break; - - case G_TYPE_FLAGS: - MAKE_ZVAL_IF_NULL(*value); - ZVAL_LONG(*value, (long)g_value_get_flags(gval)); - break; - - case G_TYPE_STRING: - { - gchar *cp = NULL; - gsize cp_len = 0; - zend_bool free_cp = 0; - const gchar *str = g_value_get_string(gval); - - MAKE_ZVAL_IF_NULL(*value); - if (str != NULL) { - if (do_utf8) { - cp = phpg_from_utf8(str, strlen(str), &cp_len, &free_cp TSRMLS_CC); - if (cp) { - str = cp; - } else { - php_error(E_WARNING, "Could not convert string from UTF-8"); - } - } - ZVAL_STRING(*value, (char *)str, 1); - if (free_cp) { - g_free(cp); - } - } else - ZVAL_NULL(*value); - } - break; - - case G_TYPE_PARAM: - phpg_paramspec_new(value, g_value_get_param(gval) TSRMLS_CC); - break; - - case G_TYPE_OBJECT: - phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); - break; - - case G_TYPE_INTERFACE: - if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) { - phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); - } else { - php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); - MAKE_STD_ZVAL(*value); - ZVAL_NULL(*value); - return FAILURE; - } - break; - - case G_TYPE_POINTER: - phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC); - break; - - case G_TYPE_BOXED: - { - phpg_gboxed_marshal_t *gbm; - - if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { - zval *object = (zval *) g_value_dup_boxed(gval); - MAKE_ZVAL_IF_NULL(*value); - if (object) { - REPLACE_ZVAL_VALUE(value, object, 1); - zval_ptr_dtor(&object); - return SUCCESS; - } else { - ZVAL_NULL(*value); - return FAILURE; - } - } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) { - int i; - zval *item; - int value_count; - - GValueArray *array = (GValueArray *) g_value_get_boxed(gval); - MAKE_ZVAL_IF_NULL(*value); - array_init(*value); - value_count = array->n_values; - - for (i = 0; i < value_count; i++) { - MAKE_STD_ZVAL(item); - phpg_gvalue_to_zval(array->values + i, &item, copy_boxed, TRUE TSRMLS_CC); - add_next_index_zval(*value, item); - } - } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { - MAKE_STD_ZVAL(*value); - return gbm->to_zval(gval, value TSRMLS_CC); - } else { - if (copy_boxed) { - phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC); - } else { - phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC); - } - } - break; - } - - default: - php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); - MAKE_STD_ZVAL(*value); - ZVAL_NULL(*value); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */ -PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval **value, zend_bool do_utf8 TSRMLS_DC) -{ - switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { - /* - * For whatever reason, we should apparently respect that the gval may be of these - * types and they do not need a value. - */ - case G_TYPE_INVALID: - case G_TYPE_NONE: - break; - - case G_TYPE_BOOLEAN: - convert_to_boolean_ex(value); - g_value_set_boolean(gval, (gboolean)Z_BVAL_PP(value)); - break; - - case G_TYPE_CHAR: - convert_to_string_ex(value); - g_value_set_char(gval, Z_STRVAL_PP(value)[0]); - break; - - case G_TYPE_UCHAR: - convert_to_string_ex(value); - g_value_set_uchar(gval, (guchar)Z_STRVAL_PP(value)[0]); - break; - - case G_TYPE_INT: - convert_to_long_ex(value); - g_value_set_int(gval, (gint)Z_LVAL_PP(value)); - break; - - case G_TYPE_UINT: - convert_to_long_ex(value); - g_value_set_uint(gval, (guint)Z_LVAL_PP(value)); - break; - - case G_TYPE_LONG: - convert_to_long_ex(value); - g_value_set_long(gval, (glong)Z_LVAL_PP(value)); - break; - - case G_TYPE_ULONG: - convert_to_long_ex(value); - g_value_set_ulong(gval, (gulong)Z_LVAL_PP(value)); - break; - - case G_TYPE_FLOAT: - convert_to_double_ex(value); - g_value_set_float(gval, (gfloat)Z_DVAL_PP(value)); - break; - - case G_TYPE_DOUBLE: - convert_to_double_ex(value); - g_value_set_double(gval, Z_DVAL_PP(value)); - break; - - case G_TYPE_ENUM: - { - gint val = 0; - if (phpg_gvalue_get_enum(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { - return FAILURE; - } - g_value_set_enum(gval, val); - break; - } - - case G_TYPE_FLAGS: - { - gint val = 0; - if (phpg_gvalue_get_flags(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { - return FAILURE; - } - g_value_set_flags(gval, val); - break; - } - - case G_TYPE_STRING: - { - gchar *utf8 = NULL; - gsize utf8_len = 0; - zend_bool free_utf8 = 0; - gchar *str; - - convert_to_string_ex(value); - str = Z_STRVAL_PP(value); - if (do_utf8) { - utf8 = phpg_to_utf8(Z_STRVAL_PP(value), Z_STRLEN_PP(value), &utf8_len, &free_utf8 TSRMLS_CC); - if (utf8) { - str = utf8; - } else { - php_error(E_WARNING, "Could not convert string to UTF-8"); - } - } - g_value_set_string(gval, str); - if (free_utf8) { - g_free(utf8); - } - break; - } - - case G_TYPE_POINTER: - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_pointer(gval, NULL); - } else if (Z_TYPE_PP(value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gpointer_ce TSRMLS_CC) - && G_VALUE_HOLDS(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->gtype)) { - g_value_set_pointer(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->pointer); - } else { - return FAILURE; - } - break; - - case G_TYPE_BOXED: - { - phpg_gboxed_marshal_t *gbm; - - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_boxed(gval, NULL); - /* - * We should be safe just setting the zval here, since G_TYPE_PHP_VALUE is - * supposed to take any zval type. - */ - } else if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { - g_value_set_boxed(gval, *value); - } else if (Z_TYPE_PP(value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gboxed_ce TSRMLS_CC) - && G_VALUE_HOLDS(gval, ((phpg_gboxed_t*)PHPG_GET(*value))->gtype)) { - g_value_set_boxed(gval, PHPG_GBOXED(*value)); - } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { - return gbm->from_zval(*value, gval TSRMLS_CC); - } else - return FAILURE; - break; - } - - case G_TYPE_PARAM: - if (php_gtk_check_class(*value, gparamspec_ce)) { - g_value_set_param(gval, PHPG_GPARAMSPEC(*value)); - } else { - return FAILURE; - } - break; - - case G_TYPE_OBJECT: - if (Z_TYPE_PP(value) == IS_NULL) { - g_value_set_object(gval, NULL); - } else if (Z_TYPE_P(*value) == IS_OBJECT - && instanceof_function(Z_OBJCE_PP(value), gobject_ce TSRMLS_CC) - && G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { - g_value_set_object(gval, PHPG_GOBJECT(*value)); - } else - return FAILURE; - break; - - case G_TYPE_INTERFACE: - if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT) && - Z_TYPE_PP(value) == IS_OBJECT && - G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { - g_value_set_object(gval, PHPG_GOBJECT(*value)); - } else { - php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); - return FAILURE; - } - break; - - default: - php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); - return FAILURE; - - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_param_gvalue_to_zval() */ -PHP_GTK_API int phpg_param_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, const GParamSpec *pspec TSRMLS_DC) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - /* TODO */ - return FAILURE; - } else { - return phpg_gvalue_to_zval(gval, value, copy_boxed, TRUE TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_param_gvalue_from_zval() */ -PHP_GTK_API int phpg_param_gvalue_from_zval(GValue *gval, zval **value, const GParamSpec *pspec TSRMLS_DC) -{ - if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { - /* TODO */ - return FAILURE; - } else { - return phpg_gvalue_from_zval(gval, value, TRUE TSRMLS_CC); - } -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalues_to_array() */ -PHP_GTK_API zval *phpg_gvalues_to_array(const GValue *values, uint n_values) -{ - zval *hash; - zval *item = NULL; - int i; - int value_count; - - MAKE_STD_ZVAL(hash); - array_init(hash); - value_count = n_values; - - for (i = 0; i < value_count; i++) { - //item = phpg_gvalue_to_zval(&values[i], FALSE); - if (!item) { - MAKE_STD_ZVAL(item); - ZVAL_NULL(item); - } - zend_hash_next_index_insert(Z_ARRVAL_P(hash), &item, sizeof(zval *), NULL); - } - - return hash; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_get_enum() */ -PHP_GTK_API int phpg_gvalue_get_enum(GType enum_type, zval *enum_val, gint *result) -{ - if (result == NULL) - return FAILURE; - - if (enum_val == NULL) { - *result = 0; - } else if (Z_TYPE_P(enum_val) == IS_LONG) { - *result = Z_LVAL_P(enum_val); - } else if (Z_TYPE_P(enum_val) == IS_STRING) { - GEnumClass *eclass = NULL; - GEnumValue *info = NULL; - - if (enum_type != G_TYPE_NONE) { - eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of enum"); - return FAILURE; - } - - info = g_enum_get_value_by_name(eclass, Z_STRVAL_P(enum_val)); - - if (info == NULL) { - info = g_enum_get_value_by_nick(eclass, Z_STRVAL_P(enum_val)); - } - g_type_class_unref(eclass); - - if (info != NULL) { - *result = info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to enum", Z_STRVAL_P(enum_val)); - return FAILURE; - } - } else { - php_error(E_WARNING, "PHP-GTK internal error: enums must be strings or integers"); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -/* {{{ PHP_GTK_API phpg_gvalue_get_flags() */ -PHP_GTK_API int phpg_gvalue_get_flags(GType flags_type, zval *flags_val, gint *result) -{ - GFlagsClass *fclass = NULL; - GFlagsValue *info = NULL; - - if (result == NULL) - return FAILURE; - - if (flags_val == NULL) { - *result = 0; - } else if (Z_TYPE_P(flags_val) == IS_LONG) { - *result = Z_LVAL_P(flags_val); - } else if (Z_TYPE_P(flags_val) == IS_STRING) { - if (flags_type != G_TYPE_NONE) { - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); - return FAILURE; - } - - info = g_flags_get_value_by_name(fclass, Z_STRVAL_P(flags_val)); - if (info == NULL) { - info = g_flags_get_value_by_nick(fclass, Z_STRVAL_P(flags_val)); - } - g_type_class_unref(fclass); - - if (info != NULL) { - *result = info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_P(flags_val)); - return FAILURE; - } - } else if (Z_TYPE_P(flags_val) == IS_ARRAY) { - zval **flag; - - *result = 0; - if (flags_type != G_TYPE_NONE) { - fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); - return FAILURE; - } - - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(flags_val)); - zend_hash_get_current_data(Z_ARRVAL_P(flags_val), (void **)&flag) == SUCCESS; - zend_hash_move_forward(Z_ARRVAL_P(flags_val))) { - - if (Z_TYPE_PP(flag) == IS_LONG) { - *result |= Z_LVAL_PP(flag); - } else if (Z_TYPE_PP(flag) == IS_STRING) { - info = g_flags_get_value_by_name(fclass, Z_STRVAL_PP(flag)); - if (info == NULL) { - info = g_flags_get_value_by_nick(fclass, Z_STRVAL_PP(flag)); - } - if (info != NULL) { - *result |= info->value; - } else { - php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_PP(flag)); - g_type_class_unref(fclass); - return FAILURE; - } - } else { - php_error(E_WARNING, "PHP-GTK flag arrays can contain only integers or strings"); - g_type_class_unref(fclass); - return 0; - } - } - g_type_class_unref(fclass); - } else { - php_error(E_WARNING, "PHP-GTK flags must be strings, integers, or arrays of strings or integers"); - return FAILURE; - } - - return SUCCESS; -} -/* }}} */ - -#endif - -/* vim: set fdm=marker et : */ +/* + * PHP-GTK - The PHP language bindings for GTK+ + * + * Copyright (C) 2001-2008 Andrei Zmievski <andrei@php.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "php_gtk.h" + +#if HAVE_PHP_GTK + +/* + * GValue related functions + */ + + +/* {{{ PHP_GTK_API phpg_gvalue_to_zval() */ +PHP_GTK_API int phpg_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, zend_bool do_utf8 TSRMLS_DC) +{ + assert(value != NULL); + + switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { + case G_TYPE_INVALID: + case G_TYPE_NONE: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_NULL(*value); + break; + + case G_TYPE_CHAR: + { + gchar val = g_value_get_char(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_STRINGL(*value, (char *)&val, 1, 1); + } + break; + + case G_TYPE_UCHAR: + { + guchar val = g_value_get_uchar(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_STRINGL(*value, (char *)&val, 1, 1); + } + break; + + case G_TYPE_BOOLEAN: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_BOOL(*value, g_value_get_boolean(gval)); + break; + + case G_TYPE_INT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_int(gval)); + break; + + case G_TYPE_LONG: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_long(gval)); + break; + + case G_TYPE_UINT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_uint(gval)); + break; + + case G_TYPE_ULONG: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_ulong(gval)); + break; + + case G_TYPE_FLOAT: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_DOUBLE(*value, (double)g_value_get_float(gval)); + break; + + case G_TYPE_DOUBLE: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_DOUBLE(*value, (double)g_value_get_double(gval)); + break; + + case G_TYPE_ENUM: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_enum(gval)); + break; + + case G_TYPE_FLAGS: + MAKE_ZVAL_IF_NULL(*value); + ZVAL_LONG(*value, (long)g_value_get_flags(gval)); + break; + + case G_TYPE_STRING: + { + gchar *cp = NULL; + gsize cp_len = 0; + zend_bool free_cp = 0; + const gchar *str = g_value_get_string(gval); + + MAKE_ZVAL_IF_NULL(*value); + if (str != NULL) { + if (do_utf8) { + cp = phpg_from_utf8(str, strlen(str), &cp_len, &free_cp TSRMLS_CC); + if (cp) { + str = cp; + } else { + php_error(E_WARNING, "Could not convert string from UTF-8"); + } + } + ZVAL_STRING(*value, (char *)str, 1); + if (free_cp) { + g_free(cp); + } + } else + ZVAL_NULL(*value); + } + break; + + case G_TYPE_PARAM: + phpg_paramspec_new(value, g_value_get_param(gval) TSRMLS_CC); + break; + + case G_TYPE_OBJECT: + phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); + break; + + case G_TYPE_INTERFACE: + if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT)) { + phpg_gobject_new(value, g_value_get_object(gval) TSRMLS_CC); + } else { + php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); + MAKE_STD_ZVAL(*value); + ZVAL_NULL(*value); + return FAILURE; + } + break; + + case G_TYPE_POINTER: + phpg_gpointer_new(value, G_VALUE_TYPE(gval), g_value_get_pointer(gval) TSRMLS_CC); + break; + + case G_TYPE_BOXED: + { + phpg_gboxed_marshal_t *gbm; + + if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { + zval *object = (zval *) g_value_dup_boxed(gval); + MAKE_ZVAL_IF_NULL(*value); + ZVAL_NULL(*value); + if (object) { + REPLACE_ZVAL_VALUE(value, object, 1); + zval_ptr_dtor(&object); + return SUCCESS; + } else { + ZVAL_NULL(*value); + return FAILURE; + } + } else if (G_VALUE_HOLDS(gval, G_TYPE_VALUE_ARRAY)) { + int i; + zval *item; + int value_count; + + GValueArray *array = (GValueArray *) g_value_get_boxed(gval); + MAKE_ZVAL_IF_NULL(*value); + array_init(*value); + value_count = array->n_values; + + for (i = 0; i < value_count; i++) { + MAKE_STD_ZVAL(item); + phpg_gvalue_to_zval(array->values + i, &item, copy_boxed, TRUE TSRMLS_CC); + add_next_index_zval(*value, item); + } + } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { + MAKE_STD_ZVAL(*value); + return gbm->to_zval(gval, value TSRMLS_CC); + } else { + if (copy_boxed) { + phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), TRUE, TRUE TSRMLS_CC); + } else { + phpg_gboxed_new(value, G_VALUE_TYPE(gval), g_value_get_boxed(gval), FALSE, FALSE TSRMLS_CC); + } + } + break; + } + + default: + php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); + MAKE_STD_ZVAL(*value); + ZVAL_NULL(*value); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_from_zval() */ +PHP_GTK_API int phpg_gvalue_from_zval(GValue *gval, zval **value, zend_bool do_utf8 TSRMLS_DC) +{ + switch (G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(gval))) { + /* + * For whatever reason, we should apparently respect that the gval may be of these + * types and they do not need a value. + */ + case G_TYPE_INVALID: + case G_TYPE_NONE: + break; + + case G_TYPE_BOOLEAN: + convert_to_boolean_ex(value); + g_value_set_boolean(gval, (gboolean)Z_BVAL_PP(value)); + break; + + case G_TYPE_CHAR: + convert_to_string_ex(value); + g_value_set_char(gval, Z_STRVAL_PP(value)[0]); + break; + + case G_TYPE_UCHAR: + convert_to_string_ex(value); + g_value_set_uchar(gval, (guchar)Z_STRVAL_PP(value)[0]); + break; + + case G_TYPE_INT: + convert_to_long_ex(value); + g_value_set_int(gval, (gint)Z_LVAL_PP(value)); + break; + + case G_TYPE_UINT: + convert_to_long_ex(value); + g_value_set_uint(gval, (guint)Z_LVAL_PP(value)); + break; + + case G_TYPE_LONG: + convert_to_long_ex(value); + g_value_set_long(gval, (glong)Z_LVAL_PP(value)); + break; + + case G_TYPE_ULONG: + convert_to_long_ex(value); + g_value_set_ulong(gval, (gulong)Z_LVAL_PP(value)); + break; + + case G_TYPE_FLOAT: + convert_to_double_ex(value); + g_value_set_float(gval, (gfloat)Z_DVAL_PP(value)); + break; + + case G_TYPE_DOUBLE: + convert_to_double_ex(value); + g_value_set_double(gval, Z_DVAL_PP(value)); + break; + + case G_TYPE_ENUM: + { + gint val = 0; + if (phpg_gvalue_get_enum(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { + return FAILURE; + } + g_value_set_enum(gval, val); + break; + } + + case G_TYPE_FLAGS: + { + gint val = 0; + if (phpg_gvalue_get_flags(G_VALUE_TYPE(gval), *value, &val) == FAILURE) { + return FAILURE; + } + g_value_set_flags(gval, val); + break; + } + + case G_TYPE_STRING: + { + gchar *utf8 = NULL; + gsize utf8_len = 0; + zend_bool free_utf8 = 0; + gchar *str; + + convert_to_string_ex(value); + str = Z_STRVAL_PP(value); + if (do_utf8) { + utf8 = phpg_to_utf8(Z_STRVAL_PP(value), Z_STRLEN_PP(value), &utf8_len, &free_utf8 TSRMLS_CC); + if (utf8) { + str = utf8; + } else { + php_error(E_WARNING, "Could not convert string to UTF-8"); + } + } + g_value_set_string(gval, str); + if (free_utf8) { + g_free(utf8); + } + break; + } + + case G_TYPE_POINTER: + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_pointer(gval, NULL); + } else if (Z_TYPE_PP(value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gpointer_ce TSRMLS_CC) + && G_VALUE_HOLDS(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->gtype)) { + g_value_set_pointer(gval, ((phpg_gpointer_t*)PHPG_GET(*value))->pointer); + } else { + return FAILURE; + } + break; + + case G_TYPE_BOXED: + { + phpg_gboxed_marshal_t *gbm; + + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_boxed(gval, NULL); + /* + * We should be safe just setting the zval here, since G_TYPE_PHP_VALUE is + * supposed to take any zval type. + */ + } else if (G_VALUE_HOLDS(gval, G_TYPE_PHP_VALUE)) { + g_value_set_boxed(gval, *value); + } else if (Z_TYPE_PP(value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gboxed_ce TSRMLS_CC) + && G_VALUE_HOLDS(gval, ((phpg_gboxed_t*)PHPG_GET(*value))->gtype)) { + g_value_set_boxed(gval, PHPG_GBOXED(*value)); + } else if ((gbm = phpg_gboxed_lookup_custom(G_VALUE_TYPE(gval)))) { + return gbm->from_zval(*value, gval TSRMLS_CC); + } else + return FAILURE; + break; + } + + case G_TYPE_PARAM: + if (php_gtk_check_class(*value, gparamspec_ce)) { + g_value_set_param(gval, PHPG_GPARAMSPEC(*value)); + } else { + return FAILURE; + } + break; + + case G_TYPE_OBJECT: + if (Z_TYPE_PP(value) == IS_NULL) { + g_value_set_object(gval, NULL); + } else if (Z_TYPE_P(*value) == IS_OBJECT + && instanceof_function(Z_OBJCE_PP(value), gobject_ce TSRMLS_CC) + && G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { + g_value_set_object(gval, PHPG_GOBJECT(*value)); + } else + return FAILURE; + break; + + case G_TYPE_INTERFACE: + if (g_type_is_a(G_VALUE_TYPE(gval), G_TYPE_OBJECT) && + Z_TYPE_PP(value) == IS_OBJECT && + G_TYPE_CHECK_INSTANCE_TYPE(PHPG_GOBJECT(*value), G_VALUE_TYPE(gval))) { + g_value_set_object(gval, PHPG_GOBJECT(*value)); + } else { + php_error(E_WARNING, "Could not access interface %s", g_type_name(G_VALUE_TYPE(gval))); + return FAILURE; + } + break; + + default: + php_error(E_WARNING, "PHP-GTK internal error: unsupported type %s", g_type_name(G_VALUE_TYPE(gval))); + return FAILURE; + + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_param_gvalue_to_zval() */ +PHP_GTK_API int phpg_param_gvalue_to_zval(const GValue *gval, zval **value, zend_bool copy_boxed, const GParamSpec *pspec TSRMLS_DC) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + /* TODO */ + return FAILURE; + } else { + return phpg_gvalue_to_zval(gval, value, copy_boxed, TRUE TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_param_gvalue_from_zval() */ +PHP_GTK_API int phpg_param_gvalue_from_zval(GValue *gval, zval **value, const GParamSpec *pspec TSRMLS_DC) +{ + if (G_IS_PARAM_SPEC_UNICHAR(pspec)) { + /* TODO */ + return FAILURE; + } else { + return phpg_gvalue_from_zval(gval, value, TRUE TSRMLS_CC); + } +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalues_to_array() */ +PHP_GTK_API zval *phpg_gvalues_to_array(const GValue *values, uint n_values) +{ + zval *hash; + zval *item = NULL; + int i; + int value_count; + + MAKE_STD_ZVAL(hash); + array_init(hash); + value_count = n_values; + + for (i = 0; i < value_count; i++) { + //item = phpg_gvalue_to_zval(&values[i], FALSE); + if (!item) { + MAKE_STD_ZVAL(item); + ZVAL_NULL(item); + } + zend_hash_next_index_insert(Z_ARRVAL_P(hash), &item, sizeof(zval *), NULL); + } + + return hash; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_get_enum() */ +PHP_GTK_API int phpg_gvalue_get_enum(GType enum_type, zval *enum_val, gint *result) +{ + if (result == NULL) + return FAILURE; + + if (enum_val == NULL) { + *result = 0; + } else if (Z_TYPE_P(enum_val) == IS_LONG) { + *result = Z_LVAL_P(enum_val); + } else if (Z_TYPE_P(enum_val) == IS_STRING) { + GEnumClass *eclass = NULL; + GEnumValue *info = NULL; + + if (enum_type != G_TYPE_NONE) { + eclass = G_ENUM_CLASS(g_type_class_ref(enum_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of enum"); + return FAILURE; + } + + info = g_enum_get_value_by_name(eclass, Z_STRVAL_P(enum_val)); + + if (info == NULL) { + info = g_enum_get_value_by_nick(eclass, Z_STRVAL_P(enum_val)); + } + g_type_class_unref(eclass); + + if (info != NULL) { + *result = info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to enum", Z_STRVAL_P(enum_val)); + return FAILURE; + } + } else { + php_error(E_WARNING, "PHP-GTK internal error: enums must be strings or integers"); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_GTK_API phpg_gvalue_get_flags() */ +PHP_GTK_API int phpg_gvalue_get_flags(GType flags_type, zval *flags_val, gint *result) +{ + GFlagsClass *fclass = NULL; + GFlagsValue *info = NULL; + + if (result == NULL) + return FAILURE; + + if (flags_val == NULL) { + *result = 0; + } else if (Z_TYPE_P(flags_val) == IS_LONG) { + *result = Z_LVAL_P(flags_val); + } else if (Z_TYPE_P(flags_val) == IS_STRING) { + if (flags_type != G_TYPE_NONE) { + fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); + return FAILURE; + } + + info = g_flags_get_value_by_name(fclass, Z_STRVAL_P(flags_val)); + if (info == NULL) { + info = g_flags_get_value_by_nick(fclass, Z_STRVAL_P(flags_val)); + } + g_type_class_unref(fclass); + + if (info != NULL) { + *result = info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_P(flags_val)); + return FAILURE; + } + } else if (Z_TYPE_P(flags_val) == IS_ARRAY) { + zval **flag; + + *result = 0; + if (flags_type != G_TYPE_NONE) { + fclass = G_FLAGS_CLASS(g_type_class_ref(flags_type)); + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not obtain the type of flags"); + return FAILURE; + } + + for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(flags_val)); + zend_hash_get_current_data(Z_ARRVAL_P(flags_val), (void **)&flag) == SUCCESS; + zend_hash_move_forward(Z_ARRVAL_P(flags_val))) { + + if (Z_TYPE_PP(flag) == IS_LONG) { + *result |= Z_LVAL_PP(flag); + } else if (Z_TYPE_PP(flag) == IS_STRING) { + info = g_flags_get_value_by_name(fclass, Z_STRVAL_PP(flag)); + if (info == NULL) { + info = g_flags_get_value_by_nick(fclass, Z_STRVAL_PP(flag)); + } + if (info != NULL) { + *result |= info->value; + } else { + php_error(E_WARNING, "PHP-GTK internal error: could not convert '%s' to flags", Z_STRVAL_PP(flag)); + g_type_class_unref(fclass); + return FAILURE; + } + } else { + php_error(E_WARNING, "PHP-GTK flag arrays can contain only integers or strings"); + g_type_class_unref(fclass); + return 0; + } + } + g_type_class_unref(fclass); + } else { + php_error(E_WARNING, "PHP-GTK flags must be strings, integers, or arrays of strings or integers"); + return FAILURE; + } + + return SUCCESS; +} +/* }}} */ + +#endif + +/* vim: set fdm=marker et : */ diff --git a/win32/config.w32.in b/win32/config.w32.in index 88e295e..fafa61e 100644 --- a/win32/config.w32.in +++ b/win32/config.w32.in @@ -1,157 +1,162 @@ -// vim:ft=javascript -// $Id$ -// "Master" config file; think of it as a configure.in equivalent. - -// MSVC version table -var MSVCVERS = []; -MSVCVERS[1200] = 'MSVC6 (Visual C++ 6.0)'; -MSVCVERS[1300] = 'MSVC7 (Visual C++ 2002)'; -MSVCVERS[1310] = 'MSVC7.1 (Visual C++ 2003)'; -MSVCVERS[1400] = 'MSVC8 (Visual C++ 2005)'; -MSVCVERS[1500] = 'MSVC9 (Visual C++ 2008)'; -MSVCVERS[1600] = 'MSVC10 (Visual C++ 2010)'; - -STDOUT.WriteBlankLines(1); - -CL = PATH_PROG('cl'); - -// avoid picking up midnight commander from cygwin -PATH_PROG('mc', WshShell.Environment("Process").Item("PATH")); -PATH_PROG('rc', WshShell.Environment("Process").Item("PATH")); - -/* cygwin ships with 'link.exe'. Avoid searching the cygwin path for this, as we want the MS linker */ -PATH_PROG('link', WshShell.Environment("Process").Item("PATH"), "LD"); -PATH_PROG('nmake'); - -// check for grep and sed! -if (!PATH_PROG('grep', WshShell.Environment("Process").Item("PATH")) || - !PATH_PROG('sed', WshShell.Environment("Process").Item("PATH"))) { - ERROR("grep and sed are required"); -} - -// we don't want to define LIB, as that will override the default library path set in that env var -PATH_PROG('lib', null, 'MAKE_LIB'); -PATH_PROG('php'); - -STDOUT.WriteBlankLines(1); - -if (CL) { - var VCVERS = probe_msvc_compiler_version(CL); - - if (typeof(MSVCVERS[VCVERS]) == undefined) { - // Lets just bail out if we dont know the MSVC version - ERROR("MS C++ compiler is required -- unable to detect version"); - } else { - STDOUT.WriteLine("Detected compiler version: " + MSVCVERS[VCVERS]); - } -} else { - ERROR("MS C++ compiler is required"); -} - -STDOUT.WriteBlankLines(1); - -ARG_WITH('php-build', 'Path to where you extracted http://www.php.net/extra/win32build.zip. Assumes that it is a sibling of this source dir (..\\php_build) if not specified', 'no'); -ARG_WITH('cygwin', 'Path to cygwin utilities on your system', '\\cygwin'); -ARG_ENABLE('gd', 'Php has static gd', 'no'); -ARG_ENABLE('zts', 'Disable thread safety', 'yes'); - -// stick objects somewhere outside of the source tree -ARG_ENABLE('object-out-dir', 'Alternative location for binary objects during build', ''); -if (PHP_GTK_OBJECT_OUT_DIR.length) { - if (!FSO.FolderExists(PHP_GTK_OBJECT_OUT_DIR)) { - ERROR('Your chosen output directory ' + PHP_GTK_OBJECT_OUT_DIR + ' does not exist'); - } - PHP_GTK_OBJECT_OUT_DIR += '\\'; -} - -ARG_ENABLE('debug', 'Compile with debugging symbols', "no"); -ARG_ENABLE('debug-pack', 'Release binaries with external debug symbols (--enable-debug must not be specified)', 'no'); -if (PHP_GTK_DEBUG == "yes" && PHP_GTK_DEBUG_PACK == "yes") { - ERROR("Use of both --enable-debug and --enable-debug-pack not allowed."); -} - -// Compile directory -if (PHP_GTK_DEBUG == "yes" && PHP_GTK_ZTS == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug_TS"); - DEFINE("PHP_LIB", "php5ts_debug.lib"); - PHP_LIB = "php5ts_debug.lib"; -} else if (PHP_GTK_DEBUG == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug"); - DEFINE("PHP_LIB", "php5_debug.lib"); - PHP_LIB = "php5_debug.lib"; -} else if (PHP_GTK_ZTS == "yes") { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release_TS"); - DEFINE("PHP_LIB", "php5ts.lib"); - PHP_LIB = "php5ts.lib"; -} else { - DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release"); - DEFINE("PHP_LIB", "php5.lib"); - PHP_LIB = "php5.lib"; -} -if (PHP_GTK_PHP_BUILD == 'no') { - if (FSO.FolderExists("..\\php_gtk_build")) { - PHP_GTK_PHP_BUILD = "..\\php_gtk_build"; - } else if (FSO.FolderExists("..\\php_build")) { - PHP_GTK_PHP_BUILD = "..\\php_build"; - } else if (FSO.FolderExists("..\\win32build")) { - PHP_GTK_PHP_BUILD = "..\\win32build"; - } else if (FSO.FolderExists("..\\php-win32-dev\\php_build")) { - PHP_GTK_PHP_BUILD = "..\\php-win32-dev\\php_build"; - } -} - -var php_usual_include_suspects = PHP_GTK_PHP_BUILD; -var php_usual_lib_suspects = PHP_GTK_PHP_BUILD; - -ARG_IS('all', 'Configure all available extensions', 'no'); - -DEFINE("PHPGTKDLL", "php_gtk2.dll"); -DEFINE("PHPGTKLIB", "php_gtk2.lib"); -get_version_numbers(); -/* pick up the version from gtk/gtkversion.h */ -get_gtk_libversion(); - -// General link flags -DEFINE("LDFLAGS", "/nologo"); -// General DLL link flags -DEFINE("DLL_LDFLAGS", "/dll /machine:I386"); -// PHP-GTK DLL link flags -DEFINE("LDFLAGS_PHP_GTK", "$(DLL_LDFLAGS)"); - -// General libs -DEFINE("LIBS", "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib"); - -if (PHP_GTK_DEBUG == "yes") { - DEFINE("CFLAGS", "/nologo /LDd /MDd /Gm /ZI /GZ /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=1 /D PHP_WIN32 /D WIN32 /D _DEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); - ADD_FLAG("LDFLAGS", "/debug"); - -} else { - DEFINE("CFLAGS", "/nologo /MD /W3 /GX /O2 /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=0 /D PHP_WIN32 /D WIN32 /D NDEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); - // Generate external debug files when --enable-debug-pack is specified - if (PHP_GTK_DEBUG_PACK == "yes") { - ADD_FLAG("CFLAGS", "/Zi"); - ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); - } -} - -if (PHP_GTK_ZTS == "yes") { - ADD_FLAG("CFLAGS", "/D ZTS=1"); - } - -if (VCVERS < 1400) { - // Enable automatic precompiled headers - ADD_FLAG('CFLAGS', '/YX /c'); -} else { - // fun stuff: MS deprecated ANSI stdio and similar functions - disable warnings - // GS hardens the binary against buffer overruns - ADD_FLAG('CFLAGS', '/GS /wd4996 '); -} - -if (PHP_GTK_GD == "yes") { - ADD_FLAG('CFLAGS', '/D HAVE_GD_BUNDLED=1'); -} - -probe_basic_headers(); - -ADD_SOURCES("main", "php_gtk.c php_gtk_ext.w32.c php_gtk_util.c phpg_closure.c phpg_exceptions.c phpg_gboxed.c phpg_gobject.c phpg_gpointer.c phpg_gtype.c phpg_gvalue.c phpg_atom.c phpg_support.c phpg_paramspec.c", "php-gtk"); - +// vim:ft=javascript +// $Id$ +// "Master" config file; think of it as a configure.in equivalent. + +// MSVC version table +var MSVCVERS = []; +MSVCVERS[1200] = 'MSVC6 (Visual C++ 6.0)'; +MSVCVERS[1300] = 'MSVC7 (Visual C++ 2002)'; +MSVCVERS[1310] = 'MSVC7.1 (Visual C++ 2003)'; +MSVCVERS[1400] = 'MSVC8 (Visual C++ 2005)'; +MSVCVERS[1500] = 'MSVC9 (Visual C++ 2008)'; +MSVCVERS[1600] = 'MSVC10 (Visual C++ 2010)'; + +STDOUT.WriteBlankLines(1); + +CL = PATH_PROG('cl'); + +// avoid picking up midnight commander from cygwin +PATH_PROG('mc', WshShell.Environment("Process").Item("PATH")); +PATH_PROG('rc', WshShell.Environment("Process").Item("PATH")); + +/* cygwin ships with 'link.exe'. Avoid searching the cygwin path for this, as we want the MS linker */ +PATH_PROG('link', WshShell.Environment("Process").Item("PATH"), "LD"); +PATH_PROG('nmake'); + +// check for grep and sed! +if (!PATH_PROG('grep', WshShell.Environment("Process").Item("PATH")) || + !PATH_PROG('sed', WshShell.Environment("Process").Item("PATH"))) { + ERROR("grep and sed are required"); +} + +// we don't want to define LIB, as that will override the default library path set in that env var +PATH_PROG('lib', null, 'MAKE_LIB'); +PATH_PROG('php'); + +if (!PATH_PROG('php', WshShell.Environment("Process").Item("PATH"))) { + ERROR("php is required"); +} + +STDOUT.WriteBlankLines(1); + +if (CL) { + var VCVERS = probe_msvc_compiler_version(CL); + STDOUT.WriteLine("Detected compiler version: " + VCVERS); + + if (typeof(MSVCVERS[VCVERS]) == undefined) { + // Lets just bail out if we dont know the MSVC version + ERROR("MS C++ compiler is required -- unable to detect version"); + } else { + STDOUT.WriteLine("Detected compiler version: " + MSVCVERS[VCVERS]); + } +} else { + ERROR("MS C++ compiler is required"); +} + +STDOUT.WriteBlankLines(1); + +ARG_WITH('php-build', 'Path to where you extracted http://www.php.net/extra/win32build.zip. Assumes that it is a sibling of this source dir (..\\php_build) if not specified', 'no'); +ARG_WITH('cygwin', 'Path to cygwin utilities on your system', '\\cygwin'); +ARG_ENABLE('gd', 'Php has static gd', 'no'); +ARG_ENABLE('zts', 'Disable thread safety', 'yes'); + +// stick objects somewhere outside of the source tree +ARG_ENABLE('object-out-dir', 'Alternative location for binary objects during build', ''); +if (PHP_GTK_OBJECT_OUT_DIR.length) { + if (!FSO.FolderExists(PHP_GTK_OBJECT_OUT_DIR)) { + ERROR('Your chosen output directory ' + PHP_GTK_OBJECT_OUT_DIR + ' does not exist'); + } + PHP_GTK_OBJECT_OUT_DIR += '\\'; +} + +ARG_ENABLE('debug', 'Compile with debugging symbols', "no"); +ARG_ENABLE('debug-pack', 'Release binaries with external debug symbols (--enable-debug must not be specified)', 'no'); +if (PHP_GTK_DEBUG == "yes" && PHP_GTK_DEBUG_PACK == "yes") { + ERROR("Use of both --enable-debug and --enable-debug-pack not allowed."); +} + +// Compile directory +if (PHP_GTK_DEBUG == "yes" && PHP_GTK_ZTS == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug_TS"); + DEFINE("PHP_LIB", "php5ts_debug.lib"); + PHP_LIB = "php5ts_debug.lib"; +} else if (PHP_GTK_DEBUG == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Debug"); + DEFINE("PHP_LIB", "php5_debug.lib"); + PHP_LIB = "php5_debug.lib"; +} else if (PHP_GTK_ZTS == "yes") { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release_TS"); + DEFINE("PHP_LIB", "php5ts.lib"); + PHP_LIB = "php5ts.lib"; +} else { + DEFINE("BUILD_DIR", PHP_GTK_OBJECT_OUT_DIR + "Release"); + DEFINE("PHP_LIB", "php5.lib"); + PHP_LIB = "php5.lib"; +} +if (PHP_GTK_PHP_BUILD == 'no') { + if (FSO.FolderExists("..\\php_gtk_build")) { + PHP_GTK_PHP_BUILD = "..\\php_gtk_build"; + } else if (FSO.FolderExists("..\\php_build")) { + PHP_GTK_PHP_BUILD = "..\\php_build"; + } else if (FSO.FolderExists("..\\win32build")) { + PHP_GTK_PHP_BUILD = "..\\win32build"; + } else if (FSO.FolderExists("..\\php-win32-dev\\php_build")) { + PHP_GTK_PHP_BUILD = "..\\php-win32-dev\\php_build"; + } +} + +var php_usual_include_suspects = PHP_GTK_PHP_BUILD; +var php_usual_lib_suspects = PHP_GTK_PHP_BUILD; + +ARG_IS('all', 'Configure all available extensions', 'no'); + +DEFINE("PHPGTKDLL", "php_gtk2.dll"); +DEFINE("PHPGTKLIB", "php_gtk2.lib"); +get_version_numbers(); +/* pick up the version from gtk/gtkversion.h */ +get_gtk_libversion(); + +// General link flags +DEFINE("LDFLAGS", "/nologo"); +// General DLL link flags +DEFINE("DLL_LDFLAGS", "/dll /machine:I386"); +// PHP-GTK DLL link flags +DEFINE("LDFLAGS_PHP_GTK", "$(DLL_LDFLAGS)"); + +// General libs +DEFINE("LIBS", "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib"); + +if (PHP_GTK_DEBUG == "yes") { + DEFINE("CFLAGS", "/nologo /LDd /MDd /Gm /ZI /GZ /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=1 /D PHP_WIN32 /D WIN32 /D _DEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); + ADD_FLAG("LDFLAGS", "/debug"); + +} else { + DEFINE("CFLAGS", "/nologo /MD /W3 /EHsc /Ox /I . /I ..\\ /I ..\\.. /I main /I ..\\main /I ext /I ..\\ext /D ZEND_WIN32 /D ZEND_DEBUG=0 /D PHP_WIN32 /D WIN32 /D NDEBUG /D _WINDOWS /D _MBCS /D _USRDLL"); + // Generate external debug files when --enable-debug-pack is specified + if (PHP_GTK_DEBUG_PACK == "yes") { + ADD_FLAG("CFLAGS", "/Zi"); + ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); + } +} + +if (PHP_GTK_ZTS == "yes") { + ADD_FLAG("CFLAGS", "/D ZTS=1"); + } + +if (VCVERS < 1400) { + // Enable automatic precompiled headers + ADD_FLAG('CFLAGS', '/YX /c'); +} else { + // fun stuff: MS deprecated ANSI stdio and similar functions - disable warnings + // GS hardens the binary against buffer overruns + ADD_FLAG('CFLAGS', '/GS /wd4996 '); +} + +if (PHP_GTK_GD == "yes") { + ADD_FLAG('CFLAGS', '/D HAVE_GD_BUNDLED=1'); +} + +probe_basic_headers(); + +ADD_SOURCES("main", "php_gtk.c php_gtk_ext.w32.c php_gtk_util.c phpg_closure.c phpg_exceptions.c phpg_gboxed.c phpg_gobject.c phpg_gpointer.c phpg_gtype.c phpg_gvalue.c phpg_atom.c phpg_support.c phpg_paramspec.c", "php-gtk"); + diff --git a/win32/confutils.js b/win32/confutils.js index a19cf7f..5ce08e9 100644 --- a/win32/confutils.js +++ b/win32/confutils.js @@ -1,1263 +1,1263 @@ -// Utils for configure script -/* - +----------------------------------------------------------------------+ - | PHP-GTK Version 2 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2005 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 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_0.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. | - +----------------------------------------------------------------------+ - | Author: Wez Furlong <wez@thebrainroom.com> | - +----------------------------------------------------------------------+ -*/ - -// $Id: confutils.js,v 1.24 2008-08-01 14:34:43 auroraeosrose Exp $ - -/* set vars */ -var STDOUT = WScript.StdOut; -var STDERR = WScript.StdErr; -var WshShell = WScript.CreateObject("WScript.Shell"); -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var MFO = null; -var MFE = null; -var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); -var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); - -if (PROGRAM_FILES == null) { - PROGRAM_FILES = "C:\\Program Files"; -} - -var CWD = WshShell.CurrentDirectory; - -if (typeof(CWD) == "undefined") { - CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("buildconf.bat")); -} - -configure_args = new Array(); -configure_subst = WScript.CreateObject("Scripting.Dictionary"); - -configure_hdr = WScript.CreateObject("Scripting.Dictionary"); -build_dirs = new Array(); -make_builds = new Array(); - -extension_include_code = ""; -extension_module_ptrs = ""; - -/* functions */ - -function get_gtk_libversion() -{ - var env, i, vin, major, minor; - var found = false; - - found = CHECK_HEADER("gtk/gtkversion.h"); - - if (found) { - STDOUT.WriteLine(" <in default path>"); - vin = file_get_contents(found + "\\gtk\\gtkversion.h"); - - regex = new RegExp("GTK_MAJOR_VERSION\\s+\\(([0-9]+)\\)"); - regex.exec(vin); - major = RegExp.$1; - if (major < 2) - major = 2; - - regex = new RegExp("GTK_MINOR_VERSION\\s+\\(([0-9]+)\\)"); - regex.exec(vin); - minor = RegExp.$1; - if (minor < 6) - minor = 6; - - if (major >= 2 && minor >=8) { - ENABLE_CAIRO = 1; - } else { - ENABLE_CAIRO = 0; - } - PHP_GTK_LIBVERSION = major + '.' + minor; - } else { - STDOUT.WriteLine(" <not found>"); - PHP_GTK_LIBVERSION = '2.6'; - } - - STDOUT.Write("Library definitions for " + PHP_GTK_LIBVERSION + " will be used"); - STDERR.WriteBlankLines(1); -} - -function generate_source() { - - if (!FSO.FileExists("ext\\gtk+\\complete.txt")) { - if (!FSO.FileExists("win32\\temp.bat")) { - STDERR.WriteLine("Run buildconf first - the source file generator is missing"); - WScript.Quit(10); - } else { - var temp = FSO.OpenTextFile("win32\\temp.bat", 8); - temp.WriteLine("@echo off > source_complete.txt"); - temp.Close(); - WshShell.Run("win32\\temp", 0); - } - } - return; -} - -function check_generation() { - - if (!FSO.FileExists("source_complete.txt")) { - STDOUT.WriteLine("Waiting for source files to generate..."); - WScript.Sleep(3500); - check_generation(); - } - return; -} - -function get_version_numbers() { - - /* pick up the version from main/php_gtk.h */ - var vin = file_get_contents("main\\php_gtk.h"); - var version, version_strings, major, minor, details, release = "", extra = ""; - - if (vin.match(new RegExp("PHP_GTK_VERSION \"([^\"]+)\""))) { - version = RegExp.$1; - version_strings = version.split("."); - - major = version_strings[0]; - minor = version_strings[1]; - details = version_strings[2]; - - for (i = 0; i < details.length; i++) { - if(!isNaN(details.charAt(i))) { - release = release + details.charAt(i); - } else { - extra = details.substring(i); - break; - } - } - } - - var vfile = FSO.CreateTextFile("main/php_gtk_version.h", true); - vfile.WriteLine("/* This file is automatically generated during win32 configuration */"); - vfile.WriteLine("/* Edit php_gtk.h to change the version number */"); - vfile.WriteLine("#define PHP_GTK_MAJOR_VERSION " + major); - vfile.WriteLine("#define PHP_GTK_MINOR_VERSION " + minor); - vfile.WriteLine("#define PHP_GTK_RELEASE_VERSION " + release); - if (PHP_GTK_DEBUG == "yes") { - vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + " (DEBUG)\""); - } else { - vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + "\""); - } - - DEFINE('PHP_GTK_VERSION_STRING', version); -} - -function condense_path(path) { - - path = FSO.GetAbsolutePathName(path); - - if (path.substr(0, CWD.length).toLowerCase() - == CWD.toLowerCase() && - (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { - return path.substr(CWD.length + 1); - } - - var a = CWD.split("\\"); - var b = path.split("\\"); - var i, j; - - for (i = 0; i < b.length; i++) { - if (a[i].toLowerCase() == b[i].toLowerCase()) - continue; - if (i > 0) { - /* first difference found */ - path = ""; - for (j = 0; j < a.length - i; j++) { - path += "..\\"; - } - for (j = i; j < b.length; j++) { - path += b[j]; - if (j < b.length - 1) - path += "\\"; - } - return path; - } - /* on a different drive */ - break; - } - - return path; -} - -function ConfigureArg(type, optname, helptext, defval) { - - var opptype = ""; - - if (type) { - - opptype = type == "enable" ? "disable" : "without"; - - if (defval == "yes" || defval == "yes,shared") { - this.arg = "--" + opptype + "-" + optname; - this.imparg = "--" + type + "-" + optname; - } else { - this.arg = "--" + type + "-" + optname; - this.imparg = "--" + opptype + "-" + optname; - } - } else { - this.arg = "--" + optname; - } - - this.optname = optname; - this.helptext = helptext; - this.defval = defval; - this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); - this.seen = false; - this.argval = defval; -} - -function analyze_arg(argval) { - - var ret = new Array(); - - if (argval == "shared") { - argval = "yes"; - } else if (argval == null) { - /* nothing */ - } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { - argval = arg_match[1]; - } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { - argval = arg_match[1]; - } - - ret[0] = argval; - return ret; -} - -function conf_process_args() { - - var i, j; - var configure_help_mode = false; - var analyzed = false; - var nice = "cscript /nologo configure.js "; - - args = WScript.Arguments; - - for (i = 0; i < args.length; i++) { - arg = args(i); - nice += ' "' + arg + '"'; - if (arg == "--help") { - configure_help_mode = true; - break; - } - - // If it is --foo=bar, split on the equals sign - arg = arg.split("=", 2); - argname = arg[0]; - if (arg.length > 1) { - argval = arg[1]; - } else { - argval = null; - } - - // Find the arg - found = false; - for (j = 0; j < configure_args.length; j++) { - if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { - found = true; - - arg = configure_args[j]; - arg.seen = true; - - analyzed = analyze_arg(argval); - argval = analyzed[0]; - - if (argname == arg.imparg) { - /* we matched the implicit, or default arg */ - if (argval == null) { - argval = arg.defval; - } - } else { - /* we matched the non-default arg */ - if (argval == null) { - argval = arg.defval == "no" ? "yes" : "no"; - } - } - - arg.argval = argval; - eval("PHP_GTK_" + arg.symval + " = argval;"); - break; - } - } - if (!found) { - STDERR.WriteLine("Unknown option " + argname); - STDERR.WriteLine("Please try configure.js --help for a list of valid options"); - WScript.Quit(2); - } - } - - if (configure_help_mode) { - - STDOUT.WriteBlankLines(1); - - // Measure width to pretty-print the output - max_width = 0; - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.arg.length > max_width) { - max_width = arg.arg.length; - } - } - - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - - n = max_width - arg.arg.length; - pad = " "; - for (j = 0; j < n; j++) { - pad += " "; - } - STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); - } - WScript.Quit(1); - } - - // Now set any defaults we might have missed out earlier - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.seen) - continue; - analyzed = analyze_arg(arg.defval); - argval = analyzed[0]; - - eval("PHP_GTK_" + arg.symval + " = argval;"); - } - - MFO = FSO.CreateTextFile("Makefile.objects", true); - MFE = FSO.CreateTextFile("Makefile.extensions", true); - - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Saving configure options to configure.bat"); - var nicefile = FSO.CreateTextFile("configure.bat", true); - nicefile.WriteLine(nice); - nicefile.Close(); - - AC_DEFINE('CONFIGURE_COMMAND', nice); -} - -function find_pattern_in_path(pattern, path) { - - if (path == null) { - return false; - } - - var dirs = path.split(';'); - var i; - var items; - - for (i = 0; i < dirs.length; i++) { - items = glob(dirs[i] + "\\" + pattern); - if (items) { - return condense_path(items[0]); - } - } - return false; -} - -function ARG_IS(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("", optname, helptext, defval); -} - -function ARG_WITH(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); -} - -function ARG_ENABLE(optname, helptext, defval) { - - configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); -} - -function DEFINE(name, value) { - - if (configure_subst.Exists(name)) { - configure_subst.Remove(name); - } - configure_subst.Add(name, value); -} - -function AC_DEFINE(name, value, comment, quote) { - - if (quote == null) { - quote = true; - } - if (quote && typeof(value) == "string") { - value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; - } else if (value.length == 0) { - value = '""'; - } - var item = new Array(value, comment); - if (configure_hdr.Exists(name)) { - var orig_item = configure_hdr.Item(name); - STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + item[0]); - } else { - configure_hdr.Add(name, item); - } -} - -function PATH_PROG(progname, additional_paths, symbol) { - - var exe; - var place; - var cyg_path = PHP_GTK_CYGWIN + "\\bin;" + PHP_GTK_CYGWIN + "\\usr\\local\\bin"; - - exe = progname + ".exe"; - - if (additional_paths == null) { - additional_paths = cyg_path; - } else { - additional_paths += ";" + cyg_path; - } - - place = search_paths(exe, additional_paths, "PATH"); - - if (place == true) { - place = exe; - } else if (place != false) { - - if (place.lastIndexOf("\\") != place.length - 1) { - place += "\\"; - } - - place = place + exe; - - if (place.indexOf(" ")) { - place = '"' + place + '"'; - } - } - - if (place) { - if (symbol == null) { - symbol = progname.toUpperCase(); - } - DEFINE(symbol, place); - } - return place; -} - -function CHECK_LIB(libnames, target, path_to_check, common_name) { - - STDOUT.Write("Checking for " + libnames + " ... "); - - if (common_name == null && target != null) { - common_name = target; - } - - if (path_to_check == null) { - path_to_check = ""; - } - - // if they specified a common name for the package that contains - // the library, tag some useful defaults on to the end of the - // path to be searched - if (common_name != null) { - path_to_check += ";..\\" + common_name + "*"; - } - - // Determine target for build flags - if (target == null) { - target = ""; - } else { - target = "_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); - } - - // Expand path to include general dirs - path_to_check += ";" + php_usual_lib_suspects; - - // It is common practice to put libs under one of these dir names - var subdirs = new Array(PHP_GTK_DEBUG == "yes" ? "Debug" : "Release", "lib", "libs", "libexec"); - - // libnames can be ; separated list of accepted library names - libnames = libnames.split(';'); - - var i, j, k, libname; - var location = false; - var path = path_to_check.split(';'); - - for (i = 0; i < libnames.length; i++) { - libname = libnames[i]; - - for (k = 0; k < path.length; k++) { - location = glob(path[k] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - for (j = 0; j < subdirs.length; j++) { - location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - } - if (location) - break; - } - - if (location) { - location = condense_path(location); - var libdir = FSO.GetParentFolderName(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine( location); - - return location; - } - - // Check in their standard lib path - location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); - - if (location) { - location = condense_path(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine(" <in LIB path> " + libname); - return location; - } - } - - ERROR(" " + libname + " not found - aborting configure process"); - - return false; -} - -function CHECK_HEADER(header_name, path_to_check) { - if (!path_to_check) { - path_to_check = php_usual_include_suspects; - } - - var path = search_paths(header_name, path_to_check, "INCLUDE"); - - if (!path) { - ERROR(" " + header_name + " not found - aborting configure process"); - } - - return path; -} - -// use this for version checking -function GREP_HEADER(header_name, regex, path_to_check) { - - var c = false; - - if (FSO.FileExists(path_to_check + "\\" + header_name)) { - c = file_get_contents(path_to_check + "\\" + header_name); - } - - if (!c) { - /* look in the include path */ - - var p = search_paths(header_name, path_to_check, "INCLUDE"); - - if (typeof(p) == "string") { - c = file_get_contents(p); - } - - if (!c) { - return false; - } - } - - if (typeof(regex) == "string") { - regex = new RegExp(regex); - } - - if (c.match(regex)) { - /* caller can now use RegExp.$1 etc. to get at patterns */ - return true; - } - return false; -} - -function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) { - - var dir_part_to_add = ""; - - if (use_env == null) { - use_env = true; - } - - // if true, add the dir part of the header_name to the include path - if (add_dir_part == null) { - add_dir_part = false; - } else if (add_dir_part) { - var basename = FSO.GetFileName(header_name); - dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); - } - - if (path_to_check == null) { - path_to_check = php_usual_include_suspects; - } else { - path_to_check += ";" + php_usual_include_suspects; - } - - var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); - var have = 0; - var sym; - - if (typeof(p) == "string") { - ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); - } - - have = p ? 1 : 0 - - sym = header_name.toUpperCase(); - sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); - - if (typeof(add_to_flag_only) == undefined && - flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { - add_to_flag_only = true; - } - - if (typeof(add_to_flag_only) != "undefined") { - ADD_FLAG(flag_name, "/D HAVE_" + sym + "=" + have); - } else { - AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); - } - - return p; -} - -function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) { - - var dllflags = ""; - var dep_libs = ""; - var EXT = extname.toUpperCase().replace(new RegExp("-", "g"), "_"); - var extname_for_printing; - var res_var = ""; - var file; - - if (cflags == null) { - cflags = ""; - } - - if (typeof(obj_dir) == "undefined") { - - extname_for_printing = configure_module_dirname; - - } else { - - extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; - } - - STDOUT.WriteLine("Enabling extension " + extname_for_printing); - - if (extname == 'php-gtk') { - cflags = "/D COMPILE_DL_" + EXT + "2 /D " + EXT + "_EXPORTS=1" + cflags; - file = MFO; - } else { - cflags = "/D PHP_GTK_COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1" + cflags; - file = MFE; - } - - file.WriteBlankLines(1); - file.WriteLine("# objects for EXT " + extname); - file.WriteBlankLines(1); - - ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); - - file.WriteBlankLines(1); - - // PHP-GTK and its extensions are always built as shared for now - - if (dllname == null) { - if (extname == 'php-gtk') { - dllname = "php_gtk2.dll"; - resname = generate_version_info_resource(dllname, configure_module_dirname); - res_var = " $(PHPGTKDLL_RES)"; - } else { - cflags = "/D GTK_SHARED=1 " + cflags; - dllname = "php_gtk_" + extname + "2.dll"; - dllflags = " $(DLL_LDFLAGS)"; - dep_libs = " $(BUILD_DIR)\\$(PHPGTKLIB) $(LIBS_PHP_GTK)"; - } - } - var libname = dllname.substring(0, dllname.length - 4) + ".lib"; - var ld = "@$(LD)"; - - ADD_FLAG("EXT_TARGETS", "$(BUILD_DIR)\\" + dllname); - make_builds[make_builds.length] = extname + ": $(BUILD_DIR)\\" + dllname; - - file.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(" + EXT + "_GLOBAL_OBJS)" + res_var); - file.WriteLine("\t" + ld + " /out:$(BUILD_DIR)\\" + dllname + " $(LDFLAGS_" + EXT + ")" + dllflags + " $(LDFLAGS) $(" + EXT + "_GLOBAL_OBJS) $(LIBS_" + EXT + ")" + dep_libs + " $(LIBS)" + res_var); - - file.WriteBlankLines(1); - file.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); - file.WriteLine("\t@echo EXT " + extname + " build complete"); - file.WriteBlankLines(1); - - ADD_FLAG("CFLAGS_" + EXT, cflags); -} - -function ADD_SOURCES(dir, file_list, target, obj_dir) { - - var i; - var tv; - var src, obj, sym, flags; - var core_cflags = ""; - var file; - - sym = target.toUpperCase().replace(new RegExp("-", "g"), "_") + "_GLOBAL_OBJS"; - flags = "CFLAGS_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); - - if (configure_subst.Exists(sym)) { - tv = configure_subst.Item(sym); - } else { - tv = ""; - } - - if (target != "php-gtk") { - file = MFE; - core_cflags = "$(CFLAGS_PHP_GTK) "; - } else { - file = MFO; - } - - file_list = file_list.split(new RegExp("\\s+")); - file_list.sort(); - - var re = new RegExp("\.[a-z0-9A-Z\-]+$"); - - dir = dir.replace(new RegExp("/", "g"), "\\"); - var objs_line = ""; - var srcs_line = ""; - - var sub_build = "$(BUILD_DIR)\\"; - - /* if module dir is not a child of the main source dir, - * we need to tweak it; we should have detected such a - * case in condense_path and rewritten the path to - * be relative. - * This probably breaks for non-sibling dirs */ - if (obj_dir == null) { - var build_dir = dir.replace(new RegExp("^..\\\\"), ""); - } else { - var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); - } - - var mangle_dir = build_dir.replace(new RegExp("[\\\\/.+-]", "g"), "_"); - - /* kill trailing underscores */ - if (mangle_dir.substring(mangle_dir.length - 1) == "_") { - mangle_dir = mangle_dir.substring(0, mangle_dir.length - 1); - } - - var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); - - var dirs = build_dir.split("\\"); - var i, d = ""; - for (i = 0; i < dirs.length; i++) { - d += dirs[i]; - build_dirs[build_dirs.length] = d; - d += "\\"; - } - sub_build += d; - - DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build); - - for (i in file_list) { - src = file_list[i]; - obj = src.replace(re, ".obj"); - tv += " " + sub_build + obj; - - file.WriteLine(sub_build + obj + ": " + dir + "\\" + src); - file.WriteLine("\t@$(CC) $(" + flags + ") " + core_cflags + "$(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); - } - - DEFINE(sym, tv); -} - -function ADD_FLAG(name, flags, target) { - - if (target != null) { - name = target.toUpperCase() + "_" + name; - } - if (configure_subst.Exists(name)) { - var curr_flags = configure_subst.Item(name); - - if (curr_flags.indexOf(flags) >= 0) { - return; - } - - flags = flags + " " + curr_flags; - configure_subst.Remove(name); - } - configure_subst.Add(name, flags); -} - -function get_define(name) { - - return configure_subst.Item(name); -} - -function ERROR(msg) { - - STDERR.WriteBlankLines(2); - STDERR.WriteLine("ERROR: " + msg); - WScript.Quit(3); -} - -function WARNING(msg) { - - STDERR.WriteLine("WARNING: " + msg); - STDERR.WriteBlankLines(1); -} - -/* Searches a set of paths for a file; returns the dir in which the file was found, true if it -was found in the default env path, or false if it was not found at all. env_name is the optional -name of an env var specifying the default path to search */ -function search_paths(thing_to_find, explicit_path, env_name) { - - var i, found = false, place = false, file, env; - - STDOUT.Write("Checking for " + thing_to_find + " ... "); - - if (thing_to_find.length < 6) { - STDOUT.Write(" "); - } - - thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); - - if (explicit_path != null) { - if (typeof(explicit_path) == "string") { - explicit_path = explicit_path.split(";"); - } - - for (i = 0; i < explicit_path.length; i++) { - file = glob(explicit_path[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = file[0]; - place = place.substr(0, place.length - thing_to_find.length - 1); - break; - } - } - } - - if (!found && env_name != null) { - env = WshShell.Environment("Process").Item(env_name); - env = env.split(";"); - for (i = 0; i < env.length; i++) { - file = glob(env[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = true; - break; - } - } - } - - if (found && place == true) { - STDOUT.WriteLine(" <in default path>"); - place = file[0]; - place = place.substr(0, place.length - thing_to_find.length - 1); - } else if (found) { - STDOUT.WriteLine(" " + place); - } else { - STDOUT.WriteLine(" <not found>"); - } - return place; -} - -function word_wrap_and_indent(indent, text, line_suffix, indent_char) { - - if (text == null) { - return ""; - } - - var words = text.split(new RegExp("\\s+", "g")); - var i = 0; - var ret_text = ""; - var this_line = ""; - var t; - var space = ""; - var lines = 0; - - if (line_suffix == null) { - line_suffix = ""; - } - - if (indent_char == null) { - indent_char = " "; - } - - for (i = 0; i < indent; i++) { - space += indent_char; - } - - for (i = 0; i < words.length; i++) { - if (this_line.length) { - t = this_line + " " + words[i]; - } else { - t = words[i]; - } - - if (t.length + indent > 78) { - if (lines++) { - ret_text += space; - } - ret_text += this_line + line_suffix + "\r\n"; - this_line = ""; - } - - if (this_line.length) { - this_line += " " + words[i]; - } else { - this_line = words[i]; - } - } - - if (this_line.length) { - if (lines) - ret_text += space; - ret_text += this_line; - } - - return ret_text; -} - -function file_get_contents(filename) { - - var f, c; - - try { - f = FSO.OpenTextFile(filename, 1); - c = f.ReadAll(); - f.Close(); - return c; - } catch (e) { - STDOUT.WriteLine("Problem reading " + filename); - return false; - } -} - -function generate_files() { - - var i, dir, bd, last; - - generate_source(); - - STDOUT.WriteLine("Generating source files - this may take a few seconds"); - WScript.Sleep(3500); - check_generation(); - - // Check to see if we have additional objects to add - var sources = file_get_contents("sources.temp"); - configure_module_dirname = condense_path("ext\\gtk+\\"); - EXTENSION("php-gtk", php_gtk_files + sources, true); - - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Creating build dirs..."); - dir = get_define("BUILD_DIR"); - build_dirs.sort(); - last = null; - - if (!FSO.FolderExists(dir)) { - FSO.CreateFolder(dir); - } - - for (i = 0; i < build_dirs.length; i++) { - bd = FSO.BuildPath(dir, build_dirs[i]); - if (bd == last) { - continue; - } - last = bd; - ADD_FLAG("BUILD_DIRS_SUB", bd); - if (!FSO.FolderExists(bd)) { - FSO.CreateFolder(bd); - } - } - - generate_makefile(); - - STDOUT.WriteLine("Done."); - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Type 'nmake' to build all targets, or 'nmake php-gtk' to build PHP-GTK alone"); - STDOUT.WriteLine("* Configured PHP-GTK extensions can be built individually at a later stage *"); -} - -function generate_makefile() { - - MFE.WriteLine(""); // To avoid error if MFE will be complete - MFE.Close(); // Makefile.extensions is now complete - MFO.Close(); // Makefile.objects is now complete - var MF = FSO.CreateTextFile("Makefile", true); - STDOUT.WriteLine("Generating Makefile"); - - MF.WriteLine("# Generated by configure.js"); - MF.WriteBlankLines(1); - - /* spit out variable definitions */ - var keys = (new VBArray(configure_subst.Keys())).toArray(); - var i; - - for (i in keys) { - /* The trailing space is needed to prevent the trailing backslash that is part of - the build dir flags (CFLAGS_BD_XXX) from being seen as a line continuation character */ - MF.WriteLine(keys[i] + "=" + configure_subst.Item(keys[i]) + " "); - } - - MF.WriteBlankLines(1); - MF.WriteLine("all: $(EXT_TARGETS)"); - - for (i = make_builds.length; i >= 0; i--) { - if (i == make_builds.length) { - MF.WriteLine("!IF EXIST($(BUILD_DIR)\\$(PHPGTKLIB))"); - } - MF.WriteLine(make_builds[i]); - } - - if (make_builds.length > 1) { - MF.WriteLine("!ELSE"); - MF.WriteLine("!MESSAGE Note: $(PHPGTKLIB) must be created before PHP-GTK extensions can be built"); - } - - MF.WriteLine("!ENDIF"); - MF.WriteLine("build_dirs: $(BUILD_DIR) $(BUILD_DIRS_SUB)"); - MF.WriteBlankLines(1); - - TF = FSO.OpenTextFile("Makefile.objects", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - TF = FSO.OpenTextFile("Makefile.extensions", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - MF.Close(); - - FSO.DeleteFile("Makefile.objects"); - FSO.DeleteFile("Makefile.extensions"); -} - -function copy_and_subst(srcname, destname, subst_array) { - - if (!FSO.FileExists(srcname)) { - srcname = configure_module_dirname + "\\" + srcname; - destname = configure_module_dirname + "\\" + destname; - } - - var content = file_get_contents(srcname); - var i; - - for (i = 0; i < subst_array.length; i+=2) { - var re = subst_array[i]; - var rep = subst_array[i+1]; - - content = content.replace(re, rep); - } - - var f = FSO.CreateTextFile(destname, true); - f.Write(content); - f.Close(); -} - -// glob using simple filename wildcards; returns an array of matches found in the filesystem -function glob(path_pattern) { - - var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); - var p; - var base = ""; - var is_pat_re = /\*/; - - if (FSO.FileExists(path_pattern)) { - return new Array(path_pattern); - } - - // first, build as much as possible that doesn't have a pattern - for (p = 0; p < path_parts.length; p++) { - if (path_parts[p].match(is_pat_re)) - break; - if (p) - base += "\\"; - base += path_parts[p]; - } - - return _inner_glob(base, p, path_parts); -} - -function _inner_glob(base, p, parts) { - - var pat = parts[p]; - var full_name = base + "\\" + pat; - var re = null; - var items = null; - - if (p == parts.length) { - return false; - } - - if (FSO.FileExists(full_name)) { - if (p < parts.length - 1) { - // we didn't reach the full extent of the pattern - return false; - } - return new Array(full_name); - } - - if (FSO.FolderExists(full_name) && p == parts.length - 1) { - // we have reached the end of the pattern; no need to recurse - return new Array(full_name); - } - - // Convert the pattern into a regexp - re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); - - items = new Array(); - - if (!FSO.FolderExists(base)) { - return false; - } - - var folder = FSO.GetFolder(base); - var fc = null; - var subitems = null; - var item_name = null; - var j; - - fc = new Enumerator(folder.SubFolders); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - - if (item_name.match(re)) { - // got a match; if we are at the end of the pattern, just add these - // things to the items array - if (p == parts.length - 1) { - items[items.length] = fc.item(); - } else { - // we should recurse and do more matches - subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); - if (subitems) { - for (j = 0; j < subitems.length; j++) { - items[items.length] = subitems[j]; - } - } - } - } - } - - // if we are at the end of the pattern, we should match files too - if (p == parts.length - 1) { - fc = new Enumerator(folder.Files); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - if (item_name.match(re)) { - items[items.length] = fc.item(); - } - } - } - - if (items.length == 0) - return false; - - return items; -} - -/* Emits rule to generate version info for an extension. -Returns the name of the .res file that will be generated */ -function generate_version_info_resource(makefiletarget, creditspath) { - - // makefiletarget is php-gtk.dll - // creditspath is ext\gtk+ - - var resname = makefiletarget + ".res"; - var res_desc = "PHP-GTK Script Interpreter"; - var res_prod_name = "PHP-GTK"; - var credits; - var thanks = "Thanks to Andrei Zmievski"; - var logo = ""; - - if (FSO.FileExists(creditspath + '/CREDITS')) { - credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); - res_desc = credits.ReadLine(); - try { - thanks = credits.ReadLine(); - } catch (e) { - thanks = null; - } - if (thanks == null) { - thanks = ""; - } else { - thanks = "Thanks to " + thanks; - } - credits.Close(); - } - - MFO.WriteLine("PHPGTKDLL_RES=$(BUILD_DIR)\\$(PHPGTKDLL).res"); - MFO.WriteBlankLines(1); - - if (makefiletarget.match(new RegExp("\\.exe$"))) { - logo = " /D WANT_LOGO"; - } - - MFO.WriteLine("$(PHPGTKDLL_RES): win32\\template.rc"); - MFO.WriteLine("\t$(RC) /fo $(PHPGTKDLL_RES)" + logo + ' /D FILE_DESCRIPTION="\\"' + res_desc + '\\"" /D FILE_NAME="\\"$(PHPGTKDLL)\\"" /D PRODUCT_NAME="\\"' + res_prod_name + '\\"" /D THANKS_GUYS="\\"' + thanks + '\\"" win32\\template.rc'); - MFO.WriteBlankLines(1); - - return resname; -} - -/* execute a command and return the output as a string */ -function execute(command_line) { - var e = WshShell.Exec(command_line); - var ret = ""; - - ret = e.StdOut.ReadAll(); - - return ret; -} - -// Which version of the compiler do we have? +// Utils for configure script +/* + +----------------------------------------------------------------------+ + | PHP-GTK Version 2 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2005 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 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_0.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. | + +----------------------------------------------------------------------+ + | Author: Wez Furlong <wez@thebrainroom.com> | + +----------------------------------------------------------------------+ +*/ + +// $Id: confutils.js,v 1.24 2008-08-01 14:34:43 auroraeosrose Exp $ + +/* set vars */ +var STDOUT = WScript.StdOut; +var STDERR = WScript.StdErr; +var WshShell = WScript.CreateObject("WScript.Shell"); +var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var MFO = null; +var MFE = null; +var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); +var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); + +if (PROGRAM_FILES == null) { + PROGRAM_FILES = "C:\\Program Files"; +} + +var CWD = WshShell.CurrentDirectory; + +if (typeof(CWD) == "undefined") { + CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("buildconf.bat")); +} + +configure_args = new Array(); +configure_subst = WScript.CreateObject("Scripting.Dictionary"); + +configure_hdr = WScript.CreateObject("Scripting.Dictionary"); +build_dirs = new Array(); +make_builds = new Array(); + +extension_include_code = ""; +extension_module_ptrs = ""; + +/* functions */ + +function get_gtk_libversion() +{ + var env, i, vin, major, minor; + var found = false; + + found = CHECK_HEADER("gtk/gtkversion.h"); + + if (found) { + STDOUT.WriteLine(" <in default path>"); + vin = file_get_contents(found + "\\gtk\\gtkversion.h"); + + regex = new RegExp("GTK_MAJOR_VERSION\\s+\\(([0-9]+)\\)"); + regex.exec(vin); + major = RegExp.$1; + if (major < 2) + major = 2; + + regex = new RegExp("GTK_MINOR_VERSION\\s+\\(([0-9]+)\\)"); + regex.exec(vin); + minor = RegExp.$1; + if (minor < 6) + minor = 6; + + if (major >= 2 && minor >=8) { + ENABLE_CAIRO = 1; + } else { + ENABLE_CAIRO = 0; + } + PHP_GTK_LIBVERSION = major + '.' + minor; + } else { + STDOUT.WriteLine(" <not found>"); + PHP_GTK_LIBVERSION = '2.6'; + } + + STDOUT.Write("Library definitions for " + PHP_GTK_LIBVERSION + " will be used"); + STDERR.WriteBlankLines(1); +} + +function generate_source() { + + if (!FSO.FileExists("ext\\gtk+\\complete.txt")) { + if (!FSO.FileExists("win32\\temp.bat")) { + STDERR.WriteLine("Run buildconf first - the source file generator is missing"); + WScript.Quit(10); + } else { + var temp = FSO.OpenTextFile("win32\\temp.bat", 8); + temp.WriteLine("@echo off > source_complete.txt"); + temp.Close(); + WshShell.Run("win32\\temp", 0); + } + } + return; +} + +function check_generation() { + + if (!FSO.FileExists("source_complete.txt")) { + STDOUT.WriteLine("Waiting for source files to generate..."); + WScript.Sleep(3500); + check_generation(); + } + return; +} + +function get_version_numbers() { + + /* pick up the version from main/php_gtk.h */ + var vin = file_get_contents("main\\php_gtk.h"); + var version, version_strings, major, minor, details, release = "", extra = ""; + + if (vin.match(new RegExp("PHP_GTK_VERSION \"([^\"]+)\""))) { + version = RegExp.$1; + version_strings = version.split("."); + + major = version_strings[0]; + minor = version_strings[1]; + details = version_strings[2]; + + for (i = 0; i < details.length; i++) { + if(!isNaN(details.charAt(i))) { + release = release + details.charAt(i); + } else { + extra = details.substring(i); + break; + } + } + } + + var vfile = FSO.CreateTextFile("main/php_gtk_version.h", true); + vfile.WriteLine("/* This file is automatically generated during win32 configuration */"); + vfile.WriteLine("/* Edit php_gtk.h to change the version number */"); + vfile.WriteLine("#define PHP_GTK_MAJOR_VERSION " + major); + vfile.WriteLine("#define PHP_GTK_MINOR_VERSION " + minor); + vfile.WriteLine("#define PHP_GTK_RELEASE_VERSION " + release); + if (PHP_GTK_DEBUG == "yes") { + vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + " (DEBUG)\""); + } else { + vfile.WriteLine("#define PHP_GTK_EXTRA_VERSION \"" + extra + "\""); + } + + DEFINE('PHP_GTK_VERSION_STRING', version); +} + +function condense_path(path) { + + path = FSO.GetAbsolutePathName(path); + + if (path.substr(0, CWD.length).toLowerCase() + == CWD.toLowerCase() && + (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { + return path.substr(CWD.length + 1); + } + + var a = CWD.split("\\"); + var b = path.split("\\"); + var i, j; + + for (i = 0; i < b.length; i++) { + if (a[i].toLowerCase() == b[i].toLowerCase()) + continue; + if (i > 0) { + /* first difference found */ + path = ""; + for (j = 0; j < a.length - i; j++) { + path += "..\\"; + } + for (j = i; j < b.length; j++) { + path += b[j]; + if (j < b.length - 1) + path += "\\"; + } + return path; + } + /* on a different drive */ + break; + } + + return path; +} + +function ConfigureArg(type, optname, helptext, defval) { + + var opptype = ""; + + if (type) { + + opptype = type == "enable" ? "disable" : "without"; + + if (defval == "yes" || defval == "yes,shared") { + this.arg = "--" + opptype + "-" + optname; + this.imparg = "--" + type + "-" + optname; + } else { + this.arg = "--" + type + "-" + optname; + this.imparg = "--" + opptype + "-" + optname; + } + } else { + this.arg = "--" + optname; + } + + this.optname = optname; + this.helptext = helptext; + this.defval = defval; + this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); + this.seen = false; + this.argval = defval; +} + +function analyze_arg(argval) { + + var ret = new Array(); + + if (argval == "shared") { + argval = "yes"; + } else if (argval == null) { + /* nothing */ + } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { + argval = arg_match[1]; + } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { + argval = arg_match[1]; + } + + ret[0] = argval; + return ret; +} + +function conf_process_args() { + + var i, j; + var configure_help_mode = false; + var analyzed = false; + var nice = "cscript /nologo configure.js "; + + args = WScript.Arguments; + + for (i = 0; i < args.length; i++) { + arg = args(i); + nice += ' "' + arg + '"'; + if (arg == "--help") { + configure_help_mode = true; + break; + } + + // If it is --foo=bar, split on the equals sign + arg = arg.split("=", 2); + argname = arg[0]; + if (arg.length > 1) { + argval = arg[1]; + } else { + argval = null; + } + + // Find the arg + found = false; + for (j = 0; j < configure_args.length; j++) { + if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { + found = true; + + arg = configure_args[j]; + arg.seen = true; + + analyzed = analyze_arg(argval); + argval = analyzed[0]; + + if (argname == arg.imparg) { + /* we matched the implicit, or default arg */ + if (argval == null) { + argval = arg.defval; + } + } else { + /* we matched the non-default arg */ + if (argval == null) { + argval = arg.defval == "no" ? "yes" : "no"; + } + } + + arg.argval = argval; + eval("PHP_GTK_" + arg.symval + " = argval;"); + break; + } + } + if (!found) { + STDERR.WriteLine("Unknown option " + argname); + STDERR.WriteLine("Please try configure.js --help for a list of valid options"); + WScript.Quit(2); + } + } + + if (configure_help_mode) { + + STDOUT.WriteBlankLines(1); + + // Measure width to pretty-print the output + max_width = 0; + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.arg.length > max_width) { + max_width = arg.arg.length; + } + } + + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + + n = max_width - arg.arg.length; + pad = " "; + for (j = 0; j < n; j++) { + pad += " "; + } + STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); + } + WScript.Quit(1); + } + + // Now set any defaults we might have missed out earlier + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.seen) + continue; + analyzed = analyze_arg(arg.defval); + argval = analyzed[0]; + + eval("PHP_GTK_" + arg.symval + " = argval;"); + } + + MFO = FSO.CreateTextFile("Makefile.objects", true); + MFE = FSO.CreateTextFile("Makefile.extensions", true); + + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Saving configure options to configure.bat"); + var nicefile = FSO.CreateTextFile("configure.bat", true); + nicefile.WriteLine(nice); + nicefile.Close(); + + AC_DEFINE('CONFIGURE_COMMAND', nice); +} + +function find_pattern_in_path(pattern, path) { + + if (path == null) { + return false; + } + + var dirs = path.split(';'); + var i; + var items; + + for (i = 0; i < dirs.length; i++) { + items = glob(dirs[i] + "\\" + pattern); + if (items) { + return condense_path(items[0]); + } + } + return false; +} + +function ARG_IS(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("", optname, helptext, defval); +} + +function ARG_WITH(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); +} + +function ARG_ENABLE(optname, helptext, defval) { + + configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); +} + +function DEFINE(name, value) { + + if (configure_subst.Exists(name)) { + configure_subst.Remove(name); + } + configure_subst.Add(name, value); +} + +function AC_DEFINE(name, value, comment, quote) { + + if (quote == null) { + quote = true; + } + if (quote && typeof(value) == "string") { + value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; + } else if (value.length == 0) { + value = '""'; + } + var item = new Array(value, comment); + if (configure_hdr.Exists(name)) { + var orig_item = configure_hdr.Item(name); + STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + item[0]); + } else { + configure_hdr.Add(name, item); + } +} + +function PATH_PROG(progname, additional_paths, symbol) { + + var exe; + var place; + var cyg_path = PHP_GTK_CYGWIN + "\\bin;" + PHP_GTK_CYGWIN + "\\usr\\local\\bin"; + + exe = progname + ".exe"; + + if (additional_paths == null) { + additional_paths = cyg_path; + } else { + additional_paths += ";" + cyg_path; + } + + place = search_paths(exe, additional_paths, "PATH"); + + if (place == true) { + place = exe; + } else if (place != false) { + + if (place.lastIndexOf("\\") != place.length - 1) { + place += "\\"; + } + + place = place + exe; + + if (place.indexOf(" ")) { + place = '"' + place + '"'; + } + } + + if (place) { + if (symbol == null) { + symbol = progname.toUpperCase(); + } + DEFINE(symbol, place); + } + return place; +} + +function CHECK_LIB(libnames, target, path_to_check, common_name) { + + STDOUT.Write("Checking for " + libnames + " ... "); + + if (common_name == null && target != null) { + common_name = target; + } + + if (path_to_check == null) { + path_to_check = ""; + } + + // if they specified a common name for the package that contains + // the library, tag some useful defaults on to the end of the + // path to be searched + if (common_name != null) { + path_to_check += ";..\\" + common_name + "*"; + } + + // Determine target for build flags + if (target == null) { + target = ""; + } else { + target = "_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); + } + + // Expand path to include general dirs + path_to_check += ";" + php_usual_lib_suspects; + + // It is common practice to put libs under one of these dir names + var subdirs = new Array(PHP_GTK_DEBUG == "yes" ? "Debug" : "Release", "lib", "libs", "libexec"); + + // libnames can be ; separated list of accepted library names + libnames = libnames.split(';'); + + var i, j, k, libname; + var location = false; + var path = path_to_check.split(';'); + + for (i = 0; i < libnames.length; i++) { + libname = libnames[i]; + + for (k = 0; k < path.length; k++) { + location = glob(path[k] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + for (j = 0; j < subdirs.length; j++) { + location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + } + if (location) + break; + } + + if (location) { + location = condense_path(location); + var libdir = FSO.GetParentFolderName(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine( location); + + return location; + } + + // Check in their standard lib path + location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); + + if (location) { + location = condense_path(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine(" <in LIB path> " + libname); + return location; + } + } + + ERROR(" " + libname + " not found - aborting configure process"); + + return false; +} + +function CHECK_HEADER(header_name, path_to_check) { + if (!path_to_check) { + path_to_check = php_usual_include_suspects; + } + + var path = search_paths(header_name, path_to_check, "INCLUDE"); + + if (!path) { + ERROR(" " + header_name + " not found - aborting configure process"); + } + + return path; +} + +// use this for version checking +function GREP_HEADER(header_name, regex, path_to_check) { + + var c = false; + + if (FSO.FileExists(path_to_check + "\\" + header_name)) { + c = file_get_contents(path_to_check + "\\" + header_name); + } + + if (!c) { + /* look in the include path */ + + var p = search_paths(header_name, path_to_check, "INCLUDE"); + + if (typeof(p) == "string") { + c = file_get_contents(p); + } + + if (!c) { + return false; + } + } + + if (typeof(regex) == "string") { + regex = new RegExp(regex); + } + + if (c.match(regex)) { + /* caller can now use RegExp.$1 etc. to get at patterns */ + return true; + } + return false; +} + +function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) { + + var dir_part_to_add = ""; + + if (use_env == null) { + use_env = true; + } + + // if true, add the dir part of the header_name to the include path + if (add_dir_part == null) { + add_dir_part = false; + } else if (add_dir_part) { + var basename = FSO.GetFileName(header_name); + dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); + } + + if (path_to_check == null) { + path_to_check = php_usual_include_suspects; + } else { + path_to_check += ";" + php_usual_include_suspects; + } + + var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); + var have = 0; + var sym; + + if (typeof(p) == "string") { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } + + have = p ? 1 : 0 + + sym = header_name.toUpperCase(); + sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); + + if (typeof(add_to_flag_only) == undefined && + flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { + add_to_flag_only = true; + } + + if (typeof(add_to_flag_only) != "undefined") { + ADD_FLAG(flag_name, "/D HAVE_" + sym + "=" + have); + } else { + AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); + } + + return p; +} + +function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) { + + var dllflags = ""; + var dep_libs = ""; + var EXT = extname.toUpperCase().replace(new RegExp("-", "g"), "_"); + var extname_for_printing; + var res_var = ""; + var file; + + if (cflags == null) { + cflags = ""; + } + + if (typeof(obj_dir) == "undefined") { + + extname_for_printing = configure_module_dirname; + + } else { + + extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; + } + + STDOUT.WriteLine("Enabling extension " + extname_for_printing); + + if (extname == 'php-gtk') { + cflags = "/D COMPILE_DL_" + EXT + "2 /D " + EXT + "_EXPORTS=1" + cflags; + file = MFO; + } else { + cflags = "/D PHP_GTK_COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1" + cflags; + file = MFE; + } + + file.WriteBlankLines(1); + file.WriteLine("# objects for EXT " + extname); + file.WriteBlankLines(1); + + ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); + + file.WriteBlankLines(1); + + // PHP-GTK and its extensions are always built as shared for now + + if (dllname == null) { + if (extname == 'php-gtk') { + dllname = "php_gtk2.dll"; + resname = generate_version_info_resource(dllname, configure_module_dirname); + res_var = " $(PHPGTKDLL_RES)"; + } else { + cflags = "/D GTK_SHARED=1 " + cflags; + dllname = "php_gtk_" + extname + "2.dll"; + dllflags = " $(DLL_LDFLAGS)"; + dep_libs = " $(BUILD_DIR)\\$(PHPGTKLIB) $(LIBS_PHP_GTK)"; + } + } + var libname = dllname.substring(0, dllname.length - 4) + ".lib"; + var ld = "@$(LD)"; + + ADD_FLAG("EXT_TARGETS", "$(BUILD_DIR)\\" + dllname); + make_builds[make_builds.length] = extname + ": $(BUILD_DIR)\\" + dllname; + + file.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(" + EXT + "_GLOBAL_OBJS)" + res_var); + file.WriteLine("\t" + ld + " /out:$(BUILD_DIR)\\" + dllname + " $(LDFLAGS_" + EXT + ")" + dllflags + " $(LDFLAGS) $(" + EXT + "_GLOBAL_OBJS) $(LIBS_" + EXT + ")" + dep_libs + " $(LIBS)" + res_var); + + file.WriteBlankLines(1); + file.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); + file.WriteLine("\t@echo EXT " + extname + " build complete"); + file.WriteBlankLines(1); + + ADD_FLAG("CFLAGS_" + EXT, cflags); +} + +function ADD_SOURCES(dir, file_list, target, obj_dir) { + + var i; + var tv; + var src, obj, sym, flags; + var core_cflags = ""; + var file; + + sym = target.toUpperCase().replace(new RegExp("-", "g"), "_") + "_GLOBAL_OBJS"; + flags = "CFLAGS_" + target.toUpperCase().replace(new RegExp("-", "g"), "_"); + + if (configure_subst.Exists(sym)) { + tv = configure_subst.Item(sym); + } else { + tv = ""; + } + + if (target != "php-gtk") { + file = MFE; + core_cflags = "$(CFLAGS_PHP_GTK) "; + } else { + file = MFO; + } + + file_list = file_list.split(new RegExp("\\s+")); + file_list.sort(); + + var re = new RegExp("\.[a-z0-9A-Z\-]+$"); + + dir = dir.replace(new RegExp("/", "g"), "\\"); + var objs_line = ""; + var srcs_line = ""; + + var sub_build = "$(BUILD_DIR)\\"; + + /* if module dir is not a child of the main source dir, + * we need to tweak it; we should have detected such a + * case in condense_path and rewritten the path to + * be relative. + * This probably breaks for non-sibling dirs */ + if (obj_dir == null) { + var build_dir = dir.replace(new RegExp("^..\\\\"), ""); + } else { + var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); + } + + var mangle_dir = build_dir.replace(new RegExp("[\\\\/.+-]", "g"), "_"); + + /* kill trailing underscores */ + if (mangle_dir.substring(mangle_dir.length - 1) == "_") { + mangle_dir = mangle_dir.substring(0, mangle_dir.length - 1); + } + + var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); + + var dirs = build_dir.split("\\"); + var i, d = ""; + for (i = 0; i < dirs.length; i++) { + d += dirs[i]; + build_dirs[build_dirs.length] = d; + d += "\\"; + } + sub_build += d; + + DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build); + + for (i in file_list) { + src = file_list[i]; + obj = src.replace(re, ".obj"); + tv += " " + sub_build + obj; + + file.WriteLine(sub_build + obj + ": " + dir + "\\" + src); + file.WriteLine("\t@$(CC) $(" + flags + ") " + core_cflags + "$(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); + } + + DEFINE(sym, tv); +} + +function ADD_FLAG(name, flags, target) { + + if (target != null) { + name = target.toUpperCase() + "_" + name; + } + if (configure_subst.Exists(name)) { + var curr_flags = configure_subst.Item(name); + + if (curr_flags.indexOf(flags) >= 0) { + return; + } + + flags = flags + " " + curr_flags; + configure_subst.Remove(name); + } + configure_subst.Add(name, flags); +} + +function get_define(name) { + + return configure_subst.Item(name); +} + +function ERROR(msg) { + + STDERR.WriteBlankLines(2); + STDERR.WriteLine("ERROR: " + msg); + WScript.Quit(3); +} + +function WARNING(msg) { + + STDERR.WriteLine("WARNING: " + msg); + STDERR.WriteBlankLines(1); +} + +/* Searches a set of paths for a file; returns the dir in which the file was found, true if it +was found in the default env path, or false if it was not found at all. env_name is the optional +name of an env var specifying the default path to search */ +function search_paths(thing_to_find, explicit_path, env_name) { + + var i, found = false, place = false, file, env; + + STDOUT.Write("Checking for " + thing_to_find + " ... "); + + if (thing_to_find.length < 6) { + STDOUT.Write(" "); + } + + thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); + + if (explicit_path != null) { + if (typeof(explicit_path) == "string") { + explicit_path = explicit_path.split(";"); + } + + for (i = 0; i < explicit_path.length; i++) { + file = glob(explicit_path[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = file[0]; + place = place.substr(0, place.length - thing_to_find.length - 1); + break; + } + } + } + + if (!found && env_name != null) { + env = WshShell.Environment("Process").Item(env_name); + env = env.split(";"); + for (i = 0; i < env.length; i++) { + file = glob(env[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = true; + break; + } + } + } + + if (found && place == true) { + STDOUT.WriteLine(" <in default path>"); + place = file[0]; + place = place.substr(0, place.length - thing_to_find.length - 1); + } else if (found) { + STDOUT.WriteLine(" " + place); + } else { + STDOUT.WriteLine(" <not found>"); + } + return place; +} + +function word_wrap_and_indent(indent, text, line_suffix, indent_char) { + + if (text == null) { + return ""; + } + + var words = text.split(new RegExp("\\s+", "g")); + var i = 0; + var ret_text = ""; + var this_line = ""; + var t; + var space = ""; + var lines = 0; + + if (line_suffix == null) { + line_suffix = ""; + } + + if (indent_char == null) { + indent_char = " "; + } + + for (i = 0; i < indent; i++) { + space += indent_char; + } + + for (i = 0; i < words.length; i++) { + if (this_line.length) { + t = this_line + " " + words[i]; + } else { + t = words[i]; + } + + if (t.length + indent > 78) { + if (lines++) { + ret_text += space; + } + ret_text += this_line + line_suffix + "\r\n"; + this_line = ""; + } + + if (this_line.length) { + this_line += " " + words[i]; + } else { + this_line = words[i]; + } + } + + if (this_line.length) { + if (lines) + ret_text += space; + ret_text += this_line; + } + + return ret_text; +} + +function file_get_contents(filename) { + + var f, c; + + try { + f = FSO.OpenTextFile(filename, 1); + c = f.ReadAll(); + f.Close(); + return c; + } catch (e) { + STDOUT.WriteLine("Problem reading " + filename); + return false; + } +} + +function generate_files() { + + var i, dir, bd, last; + + generate_source(); + + STDOUT.WriteLine("Generating source files - this may take a few seconds"); + WScript.Sleep(3500); + check_generation(); + + // Check to see if we have additional objects to add + var sources = file_get_contents("sources.temp"); + configure_module_dirname = condense_path("ext\\gtk+\\"); + EXTENSION("php-gtk", php_gtk_files + sources, true); + + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Creating build dirs..."); + dir = get_define("BUILD_DIR"); + build_dirs.sort(); + last = null; + + if (!FSO.FolderExists(dir)) { + FSO.CreateFolder(dir); + } + + for (i = 0; i < build_dirs.length; i++) { + bd = FSO.BuildPath(dir, build_dirs[i]); + if (bd == last) { + continue; + } + last = bd; + ADD_FLAG("BUILD_DIRS_SUB", bd); + if (!FSO.FolderExists(bd)) { + FSO.CreateFolder(bd); + } + } + + generate_makefile(); + + STDOUT.WriteLine("Done."); + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Type 'nmake' to build all targets, or 'nmake php-gtk' to build PHP-GTK alone"); + STDOUT.WriteLine("* Configured PHP-GTK extensions can be built individually at a later stage *"); +} + +function generate_makefile() { + + MFE.WriteLine(""); // To avoid error if MFE will be complete + MFE.Close(); // Makefile.extensions is now complete + MFO.Close(); // Makefile.objects is now complete + var MF = FSO.CreateTextFile("Makefile", true); + STDOUT.WriteLine("Generating Makefile"); + + MF.WriteLine("# Generated by configure.js"); + MF.WriteBlankLines(1); + + /* spit out variable definitions */ + var keys = (new VBArray(configure_subst.Keys())).toArray(); + var i; + + for (i in keys) { + /* The trailing space is needed to prevent the trailing backslash that is part of + the build dir flags (CFLAGS_BD_XXX) from being seen as a line continuation character */ + MF.WriteLine(keys[i] + "=" + configure_subst.Item(keys[i]) + " "); + } + + MF.WriteBlankLines(1); + MF.WriteLine("all: $(EXT_TARGETS)"); + + for (i = make_builds.length; i >= 0; i--) { + if (i == make_builds.length) { + MF.WriteLine("!IF EXIST($(BUILD_DIR)\\$(PHPGTKLIB))"); + } + MF.WriteLine(make_builds[i]); + } + + if (make_builds.length > 1) { + MF.WriteLine("!ELSE"); + MF.WriteLine("!MESSAGE Note: $(PHPGTKLIB) must be created before PHP-GTK extensions can be built"); + } + + MF.WriteLine("!ENDIF"); + MF.WriteLine("build_dirs: $(BUILD_DIR) $(BUILD_DIRS_SUB)"); + MF.WriteBlankLines(1); + + TF = FSO.OpenTextFile("Makefile.objects", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + TF = FSO.OpenTextFile("Makefile.extensions", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + MF.Close(); + + FSO.DeleteFile("Makefile.objects"); + FSO.DeleteFile("Makefile.extensions"); +} + +function copy_and_subst(srcname, destname, subst_array) { + + if (!FSO.FileExists(srcname)) { + srcname = configure_module_dirname + "\\" + srcname; + destname = configure_module_dirname + "\\" + destname; + } + + var content = file_get_contents(srcname); + var i; + + for (i = 0; i < subst_array.length; i+=2) { + var re = subst_array[i]; + var rep = subst_array[i+1]; + + content = content.replace(re, rep); + } + + var f = FSO.CreateTextFile(destname, true); + f.Write(content); + f.Close(); +} + +// glob using simple filename wildcards; returns an array of matches found in the filesystem +function glob(path_pattern) { + + var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); + var p; + var base = ""; + var is_pat_re = /\*/; + + if (FSO.FileExists(path_pattern)) { + return new Array(path_pattern); + } + + // first, build as much as possible that doesn't have a pattern + for (p = 0; p < path_parts.length; p++) { + if (path_parts[p].match(is_pat_re)) + break; + if (p) + base += "\\"; + base += path_parts[p]; + } + + return _inner_glob(base, p, path_parts); +} + +function _inner_glob(base, p, parts) { + + var pat = parts[p]; + var full_name = base + "\\" + pat; + var re = null; + var items = null; + + if (p == parts.length) { + return false; + } + + if (FSO.FileExists(full_name)) { + if (p < parts.length - 1) { + // we didn't reach the full extent of the pattern + return false; + } + return new Array(full_name); + } + + if (FSO.FolderExists(full_name) && p == parts.length - 1) { + // we have reached the end of the pattern; no need to recurse + return new Array(full_name); + } + + // Convert the pattern into a regexp + re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); + + items = new Array(); + + if (!FSO.FolderExists(base)) { + return false; + } + + var folder = FSO.GetFolder(base); + var fc = null; + var subitems = null; + var item_name = null; + var j; + + fc = new Enumerator(folder.SubFolders); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + + if (item_name.match(re)) { + // got a match; if we are at the end of the pattern, just add these + // things to the items array + if (p == parts.length - 1) { + items[items.length] = fc.item(); + } else { + // we should recurse and do more matches + subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); + if (subitems) { + for (j = 0; j < subitems.length; j++) { + items[items.length] = subitems[j]; + } + } + } + } + } + + // if we are at the end of the pattern, we should match files too + if (p == parts.length - 1) { + fc = new Enumerator(folder.Files); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + if (item_name.match(re)) { + items[items.length] = fc.item(); + } + } + } + + if (items.length == 0) + return false; + + return items; +} + +/* Emits rule to generate version info for an extension. +Returns the name of the .res file that will be generated */ +function generate_version_info_resource(makefiletarget, creditspath) { + + // makefiletarget is php-gtk.dll + // creditspath is ext\gtk+ + + var resname = makefiletarget + ".res"; + var res_desc = "PHP-GTK Script Interpreter"; + var res_prod_name = "PHP-GTK"; + var credits; + var thanks = "Thanks to Andrei Zmievski"; + var logo = ""; + + if (FSO.FileExists(creditspath + '/CREDITS')) { + credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); + res_desc = credits.ReadLine(); + try { + thanks = credits.ReadLine(); + } catch (e) { + thanks = null; + } + if (thanks == null) { + thanks = ""; + } else { + thanks = "Thanks to " + thanks; + } + credits.Close(); + } + + MFO.WriteLine("PHPGTKDLL_RES=$(BUILD_DIR)\\$(PHPGTKDLL).res"); + MFO.WriteBlankLines(1); + + if (makefiletarget.match(new RegExp("\\.exe$"))) { + logo = " /D WANT_LOGO"; + } + + MFO.WriteLine("$(PHPGTKDLL_RES): win32\\template.rc"); + MFO.WriteLine("\t$(RC) /fo $(PHPGTKDLL_RES)" + logo + ' /D FILE_DESCRIPTION="\\"' + res_desc + '\\"" /D FILE_NAME="\\"$(PHPGTKDLL)\\"" /D PRODUCT_NAME="\\"' + res_prod_name + '\\"" /D THANKS_GUYS="\\"' + thanks + '\\"" win32\\template.rc'); + MFO.WriteBlankLines(1); + + return resname; +} + +/* execute a command and return the output as a string */ +function execute(command_line) { + var e = WshShell.Exec(command_line); + var ret = ""; + + ret = e.StdOut.ReadAll(); + + return ret; +} + +// Which version of the compiler do we have? function probe_msvc_compiler_version(CL) { - var command = 'cmd /c ""' + CL + '" -v"'; - var version = execute(command + '" 2>&1"'); + var command = 'cmd /c ' + CL + ' -v'; + var version = execute(command + ' 2>&1'); if (version.match(/(\d+\.\d+)/)) { return RegExp.$1.split(".").join(""); } - - return 0; -} - -// Poke around for some headers -function probe_basic_headers() -{ - var p; - - // hack to catch common location of libs - if (typeof(p) == "string") { - p = p.replace(new RegExp("include$"), "lib"); - ADD_FLAG("LDFLAGS", '/libpath:"' + p + '" '); - php_usual_lib_suspects += ";" + p; - } - - // Make sure that tsrm, main and ZEND get added to the includes - var php_dir = CHECK_HEADER('Zend/zend.h'); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\TSRM" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\main" '); - ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\Zend" '); -} - -/* non-functions */ - -if (!FSO.FileExists("buildconf.bat")) { - STDERR.WriteLine("Must be run from the root of the PHP-GTK source"); - WScript.Quit(10); -} + + return 0; +} + +// Poke around for some headers +function probe_basic_headers() +{ + var p; + + // hack to catch common location of libs + if (typeof(p) == "string") { + p = p.replace(new RegExp("include$"), "lib"); + ADD_FLAG("LDFLAGS", '/libpath:"' + p + '" '); + php_usual_lib_suspects += ";" + p; + } + + // Make sure that tsrm, main and ZEND get added to the includes + var php_dir = CHECK_HEADER('Zend/zend.h'); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\TSRM" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\main" '); + ADD_FLAG('CFLAGS', '/I "' + php_dir + '\\Zend" '); +} + +/* non-functions */ + +if (!FSO.FileExists("buildconf.bat")) { + STDERR.WriteLine("Must be run from the root of the PHP-GTK source"); + WScript.Quit(10); +}