translate: hdrgen: detect strings, skip std funcs
authornotaz <notasas@gmail.com>
Sun, 8 Mar 2015 21:03:11 +0000 (23:03 +0200)
committernotaz <notasas@gmail.com>
Mon, 9 Mar 2015 01:17:56 +0000 (03:17 +0200)
tools/protoparse.h
tools/translate.c

index a34d1a6..3d70d86 100644 (file)
@@ -42,7 +42,8 @@ struct parsed_proto {
        unsigned int is_noreturn:1;
        unsigned int is_unresolved:1;
        unsigned int is_userstack:1;
-       unsigned int is_oslib:1;      // OS/system library func
+       unsigned int is_include:1;    // not from top-level header
+       unsigned int is_osinc:1;      // OS/system library func
        unsigned int is_arg:1;        // declared in some func arg
        unsigned int has_structarg:1;
        unsigned int has_retreg:1;
@@ -54,16 +55,17 @@ static int hdrfline = 0;
 static void pp_copy_arg(struct parsed_proto_arg *d,
        const struct parsed_proto_arg *s);
 
-static int b_pp_c_handler(char *proto, const char *fname, int is_oslib);
+static int b_pp_c_handler(char *proto, const char *fname,
+       int is_include, int is_osinc);
 
-static int do_protostrs(FILE *fhdr, const char *fname)
+static int do_protostrs(FILE *fhdr, const char *fname, int is_include)
 {
        const char *finc_name;
        const char *hdrfn_saved;
        char protostr[256];
        char path[256];
        char fname_inc[256];
-       int is_oslib;
+       int is_osinc;
        FILE *finc;
        int line = 0;
        int ret;
@@ -72,7 +74,7 @@ static int do_protostrs(FILE *fhdr, const char *fname)
        hdrfn_saved = hdrfn;
        hdrfn = fname;
 
-       is_oslib = strstr(fname, "stdc.hlist")
+       is_osinc = strstr(fname, "stdc.hlist")
                 || strstr(fname, "win32.hlist");
 
        while (fgets(protostr, sizeof(protostr), fhdr))
@@ -99,7 +101,7 @@ static int do_protostrs(FILE *fhdr, const char *fname)
                                        fname_inc, line, finc_name);
                                continue;
                        }
-                       ret = do_protostrs(finc, finc_name);
+                       ret = do_protostrs(finc, finc_name, 1);
                        fclose(finc);
                        if (ret < 0)
                                break;
@@ -116,7 +118,8 @@ static int do_protostrs(FILE *fhdr, const char *fname)
 
                hdrfline = line;
 
-               ret = b_pp_c_handler(protostr, hdrfn, is_oslib);
+               ret = b_pp_c_handler(protostr, hdrfn, is_include,
+                       is_osinc);
                if (ret < 0)
                        break;
        }
@@ -661,7 +664,8 @@ static struct parsed_proto *pp_cache;
 static int pp_cache_size;
 static int pp_cache_alloc;
 
-static int b_pp_c_handler(char *proto, const char *fname, int is_oslib)
+static int b_pp_c_handler(char *proto, const char *fname,
+       int is_include, int is_osinc)
 {
        int ret;
 
@@ -679,7 +683,8 @@ static int b_pp_c_handler(char *proto, const char *fname, int is_oslib)
        if (ret < 0)
                return -1;
 
-       pp_cache[pp_cache_size].is_oslib = is_oslib;
+       pp_cache[pp_cache_size].is_include = is_include;
+       pp_cache[pp_cache_size].is_osinc = is_osinc;
        pp_cache_size++;
        return 0;
 }
@@ -692,7 +697,7 @@ static void build_pp_cache(FILE *fhdr)
        pos = ftell(fhdr);
        rewind(fhdr);
 
-       ret = do_protostrs(fhdr, hdrfn);
+       ret = do_protostrs(fhdr, hdrfn, 0);
        if (ret < 0)
                exit(1);
 
