C++: AHK source code: StrJoin (alternating pad string)

Talk about things C/C++, some related to AutoHotkey
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

C++: AHK source code: StrJoin (alternating pad string)

Post by jeeswg » 19 May 2019, 18:49

Here is some code for a potential StrJoin function, that can accept an array of pad strings, for alternating pad strings.

See also: code for potential StrCount/StrRept/StrJoin (constant pad string) functions:
C++: AHK source code: potential functions - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=75&t=54392

Code: Select all

==================================================

for AHK v1: function names and parameters:

StrJoin(Sep, Params*)

- note: 'Sep' could be called 'Pad' instead
- note: Sep can be a string or an array
- note: for an array of pad strings, the pad strings alternate in a cycle e.g. = and CRLF

==================================================

[script.h]

BIF_DECL(BIF_StrJoin);

==================================================

[script.cpp]

	else if (!_tcsicmp(func_name, _T("StrJoin")))
	{
		bif = BIF_StrJoin;
		min_params = 2;
		max_params = 10000; // An arbitrarily high limit that will never realistically be reached.
	}

==================================================

[script2.cpp]

BIF_DECL(BIF_StrJoin)
{
	if (aParamCount < 2)
		goto return_empty_string;

	LPTSTR *aPadderList = NULL;
	int aPadderCount = 0;
	//handle padder string array (based on BIF_StrSplit)
	if (Object *obj = dynamic_cast<Object *>(TokenToObject(*aParam[0])))
	{
		aPadderCount = obj->GetNumericItemCount();
		aPadderList = (LPTSTR *)_alloca(aPadderCount * sizeof(LPTSTR *));
		if (!obj->ArrayToStrings(aPadderList, aPadderCount, aPadderCount))
			// Array contains something other than a string.
			goto return_empty_string;
		for (int i = 0; i < aPadderCount; ++i)
			if (!*aPadderList[i])
				// Empty string in padder list. Although it could be treated similarly to the
				// "no padder" case, it's far more likely to be an error. If ever this check
				// is removed, the loop below must be changed to support "" as a padder.
				goto return_empty_string;
	}
	else
	{
		aPadderList = (LPTSTR *)_alloca(sizeof(LPTSTR *));
		*aPadderList = TokenToString(*aParam[0]);
		aPadderCount = 1;
	}

	int count = aParamCount - 1; //number of items to join
	int count_trail_pad = (count-1) % aPadderCount;
	int len_unique_pad = 0;
	int len_trail_pad = 0;
	int temp = 0;

	int *aPadderListLen = (int *)_alloca(aPadderCount * 4);
	for (int i = 0; i < aPadderCount; ++i)
	{
		temp = (int)(_tcslen(aPadderList[i]));
		aPadderListLen[i] = temp;
		len_unique_pad += temp;
		if (i < count_trail_pad)
			len_trail_pad += temp;
	}

	int len_out = 0;
	for (int i = 1; i < aParamCount; ++i)
		len_out += (int)_tcslen(ParamIndexToString(i));
	len_out += ((count-1) / aPadderCount) * len_unique_pad;
	len_out += len_trail_pad + 1;
	TCHAR *output = new TCHAR[len_out];

	int j = 0;
	int len = 0;
	int len_item;
	int len_pad;
	for (int i = 1; i < aParamCount-1; ++i)
	{
		len_item = _tcslen(ParamIndexToString(i));
		tmemcpy(output+len, ParamIndexToString(i), len_item);
		len_pad = aPadderListLen[j];
		tmemcpy(output+len+len_item, aPadderList[j], len_pad);
		len += len_item+len_pad;
		j = (j + 1) % aPadderCount;
	}
	len_item = _tcslen(ParamIndexToString(aParamCount-1));
	tmemcpy(output+len, ParamIndexToString(aParamCount-1), len_item);

	*(output+len_out-1) = '\0';
	aResultToken.symbol = SYM_STRING;
	aResultToken.marker = output;
	return;

return_empty_string:
	aResultToken.symbol = SYM_STRING;
	aResultToken.marker = _T("");
}

==================================================
Relevant AHK code:
[StrJoin (with alternating join string)]
StrUnused prototype function: find unused characters for use as delimiters/separators - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=43623&p=198312#p198312
[StrRept/StrCount]
StrRept and StrCount - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=13&t=34765
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: C++: AHK source code: StrJoin (alternating pad string)

Post by Helgef » 06 Jul 2020, 03:39

Disregarding opinions on the design, this code leaks and doesn't handle numeric input properly. It is also over using the ParamIndexToString macro, imo.

Post Reply

Return to “C/C++”