You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/05/08 16:38:18 UTC

[incubator-nuttx] 02/02: tools/mksyscall: Unify the fixed and variable arguments process

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit a6c82a27dbefda646f07df1ebd6db3899f0710a5
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Fri May 8 03:33:36 2020 +0800

    tools/mksyscall: Unify the fixed and variable arguments process
    
    Signed-off-by: Xiang Xiao <ia...@xiaomi.com>
---
 tools/mksyscall.c | 186 +++++++++++++++++++++---------------------------------
 1 file changed, 71 insertions(+), 115 deletions(-)

diff --git a/tools/mksyscall.c b/tools/mksyscall.c
index ac8860b..f87e374 100644
--- a/tools/mksyscall.c
+++ b/tools/mksyscall.c
@@ -42,31 +42,14 @@ static FILE *g_stubstream;
  * Private Functions
  ****************************************************************************/
 
-static bool is_vararg(const char *type, int ndx, int nparms)
+static bool is_vararg(const char *type)
 {
-  if (strcmp(type, "...") == 0)
-    {
-      if (ndx != (nparms - 1))
-        {
-          fprintf(stderr, "%d: ... is not the last in the argument list\n",
-                  g_lineno);
-          exit(11);
-        }
-      else if (nparms < 2)
-        {
-          fprintf(stderr, "%d: Need one parameter before ...\n", g_lineno);
-          exit(14);
-        }
-
-      return true;
-    }
-
-  return false;
+  return strcmp(type, "...") == 0;
 }
 
 static bool is_union(const char *type)
 {
-  return (strncmp(type, "union", 5) == 0);
+  return strncmp(type, "union ", 6) == 0;
 }
 
 static const char *check_funcptr(const char *type)
@@ -202,14 +185,12 @@ static FILE *open_proxy(void)
   return stream;
 }
 
