Pārlūkot izejas kodu

Added 'preg_match' script command to match regular expressions.
The command is only available if the PCRE library is installed.

Updated indefinite articles in Global_Functions with regex. (credits: Kaivosukeltaja/php-indefinite-article/863f1d5)

Signed-off-by: Euphy <euphy.raliel@rathena.org>

Euphy 11 gadi atpakaļ
vecāks
revīzija
957f49563a
3 mainītis faili ar 105 papildinājumiem un 6 dzēšanām
  1. 12 1
      doc/script_commands.txt
  2. 56 5
      npc/other/Global_Functions.txt
  3. 37 0
      src/map/script.c

+ 12 - 1
doc/script_commands.txt

@@ -3,7 +3,7 @@
 //===== By: ==================================================
 //= rAthena Dev Team
 //===== Last Updated: ========================================
-//= 20140113
+//= 20140129
 //===== Description: =========================================
 //= A reference manual for the rAthena scripting language.
 //= Commands are sorted depending on their functionality.
@@ -7254,6 +7254,17 @@ Example:
 
 ---------------------------------------
 
+*preg_match(<regular expression pattern>,<string>{,<offset>})
+
+Searches a string for a match to the regular expression provided. The
+offset parameter indicates the index of the string to start searching.
+Returns offsets to captured substrings, or 0 if no match is found.
+
+This command is only available if the server is compiled with the regular 
+expressions library enabled.
+
+---------------------------------------
+
 *setfont <font>;
 
 This command sets the current RO client interface font to one of the

+ 56 - 5
npc/other/Global_Functions.txt

@@ -3,7 +3,7 @@
 //===== By: ================================================== 
 //= Lupus, kobra_k88
 //===== Current Version: ===================================== 
-//= 2.22
+//= 2.23
 //===== Compatible With: ===================================== 
 //= rAthena Project
 //===== Description: ========================================= 
@@ -45,6 +45,7 @@
 //=     Standardized descriptions, updated 'F_GetArmorType'.
 //= 2.21 Added format string to "F_InsertPlural" and more checks to "F_GetPlural". [Euphy]
 //= 2.22 Further improvements to "F_GetPlural". [Euphy]
+//= 2.23 Completed article function and added "F_GetArticle". [Euphy]
 //============================================================ 
 
 //////////////////////////////////////////////////////////////////////////////////
