From 943cf8461aa995fa3fe6c0347a683dd05b4eae7e Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 28 Dec 2016 12:00:00 -0500
Subject: [PATCH v2 4/6] Replace LookupFuncNameTypeNames() with
 LookupFuncWithArgs()

The old function took function name and function argument list as
separate arguments.  Now that all function signatures are passed around
as ObjectWithArgs structs, this is no longer necessary and can be
replaced by a function that takes ObjectWithArgs directly.  Similarly
for aggregates and operators.
---
 src/backend/catalog/aclchk.c        |  3 +--
 src/backend/catalog/objectaddress.c | 40 +++++++++++--------------------------
 src/backend/commands/functioncmds.c | 12 ++++-------
 src/backend/commands/opclasscmds.c  | 30 +++++++---------------------
 src/backend/commands/operatorcmds.c |  5 +----
 src/backend/nodes/copyfuncs.c       |  2 --
 src/backend/nodes/equalfuncs.c      |  2 --
 src/backend/parser/gram.y           | 18 ++++++++---------
 src/backend/parser/parse_func.c     | 32 ++++++++++++++---------------
 src/backend/parser/parse_oper.c     | 24 ++++++++++++----------
 src/include/nodes/parsenodes.h      |  7 ++-----
 src/include/parser/parse_func.h     |  4 ++--
 src/include/parser/parse_oper.h     |  5 ++---
 13 files changed, 68 insertions(+), 116 deletions(-)

diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 7e9ed76b80..be86d76a59 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -670,8 +670,7 @@ objectNamesToOids(GrantObjectType objtype, List *objnames)
 				ObjectWithArgs *func = (ObjectWithArgs *) lfirst(cell);
 				Oid			funcid;
 