-static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
+static void generate_proxy(int nfixed, int nparms)
 {
   FILE *stream = open_proxy();
   char formal[MAX_PARMSIZE];
+  char actual[MAX_PARMSIZE];
   char fieldname[MAX_PARMSIZE];
-  bool bvarargs = false;
-  int nformal;
-  int nactual;
   int i;
 
   /* Generate "up-front" information, include correct header files */
@@ -228,16 +209,10 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
    * final parameter type will be encoded as "..."
    */
 
-  if (is_vararg(g_parm[PARM1_INDEX + nparms - 1], nparms - 1, nparms))
+  if (nfixed != nparms)
     {
-      nformal = nparms - 1;
-      bvarargs = true;
       fprintf(stream, "#include <stdarg.h>\n");
     }
-  else
-    {
-      nformal = nparms;
-    }
 
   if (g_parm[HEADER_INDEX] && strlen(g_parm[HEADER_INDEX]) > 0)
     {
@@ -259,13 +234,13 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
 
   /* Generate the formal parameter list */
 
-  if (nformal <= 0)
+  if (nparms <= 0)
     {
       fprintf(stream, "void");
     }
   else
     {
-      for (i = 0; i < nformal; i++)
+      for (i = 0; i < nfixed; i++)
         {
           /* The formal and actual parameter types may be encoded.. extra the
            * formal parameter type.
@@ -288,7 +263,7 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
 
   /* Handle the end of the formal parameter list */
 
-  if (bvarargs)
+  if (i < nparms)
     {
       fprintf(stream, ", ...)\n{\n");
 
@@ -296,25 +271,32 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
        * the varargs.
        */
 
-      if (nvartypes > 0)
+      fprintf(stream, "  va_list ap;\n");
+      for (; i < nparms; i++)
         {
-          fprintf(stream, "  va_list ap;\n");
+          get_formalparmtype(g_parm[PARM1_INDEX + i], formal);
+          fprintf(stream, "  %s parm%d;\n", formal, i + 1);
+        }
 
-          for (i = 0; i < nvartypes; i++)
-            {
-              fprintf(stream, "  %s parm%d;\n", vartypes[i], nparms + i);
-            }
+      fprintf(stream, "\n  va_start(ap, parm%d);\n", nfixed);
 
-          fprintf(stream, "\n  va_start(ap, parm%d);\n", nparms - 1);
+      for (i = nfixed; i < nparms; i++)
+        {
+          get_formalparmtype(g_parm[PARM1_INDEX + i], formal);
+          get_actualparmtype(g_parm[PARM1_INDEX + i], actual);
 
-          for (i = 0; i < nvartypes; i++)
+          if (is_union(formal))
             {
-              fprintf(stream, "  parm%d = va_arg(ap, %s);\n",
-                      nparms + i, vartypes[i]);
+              fprintf(stream, "  parm%d = (%s)va_arg(ap, %s);\n",
+                      i + 1, formal, actual);
+            }
+          else
+            {
+              fprintf(stream, "  parm%d = va_arg(ap, %s);\n", i + 1, actual);
             }
-
-          fprintf(stream, "  va_end(ap);\n\n");
         }
+
+      fprintf(stream, "  va_end(ap);\n\n");
     }
   else
     {
@@ -325,20 +307,14 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
    * are special cases.
    */
 
-  nactual = nformal;
-  if (bvarargs)
-    {
-      nactual += nvartypes;
-    }
-
   if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
     {
-      fprintf(stream, "  (void)sys_call%d(", nactual);
+      fprintf(stream, "  (void)sys_call%d(", nparms);
     }
   else
     {
       fprintf(stream, "  return (%s)sys_call%d(", g_parm[RETTYPE_INDEX],
-              nactual);
+              nparms);
     }
 
   /* Create the parameter list with the matching types.  The first parameter
@@ -347,11 +323,11 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
 
   fprintf(stream, "(unsigned int)SYS_%s", g_parm[NAME_INDEX]);
 
-  for (i = 0; i < nactual; i++)
+  for (i = 0; i < nparms; i++)
     {
       /* Is the parameter a union member */
 
-      if (i < nparms && is_union(g_parm[PARM1_INDEX + i]))
+      if (is_union(g_parm[PARM1_INDEX + i]))
         {
           /* Then we will have to pick a field name that can be cast to a
            * uintptr_t.  There probably should be some error handling here
@@ -369,10 +345,10 @@ static void generate_proxy(int nparms, csvparm_t *vartypes, int nvartypes)
 
   /* Handle the tail end of the function. */
 
-  fprintf(stream, ");\n}\n\n");
+  fprintf(stream, ");\n}\n");
   if (g_parm[COND_INDEX][0] != '\0')
     {
-      fprintf(stream, "#endif /* %s */\n", g_parm[COND_INDEX]);
+      fprintf(stream, "\n#endif /* %s */\n", g_parm[COND_INDEX]);
     }
 
   fclose(stream);
@@ -428,13 +404,12 @@ static void stub_close(FILE *stream)
     }
 }
 
-static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
+static void generate_stub(int nfixed, int nparms)
 {
   FILE *stream = open_stub();
   char formal[MAX_PARMSIZE];
   char actual[MAX_PARMSIZE];
   int i;
-  int j;
 
   /* Generate "up-front" information, include correct header files */
 
@@ -470,19 +445,7 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
 
   for (i = 0; i < nparms; i++)
     {
-      /* Check for a variable number of arguments */
-
-      if (is_vararg(g_parm[PARM1_INDEX + i], i, nparms))
-        {
-          for (j = 0; j < nvartypes; j++)
-            {
-              fprintf(stream, ", uintptr_t parm%d", nparms + j);
-            }
-        }
-      else
-        {
-          fprintf(stream, ", uintptr_t parm%d", i + 1);
-        }
+      fprintf(stream, ", uintptr_t parm%d", i + 1);
     }
 
   fprintf(stream, ")\n{\n");
@@ -508,7 +471,7 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
     {
       /* Get the formal type of the parameter, and get the type that we
        * actually have to cast to.  For example for a formal type like
-       * 'int parm[]' we have to cast the actual parameter to 'int*'.
+       * 'int parm[]' we have to cast the actual parameter to 'int *'.
        * The worst is a union type like 'union sigval' where we have to
        * cast to (union sigval)((FAR void *)parm)
        * -- Yech.
@@ -523,57 +486,35 @@ static void generate_stub(int nparms, csvparm_t *vartypes, int nvartypes)
 
       if (i > 0)
         {
-          /* Check for a variable number of arguments */
+          fprintf(stream, ", ");
+        }
 
-          if (is_vararg(actual, i, nparms))
-            {
-              for (j = 0; j < nvartypes; j++)
-                {
-                  fprintf(stream, ", (%s)parm%d", vartypes[j], i + j + 1);
-                }
-            }
-          else
-            {
-              if (is_union(formal))
-                {
-                  fprintf(stream, ", (%s)((%s)parm%d)", formal, actual,
-                          i + 1);
-                }
-              else
-                {
-                  fprintf(stream, ", (%s)parm%d", actual, i + 1);
-                }
-            }
+      if (is_union(formal))
+        {
+          fprintf(stream, "(%s)((%s)parm%d)", formal, actual, i + 1);
         }
       else
         {
-          if (is_union(formal))
-            {
-              fprintf(stream, "(%s)((%s)parm%d)", formal, actual, i + 1);
-            }
-          else
-            {
-              fprintf(stream, "(%s)parm%d", actual, i + 1);
-            }
+          fprintf(stream, "(%s)parm%d", actual, i + 1);
         }
     }
 
-  /* Tail end of the function.  If the proxied function has no return
+  /* Tail end of the function.  If the stubs function has no return
    * value, just return zero (OK).
    */
 
   if (strcmp(g_parm[RETTYPE_INDEX], "void") == 0)
     {
-      fprintf(stream, ");\n  return 0;\n}\n\n");
+      fprintf(stream, ");\n  return 0;\n}\n");
     }
   else
     {
-      fprintf(stream, ");\n}\n\n");
+      fprintf(stream, ");\n}\n");
     }
 
   if (g_parm[COND_INDEX][0] != '\0')
     {
-      fprintf(stream, "#endif /* %s */\n", g_parm[COND_INDEX]);
+      fprintf(stream, "\n#endif /* %s */\n", g_parm[COND_INDEX]);
     }
 
   stub_close(stream);
@@ -668,8 +609,7 @@ int main(int argc, char **argv, char **envp)
 
   while ((ptr = read_line(stream)) != NULL)
     {
-      csvparm_t *vartypes = NULL;
-      int nvartypes = 0;
+      int nfixed;
 
       /* Parse the line from the CVS file */
 
@@ -680,6 +620,10 @@ int main(int argc, char **argv, char **envp)
           exit(8);
         }
 
+      /* Assume no variable arguments by default */
+
+      nfixed = nargs - PARM1_INDEX;
+
       /* Search for an occurrence of "...".  This is followed by the list
        * types in the variable arguments.  The number of types is the
        * maximum number of variable arguments.
@@ -687,28 +631,40 @@ int main(int argc, char **argv, char **envp)
 
       for (i = PARM1_INDEX; i < nargs; i++)
         {
-          if (strcmp(g_parm[i], "...") == 0)
+          if (is_vararg(g_parm[i]))
             {
-              nvartypes = nargs - i - 1;
-              nargs     = i + 1;
+              /* "..." is the last argument? */
 
-              if (nvartypes > 0)
+              if (i == --nargs)
                 {
-                  vartypes = &g_parm[i + 1];
+                  /* Yes, generate the default variable arguments */
+
+                  while (nargs < PARM1_INDEX + 6)
+                    {
+                      strcpy(g_parm[nargs++], "uintptr_t");
+                    }
+                }
+              else
+                {
+                  /* Move up one slot to overwrite "..." */
+
+                  memmove(g_parm[i], g_parm[i + 1],
+                          sizeof(g_parm[i]) * (nargs - i));
                 }
 
+              nfixed = i - PARM1_INDEX;
               break;
             }
         }
 
       if (proxies)
         {
-          generate_proxy(nargs - PARM1_INDEX, vartypes, nvartypes);
+          generate_proxy(nfixed, nargs - PARM1_INDEX);
         }
       else
         {
           g_stubstream = NULL;
-          generate_stub(nargs - PARM1_INDEX, vartypes, nvartypes);
+          generate_stub(nfixed, nargs - PARM1_INDEX);
           if (g_stubstream != NULL)
             {
               fprintf(g_stubstream, "\n#endif /* __STUB_H */\n");