@@ -458,14 +459,64 @@ function	script	F_InsertPlural	{
 
 
 //////////////////////////////////////////////////////////////////////////////////
-// Returns 'a' or 'an' based on a word - only follows basic rules, without exceptions!
+// Returns 'a' or 'an' based on a word.
+// -- callfunc "F_GetArticle","<noun>";
+// Examples:
+//    callfunc("F_GetArticle","Apple")  // returns "an"
+//    callfunc("F_GetArticle","dog")    // returns "a"
+//
+// Returns 'a' or 'an' based on a word, followed by the word.
 // -- callfunc "F_InsertArticle","<word>"{,<0:lowercase a/1:uppercase A>}
 // Examples:
-//    callfunc("F_InsertArticle","apple")  // returns "an apple"
+//    callfunc("F_InsertArticle","Apple")  // returns "an Apple"
 //    callfunc("F_InsertArticle","dog",1)  // returns "A dog"
 //////////////////////////////////////////////////////////////////////////////////
+function	script	F_GetArticle	{
+	set .@str$, strtolower(getarg(0));
+
+	// not a word
+	if (!charisalpha(.@str$,0))
+		return "a";
+
+	// 1-letter words
+	if (getstrlen(.@str$) == 1) {
+		if (strpos("aefhilmnorsx",.@str$) > -1)
+			return "an";
+		else
+			return "a";
+	}
+
+	// special cases
+	if (preg_match("(euler|hour(?!i)|heir|honest|hono)",.@str$))
+		return "an";
+
+	// consonants
+	if (preg_match("^[^aeiouy]",.@str$))
+		return "a";
+
+	// special vowel forms
+	if (preg_match("^e[uw]",.@str$) || preg_match("^onc?e\b",.@str$) || preg_match("^uni([^nmd]|mo)",.@str$) || preg_match("^u[bcfhjkqrst][aeiou]",.@str$))
+		return "a";
+	if (preg_match("^ut[th]",.@str$))
+		return "an";
+
+	// special capitals (rare)
+	//if (preg_match("^U[NK][AIEO]?",getarg(0)))
+	//	return "a";
+
+	// vowels
+	if (preg_match("^[aeiou]",.@str$))
+		return "an";
+
+	// y... (rare)
+	//if (preg_match("^(y(b[lor]|cl[ea]|fere|gg|p[ios]|rou|tt))",.@str$))
+	//	return "an";
+
+	return "a";
+}
 function	script	F_InsertArticle	{
-	return ((getarg(1,0)) ? "A" : "a") + ((compare("aeiou", charat(getarg(0),0))) ? "n " : " ") + getarg(0);
+	set .@article$, callfunc("F_GetArticle",getarg(0));
+	return sprintf("%s %s", ((getarg(1,0)) ? replacestr(.@article$,"a","A") : .@article$), getarg(0));
 }
 
 
@@ -494,7 +545,7 @@ function	script	F_InsertComma	{
 function	script	F_GetNumSuffix	{
 	set .@n, getarg(0);
 	set .@mod, .@n % 10;
-	if (.@mod == 1 && .@n != 11) return .@n+"st";
+	if      (.@mod == 1 && .@n != 11) return .@n+"st";
 	else if (.@mod == 2 && .@n != 12) return .@n+"nd";
 	else if (.@mod == 3 && .@n != 13) return .@n+"rd";
 	else return .@n+"th";

+ 37 - 0
src/map/script.c

@@ -51,6 +51,10 @@
 #include "elemental.h"
 #include "../config/core.h"
 
+#ifdef PCRE_SUPPORT
+#include "../../3rdparty/pcre/include/pcre.h" // preg_match
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -18357,6 +18361,38 @@ BUILDIN_FUNC(defpattern);
 BUILDIN_FUNC(activatepset);
 BUILDIN_FUNC(deactivatepset);
 BUILDIN_FUNC(deletepset);
+
+/** Regular expression matching
+ * preg_match(<pattern>,<string>{,<offset>})
+ */
+BUILDIN_FUNC(preg_match) {
+	pcre *re;
+	pcre_extra *pcreExtra;
+	const char *error;
+	int erroffset, r, offset = 0;
+	int subStrVec[30];
+
+	const char* pattern = script_getstr(st,2);
+	const char* subject = script_getstr(st,3);
+	if (script_hasdata(st,4))
+		offset = script_getnum(st,4);
+
+	re = pcre_compile(pattern, 0, &error, &erroffset, NULL);
+	pcreExtra = pcre_study(re, 0, &error);
+
+	r = pcre_exec(re, pcreExtra, subject, (int)strlen(subject), offset, 0, subStrVec, 30);
+
+	pcre_free(re);
+	if (pcreExtra != NULL)
+		pcre_free(pcreExtra);
+
+	if (r < 0)
+		script_pushint(st,0);
+	else
+		script_pushint(st,(r > 0) ? r : 30 / 3);
+
+	return SCRIPT_CMD_SUCCESS;
+}
 #endif
 
 /// script command definitions
@@ -18627,6 +18663,7 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(activatepset,"i"), // Activate a pattern set [MouseJstr]
 	BUILDIN_DEF(deactivatepset,"i"), // Deactive a pattern set [MouseJstr]
 	BUILDIN_DEF(deletepset,"i"), // Delete a pattern set [MouseJstr]
+	BUILDIN_DEF(preg_match,"ss?"),
 #endif
 	BUILDIN_DEF(dispbottom,"s"), //added from jA [Lupus]
 	BUILDIN_DEF(getusersname,""),