-				funcid = LookupFuncNameTypeNames(func->objname,
-												 func->objargs, false);
+				funcid = LookupFuncWithArgs(func, false);
 				objects = lappend_oid(objects, funcid);
 			}
 			break;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index b6b3ff3db1..a9ef313dc5 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -868,36 +868,20 @@ get_object_address(ObjectType objtype, Node *object,
 				address = get_object_address_type(objtype, castNode(TypeName, object), missing_ok);
 				break;
 			case OBJECT_AGGREGATE:
-				{
-					ObjectWithArgs *owa = castNode(ObjectWithArgs, object);
-					address.classId = ProcedureRelationId;
-					address.objectId =
-						LookupAggNameTypeNames(owa->objname, owa->objargs, missing_ok);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = ProcedureRelationId;
+				address.objectId = LookupAggWithArgs(castNode(ObjectWithArgs, object), missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_FUNCTION:
-				{
-					ObjectWithArgs *owa = castNode(ObjectWithArgs, object);
-					address.classId = ProcedureRelationId;
-					address.objectId =
-						LookupFuncNameTypeNames(owa->objname, owa->objargs, missing_ok);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = ProcedureRelationId;
+				address.objectId = LookupFuncWithArgs(castNode(ObjectWithArgs, object), missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_OPERATOR:
-				{
-					ObjectWithArgs *owa = castNode(ObjectWithArgs, object);
-					address.classId = OperatorRelationId;
-					Assert(list_length(owa->objargs) == 2);
-					address.objectId =
-						LookupOperNameTypeNames(NULL, owa->objname,
-												castNode(TypeName, linitial(owa->objargs)),
-												castNode(TypeName, lsecond(owa->objargs)),
-												missing_ok, -1);
-					address.objectSubId = 0;
-					break;
-				}
+				address.classId = OperatorRelationId;
+				address.objectId = LookupOperWithArgs(castNode(ObjectWithArgs, object), missing_ok);
+				address.objectSubId = 0;
+				break;
 			case OBJECT_COLLATION:
 				address.classId = CollationRelationId;
 				address.objectId = get_collation_oid(castNode(List, object), missing_ok);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3d1b64549e..b9aedb2292 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -1181,9 +1181,7 @@ AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
 
 	rel = heap_open(ProcedureRelationId, RowExclusiveLock);
 
-	funcOid = LookupFuncNameTypeNames(stmt->func->objname,
-									  stmt->func->objargs,
-									  false);
+	funcOid = LookupFuncWithArgs(stmt->func, false);
 
 	tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(funcOid));
 	if (!HeapTupleIsValid(tup)) /* should not happen */
@@ -1453,9 +1451,7 @@ CreateCast(CreateCastStmt *stmt)
 	{
 		Form_pg_proc procstruct;
 
-		funcid = LookupFuncNameTypeNames(stmt->func->objname,
-										 stmt->func->objargs,
-										 false);
+		funcid = LookupFuncWithArgs(stmt->func, false);
 
 		tuple = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid));
 		if (!HeapTupleIsValid(tuple))
@@ -1836,7 +1832,7 @@ CreateTransform(CreateTransformStmt *stmt)
 	 */
 	if (stmt->fromsql)
 	{
-		fromsqlfuncid = LookupFuncNameTypeNames(stmt->fromsql->objname, stmt->fromsql->objargs, false);
+		fromsqlfuncid = LookupFuncWithArgs(stmt->fromsql, false);
 
 		if (!pg_proc_ownercheck(fromsqlfuncid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(stmt->fromsql->objname));
@@ -1862,7 +1858,7 @@ CreateTransform(CreateTransformStmt *stmt)
 
 	if (stmt->tosql)
 	{
-		tosqlfuncid = LookupFuncNameTypeNames(stmt->tosql->objname, stmt->tosql->objargs, false);
+		tosqlfuncid = LookupFuncWithArgs(stmt->tosql, false);
 
 		if (!pg_proc_ownercheck(tosqlfuncid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, NameListToString(stmt->tosql->objname));
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 9bd50a3bec..822b331e0d 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -475,19 +475,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
 							 errmsg("invalid operator number %d,"
 									" must be between 1 and %d",
 									item->number, maxOpNumber)));
-				if (item->args != NIL)
-				{
-					TypeName   *typeName1 = (TypeName *) linitial(item->args);
-					TypeName   *typeName2 = (TypeName *) lsecond(item->args);
-
-					operOid = LookupOperNameTypeNames(NULL, item->name,
-													  typeName1, typeName2,
-													  false, -1);
-				}
+				if (item->name->objargs != NIL)
+					operOid = LookupOperWithArgs(item->name, false);
 				else
 				{
 					/* Default to binary op on input datatype */
-					operOid = LookupOperName(NULL, item->name,
+					operOid = LookupOperName(NULL, item->name->objname,
 											 typeoid, typeoid,
 											 false, -1);
 				}
@@ -526,8 +519,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 							 errmsg("invalid procedure number %d,"
 									" must be between 1 and %d",
 									item->number, maxProcNumber)));
-				funcOid = LookupFuncNameTypeNames(item->name, item->args,
-												  false);
+				funcOid = LookupFuncWithArgs(item->name, false);
 #ifdef NOT_USED
 				/* XXX this is unnecessary given the superuser check above */
 				/* Caller must own function */
@@ -857,15 +849,8 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
 							 errmsg("invalid operator number %d,"
 									" must be between 1 and %d",
 									item->number, maxOpNumber)));
-				if (item->args != NIL)
-				{
-					TypeName   *typeName1 = (TypeName *) linitial(item->args);
-					TypeName   *typeName2 = (TypeName *) lsecond(item->args);
-
-					operOid = LookupOperNameTypeNames(NULL, item->name,
-													  typeName1, typeName2,
-													  false, -1);
-				}
+				if (item->name->objargs != NIL)
+					operOid = LookupOperWithArgs(item->name, false);
 				else
 				{
 					ereport(ERROR,
@@ -908,8 +893,7 @@ AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
 							 errmsg("invalid procedure number %d,"
 									" must be between 1 and %d",
 									item->number, maxProcNumber)));
-				funcOid = LookupFuncNameTypeNames(item->name, item->args,
-												  false);
+				funcOid = LookupFuncWithArgs(item->name, false);
 #ifdef NOT_USED
 				/* XXX this is unnecessary given the superuser check above */
 				/* Caller must own function */
diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c
index b063467bbd..739d5875eb 100644
--- a/src/backend/commands/operatorcmds.c
+++ b/src/backend/commands/operatorcmds.c
@@ -402,10 +402,7 @@ AlterOperator(AlterOperatorStmt *stmt)
 	Oid			joinOid;
 
 	/* Look up the operator */
-	oprId = LookupOperNameTypeNames(NULL, stmt->opername,
-									(TypeName *) linitial(stmt->operargs),
-									(TypeName *) lsecond(stmt->operargs),
-									false, -1);
+	oprId = LookupOperWithArgs(stmt->opername, false);
 	catalog = heap_open(OperatorRelationId, RowExclusiveLock);
 	tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(oprId));
 	if (tup == NULL)
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 598ba944a1..bb2a8a3586 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -3314,7 +3314,6 @@ _copyAlterOperatorStmt(const AlterOperatorStmt *from)
 	AlterOperatorStmt *newnode = makeNode(AlterOperatorStmt);
 
 	COPY_NODE_FIELD(opername);
-	COPY_NODE_FIELD(operargs);
 	COPY_NODE_FIELD(options);
 
 	return newnode;
@@ -3487,7 +3486,6 @@ _copyCreateOpClassItem(const CreateOpClassItem *from)
 
 	COPY_SCALAR_FIELD(itemtype);
 	COPY_NODE_FIELD(name);
-	COPY_NODE_FIELD(args);
 	COPY_SCALAR_FIELD(number);
 	COPY_NODE_FIELD(order_family);
 	COPY_NODE_FIELD(class_args);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 876b8aabb9..9fa83b9453 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -1390,7 +1390,6 @@ static bool
 _equalAlterOperatorStmt(const AlterOperatorStmt *a, const AlterOperatorStmt *b)
 {
 	COMPARE_NODE_FIELD(opername);
-	COMPARE_NODE_FIELD(operargs);
 	COMPARE_NODE_FIELD(options);
 
 	return true;
@@ -1535,7 +1534,6 @@ _equalCreateOpClassItem(const CreateOpClassItem *a, const CreateOpClassItem *b)
 {
 	COMPARE_SCALAR_FIELD(itemtype);
 	COMPARE_NODE_FIELD(name);
-	COMPARE_NODE_FIELD(args);
 	COMPARE_SCALAR_FIELD(number);
 	COMPARE_NODE_FIELD(order_family);
 	COMPARE_NODE_FIELD(class_args);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 53ee3a963e..41daab57c7 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -5778,9 +5778,11 @@ opclass_item:
 			OPERATOR Iconst any_operator opclass_purpose opt_recheck
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
+					ObjectWithArgs *owa = makeNode(ObjectWithArgs);
+					owa->objname = $3;
+					owa->objargs = NIL;
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
-					n->name = $3;
-					n->args = NIL;
+					n->name = owa;
 					n->number = $2;
 					n->order_family = $4;
 					$$ = (Node *) n;
@@ -5790,8 +5792,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_OPERATOR;
-					n->name = $3->objname;
-					n->args = $3->objargs;
+					n->name = $3;
 					n->number = $2;
 					n->order_family = $4;
 					$$ = (Node *) n;
@@ -5800,8 +5801,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
-					n->name = $3->objname;
-					n->args = $3->objargs;
+					n->name = $3;
 					n->number = $2;
 					$$ = (Node *) n;
 				}
@@ -5809,8 +5809,7 @@ opclass_item:
 				{
 					CreateOpClassItem *n = makeNode(CreateOpClassItem);
 					n->itemtype = OPCLASS_ITEM_FUNCTION;
-					n->name = $6->objname;
-					n->args = $6->objargs;
+					n->name = $6;
 					n->number = $2;
 					n->class_args = $4;
 					$$ = (Node *) n;
@@ -8771,8 +8770,7 @@ AlterOperatorStmt:
 			ALTER OPERATOR operator_with_argtypes SET '(' operator_def_list ')'
 				{
 					AlterOperatorStmt *n = makeNode(AlterOperatorStmt);
-					n->opername = $3->objname;
-					n->operargs = $3->objargs;
+					n->opername = $3;
 					n->options = $6;
 					$$ = (Node *)n;
 				}
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 672f7f65f1..dd9749f205 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -1932,19 +1932,19 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
 }
 
 /*
- * LookupFuncNameTypeNames
+ * LookupFuncWithArgs
  *		Like LookupFuncName, but the argument types are specified by a
- *		list of TypeName nodes.
+ *		ObjectWithArgs node.
  */
 Oid
-LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
+LookupFuncWithArgs(ObjectWithArgs *func, bool noError)
 {
 	Oid			argoids[FUNC_MAX_ARGS];
 	int			argcount;
 	int			i;
 	ListCell   *args_item;
 
-	argcount = list_length(argtypes);
+	argcount = list_length(func->objargs);
 	if (argcount > FUNC_MAX_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
@@ -1953,7 +1953,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 							   FUNC_MAX_ARGS,
 							   FUNC_MAX_ARGS)));
 
-	args_item = list_head(argtypes);
+	args_item = list_head(func->objargs);
 	for (i = 0; i < argcount; i++)
 	{
 		TypeName   *t = (TypeName *) lfirst(args_item);
@@ -1962,19 +1962,19 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
 		args_item = lnext(args_item);
 	}
 
-	return LookupFuncName(funcname, argcount, argoids, noError);
+	return LookupFuncName(func->objname, argcount, argoids, noError);
 }
 
 /*
- * LookupAggNameTypeNames
- *		Find an aggregate function given a name and list of TypeName nodes.
+ * LookupAggWithArgs
+ *		Find an aggregate function from a given ObjectWithArgs node.
  *
- * This is almost like LookupFuncNameTypeNames, but the error messages refer
+ * This is almost like LookupFuncWithArgs, but the error messages refer
  * to aggregates rather than plain functions, and we verify that the found
  * function really is an aggregate.
  */
 Oid
-LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
+LookupAggWithArgs(ObjectWithArgs *agg, bool noError)
 {
 	Oid			argoids[FUNC_MAX_ARGS];
 	int			argcount;
@@ -1984,7 +1984,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 	HeapTuple	ftup;
 	Form_pg_proc pform;
 
-	argcount = list_length(argtypes);
+	argcount = list_length(agg->objargs);
 	if (argcount > FUNC_MAX_ARGS)
 		ereport(ERROR,
 				(errcode(ERRCODE_TOO_MANY_ARGUMENTS),
@@ -1994,7 +1994,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 							   FUNC_MAX_ARGS)));
 
 	i = 0;
-	foreach(lc, argtypes)
+	foreach(lc, agg->objargs)
 	{
 		TypeName   *t = (TypeName *) lfirst(lc);
 
@@ -2002,7 +2002,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 		i++;
 	}
 
-	oid = LookupFuncName(aggname, argcount, argoids, true);
+	oid = LookupFuncName(agg->objname, argcount, argoids, true);
 
 	if (!OidIsValid(oid))
 	{
@@ -2012,12 +2012,12 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 			ereport(ERROR,
 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
 					 errmsg("aggregate %s(*) does not exist",
-							NameListToString(aggname))));
+							NameListToString(agg->objname))));
 		else
 			ereport(ERROR,
 					(errcode(ERRCODE_UNDEFINED_FUNCTION),
 					 errmsg("aggregate %s does not exist",
-							func_signature_string(aggname, argcount,
+							func_signature_string(agg->objname, argcount,
 												  NIL, argoids))));
 	}
 
