NEW ParseMacroParameter()!!

A forum for feature requests/discussions and user submitted patches that improve MQ2

Moderator: MacroQuest Developers

Valerian
a grimling bloodguard
a grimling bloodguard
Posts: 709
Joined: Sun Jul 28, 2002 3:29 am

NEW ParseMacroParameter()!!

Post by Valerian » Sat Aug 02, 2003 1:15 pm

Ok, big change coming up... ability to modularize ParseMacroParameter()... I have added a header file (EQLib_MacroParser.h) and made a few minor changes to ParseMacroParameter(). I will attempt to detail those changes here well enough for someone to make the changes.

NOTE: To add a macro parm, simply add to the bolded lines, using them as a template. New macro parms are ONLY required to append text to szOutput, and return the length of their parm (e.g. old i+= value)

First, EQLib_MacroParser.h: ***NEW***

Code: Select all

typedef DWORD (__cdecl *fParmCmd)(PCHAR,PCHAR);

//PMP funcs
extern "C" EQLIB_API DWORD pGetLastFindSlot(PCHAR, PCHAR);

typedef struct _PARMLIST {
	CHAR szName[MAX_STRING];
	CHAR szFuncName[MAX_STRING];
	DWORD (__cdecl *fAddress)(PCHAR, PCHAR);
} PARMLIST, *PPARMLIST;

//PMP globals
BOOL gPMPInit = FALSE;
PARMLIST Parms[] = {
	{"getlastfindslot",		"pGetLastFindSlot", NULL},
	{NULL,NULL,NULL},
};
Changes to ParseMacroParameter():

Code: Select all

[color=red]#include "EQLib.h"[/color]
#include "EQLib_MacroParser.h"
*note* entire PMP() here should be copied, including the last line.

Code: Select all

