# AG\_XFUNC
> [HTML Version](ag_xfunc.htm)
_Rewritten December 2023_
Numeric Function:
**tab(-10, AG\_XFUNC); sbxname; arg1, arg2,....argn; chr(127);** [Tab(-10,x) Syntax Notes](ag_xxx_syntax-notes.htm.md)
String Function:
**tab(-10, AG\_XFUNCS); sbxname; arg1, arg2,....argn; chr(127);**
No Response:
**tab(-10, AG\_XFUNC2); sbxname; arg1,arg2,...argn; chr(127);**
AG\_XFUNC (25), AG\_XFUNCS (75), and AG\_FUNC2 (73) invoke a function implemented via an SBX, returning a numeric, string or no result, respectively.
**Parameters**
_sbxname_
File name (no device or extension) of an SBX Subroutine stored in the SBX search path (normally BAS:) of the ATE or windows client. For the XFUNC() and XFUNC\$() versions, it must include a RETURN expression.
_arg1, arg2, ..., argn_
Zero or more arguments passed to the SBX. These will appear to the target SBX as individual arguments passed in an XCALL statement.
**Response**
For AG\_XFUNC, the response is a single numeric value:
_numvalue_ CR
For AG\_XFUNCS, the response is a string, which may potentially be in the form of a list, depending on the SBX, so should be parsed appropriately:
_strvalue_ CR
For AG\_XFUNC2, there is no response
**Example 1**
writecd tab(-10,AG\_XFUNC);"CALCLCD", 21, 35; chr(127);
input "", lcd
This example passes a pair of numbers to a routine CALCLDC.SBX on the client and gets back the least common denominator. Note that writecd was used in place of the more typical print or ? statement in order to get the benefit of automatic comma delimiters. The equivalent print statement version would be:
? tab(-10,AG\_XFUNC);"CALCLCD"; ","; 21; ","; 35; chr(127);
or
? tab(-10,AG\_XFUNC);"CALCLCD,21,35"; chr(127);
The target CALCLDC.SBX would be internally invoked on the client side via:
xcall CALCLCD, 21, 35
To work properly, it should be constructed something like this:
xgetargs value1,value2 \! receive the two arguments
result = Fn'LCD(value1,value2) \! calc the least common denominator
return (result) \! return the result
**Example 2**
writecd tab(-10,AG\_XFUNCS);"FGREP", file\$, pattern\$; chr(127);
input line "", match\$
This example passes a filespec and a pattern to a routine FGREP.SBX on the client to search the specified field for the specified pattern, returning the first match, if any. Note the use of _input line_ rather than just _input_ for the response since we can't be sure if the return string contains commas (or anything at all).
**Example 3**
writecd tab(-10,AG\_XFUNC2);"ARCFILE", file\$, file2\$, file3\$; chr(127);
This example calls a routine ARCFILE.SBX on the client to archive the specified files, whatever that may mean. There is no response in this case.
**Comments**
Getting the SBX installed on the client is outside the scope of the function. To simplify this prerequisite, see [Fn'ATE'SBX in SOSLIB:\[907,11\]](https://bitbucket.org/microsabio/soslib/src/master/907011/fnatesbx.bp) which automatically takes care of transferring or updating the SBX from the application/server to the ATE/client if necessary, invoking the routine remotely, and return the result.
See the [OSVERCLI.SBX in SOSLIB:\[907,33\]](https://bitbucket.org/microsabio/soslib/src/master/907033/osvercli.bp) for an example of a function invoked by AG\_XFUNCS using the Fn'ATE'SBX\$() wrapper.
An example of a standard routine using this mechanism is provided in the documentation for [HTTP](http_sbr.htm.md), subtopic "ATE."
Note that the SBX may **not** perform any standard text mode input operations, as these would interfere with the host/client communication (TELNET/SSH) channel. Instead, if input is needed, use AUI functions, e.g. MSGBOX, EVENTWAIT, INFLD (in GUI mode), etc.
Note that AG\_XFUNCS is to AG\_XFUNC as the underlying built-in function XFUNC\$() is to [XFUNC()](xfunc().htm.md). The former deals with functions returning a string, while the latter deals with functions returning a numeric value. In both cases, if the specified SBX is not found the return value will be -1, although in the case of AG\_XFUNCS, it will be a string representing -1, e.g. "-1", as opposed to the numeric value -1. There is no particular limit on the length of the returned string.
For the variations with a return value (i.e. AG\_XFUNC and AG\_XFUNCS but not AG\_XFUNC2), see [MX\_AGWRAPPER](mx_agwrapper.htm.md)[xs](keyword-types.htm.md) as a way to encapsulate the two parts of the operation (Tab output and response input) into a single operation. In particular, its timeout feature would provide a measure of robustness given that the complexity of these remote calls increases the possibility of unexpected failures which might otherwise leave the application stuck waiting for a response that isn't coming.
**History**
2017 November, A-Shell 6.5.1621, Corruption avoidance fix: the string containing the argument list was previously used in place, but since the area is within the terminal system output buffer, it was subject to possible corruption by other functions that use the output system. This could have interfered with the operation of XGETARG(S). For example, in the following SBX code, the second XGETARG might have returned incorrect information due to potential sharing of the same buffer space with DEBUG.PRINT:
XGETARG 1,ARG1
DEBUG.PRINT "ARG1 = "+ARG1
XGETARG 2,ARG2
This patch eliminates the danger of such a conflict.
2016 October, A-Shell/ATE 6.3.1534: Eliminate 1K limit on size of returned string.