index 81c555b..c7e6ce1 100644 (file)
@@ -1720,7 +1720,7 @@ static void check_func_pp(struct parsed_op *po,
   // fptrs must use 32bit args, callsite might have no information and
   // lack a cast to smaller types, which results in incorrectly masked
   // args passed (callee may assume masked args, it does on ARM)
-  if (!pp->is_oslib) {
+  if (!pp->is_osinc) {
     for (i = 0; i < pp->argc; i++) {
       ret = guess_lmod_from_c_type(&tmp_lmod, &pp->arg[i].type);
       if (ret && tmp_lmod != OPLM_DWORD)
@@ -5488,6 +5488,7 @@ static struct scanned_var {
   char name[NAMELEN];
   enum opr_lenmod lmod;
   unsigned int is_seeded:1;
+  unsigned int is_c_str:1;
 } *hg_vars;
 static int hg_var_cnt;
 
@@ -5874,8 +5875,9 @@ static void hg_fp_resolve_deps(struct func_prototype *fp)
 static void output_hdr_fp(FILE *fout, const struct func_prototype *fp,
   int count)
 {
-  char *p, buf[NAMELEN];
-  const char *cp;
+  const struct parsed_proto *pp;
+  char *p, namebuf[NAMELEN];
+  const char *name;
   int regmask_dep;
   int argc_stack;
   int j, arg;
@@ -5894,6 +5896,21 @@ static void output_hdr_fp(FILE *fout, const struct func_prototype *fp,
     fprintf(fout, "\n");
 #endif
 
+    p = strchr(fp->name, '@');
+    if (p != NULL) {
+      memcpy(namebuf, fp->name, p - fp->name);
+      namebuf[p - fp->name] = 0;
+      name = namebuf;
+    }
+    else
+      name = fp->name;
+    if (name[0] == '_')
+      name++;
+
+    pp = proto_parse(g_fhdr, name, 1);
+    if (pp != NULL && pp->is_include)
+      continue;
+
     regmask_dep = fp->regmask_dep;
     argc_stack = fp->argc_stack;
 
@@ -5919,17 +5936,7 @@ static void output_hdr_fp(FILE *fout, const struct func_prototype *fp,
     else
       fprintf(fout, "  __cdecl       ");
 
-    p = strchr(fp->name, '@');
-    if (p != NULL) {
-      memcpy(buf, fp->name, p - fp->name);
-      buf[p - fp->name] = 0;
-      cp = buf;
-    }
-    else
-      cp = fp->name;
-    if (cp[0] == '_')
-      cp++;
-    fprintf(fout, "%s(", cp);
+    fprintf(fout, "%s(", name);
 
     arg = 0;
     for (j = 0; j < xSP; j++) {
@@ -5976,8 +5983,11 @@ static void output_hdr(FILE *fout)
   for (i = 0; i < hg_var_cnt; i++) {
     var = &hg_vars[i];
 
-    fprintf(fout, "extern %-8s %s;",
-      lmod_c_names[var->lmod], var->name);
+    if (var->is_c_str)
+      fprintf(fout, "extern %-8s %s[];", "char", var->name);
+    else
+      fprintf(fout, "extern %-8s %s;",
+        lmod_c_names[var->lmod], var->name);
 
     if (var->is_seeded)
       fprintf(fout, " // seeded");
@@ -6014,24 +6024,39 @@ static char *my_fgets(char *s, size_t size, FILE *stream)
   return ret;
 }
 
-// '=' needs special treatment..
+// '=' needs special treatment
+// also ' quote
 static char *next_word_s(char *w, size_t wsize, char *s)
 {
-       size_t i;
+  size_t i;
 
-       s = sskip(s);
+  s = sskip(s);
 
-       for (i = 0; i < wsize - 1; i++) {
-               if (s[i] == 0 || my_isblank(s[i]) || (s[i] == '=' && i > 0))
-                       break;
-               w[i] = s[i];
-       }
-       w[i] = 0;
+  i = 0;
+  if (*s == '\'') {
+    w[0] = s[0];
+    for (i = 1; i < wsize - 1; i++) {
+      if (s[i] == 0) {
+        printf("warning: missing closing quote: \"%s\"\n", s);
+        break;
+      }
+      if (s[i] == '\'')
+        break;
+      w[i] = s[i];
+    }
+  }
 
-       if (s[i] != 0 && !my_isblank(s[i]) && s[i] != '=')
-               printf("warning: '%s' truncated\n", w);
+  for (; i < wsize - 1; i++) {
+    if (s[i] == 0 || my_isblank(s[i]) || (s[i] == '=' && i > 0))
+      break;
+    w[i] = s[i];
+  }
+  w[i] = 0;
+
+  if (s[i] != 0 && !my_isblank(s[i]) && s[i] != '=')
+    printf("warning: '%s' truncated\n", w);
 
-       return s + i;
+  return s + i;
 }
 
 static void scan_variables(FILE *fasm)
@@ -6039,9 +6064,10 @@ static void scan_variables(FILE *fasm)
   const struct parsed_proto *pp_c;
   struct scanned_var *var;
   char line[256] = { 0, };
-  char words[2][256];
+  char words[3][256];
   char *p = NULL;
   int wordc;
+  int l;
 
   while (!feof(fasm))
   {
@@ -6095,6 +6121,8 @@ static void scan_variables(FILE *fasm)
 
       if (wordc == 2 && IS(words[1], "ends"))
         break;
+      if (wordc < 2)
+        continue;
 
       if ((hg_var_cnt & 0xff) == 0) {
         hg_vars = realloc(hg_vars, sizeof(hg_vars[0])
@@ -6127,8 +6155,13 @@ static void scan_variables(FILE *fasm)
         var->lmod = OPLM_DWORD;
       else if (IS(words[1], "dw"))
         var->lmod = OPLM_WORD;
-      else if (IS(words[1], "db"))
+      else if (IS(words[1], "db")) {
         var->lmod = OPLM_BYTE;
+        if (wordc >= 3 && (l = strlen(words[2])) > 4) {
+          if (words[2][0] == '\'' && IS(words[2] + l - 2, ",0"))
+            var->is_c_str = 1;
+        }
+      }
       else if (IS(words[1], "dq"))
         var->lmod = OPLM_QWORD;
       //else if (IS(words[1], "dt"))