Commit Diff


commit - ee680ff06607507d02b4777f89bd8bf902d751da
commit + 8250ab192888019ae762c2ef54dbd843f8b42d5f
blob - 6c5de914e4816aeddea7633deef21e3b8b3455d1
blob + a92efa0a90dff3aebb9af6b0a16198e13a4cbbb6
--- np.y
+++ np.y
@@ -99,7 +99,7 @@ typedef struct {
 %token	<v.num>		NUMBER
 
 %type	<v.op>		cast cexpr check expr faccess funcall
-%type	<v.op>		literal var varref
+%type	<v.op>		literal sfail var varref
 
 %type	<v.proc>	procname
 
@@ -240,8 +240,13 @@ block	: /* empty */
 	| block var nl		{ block_push($2); }
 	| block funcall nl	{ block_push($2); }
 	| block assert nl
+	| block sfail nl	{ block_push($2); }
 	;
 
+sfail	: SHOULD_FAIL expr		{ $$ = op_sfail($2, NULL); }
+	| SHOULD_FAIL expr ':' STRING	{ $$ = op_sfail($2, $4); }
+	;
+
 assert	: ASSERT asserti
 	| ASSERT '(' optnl massert ')'
 	;
blob - 9511faba88384dc377c67c82817d1fa8a44ce49e
blob + 77f26ae978010ffa16f5f0b97f2713fa11a530d9
--- script.c
+++ script.c
@@ -464,7 +464,19 @@ op_faccess(struct op *expr, char *field)
 
 	return op;
 }
+
+struct op *
+op_sfail(struct op *expr, char *msg)
+{
+	struct op	*op;
 
+	op = newop(OP_SFAIL);
+	op->v.sfail.expr = expr;
+	op->v.sfail.msg = msg;
+
+	return op;
+}
+
 void
 ppf_val(FILE *f, struct value *val)
 {
@@ -716,6 +728,12 @@ pp_op(struct op *op)
 	case OP_FACCESS:
 		pp_op(op->v.faccess.expr);
 		printf(".%s", op->v.faccess.field);
+		break;
+	case OP_SFAIL:
+		printf("should-fail ");
+		pp_op(op->v.sfail.expr);
+		if (op->v.sfail.msg != NULL)
+			printf(": \"%s\"", op->v.sfail.msg);
 		break;
 	default:
 		printf(" ???[%d] ", op->type);
@@ -877,6 +895,22 @@ eval(struct op *op)
 		    != EVAL_OK)
 			return ret;
 		pushv(&b);
+		break;
+
+	case OP_SFAIL:
+		if ((ret = eval(op->v.sfail.expr)) == EVAL_OK) {
+			before_printing();
+			printf("expecting failure");
+			if (op->v.sfail.msg != NULL)
+				printf(" \"%s\"", op->v.sfail.msg);
+			printf("\n");
+			printf("expression: ");
+			pp_op(op->v.sfail.expr);
+			printf("\n");
+			return EVAL_ERR;
+		}
+		if (ret == EVAL_SKIP)
+			return ret;
 		break;
 
 	default:
blob - 3331b113f627d5fb4b3f87b1c0867389857e75aa
blob + b92f93be2f080881f2d911f7d46d321466083e93
--- script.h
+++ script.h
@@ -65,6 +65,7 @@ enum {
 	OP_CAST,
 	OP_CMP_EQ,
 	OP_FACCESS,
+	OP_SFAIL,
 };
 
 struct proc;
@@ -97,6 +98,10 @@ struct op {
 			struct op	*expr;
 			char		*field;
 		} faccess;
+		struct {
+			char		*msg;
+			struct op	*expr;
+		} sfail;
 	} v;
 };
 
@@ -167,6 +172,7 @@ struct op	*op_lit_num(uint64_t);
 struct op	*op_cmp_eq(struct op *, struct op *);
 struct op	*op_cast(struct op *, int);
 struct op	*op_faccess(struct op *, char *);
+struct op	*op_sfail(struct op *, char *);
 
 void		 ppf_val(FILE *, struct value *);
 void		 pp_val(struct value *);