PCHAR ParseMacroParameter(PSPAWNINFO pChar, PCHAR szOriginal)
{
	BOOL FoundNewCmd=FALSE;
	CHAR szOutput[MAX_STRING] = {0};
	CHAR szVar[MAX_STRING] = {0};
	CHAR szTmp[MAX_STRING] = {0};
	DWORD i,j,k,l = 0;
	PCHARINFO pCharInfo = NULL;
	if (NULL == (pCharInfo = GetCharInfo())) return szOriginal;
	if (!gPMPInit) {
		gPMPInit = TRUE;
		DebugSpew("PMP - Setting up Proc Addresses...");
        for (l=0; Parms[l].szName[0]; l++) {
			Parms[l].fAddress=(fParmCmd)GetProcAddress(ghModule,Parms[l].szFuncName);
			DebugSpew("PMP - Parm '%s' - Proc '%s' - Address '%d'",Parms[l].szName, Parms[l].szFuncName, (DWORD)Parms[l].fAddress);
			if ((DWORD)&Parms[l].fAddress == NULL) return szOriginal;
		}
	}
	while (strstr(szOriginal,"$")) {
		DebugSpew("PMP - Current string - '%s'",szOriginal);
		ZeroMemory(szOutput,MAX_STRING);
		ZeroMemory(szVar,MAX_STRING);
		i=0;
		j=0;

		strncpy(szOutput,szOriginal,MAX_STRING);
		for (i=0;i<strlen(szOriginal);i++) {
			if (szOriginal[i] == '$') j=i;
		}
		for (i=j;i<strlen(szOriginal);i++) {
			szOutput[i]=0;
		};
		for (i=j;i<strlen(szOriginal);i++) {
			if (szOriginal[i] != '$') {
				szOutput[j] = szOriginal[i];
				j++;
			} else {
				i++;
				if ((szOriginal[i]==0) || (szOriginal[i]==' ')) {
					DebugSpew("PMP - Bad $ '%s'",szVar);
					i--;
					szOutput[j] = '@';
					j++;
				} else {
					GetArg(szVar,szOriginal+i,1,TRUE,TRUE);
					_strlwr(szVar);
					DebugSpew("PMP - Current param - '%s'",szVar);
					FoundNewCmd = FALSE;
[color=orange]					for (k=0;Parms[k].szName[0]!='\0';k++) {
						if ((!strncmp(szVar,Parms[k].szName,strlen(Parms[k].szName)))
							&& ((DWORD)&Parms[k].fAddress)) {
							l = Parms[k].fAddress(szVar,szOutput);
							if (l==10000) {
								i--;
								szOutput[j]='@';
								j++;
								FoundNewCmd=TRUE;
								break;
							}
							i += l;
							j += (strlen(szOutput)-j);
							FoundNewCmd=TRUE;
							break;
						}
					}
[/color]					if (FoundNewCmd) {
					// $cursor(xxx)
					} else if (!strncmp("cursor(",szVar,7)) {
and finally, the parm I recently made, and am using as an example: (in EQLib_Macroparser.cpp, outside any other functions of course)

Code: Select all

DWORD pGetLastFindSlot(PCHAR szVar, PCHAR szOutput)
{
	// $getlastfindslot
	if (gLastFindSlot[0] == 0) {
		strcat(szOutput,"NULL");
	} else {
		strcat(szOutput,gLastFindSlot);
	}
    return 14;
}
Please, try this out, and let me know if I left anything out...

EDIT: changed it to use globals and only initialize the func addresses once.
EDIT: Code in orange has changed to allow for bad parameter return value. return 10000 for a bad $parm.
Last edited by Valerian on Sun Aug 03, 2003 11:08 am, edited 3 times in total.

Valerian
a grimling bloodguard
a grimling bloodguard
Posts: 709
Joined: Sun Jul 28, 2002 3:29 am

Post by Valerian » Sun Aug 03, 2003 7:21 am

wow, overwhelming response to this... makes me wonder why I bother.

wassup
Official Guardian and Writer of TFM
Official Guardian and Writer of TFM
Posts: 1487
Joined: Sat Oct 26, 2002 5:15 pm

Post by wassup » Sun Aug 03, 2003 8:51 am

I'm sure people appreciate everything you do Valerian.

I'm trying to figure out what it does and then determine if it is something I need with the macro's I use.

One thing I am curious about though:

Code: Select all

DWORD pGetLastFindSlot(PCHAR szVar, PCHAR szOutput) 
{ 
   // $getlastfindslot 
   if (gLastFindSlot[0] == 0) { 
      strcat(szOutput,"NULL"); 
   } else { 
      strcat(szOutput,gLastFindSlot); 
   } 
[b]    return 14; [/b]
}
is the return 14; a typo? Maybe I am not understanding something

fwiggles
a hill giant
a hill giant
Posts: 161
Joined: Mon Jun 17, 2002 8:29 pm

Post by fwiggles » Sun Aug 03, 2003 8:56 am

Very good work Velerian, i don't code, but i know that stuff works better if it is more organized or something...Ok i really have no idea what i'm talking about, but good effort and keep up the good work!
[color=red]Latest survey shows that 3 out of 4 people make up 75% of the world's population.[/color]

Valerian
a grimling bloodguard
a grimling bloodguard
Posts: 709
Joined: Sun Jul 28, 2002 3:29 am

Post by Valerian » Sun Aug 03, 2003 9:45 am

Wassup wrote:is the return 14; a typo? Maybe I am not understanding something
No, a macro parameter func needs to return the number of chars to skip in the original string (e.g. the "i+=" value from the old style).

The old style of this would have had an i+=14; in there, and been in amongst the VERY FAT PIG ParseMacroParameter() func.

Basically, the syntax for a new macro parameter must be:

Code: Select all

DWORD <funcname>(PCHAR szVar, PCHAR szOutput)


szVar will contain the entire macro parm from the original (e.g. szVar would contain "target(distance,nopredict)" (without quotes) when parsing a $target(distance,nopredict).

szOutput will need the output of the macro parm appended to it. No worries about setting the j+= value from the "old style", it is set automatically. If you were returning, for example, "NULL", you would use a

Code: Select all

strcat(szOutput,"NULL");
the Return value is the number of chars in the original string to "skip". basically, it's the length of your parameter, including all optional/string/etc parameters inside it. e.g. if your parameter is target(distance,nopredict) you would return 25. (string length -1) Note that this must be calculated by you, since you cannot always rely on a strlen(szVar) to provide the length of YOUR parm. ($GetLastFindSlot, if used inside a $item(stack), will have "getlastfindslot,stack)" in szVar)