Clarifies rules for allowed symbol and param names.
authorJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 8 Apr 2011 00:14:38 +0000 (20:14 -0400)
committerJustin Seyster <jseyster@cs.sunysb.edu>
Fri, 8 Apr 2011 00:14:38 +0000 (20:14 -0400)
Simplifies tc_declare_call_symbol parsing code.

src/tracecut.c
src/tracecut.h

index bcb526c22c6065258361c5874e63e2c9e42e6803..8205a2f1b3ca7a09810428f4253587204d5b4780 100644 (file)
@@ -31,6 +31,7 @@
 #undef PACKAGE_TARNAME
 #undef PACKAGE_VERSION
 
+#include <ctype.h>
 #include <locale.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -169,6 +170,33 @@ return_error (struct tc_tracecut *tc, enum tc_error tc_error)
   return tc_error;
 }
 
+/* Tracecut identifiers must consist entirely of the characters
+   [_0-9a-zA-Z] with no spaces. */
+static int
+is_id_char(char c)
+{
+  return (c == '_' || ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z'))
+         || ((c >= 'A') && (c <= 'Z')));
+}
+
+/* Does the input string follow the rules for tracecut identifiers? */
+static int
+is_valid_identifier(const char *str)
+{
+  int i;
+
+  for (i = 0; str[i] != '\0'; i++)
+    {
+      if (!is_id_char (*str))
+       return 0;
+    }
+
+  if (i > TC_MAX_ID_SIZE)
+    return 0;
+
+  return 1;
+}
+
 /**
  * The first operation on a tracecut that fails stores its error code
  * in the tracecut.  This function returns that error code, or
@@ -201,8 +229,8 @@ tc_reset_error (struct tc_tracecut *tc)
       tc->tc_error = TC_SUCCESS;
 }
 
-enum tc_error
-tc_check_param_type(const struct aop_type *type)
+static enum tc_error
+check_param_type(const struct aop_type *type)
 {
     if(aop_is_pointer_type (type) ||
        aop_is_all_signed_subtype (type) ||
@@ -232,6 +260,10 @@ tc_check_param_type(const struct aop_type *type)
  *      started;
  * - #TC_DUPLICATE, if there already exists a param with the
  *    specified name;
+ * - #TC_BAD_ID if name is not an acceptable identifier.  (Identifiers
+ *    must only contain letters, numbers and the underscore character,
+ *    with no spaces.  Identifiers are case sensitive and should be no
+ *    longer than #TC_MAX_ID_SIZE.)
  * - #TC_INVAL, if aop_is_pointer_type() is false for the specified
  *    type;
  * - #TC_NOMEM, if memory runs out.
@@ -246,9 +278,12 @@ tc_add_param (struct tc_tracecut *tc, const char *name,
   if (tc_in_compilation)
     return return_error (tc, TC_BAD_CONTEXT);
 
-  tc_err = tc_check_param_type(type);
+  if (!is_valid_identifier (name))
+    return return_error (tc, TC_BAD_ID);
+
+  tc_err = check_param_type(type);
   if(tc_err != TC_SUCCESS) 
-    return tc_err;
+    return return_error (tc, tc_err);
 
   if (lookup_param (tc, name) != NULL)
     return return_error (tc, TC_DUPLICATE);
@@ -310,6 +345,10 @@ lookup_call_symbol (struct tc_tracecut *tc, const char *name)
  *      started;
  * - #TC_DUPLICATE, if there already exists a symbol with the
  *    specified name;
+ * - #TC_BAD_ID if name is not an acceptable identifier.  (Identifiers
+ *    must only contain letters, numbers and the underscore character,
+ *    with no spaces.  Identifiers are case sensitive and should be no
+ *    longer than #TC_MAX_ID_SIZE.)
  * - #TC_NOMEM, if memory runs out.
  */
 enum tc_error
