getobj vs CMDQ handling

The queued command handling rejected a non-object even in cases where
getobj()'s object callback would accept it.
This commit is contained in:
PatR
2022-04-10 12:14:07 -07:00
parent 58bc545cc6
commit 138d34198e
+19 -16
View File
@@ -1477,13 +1477,14 @@ any_obj_ok(struct obj *obj)
* getobj returns: * getobj returns:
* struct obj *xxx: object to do something with. * struct obj *xxx: object to do something with.
* (struct obj *) 0 error return: no object. * (struct obj *) 0 error return: no object.
* &cg.zeroobj explicitly no object (as in w-). * &cg.zeroobj explicitly no object (as in w-).
* The obj_ok callback should not have side effects (apart from * The obj_ok callback should not have side effects (apart from
* abnormal-behavior things like impossible calls); it can be called multiple * abnormal-behavior things like impossible calls); it can be called multiple
* times on the same object during the execution of this function. * times on the same object during the execution of this function.
* Callbacks' argument is either a valid object pointer or a null pointer, which * Callbacks' argument is either a valid object pointer or a null pointer,
* represents the validity of doing that action on HANDS_SYM. getobj won't call * which represents the validity of doing that action on HANDS_SYM. getobj
* it with &cg.zeroobj, so its behavior can be undefined in that case. * won't call it with &cg.zeroobj, so its behavior can be undefined in that
* case.
*/ */
struct obj * struct obj *
getobj(const char *word, getobj(const char *word,
@@ -1511,26 +1512,28 @@ getobj(const char *word,
struct _cmd_queue *cmdq = cmdq_pop(); struct _cmd_queue *cmdq = cmdq_pop();
if (cmdq && cmdq->typ != CMDQ_USER_INPUT) { if (cmdq && cmdq->typ != CMDQ_USER_INPUT) {
int v;
/* it's not a key, abort */ /* it's not a key, abort */
if (cmdq->typ != CMDQ_KEY) { if (cmdq->typ != CMDQ_KEY) {
free(cmdq); free(cmdq);
return (struct obj *)0; return (struct obj *) 0;
} }
for (otmp = g.invent; otmp; otmp = otmp->nobj) for (otmp = g.invent; otmp; otmp = otmp->nobj)
if (otmp->invlet == cmdq->key) { if (otmp->invlet == cmdq->key) {
int v = (*obj_ok)(otmp); v = (*obj_ok)(otmp);
if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY)
if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY) { break;
free(cmdq);
return otmp;
}
} }
if (!otmp) {
/* did not find the object, abort */ v = (*obj_ok)((struct obj *) 0);
if (v == GETOBJ_SUGGEST || v == GETOBJ_DOWNPLAY)
otmp = (struct obj *) &cg.zeroobj; /* cast away const */
}
free(cmdq); free(cmdq);
cmdq_clear(); if (!otmp)
return (struct obj *)0; cmdq_clear();
return otmp;
} }
if (cmdq) if (cmdq)
free(cmdq); free(cmdq);