@@ -2036,7 +2036,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("function %s is not an aggregate",
-						func_signature_string(aggname, argcount,
+						func_signature_string(agg->objname, argcount,
 											  NIL, argoids))));
 	}
 
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 894e900073..e40b10d4f6 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -132,32 +132,34 @@ LookupOperName(ParseState *pstate, List *opername, Oid oprleft, Oid oprright,
 }
 
 /*
- * LookupOperNameTypeNames
+ * LookupOperWithArgs
  *		Like LookupOperName, but the argument types are specified by
- *		TypeName nodes.
- *
- * Pass oprleft = NULL for a prefix op, oprright = NULL for a postfix op.
+ *		a ObjectWithArg node.
  */
 Oid
-LookupOperNameTypeNames(ParseState *pstate, List *opername,
-						TypeName *oprleft, TypeName *oprright,
-						bool noError, int location)
+LookupOperWithArgs(ObjectWithArgs *oper, bool noError)
 {
+	TypeName   *oprleft,
+			   *oprright;
 	Oid			leftoid,
 				rightoid;
 
+	Assert(list_length(oper->objargs) == 2);
+	oprleft = linitial(oper->objargs);
+	oprright = lsecond(oper->objargs);
+
 	if (oprleft == NULL)
 		leftoid = InvalidOid;
 	else
-		leftoid = LookupTypeNameOid(pstate, oprleft, noError);
+		leftoid = LookupTypeNameOid(NULL, oprleft, noError);
 
 	if (oprright == NULL)
 		rightoid = InvalidOid;
 	else
-		rightoid = LookupTypeNameOid(pstate, oprright, noError);
+		rightoid = LookupTypeNameOid(NULL, oprright, noError);
 
-	return LookupOperName(pstate, opername, leftoid, rightoid,
-						  noError, location);
+	return LookupOperName(NULL, oper->objname, leftoid, rightoid,
+						  noError, -1);
 }
 
 /*
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 7c7530bd3f..956f99830c 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -2418,9 +2418,7 @@ typedef struct CreateOpClassItem
 {
 	NodeTag		type;
 	int			itemtype;		/* see codes above */
