Revision: 5987 http://geany.svn.sourceforge.net/geany/?rev=5987&view=rev Author: ntrel Date: 2011-10-03 14:35:11 +0000 (Mon, 03 Oct 2011) Log Message: ----------- * Merge branches/unstable: - tagmanager/php.c: Fix parsing keyword-qualified functions strictly, e.g. don't parse 'staticfunction' or 'fatfunction'. - src/utils.c, src/utils.h, src/editor.c: Use GRegex for snippet indentation replacement - fixes wrong behaviour with Mac line endings. - tagmanager/lregex.c, TODO: Use GRegex for CTags instead of POSIX regex - GRegex is more powerful. This also fixes a (HTML) performance issue on Windows. Geany will now print a debug warning when using the "b" CTags regex flag option for non-extended syntax. This is not currently used by Geany's parsers. Note: GNU regex can't be removed yet as it's still used elsewhere by Geany. - src/build.c, doc/pluginsignals.c: When saving on build, prompt for a filename if necessary. Emit the "build-start" signal only if saving succeeds. - src/build.c: Use #ifdef SYNC_SPAWN instead of G_OS_WIN32 for easier testing with glib's asynchronous spawning (which doesn't work on Windows). - src/win32.c, src/win32.h, src/dialogs.c: Use GTK unsaved file dialog on Windows too because the button names should be specific.
Modified Paths: -------------- trunk/ChangeLog trunk/TODO trunk/doc/pluginsignals.c trunk/src/build.c trunk/src/dialogs.c trunk/src/editor.c trunk/src/socket.c trunk/src/utils.c trunk/src/utils.h trunk/src/win32.c trunk/src/win32.h trunk/tagmanager/lregex.c trunk/tagmanager/php.c
Property Changed: ---------------- trunk/
Property changes on: trunk ___________________________________________________________________ Modified: svn:mergeinfo - /branches/build-system:3867-4119 + /branches/build-system:3867-4119 /branches/unstable:5939-5986
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/ChangeLog 2011-10-03 14:35:11 UTC (rev 5987) @@ -1,3 +1,31 @@ +2011-10-03 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com> + + * Merge branches/unstable: + - tagmanager/php.c: + Fix parsing keyword-qualified functions strictly, e.g. don't + parse 'staticfunction' or 'fatfunction'. + - src/utils.c, src/utils.h, src/editor.c: + Use GRegex for snippet indentation replacement - fixes wrong + behaviour with Mac line endings. + - tagmanager/lregex.c, TODO: + Use GRegex for CTags instead of POSIX regex - GRegex is more + powerful. This also fixes a (HTML) performance issue on Windows. + Geany will now print a debug warning when using the "b" CTags + regex flag option for non-extended syntax. This is not currently + used by Geany's parsers. + Note: GNU regex can't be removed yet as it's still used elsewhere + by Geany. + - src/build.c, doc/pluginsignals.c: + When saving on build, prompt for a filename if necessary. + Emit the "build-start" signal only if saving succeeds. + - src/build.c: + Use #ifdef SYNC_SPAWN instead of G_OS_WIN32 for easier testing with + glib's asynchronous spawning (which doesn't work on Windows). + - src/win32.c, src/win32.h, src/dialogs.c: + Use GTK unsaved file dialog on Windows too because the button names + should be specific. + + 2011-10-02 Colomban Wendling <colomban(at)geany(dot)org>
* doc/geany.txt, doc/geany.html:
Modified: trunk/TODO =================================================================== --- trunk/TODO 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/TODO 2011-10-03 14:35:11 UTC (rev 5987) @@ -14,7 +14,7 @@ o common default highlighting styles configurable for all programming languages (done for C-like filetypes using filetypes.common named styles) - o update included regex library (and other CTags improvements) + o use GRegex only and remove GNU regex o asynchronous build commands on Windows o (filetype-independent run command in build dialog & keybinding) o (better custom filetype support)
Modified: trunk/doc/pluginsignals.c =================================================================== --- trunk/doc/pluginsignals.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/doc/pluginsignals.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -187,7 +187,7 @@ */ signal void (*geany_startup_complete)(GObject *obj, gpointer user_data);
-/** Sent before build is started. Plugins can use this signal e.g. to save the opened documents +/** Sent before build is started. A plugin could use this signal e.g. to save all unsaved documents * before the build starts. * * @param obj a GeanyObject instance, should be ignored.
Modified: trunk/src/build.c =================================================================== --- trunk/src/build.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/build.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -64,6 +64,11 @@ #include "toolbar.h" #include "geanymenubuttonaction.h"
+/* g_spawn_async_with_pipes doesn't work on Windows */ +#ifdef G_OS_WIN32 +#define SYNC_SPAWN +#endif + /* Number of editor indicators to draw - limited as this can affect performance */ #define GEANY_BUILD_ERR_HIGHLIGHT_MAX 50
@@ -114,7 +119,7 @@ static gint build_groups_count[GEANY_GBG_COUNT] = { 3, 4, 2 }; static gint build_items_count = 9;
-#ifndef G_OS_WIN32 +#ifndef SYNC_SPAWN static void build_exit_cb(GPid child_pid, gint status, gpointer user_data); static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data); #endif @@ -571,7 +576,7 @@ }
-#ifdef G_OS_WIN32 +#ifdef SYNC_SPAWN static void parse_build_output(const gchar **output, gint status) { guint x, i, len; @@ -590,7 +595,7 @@ { line = lines[i]; while (*line != '\0') - { /* replace any conrol characters in the output */ + { /* replace any control characters in the output */ if (*line < 32) *line = 32; line++; @@ -679,7 +684,7 @@ gchar *utf8_working_dir; gchar *cmd_string; gchar *utf8_cmd_string; -#ifdef G_OS_WIN32 +#ifdef SYNC_SPAWN gchar *output[2]; gint status; #else @@ -726,7 +731,7 @@ build_info.file_type_id = (doc == NULL) ? GEANY_FILETYPES_NONE : doc->file_type->id; build_info.message_count = 0;
-#ifdef G_OS_WIN32 +#ifdef SYNC_SPAWN if (! utils_spawn_sync(working_dir, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &output[0], &output[1], &status, &error)) #else @@ -744,7 +749,7 @@ return (GPid) 0; }
-#ifdef G_OS_WIN32 +#ifdef SYNC_SPAWN parse_build_output((const gchar**) output, status); g_free(output[0]); g_free(output[1]); @@ -1026,7 +1031,7 @@ }
-#ifndef G_OS_WIN32 +#ifndef SYNC_SPAWN static gboolean build_iofunc(GIOChannel *ioc, GIOCondition cond, gpointer data) { if (cond & (G_IO_IN | G_IO_PRI)) @@ -1121,11 +1126,14 @@ }
-#ifndef G_OS_WIN32 +#ifndef SYNC_SPAWN static void build_exit_cb(GPid child_pid, gint status, gpointer user_data) { gboolean failure = FALSE;
+#ifdef G_OS_WIN32 + failure = status; +#else if (WIFEXITED(status)) { if (WEXITSTATUS(status) != EXIT_SUCCESS) @@ -1140,6 +1148,7 @@ { /* any other failure occured */ failure = TRUE; } +#endif show_build_result_message(failure);
utils_beep(); @@ -1261,10 +1270,16 @@ gint grp = GPOINTER_TO_GRP(user_data); gint cmd = GPOINTER_TO_CMD(user_data);
+ if (doc && doc->changed) + { + if (document_need_save_as(doc) && !dialogs_show_save_as()) + return; + + if (!document_save_file(doc, FALSE)) + return; + } g_signal_emit_by_name(geany_object, "build-start");
- if (doc && doc->changed) - document_save_file(doc, FALSE); if (grp == GEANY_GBG_NON_FT && cmd == GBO_TO_CMD(GEANY_GBO_CUSTOM)) { static GtkWidget *dialog = NULL; /* keep dialog for combo history */
Modified: trunk/src/dialogs.c =================================================================== --- trunk/src/dialogs.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/dialogs.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -804,7 +804,6 @@ }
-#ifndef G_OS_WIN32 static gint run_unsaved_dialog(const gchar *msg, const gchar *msg2) { GtkWidget *dialog, *button; @@ -812,6 +811,7 @@
dialog = gtk_message_dialog_new(GTK_WINDOW(main_widgets.window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", msg); + gtk_window_set_title(GTK_WINDOW(dialog), _("Question")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", msg2); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
@@ -828,7 +828,6 @@
return ret; } -#endif
gboolean dialogs_show_unsaved_file(GeanyDocument *doc) @@ -851,12 +850,7 @@ msg2 = _("Do you want to save it before closing?"); g_free(short_fn);
-#ifdef G_OS_WIN32 - setptr(msg, g_strconcat(msg, "\n", msg2, NULL)); - ret = win32_message_dialog_unsaved(msg); -#else ret = run_unsaved_dialog(msg, msg2); -#endif g_free(msg);
switch (ret)
Modified: trunk/src/editor.c =================================================================== --- trunk/src/editor.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/editor.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -2272,63 +2272,18 @@ }
-static gboolean utils_regex_find(regex_t *regex, const gchar *haystack, gsize start, - gsize nmatches, regmatch_t *matches) -{ - gint eflags = 0; - - if (start > 0) - { - gchar c = haystack[start - 1]; - - if (c == '\n' || c == '\r') - eflags = REG_NOTBOL; - } - return regexec(regex, haystack + start, nmatches, matches, eflags) == 0; -} - - -/* match_index: which match to replace, 0 for whole regex. - * note: this doesn't support backreferences in replacements */ -static guint utils_string_regex_replace_all(GString *haystack, - regex_t *regex, guint match_index, const gchar *replace) -{ - gssize pos; - regmatch_t matches[10]; - guint ret = 0; - - g_return_val_if_fail(match_index < 10, 0); - - /* ensure haystack->str is not null */ - if (haystack->len == 0) - return 0; - - pos = 0; - while (utils_regex_find(regex, haystack->str, pos, G_N_ELEMENTS(matches), matches)) - { - regmatch_t *match = &matches[match_index]; - - g_return_val_if_fail(match->rm_so >= 0, FALSE); - pos += match->rm_so; - pos = utils_string_replace(haystack, pos, match->rm_eo - match->rm_so, replace); - ret++; - } - return ret; -} - - static void fix_indentation(GeanyEditor *editor, GString *buf) { const GeanyIndentPrefs *iprefs = editor_get_indent_prefs(editor); gchar *whitespace; - regex_t regex; - gint cflags = REG_EXTENDED | REG_NEWLINE; + GRegex *regex; + gint cflags = G_REGEX_MULTILINE;
/* transform leading tabs into indent widths (in spaces) */ whitespace = g_strnfill(iprefs->width, ' '); - regcomp(®ex, "^ *(\t)", cflags); - while (utils_string_regex_replace_all(buf, ®ex, 1, whitespace)); - regfree(®ex); + regex = g_regex_new("^ *(\t)", cflags, 0, NULL); + while (utils_string_regex_replace_all(buf, regex, 1, whitespace, TRUE)); + g_regex_unref(regex);
/* remaining tabs are for alignment */ if (iprefs->type != GEANY_INDENT_TYPE_TABS) @@ -2343,9 +2298,9 @@ setptr(whitespace, g_strnfill(sci_get_tab_width(editor->sci), ' ')); str = g_strdup_printf("^\t*(%s)", whitespace);
- regcomp(®ex, str, cflags); - while (utils_string_regex_replace_all(buf, ®ex, 1, "\t")); - regfree(®ex); + regex = g_regex_new(str, cflags, 0, NULL); + while (utils_string_regex_replace_all(buf, regex, 1, "\t", TRUE)); + g_regex_unref(regex); g_free(str); } g_free(whitespace);
Modified: trunk/src/socket.c =================================================================== --- trunk/src/socket.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/socket.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -588,7 +588,7 @@ gint fd, sock; gchar buf[BUFFER_LENGTH]; struct sockaddr_in caddr; - guint caddr_len = sizeof(caddr); + socklen_t caddr_len = sizeof(caddr); GtkWidget *window = data; gboolean popup = FALSE;
Modified: trunk/src/utils.c =================================================================== --- trunk/src/utils.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/utils.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -1622,6 +1622,45 @@ }
+/* Similar to g_regex_replace but allows matching a subgroup. + * match_num: which match to replace, 0 for whole match. + * literal: FALSE to interpret escape sequences in @a replace. + * returns: number of replacements. + * bug: replaced text can affect matching of ^ or \b */ +guint utils_string_regex_replace_all(GString *haystack, GRegex *regex, + guint match_num, const gchar *replace, gboolean literal) +{ + GMatchInfo *minfo; + guint ret = 0; + gint start = 0; + + g_assert(literal); /* escapes not implemented yet */ + g_return_val_if_fail(replace, 0); + + /* ensure haystack->str is not null */ + if (haystack->len == 0) + return 0; + + /* passing a start position makes G_REGEX_MATCH_NOTBOL automatic */ + while (g_regex_match_full(regex, haystack->str, -1, start, 0, &minfo, NULL)) + { + gint end, len; + + g_match_info_fetch_pos(minfo, match_num, &start, &end); + len = end - start; + utils_string_replace(haystack, start, len, replace); + ret++; + + /* skip past whole match */ + g_match_info_fetch_pos(minfo, 0, NULL, &end); + start = end - len + strlen(replace); + g_match_info_free(minfo); + } + g_match_info_free(minfo); + return ret; +} + + /* Get project or default startup directory (if set), or NULL. */ const gchar *utils_get_default_dir_utf8(void) {
Modified: trunk/src/utils.h =================================================================== --- trunk/src/utils.h 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/utils.h 2011-10-03 14:35:11 UTC (rev 5987) @@ -178,6 +178,9 @@
guint utils_string_replace_first(GString *haystack, const gchar *needle, const gchar *replace);
+guint utils_string_regex_replace_all(GString *haystack, GRegex *regex, + guint match_num, const gchar *replace, gboolean literal); + void utils_str_replace_all(gchar **haystack, const gchar *needle, const gchar *replacement);
gint utils_strpos(const gchar* haystack, const gchar *needle);
Modified: trunk/src/win32.c =================================================================== --- trunk/src/win32.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/win32.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -732,33 +732,6 @@ }
-/* Special dialog to ask for an action when closing an unsaved file */ -gint win32_message_dialog_unsaved(const gchar *msg) -{ - static wchar_t w_msg[512]; - static wchar_t w_title[512]; - HWND parent_hwnd = NULL; - gint ret; - - /* convert the Unicode chars to wide chars */ - MultiByteToWideChar(CP_UTF8, 0, msg, -1, w_msg, G_N_ELEMENTS(w_msg)); - MultiByteToWideChar(CP_UTF8, 0, _("Question"), -1, w_title, G_N_ELEMENTS(w_title)); - - if (main_widgets.window != NULL) - parent_hwnd = GDK_WINDOW_HWND(main_widgets.window->window); - - ret = MessageBoxW(parent_hwnd, w_msg, w_title, MB_YESNOCANCEL | MB_ICONQUESTION); - switch (ret) - { - case IDYES: ret = GTK_RESPONSE_YES; break; - case IDNO: ret = GTK_RESPONSE_NO; break; - case IDCANCEL: ret = GTK_RESPONSE_CANCEL; break; - } - - return ret; -} - - /* Just a simple wrapper function to open a browser window */ void win32_open_browser(const gchar *uri) {
Modified: trunk/src/win32.h =================================================================== --- trunk/src/win32.h 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/src/win32.h 2011-10-03 14:35:11 UTC (rev 5987) @@ -40,8 +40,6 @@
gboolean win32_message_dialog(GtkWidget *parent, GtkMessageType type, const gchar *msg);
-gint win32_message_dialog_unsaved(const gchar *msg); - void win32_open_browser(const gchar *uri);
gchar *win32_show_project_open_dialog(GtkWidget *parent, const gchar *title,
Modified: trunk/tagmanager/lregex.c =================================================================== --- trunk/tagmanager/lregex.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/tagmanager/lregex.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -28,11 +28,6 @@ # ifdef HAVE_SYS_TYPES_H # include <sys/types.h> /* declare off_t (not known to regex.h on FreeBSD) */ # endif -# ifdef HAVE_REGEX_H -# include <regex.h> -# else -# include "gnuregex.h" -# endif #endif
#include "main.h" @@ -70,7 +65,7 @@ enum pType { PTRN_TAG, PTRN_CALLBACK };
typedef struct { - regex_t *pattern; + GRegex *pattern; enum pType type; union { struct { @@ -113,10 +108,7 @@ for (i = 0 ; i < set->count ; ++i) { regexPattern *p = &set->patterns [i]; -#if defined (POSIX_REGEX) - regfree (p->pattern); -#endif - eFree (p->pattern); + g_regex_unref(p->pattern); p->pattern = NULL;
if (p->type == PTRN_TAG) @@ -255,7 +247,7 @@ }
static void addCompiledTagPattern ( - const langType language, regex_t* const pattern, + const langType language, GRegex* const pattern, char* const name, const char kind, char* const kindName, char *const description) { @@ -287,7 +279,7 @@ }
static void addCompiledCallbackPattern ( - const langType language, regex_t* const pattern, + const langType language, GRegex* const pattern, const regexCallback callback) { patternSet* set; @@ -315,32 +307,27 @@
#if defined (POSIX_REGEX)
-static regex_t* compileRegex (const char* const regexp, const char* const flags) +static GRegex* compileRegex (const char* const regexp, const char* const flags) { - int cflags = REG_EXTENDED | REG_NEWLINE; - regex_t *result = NULL; - int errcode; + int cflags = G_REGEX_MULTILINE; + GRegex *result = NULL; + GError *error = NULL; int i; for (i = 0 ; flags != NULL && flags [i] != '\0' ; ++i) { switch ((int) flags [i]) { - case 'b': cflags &= ~REG_EXTENDED; break; - case 'e': cflags |= REG_EXTENDED; break; - case 'i': cflags |= REG_ICASE; break; + case 'b': g_warning("CTags 'b' flag not supported by Geany!"); break; + case 'e': break; + case 'i': cflags |= G_REGEX_CASELESS; break; default: printf ("regex: unknown regex flag: '%c'\n", *flags); break; } } - result = xMalloc (1, regex_t); - errcode = regcomp (result, regexp, cflags); - if (errcode != 0) + result = g_regex_new(regexp, cflags, 0, &error); + if (error) { - char errmsg[256]; - regerror (errcode, result, errmsg, 256); - printf ("regex: regcomp %s: %s\n", regexp, errmsg); - regfree (result); - eFree (result); - result = NULL; + printf ("regex: regcomp %s: %s\n", regexp, error->message); + g_error_free(error); } return result; } @@ -433,7 +420,7 @@
static vString* substitute ( const char* const in, const char* out, - const int nmatch, const regmatch_t* const pmatch) + const int nmatch, const GMatchInfo* const minfo) { vString* result = vStringNew (); const char* p; @@ -442,10 +429,12 @@ if (*p == '\' && isdigit ((int) *++p)) { const int dig = *p - '0'; - if (0 < dig && dig < nmatch && pmatch [dig].rm_so != -1) + int so, eo; + if (0 < dig && dig < nmatch && + g_match_info_fetch_pos(minfo, dig, &so, &eo) && so != -1) { - const int diglen = pmatch [dig].rm_eo - pmatch [dig].rm_so; - vStringNCatS (result, in + pmatch [dig].rm_so, diglen); + const int diglen = eo - so; + vStringNCatS (result, in + so, diglen); } } else if (*p != '\n' && *p != '\r') @@ -457,10 +446,10 @@
static void matchTagPattern (const vString* const line, const regexPattern* const patbuf, - const regmatch_t* const pmatch) + const GMatchInfo* const minfo) { vString *const name = substitute (vStringValue (line), - patbuf->u.tag.name_pattern, BACK_REFERENCE_COUNT, pmatch); + patbuf->u.tag.name_pattern, BACK_REFERENCE_COUNT, minfo); vStringStripLeading (name); vStringStripTrailing (name); if (vStringLength (name) > 0) @@ -474,15 +463,18 @@
static void matchCallbackPattern ( const vString* const line, const regexPattern* const patbuf, - const regmatch_t* const pmatch) + const GMatchInfo* const minfo) { regexMatch matches [BACK_REFERENCE_COUNT]; unsigned int count = 0; int i; - for (i = 0 ; i < BACK_REFERENCE_COUNT && pmatch [i].rm_so != -1 ; ++i) + for (i = 0 ; i < BACK_REFERENCE_COUNT ; ++i) { - matches [i].start = pmatch [i].rm_so; - matches [i].length = pmatch [i].rm_eo - pmatch [i].rm_so; + int so, eo; + if (!g_match_info_fetch_pos(minfo, i, &so, &eo) || so == -1) + break; + matches [i].start = so; + matches [i].length = eo - so; ++count; } patbuf->u.callback.function (vStringValue (line), matches, count); @@ -492,22 +484,21 @@ const regexPattern* const patbuf) { boolean result = FALSE; - regmatch_t pmatch [BACK_REFERENCE_COUNT]; - const int match = regexec (patbuf->pattern, vStringValue (line), - BACK_REFERENCE_COUNT, pmatch, 0); - if (match == 0) + GMatchInfo *minfo; + if (g_regex_match(patbuf->pattern, vStringValue(line), 0, &minfo)) { result = TRUE; if (patbuf->type == PTRN_TAG) - matchTagPattern (line, patbuf, pmatch); + matchTagPattern (line, patbuf, minfo); else if (patbuf->type == PTRN_CALLBACK) - matchCallbackPattern (line, patbuf, pmatch); + matchCallbackPattern (line, patbuf, minfo); else { Assert ("invalid pattern type" == NULL); result = FALSE; } } + g_match_info_free(minfo); return result; }
@@ -554,7 +545,7 @@ Assert (name != NULL); if (! regexBroken) { - regex_t* const cp = compileRegex (regex, flags); + GRegex* const cp = compileRegex (regex, flags); if (cp != NULL) { char kind; @@ -578,7 +569,7 @@ Assert (regex != NULL); if (! regexBroken) { - regex_t* const cp = compileRegex (regex, flags); + GRegex* const cp = compileRegex (regex, flags); if (cp != NULL) addCompiledCallbackPattern (language, cp, callback); } @@ -695,7 +686,7 @@ /* Check for broken regcomp() on Cygwin */ extern void checkRegex (void) { -#if defined (HAVE_REGEX) && defined (CHECK_REGCOMP) +#if 0 && defined (HAVE_REGEX) && defined (CHECK_REGCOMP) regex_t patbuf; int errcode; if (regcomp (&patbuf, "/hello/", 0) != 0)
Modified: trunk/tagmanager/php.c =================================================================== --- trunk/tagmanager/php.c 2011-10-03 14:14:33 UTC (rev 5986) +++ trunk/tagmanager/php.c 2011-10-03 14:35:11 UTC (rev 5987) @@ -79,10 +79,14 @@ "\1", "m,macro,macros", NULL); addTagRegex(language, "^[ \t]*const[ \t]*([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]", "\1", "m,macro,macros", NULL); - /* Note: Using [] to match words is wrong, but using () doesn't seem to match 'function' on its own */ addCallbackRegex(language, - "^[ \t]*[(public|protected|private|static|final)[ \t]*]*[ \t]*function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)[[:space:]]*(\(.*\))", + "^[ \t]*((public|protected|private|static|final)[ \t]+)+function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)[[:space:]]*(\(.*\))", NULL, function_cb); + /* note: using (qualifiers)* instead of (qualifiers)+ in the above regex doesn't seem to + * match 'function' on its own, so we handle that separately: */ + addCallbackRegex(language, + "^[ \t]*function[ \t]+&?[ \t]*([" ALPHA "_][" ALNUM "_]*)[[:space:]]*(\(.*\))", + NULL, function_cb); addTagRegex(language, "^[ \t]*(\$|::\$|\$this->)([" ALPHA "_][" ALNUM "_]*)[ \t]*=", "\2", "v,variable,variables", NULL); addTagRegex(language, "^[ \t]*((var|public|protected|private|static)[ \t]+)+\$([" ALPHA "_][" ALNUM "_]*)[ \t]*[=;]",
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.