return NULL;
}
- tc->tc_error = TC_SUCCESS;
+ /* Here's a cool trick I learned from the DTrace source code. This
+ function sets the error code in a tracecut object and also returns
+ that error code, so you can conveniently nestle it in the return
+ statement itself. */
+ static enum tc_error
+ return_error (struct tc_tracecut *tc, enum tc_error tc_error)
+ {
+ /* The tc_error field holds the _first_ non success error code. */
+ if (tc->tc_error == TC_SUCCESS)
+ tc->tc_error = tc_error;
+
+ return tc_error;
+ }
+
+ /**
+ * The first operation on a tracecut that fails stores its error code
+ * in the tracecut. This function returns that error code, or
+ * #TC_SUCCESS if all operations succeeded. Checking error codes this
+ * ways makes it possible to call several tracecut functions in
+ * sequence without individually checking their error codes.
+ *
+ * Use tc_reset_error() to set a tracecut's error code back to
+ * #TC_SUCCESS.
+ *
+ * \param tc The tracecut to check.
+ * \return The error code of the first failed operation on this
+ * tracecut, or TC_SUCCESS if no operations failed.
+ */
+ enum tc_error
+ tc_error_code (struct tc_tracecut *tc)
+ {
+ return tc->tc_error;
+ }
+
+ /**
+ * Clear the history of any failed operations on this tracecut. After
+ * calling this, tc_error_code() will return #TC_SUCCESS until some
+ * later tracecut operation fails.
+ * \param tc The tracecut to reset.
+ */
+ void
+ tc_reset_error (struct tc_tracecut *tc)
+ {
++ tc->tc_error = TC_SUCCESS;
++}
++
+enum tc_error
+tc_check_param_type(const struct aop_type *type)
+{
+ if(aop_is_pointer_type (type) ||
+ aop_is_all_signed_subtype (type) ||
+ aop_is_all_unsigned_subtype (type) ||
+ aop_is_all_fp_subtype (type)) {
+ return TC_SUCCESS;
+ }
+
+ return TC_INVAL;
}
/**
const struct aop_type *type)
{
struct tc_param *param = NULL;
+ enum tc_error tc_err = TC_SUCCESS;
if (tc_in_compilation)
- return TC_BAD_CONTEXT;
+ return return_error (tc, TC_BAD_CONTEXT);
- if (!aop_is_pointer_type (type))
- return return_error (tc, TC_INVAL);
+ tc_err = tc_check_param_type(type);
+ if(tc_err != TC_SUCCESS)
+ return tc_err;
if (lookup_param (tc, name) != NULL)
- return TC_DUPLICATE;;
+ return return_error (tc, TC_DUPLICATE);
param = (struct tc_param *)malloc (sizeof (struct tc_param));
if (param == NULL)