Exemple #1
0
/*
 * Output text to the screen or to a file depending on the
 * selected hook.  Takes strings with "embedded formatting",
 * such that something within {red}{/} will be printed in red.
 *
 * Note that such formatting will be treated as a "breakpoint"
 * for the printing, so if used within words may lead to part of the
 * word being moved to the next line.
 */
void text_out_e(const char *fmt, ...)
{
	char buf[1024];
	char smallbuf[1024];
	va_list vp;

	const char *start, *next, *text, *tag;
	size_t textlen, taglen = 0;

	/* Begin the Varargs Stuff */
	va_start(vp, fmt);

	/* Do the va_arg fmt to the buffer */
	(void)vstrnfmt(buf, sizeof(buf), fmt, vp);

	/* End the Varargs Stuff */
	va_end(vp);

	start = buf;
	while (next_section(start, 0, &text, &textlen, &tag, &taglen, &next))
	{
		int a = -1;

		memcpy(smallbuf, text, textlen);
		smallbuf[textlen] = 0;

		if (tag)
		{
			char tagbuffer[11];

			/* Colour names are less than 11 characters long. */
			assert(taglen < 11);

			memcpy(tagbuffer, tag, taglen);
			tagbuffer[taglen] = '\0';

			a = color_text_to_attr(tagbuffer);
		}
		
		if (a == -1) 
			a = TERM_WHITE;

		/* Output now */
		text_out_hook(a, smallbuf);

		start = next;
	}
}
Exemple #2
0
int main(int argc, char *argv[])
{
  FILE *fout, *fasm, *fhdr = NULL, *frlist;
  const struct parsed_proto *pp;
  int no_decorations = 0;
  char comment_char = '#';
  char words[20][256];
  char word[256];
  char line[256];
  char last_sym[32];
  unsigned long val;
  unsigned long cnt;
  const char *sym;
  enum dx_type type;
  char **pub_syms;
  int pub_sym_cnt = 0;
  int pub_sym_alloc;
  char **rlist;
  int rlist_cnt = 0;
  int rlist_alloc;
  int header_mode = 0;
  int is_ro = 0;
  int is_label;
  int is_bss;
  int wordc;
  int first;
  int arg_out;
  int arg = 1;
  int len;
  int w, i;
  char *p;
  char *p2;

  if (argc < 4) {
    // -nd: no symbol decorations
    printf("usage:\n%s [-nd] [-i] [-a] <.s> <.asm> <hdrf> [rlist]*\n"
           "%s -hdr <.h> <.asm>\n",
      argv[0], argv[0]);
    return 1;
  }

  for (arg = 1; arg < argc; arg++) {
    if (IS(argv[arg], "-nd"))
      no_decorations = 1;
    else if (IS(argv[arg], "-i"))
      g_cconv_novalidate = 1;
    else if (IS(argv[arg], "-a")) {
      comment_char = '@';
      g_arm_mode = 1;
    }
    else if (IS(argv[arg], "-hdr"))
      header_mode = 1;
    else
      break;
  }

  arg_out = arg++;

  asmfn = argv[arg++];
  fasm = fopen(asmfn, "r");
  my_assert_not(fasm, NULL);

  if (!header_mode) {
    hdrfn = argv[arg++];
    fhdr = fopen(hdrfn, "r");
    my_assert_not(fhdr, NULL);
  }

  fout = fopen(argv[arg_out], "w");
  my_assert_not(fout, NULL);

  pub_sym_alloc = 64;
  pub_syms = malloc(pub_sym_alloc * sizeof(pub_syms[0]));
  my_assert_not(pub_syms, NULL);

  rlist_alloc = 64;
  rlist = malloc(rlist_alloc * sizeof(rlist[0]));
  my_assert_not(rlist, NULL);

  for (; arg < argc; arg++) {
    frlist = fopen(argv[arg], "r");
    my_assert_not(frlist, NULL);

    while (my_fgets(line, sizeof(line), frlist)) {
      p = sskip(line);
      if (*p == 0 || *p == ';')
        continue;

      p = next_word(words[0], sizeof(words[0]), p);
      if (words[0][0] == 0)
        continue;

      if (rlist_cnt >= rlist_alloc) {
        rlist_alloc = rlist_alloc * 2 + 64;
        rlist = realloc(rlist, rlist_alloc * sizeof(rlist[0]));
        my_assert_not(rlist, NULL);
      }
      rlist[rlist_cnt++] = strdup(words[0]);
    }

    fclose(frlist);
    frlist = NULL;
  }

  if (rlist_cnt > 0)
    qsort(rlist, rlist_cnt, sizeof(rlist[0]), cmpstringp);

  qsort(unwanted_syms, ARRAY_SIZE(unwanted_syms),
    sizeof(unwanted_syms[0]), cmpstringp);

  last_sym[0] = 0;

  while (1) {
    next_section(fasm, line);
    if (feof(fasm))
      break;
    if (IS(line + 1, "text"))
      continue;

    if (IS(line + 1, "rdata")) {
      is_ro = 1;
      if (!header_mode)
        fprintf(fout, "\n.section .rodata\n");
    }
    else if (IS(line + 1, "data")) {
      is_ro = 0;
      if (!header_mode)
        fprintf(fout, "\n.data\n");
    }
    else
      aerr("unhandled section: '%s'\n", line);

    if (!header_mode)
      fprintf(fout, ".align %d\n", align_value(4));

    while (my_fgets(line, sizeof(line), fasm))
    {
      sym = NULL;
      asmln++;

      p = sskip(line);
      if (*p == 0)
        continue;

      if (*p == ';') {
        if (IS_START(p, ";org") && sscanf(p + 5, "%Xh", &i) == 1) {
          // ;org is only seen at section start, so assume . addr 0
          i &= 0xfff;
          if (i != 0 && !header_mode)
            fprintf(fout, "\t\t  .skip 0x%x\n", i);
        }
        continue;
      }

      for (wordc = 0; wordc < ARRAY_SIZE(words); wordc++) {
        p = sskip(next_word_s(words[wordc], sizeof(words[0]), p));
        if (*p == 0 || *p == ';') {
          wordc++;
          break;
        }
        if (*p == ',') {
          p = sskip(p + 1);
        }
      }

      if (*p == ';') {
        p = sskip(p + 1);
        if (IS_START(p, "sctclrtype"))
          g_func_sym_pp = NULL;
      }

      if (wordc == 2 && IS(words[1], "ends"))
        break;
      if (wordc <= 2 && IS(words[0], "end"))
        break;
      if (wordc < 2)
        aerr("unhandled: '%s'\n", words[0]);

      // don't cares
      if (IS(words[0], "assume"))
        continue;

      if (IS(words[0], "align")) {
        if (header_mode)
          continue;

        val = parse_number(words[1]);
        fprintf(fout, "\t\t  .align %d", align_value(val));
        goto fin;
      }

      w = 1;
      type = parse_dx_directive(words[0]);
      if (type == DXT_UNSPEC) {
        type = parse_dx_directive(words[1]);
        sym = words[0];
        w = 2;
      }
      if (type == DXT_UNSPEC)
        aerr("unhandled decl: '%s %s'\n", words[0], words[1]);

      if (sym != NULL)
      {
        if (header_mode) {
          int is_str = 0;

          fprintf(fout, "extern ");
          if (is_ro)
            fprintf(fout, "const ");

          switch (type) {
          case DXT_BYTE:
            for (i = w; i < wordc; i++)
              if (words[i][0] == '\'')
                is_str = 1;
            if (is_str)
              fprintf(fout, "char     %s[];\n", sym);
            else
              fprintf(fout, "uint8_t  %s;\n", sym);
            break;

          case DXT_WORD:
            fprintf(fout, "uint16_t %s;\n", sym);
            break;

          case DXT_DWORD:
            fprintf(fout, "uint32_t %s;\n", sym);
            break;

          default:
            fprintf(fout, "_UNKNOWN %s;\n", sym);
            break;
          }

          continue;
        }

        snprintf(last_sym, sizeof(last_sym), "%s", sym);

        pp = proto_parse(fhdr, sym, 1);
        if (pp != NULL) {
          g_func_sym_pp = NULL;

          // public/global name
          if (pub_sym_cnt >= pub_sym_alloc) {
            pub_sym_alloc *= 2;
            pub_syms = realloc(pub_syms, pub_sym_alloc * sizeof(pub_syms[0]));
            my_assert_not(pub_syms, NULL);
          }
          pub_syms[pub_sym_cnt++] = strdup(sym);
        }

        len = strlen(sym);
        fprintf(fout, "%s%s:", no_decorations ? "" : "_", sym);

        len += 2;
        if (len < 8)
          fprintf(fout, "\t");
        if (len < 16)
          fprintf(fout, "\t");
        if (len <= 16)
          fprintf(fout, "  ");
        else
          fprintf(fout, " ");
      }
      else {
        if (header_mode)
          continue;

        fprintf(fout, "\t\t  ");
      }

      // fill out some unwanted strings with zeroes..
      if (type == DXT_BYTE && words[w][0] == '\''
        && is_unwanted_sym(last_sym))
      {
        len = 0;
        for (; w < wordc; w++) {
          if (words[w][0] == '\'') {
            p = words[w] + 1;
            for (; *p && *p != '\''; p++)
              len++;
          }
          else {
            // assume encoded byte
            len++;
          }
        }
        fprintf(fout, ".skip %d", len);
        goto fin;
      }
      else if (type == DXT_BYTE
        && (words[w][0] == '\''
            || (w + 1 < wordc && words[w + 1][0] == '\'')))
      {
        // string; use asciz for most common case
        if (w == wordc - 2 && IS(words[w + 1], "0")) {
          fprintf(fout, ".asciz \"");
          wordc--;
        }
        else
          fprintf(fout, ".ascii \"");

        for (; w < wordc; w++) {
          if (words[w][0] == '\'') {
            p = words[w] + 1;
            p2 = strchr(p, '\'');
            if (p2 == NULL)
              aerr("unterminated string? '%s'\n", p);
            memcpy(word, p, p2 - p);
            word[p2 - p] = 0;
            fprintf(fout, "%s", escape_string(word));
          }
          else {
            val = parse_number(words[w]);
            if (val & ~0xff)
              aerr("bad string trailing byte?\n");
            // unfortunately \xHH is unusable - gas interprets
            // things like \x27b as 0x7b, so have to use octal here
            fprintf(fout, "\\%03lo", val);
          }
        }
        fprintf(fout, "\"");
        goto fin;
      }

      if (w == wordc - 2) {
        if (IS_START(words[w + 1], "dup(")) {
          cnt = parse_number(words[w]);
          p = words[w + 1] + 4;
          p2 = strchr(p, ')');
          if (p2 == NULL)
            aerr("bad dup?\n");
          memmove(word, p, p2 - p);
          word[p2 - p] = 0;

          val = 0;
          if (!IS(word, "?"))
            val = parse_number(word);

          fprintf(fout, ".fill 0x%02lx,%d,0x%02lx",
            cnt, type_size(type), val);
          goto fin;
        }
      }

      if (type == DXT_DWORD && words[w][0] == '\''
        && words[w][5] == '\'' && strlen(words[w]) == 6)
      {
        if (w != wordc - 1)
          aerr("TODO\n");

        p = words[w];
        val = (p[1] << 24) | (p[2] << 16) | (p[3] << 8) | p[4];
        fprintf(fout, ".long 0x%lx", val);
        snprintf(g_comment, sizeof(g_comment), "%s", words[w]);
        goto fin;
      }

      if (type >= DXT_DWORD && strchr(words[w], '.'))
      {
        if (w != wordc - 1)
          aerr("TODO\n");

        if (g_arm_mode && type == DXT_TEN) {
          fprintf(fout, ".fill 10");
          snprintf(g_comment, sizeof(g_comment), "%s %s",
            type_name_float(type), words[w]);
        }
        else
          fprintf(fout, "%s %s", type_name_float(type), words[w]);
        goto fin;
      }

      first = 1;
      fprintf(fout, "%s ", type_name(type));
      for (; w < wordc; w++)
      {
        if (!first)
          fprintf(fout, ", ");

        is_label = is_bss = 0;
        if (w <= wordc - 2 && IS(words[w], "offset")) {
          is_label = 1;
          w++;
        }
        else if (IS(words[w], "?")) {
          is_bss = 1;
        }
        else if (type == DXT_DWORD
                 && !('0' <= words[w][0] && words[w][0] <= '9'))
        {
          // assume label
          is_label = 1;
        }

        if (is_bss) {
          fprintf(fout, "0");
        }
        else if (is_label) {
          p = words[w];
          if (IS_START(p, "loc_") || IS_START(p, "__imp")
             || strchr(p, '?') || strchr(p, '@')
             || bsearch(&p, rlist, rlist_cnt, sizeof(rlist[0]),
                  cmpstringp))
          {
            fprintf(fout, "0");
            snprintf(g_comment, sizeof(g_comment), "%s", p);
          }
          else {
            pp = check_var(fhdr, sym, p);
            if (pp == NULL) {
              fprintf(fout, "%s%s",
                (no_decorations || p[0] == '_') ? "" : "_", p);
            }
            else {
              if (no_decorations)
                fprintf(fout, "%s", pp->name);
              else
                output_decorated_pp(fout, pp);
            }
          }
        }
        else {
          val = parse_number(words[w]);
          if (val < 10)
            fprintf(fout, "%ld", val);
          else
            fprintf(fout, "0x%lx", val);
        }

        first = 0;
      }

fin:
      if (g_comment[0] != 0) {
        fprintf(fout, "\t\t%c %s", comment_char, g_comment);
        g_comment[0] = 0;
      }
      fprintf(fout, "\n");
    }
  }

  fprintf(fout, "\n");

  // dump public syms
  for (i = 0; i < pub_sym_cnt; i++)
    fprintf(fout, ".global %s%s\n",
      no_decorations ? "" : "_", pub_syms[i]);

  fclose(fout);
  fclose(fasm);
  if (fhdr != NULL)
    fclose(fhdr);

  return 0;
}