@@ -321,6 +360,9 @@ tc_add_call_symbol (struct tc_tracecut *tc, const char *name,
   if (tc_in_compilation)
     return return_error (tc, TC_BAD_CONTEXT);
 
+  if (!is_valid_identifier (name))
+    return return_error (tc, TC_BAD_ID);
+
   if (lookup_call_symbol (tc, name) != NULL)
     return return_error (tc, TC_DUPLICATE);
 
@@ -432,6 +474,14 @@ tc_bind_to_return_value (struct tc_tracecut *tc, const char *param_name,
   return add_call_symbol_binding (tc, param_name, symbol_name, -1);
 }
 
+/**
+ * \cond HIDDEN_SYMBOLS
+ */
+#define MAX_FUNC_SIZE 255
+/**
+ * \endcond
+ */
+
 /**
  * Create a function call symbol along with its bindings in one
  * statement.  The declaration is a string containing the function
@@ -460,11 +510,15 @@ tc_bind_to_return_value (struct tc_tracecut *tc, const char *param_name,
  * - #TC_BAD_CONTEXT, when called after compilation has already
  *      started;
  * - #TC_INVAL, when the declaration is invalid because of syntax
     errors;
*    errors;
  * - #TC_DUPLICATE, if there already exists a symbol with the
  *    specified name;
+ * - #TC_BAD_ID if name is not an acceptable identifier.  (Identifiers
+ *    must only contain letters, numbers and the underscore character,
+ *    with no spaces.  Identifiers are case sensitive and should be no
+ *    longer than #TC_MAX_ID_SIZE.)
  * - #TC_NOENT, if one of the parameters in the declaration does not
     exist;
*    exist;
  * - #TC_NOMEM, if memory runs out.
  */
 enum tc_error
@@ -472,54 +526,57 @@ tc_declare_call_symbol (struct tc_tracecut *tc, const char *name,
                        const char *declaration,
                        enum aop_insert_location location)
 {
-  int i = 0, pos = 0;
-  int param_num = 0, space_track = 0;
+  int i = 0, pos;
+  int param_num;
   enum tc_error tc_err;
-  char func_name[MAX_FUNC_SIZE], return_param[MAX_PARAM_SIZE], param_name[MAX_PARAM_SIZE];
+  char func_name[MAX_FUNC_SIZE];
+  char param_name[TC_MAX_ID_SIZE];
 
   if (tc_in_compilation)
     return return_error (tc, TC_BAD_CONTEXT);
-  
-  strcpy(return_param, "");
-  strcpy(func_name, "");
-  strcpy(param_name, "");
+
+  strcpy (param_name, "");
 
   /* Eliminate white spaces */
-  while (declaration[i] == ' '
+  while (isspace(declaration[i])
     i++;
 
   /* Check if return parameter is present */
   if (declaration[i] == '(') 
     {
-      /* Copy the return param */
+      /* Consume the (. */
       i++;
+
       /* Remove beginning spaces */
-      while (declaration[i] == ' ')
+      while (isspace(declaration[i]))
        i++;
-      while (declaration[i] != ')') 
+
+      if (declaration[i] == '?')
        {
-         /* If space, copy the name */
-         if(declaration[i] == ' ') 
-           break;
-         return_param[pos++] = declaration[i++];
-       }
-      return_param[pos] = '\0';
-      pos = 0;
-      if (declaration[i] == ')') 
+         /* Consume the ?. */
          i++;
+       }
       else
        {
-         while (declaration[i] != ')') 
-           {
-             if(declaration[i] == ' ')
-               i++;
-             else
-               {
-                 return TC_INVAL;
-               }
-           }
-           i++;
+         /* Copy the return param */
+         pos = 0;
+         while (is_id_char(declaration[i]) && pos + 1 < TC_MAX_ID_SIZE)
+           param_name[pos++] = declaration[i++];
+         param_name[pos] = '\0';
+
+         /* Bad return param. */
+         if (pos == 0)
+           return return_error (tc, TC_INVAL);
        }
+
+      while (isspace(declaration[i]))
+       i++;
+
+      /* Unmatched parenthesis. */
+      if (declaration[i] != ')')
+       return return_error (tc, TC_INVAL);
+
+      i++;  /* Consume the ). */
     }
 
   /* Ignore the white spaces in between */
@@ -527,113 +584,99 @@ tc_declare_call_symbol (struct tc_tracecut *tc, const char *name,
     i++;
 
   /* Copy the function name */
-  while(declaration[i] != '(') 
-    {
-      if (declaration[i] == ' ') 
-       break;
-      func_name[pos++] = declaration[i++];
-    }
-    
-  func_name[pos] = '\0';
   pos = 0;
+  while(is_id_char(declaration[i]) && pos + 1 < MAX_FUNC_SIZE)
+    func_name[pos++] = declaration[i++];
+  func_name[pos] = '\0';
 
-  if (declaration[i] == '(') 
+  while (isspace(declaration[i]))
     i++;
-  else
-    {
-      while (declaration[i] != '(') 
-       {
-          if (declaration[i] == ' ')
-           i++;
-         else 
-           {
-             return TC_INVAL;
-           }
-       }
-      i++;
-    }
+
+  if (pos == 0 || declaration[i] != '(')
+    return return_error (tc, TC_INVAL);
+
+  /* Consume the (. */
+  i++;
+
   /* Add functiona name */
-  if (strcmp(func_name, "")) 
-    {
-      tc_err = tc_add_call_symbol (tc, 
-                               name,
-                               func_name, 
-                               location);
-      if (tc_err != TC_SUCCESS) 
-        {
-          return tc_err;
-        }
-    }
+  tc_err = tc_add_call_symbol (tc, name, func_name, location);
+  if (tc_err != TC_SUCCESS) 
+    return tc_err;
 
   /* Bind return parameter */
-  if (strcmp(return_param, ""))
+  if (strcmp(param_name, "") != 0)
     { 
-      tc_err = tc_bind_to_return_value (tc, 
-                                    return_param,
-                                    name);
-
-       if (tc_err != TC_SUCCESS) 
-         {
-            return tc_err;
-         }
-    }
+      tc_err = tc_bind_to_return_value (tc, param_name, name);
 
-  /* Skip spaces */
-  while (declaration[i] == ' ')
-    i++;
+      if (tc_err != TC_SUCCESS) 
+       return tc_err;
+    }
 
-  /* Parse function parameters and add them */
-  while (declaration[i] != '\0') 
+  /* Parse function parameters and add them. */
+  for (param_num = 0; ; param_num++)
     {
-      if (declaration[i] == ' ' && pos == 0) 
-        { 
-          /* If it is beginning of the parameter */
+      /* Skip spaces */
+      while (isspace(declaration[i]))
+       i++;
+
+      /* Special case: no paremeters. */
+      if (declaration[i] == ')')
+       {
          i++;
-          continue;
-        }
-      else if (declaration[i] == ' '  && pos != 0) 
+         break;
+       }
+
+      if (declaration[i] == '?')
        {
-         /* Space while parsing the param name */
-         space_track = 1;
+         /* Consume the ? and ignore this parameter. */
          i++;
-         continue;
        }
-      else if ((declaration[i] != ')' && declaration[i] != ',') &&
-             (space_track == 1)) 
+      else
        {
-         return TC_INVAL;
+         pos = 0;
+         while (is_id_char(declaration[i]) && pos + 1 < TC_MAX_ID_SIZE)
+           param_name[pos++] = declaration[i++];
+         param_name[pos] = '\0';
+
+         if (pos == 0)
+           return return_error (tc, TC_INVAL);
+
+         /* Param found, insert it */
+         tc_err = tc_bind_to_call_param (tc, param_name, name, param_num);
+
+         if (tc_err != TC_SUCCESS) 
+           return tc_err;
+       }
+
+      /* Skip spaces */
+      while (isspace(declaration[i]))
+       i++;
+
+      if (declaration[i] == ')')
+       {
+         /* Done with parameters. */
+         i++;
+         break;
+       }
+      else if (declaration[i] == ',')
+       {
+         /* Consume the comma. */
+         i++;
+       }
+      else
+       {
+         return return_error (tc, TC_INVAL);
        }
-      else if (declaration[i] == ',' || declaration[i] == ')') 
-        {
-          /* Store param */
-         space_track = 0;
-          param_name[pos] = '\0';
-        
-         printf("%s\n", param_name);
-         if(strcmp(param_name, "?") && pos != 0)
-           {
-             /* Param found, insert it */
-             tc_err = tc_bind_to_call_param (tc, 
-                                   param_name,
-                                   name, 
-                                   param_num);
-
-             if (tc_err != TC_SUCCESS) 
-                {
-                 return tc_err;
-                }
-           }
-         param_num++;
-          i++;
-          pos = 0;
-          continue;
-        }
-     
-      param_name[pos++] = declaration[i++];
     }
 
- return return_error (tc, TC_SUCCESS);
+  /* Make sure there's no junk hanging off the end of the
+     declaration. */
+  while (isspace(declaration[i]))
+    i++;
+  if (declaration[i] != '\0')
+    return return_error (tc, TC_INVAL);
+
+  return return_error (tc, TC_SUCCESS);
 }
 
 /**
@@ -903,10 +946,16 @@ insert_transition_event_advice (struct aop_joinpoint *jp, int tc_index,
                     AOP_TERM_ARG);
 }
 
+/**
+ * \cond HIDDEN_SYMBOLS
+ */
 struct join_on_call_arg {
   struct tc_tracecut *tc;
   struct tc_call_symbol *symbol;
 };
+/**
+ * \endcond
+ */
 
 static void
 join_on_call (struct aop_joinpoint *jp, void *callback_arg)
index 6149dc49ceb525f8e7f5c9c3dd6e733a09d29c87..3ae3768da2bfcb83cdff513cdd3e3327ecb9251d 100644 (file)
  * All tracecut functions have a <code>tc_</code> prefix.
  */
 
-#define MAX_PARAM_IN_DECL 10
-#define MAX_PARAM_SIZE 100
-#define MAX_FUNC_SIZE 100
-
 struct aop_joinpoint;
 struct aop_type;
 struct tc_tracecut;
 
+/**
+ * Maximum size for a symbol and param names.
+ */
+#define TC_MAX_ID_SIZE 255
+
 /**
  * Possible error return values for tracecut functions.
  */
@@ -73,6 +74,14 @@ enum tc_error {
    */
   TC_DUPLICATE,
 
+  /**
+   * Attempt to name a symbol of param with a bad identifier.
+   * (Identifiers must only contain letters, numbers and the
+   * underscore character, with no spaces.  Identifiers are case
+   * sensitive.)
+   */
+  TC_BAD_ID,
+
   /**
    * Attempt to reference a name that does not exist.
    */
@@ -84,11 +93,6 @@ enum tc_error {
   TC_NOMEM,
 };
 
-struct param_name_t
-{
-    char param_name[MAX_PARAM_SIZE];
-};
-
 extern enum tc_error tc_error_code (struct tc_tracecut *tc);
 extern void tc_reset_error (struct tc_tracecut *tc);