-	/* fields used for an operator or function item: */
-	List	   *name;			/* operator or function name */
-	List	   *args;			/* argument types */
+	ObjectWithArgs *name;		/* operator or function name and args */
 	int			number;			/* strategy num or support proc num */
 	List	   *order_family;	/* only used for ordering operators */
 	List	   *class_args;		/* amproclefttype/amprocrighttype or
@@ -2730,8 +2728,7 @@ typedef struct AlterOwnerStmt
 typedef struct AlterOperatorStmt
 {
 	NodeTag		type;
-	List	   *opername;		/* operator name */
-	List	   *operargs;		/* operator's argument TypeNames */
+	ObjectWithArgs *opername;	/* operator name and argument types */
 	List	   *options;		/* List of DefElem nodes */
 } AlterOperatorStmt;
 
diff --git a/src/include/parser/parse_func.h b/src/include/parser/parse_func.h
index 1c914065c0..8ccf7a9538 100644
--- a/src/include/parser/parse_func.h
+++ b/src/include/parser/parse_func.h
@@ -62,9 +62,9 @@ extern const char *func_signature_string(List *funcname, int nargs,
 
 extern Oid LookupFuncName(List *funcname, int nargs, const Oid *argtypes,
 			   bool noError);
-extern Oid LookupFuncNameTypeNames(List *funcname, List *argtypes,
+extern Oid LookupFuncWithArgs(ObjectWithArgs *func,
 						bool noError);
-extern Oid LookupAggNameTypeNames(List *aggname, List *argtypes,
+extern Oid LookupAggWithArgs(ObjectWithArgs *agg,
 					   bool noError);
 
 extern void check_srf_call_placement(ParseState *pstate, int location);
diff --git a/src/include/parser/parse_oper.h b/src/include/parser/parse_oper.h
index b8d46637be..a8f75b5921 100644
--- a/src/include/parser/parse_oper.h
+++ b/src/include/parser/parse_oper.h
@@ -15,6 +15,7 @@
 #define PARSE_OPER_H
 
 #include "access/htup.h"
+#include "nodes/parsenodes.h"
 #include "parser/parse_node.h"
 
 
@@ -24,9 +25,7 @@ typedef HeapTuple Operator;
 extern Oid LookupOperName(ParseState *pstate, List *opername,
 			   Oid oprleft, Oid oprright,
 			   bool noError, int location);
-extern Oid LookupOperNameTypeNames(ParseState *pstate, List *opername,
-						TypeName *oprleft, TypeName *oprright,
-						bool noError, int location);
+extern Oid LookupOperWithArgs(ObjectWithArgs *oper, bool noError);
 
 /* Routines to find operators matching a name and given input types */
 /* NB: the selected operator may require coercion of the input types! */
-- 
2.11.1

