Example #1
0
File: rv2.c Project: NREL/Radiance
void
saveview(				/* save view to rad file */
	char  *s
)
{
	char  view[64];
	char  *fname;
	FILE  *fp;

	if (*atos(view, sizeof(view), s)) {
		if (isint(view)) {
			error(COMMAND, "cannot write view by number");
			return;
		}
		s = sskip(s);
	}
	if (nextword(rifname, sizeof(rifname), s) == NULL && !rifname[0]) {
		error(COMMAND, "no previous rad file");
		return;
	}
	if ((fname = getpath(rifname, NULL, 0)) == NULL ||
			(fp = fopen(fname, "a")) == NULL) {
		sprintf(errmsg, "cannot open \"%s\"", rifname);
		error(COMMAND, errmsg);
		return;
	}
	fputs("view= ", fp);
	fputs(view, fp);
	fprintview(&ourview, fp);
	putc('\n', fp);
	fclose(fp);
}
Example #2
0
int
getinterest(		/* get area of interest */
	char  *s,
	int  direc,
	FVECT  vec,
	double  *mp
)
{
	int  x, y;
	RAY  thisray;
	int  i;

	if (sscanf(s, "%lf", mp) != 1)
		*mp = 1.0;
	else if (*mp < -FTINY)		/* negative zoom is reduction */
		*mp = -1.0 / *mp;
	else if (*mp <= FTINY) {	/* too small */
		error(COMMAND, "illegal magnification");
		return(-1);
	}
	if (!sscanvec(sskip(s), vec)) {
		if (dev->getcur == NULL)
			return(-1);
		(*dev->comout)("Pick view center\n");
		if ((*dev->getcur)(&x, &y) == ABORT)
			return(-1);
		if ((thisray.rmax = viewray(thisray.rorg, thisray.rdir,
			&ourview, (x+.5)/hresolu, (y+.5)/vresolu)) < -FTINY) {
			error(COMMAND, "not on image");
			return(-1);
		}
		if (!direc || ourview.type == VT_PAR) {
			rayorigin(&thisray, PRIMARY, NULL, NULL);
			if (!localhit(&thisray, &thescene)) {
				error(COMMAND, "not a local object");
				return(-1);
			}
		}
		if (direc)
			if (ourview.type == VT_PAR)
				for (i = 0; i < 3; i++)
					vec[i] = thisray.rop[i] - ourview.vp[i];
			else
				VCOPY(vec, thisray.rdir);
		else
			VCOPY(vec, thisray.rop);
	} else if (direc) {
		for (i = 0; i < 3; i++)
			vec[i] -= ourview.vp[i];
		if (normalize(vec) == 0.0) {
			error(COMMAND, "point at view origin");
			return(-1);
		}
	}
	return(0);
}
Example #3
0
static void next_section(FILE *fasm, char *name)
{
  char words[2][256];
  char line[256];
  int wordc;
  char *p;

  name[0] = 0;

  while (my_fgets(line, sizeof(line), fasm))
  {
    wordc = 0;
    asmln++;

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

    if (*p == ';')
      continue;

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

    if (wordc < 2)
      continue;

    if (!IS(words[1], "segment"))
      continue;

    strcpy(name, words[0]);
    break;
  }
}
Example #4
0
static int ui_color_load(struct advance_ui_context* context, adv_conf* cfg_context, int f, int b, const char* tag)
{
	const char* fs;
	const char* bs;
	const char* s;
	int p;
	char c;
	char* d;

	s = conf_string_get_default(cfg_context, tag);

	d = strdup(s);

	p = 0;

	fs = stoken(&c, &p, d, " ", "");
	if (c != ' ') {
		target_err("Error in option %s\n", tag);
		return -1;
	}
	sskip(&p, d, " ");
	bs = stoken(&c, &p, d, " ", "");
	if (c != 0) {
		target_err("Error in option %s\n", tag);
		return -1;
	}

	if (f >= 0) {
		if (ui_color_hex(&context->config.ui_color[f], fs) != 0) {
			target_err("Error in option %s\n", tag);
			return -1;
		}
	}

	if (b >= 0) {
		if (ui_color_hex(&context->config.ui_color[b], bs) != 0) {
			target_err("Error in option %s\n", tag);
			return -1;
		}
	}

	free(d);

	return 0;
}
Example #5
0
static char *next_word_s(char *w, size_t wsize, char *s)
{
  int quote = 0;
	size_t i;

	s = sskip(s);

	for (i = 0; i < wsize - 1; i++) {
    if (s[i] == '\'')
      quote ^= 1;
		if (s[i] == 0 || (!quote && (my_isblank(s[i]) || s[i] == ',')))
			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;
}
Example #6
0
/* Return the hash algorithm from a KSBA sig-val. SIGVAL is a
   canonical encoded S-expression.  Return 0 if the hash algorithm is
   not encoded in SIG-VAL or it is not supported by libgcrypt.  */
int
hash_algo_from_sigval (const unsigned char *sigval)
{
    const unsigned char *s = sigval;
    size_t n;
    int depth;
    char buffer[50];

    if (!s || *s != '(')
        return 0; /* Invalid S-expression.  */
    s++;
    n = snext (&s);
    if (!n)
        return 0; /* Invalid S-expression.  */
    if (!smatch (&s, n, "sig-val"))
        return 0; /* Not a sig-val.  */
    if (*s != '(')
        return 0; /* Invalid S-expression.  */
    s++;
    /* Skip over the algo+parameter list.  */
    depth = 1;
    if (sskip (&s, &depth) || depth)
        return 0; /* Invalid S-expression.  */
    if (*s != '(')
        return 0; /* No futher list.  */
    /* Check whether this is (hash ALGO).  */
    s++;
    n = snext (&s);
    if (!n)
        return 0; /* Invalid S-expression.  */
    if (!smatch (&s, n, "hash"))
        return 0; /* Not a "hash" keyword.  */
    n = snext (&s);
    if (!n || n+1 >= sizeof (buffer))
        return 0; /* Algorithm string is missing or too long.  */
    memcpy (buffer, s, n);
    buffer[n] = 0;

    return gcry_md_map_name (buffer);
}
Example #7
0
File: rv2.c Project: NREL/Radiance
void
loadview(				/* load view from rad file */
	char  *s
)
{
	char  buf[512];
	char  *fname;
	FILE  *fp;
	VIEW  nv;

	strcpy(buf, "rad -n -s -V -v ");
	if (sscanf(s, "%s", buf+strlen(buf)) == 1)
		s = sskip(s);
	else
		strcat(buf, "1");
	if (nextword(rifname, sizeof(rifname), s) == NULL && !rifname[0]) {
		error(COMMAND, "no previous rad file");
		return;
	}
	if ((fname = getpath(rifname, "", R_OK)) == NULL) {
		sprintf(errmsg, "cannot access \"%s\"", rifname);
		error(COMMAND, errmsg);
		return;
	}
	sprintf(buf+strlen(buf), " %s", fname);
	if ((fp = popen(buf, "r")) == NULL) {
		error(COMMAND, "cannot run rad");
		return;
	}
	buf[0] = '\0';
	fgets(buf, sizeof(buf), fp);
	pclose(fp);
	nv = stdview;
	if (!sscanview(&nv, buf)) {
		error(COMMAND, "rad error -- no such view?");
		return;
	}
	newview(&nv);
}
adv_error monitor_conversion_legacy(adv_conf* context)
{
	char buffer[1024];
	adv_error p_error;
	adv_error h_error;
	adv_error v_error;
	const char* p;
	const char* h;
	const char* v;
	char* ps;
	char* hs;
	char* vs;
	char c;
	int pi,hi,vi;

	/* LEGACY support of old device_video_p/h/vclock format */
	p_error = conf_string_section_get(context, "", "device_video_pclock", &p);
	h_error = conf_string_section_get(context, "", "device_video_hclock", &h);
	v_error = conf_string_section_get(context, "", "device_video_vclock", &v);

	/* check if all are missing */
	if (p_error != 0 && h_error != 0 && v_error != 0)
		return 0;

	/* partially missing */
	if (p_error != 0 || h_error != 0 || v_error != 0) {
		error_set("Missing options 'device_video_p/h/vclock'");
		return -1;
	}

	buffer[0] = 0;

	ps = strdup(p);
	hs = strdup(h);
	vs = strdup(v);

	/* set the new format */
	pi = 0;
	sskip(&pi, ps, " ");
	while (ps[pi]) {
		const char* pt;

		pt = stoken(&c, &pi, ps, ",", " ");

		hi = 0;
		sskip(&hi, hs, " ");
		while (hs[hi]) {
			const char* ht;

			ht = stoken(&c, &hi, hs, ",", " ");

			vi = 0;
			sskip(&vi, vs, " ");
			while (vs[vi]) {
				const char* vt;

				vt = stoken(&c, &vi, vs, ",", " ");

				if (*buffer != 0)
					sncat(buffer, sizeof(buffer), " ; ");

				sncatf(buffer, sizeof(buffer), "%s / %s / %s", pt, ht, vt);

				sskip(&vi, vs, " ");
			}

			sskip(&hi, hs, " ");
		}

		sskip(&pi, ps, " ");
	}

	free(ps);
	free(hs);
	free(vs);

	conf_string_set(context, "", "device_video_clock", buffer);

	/* remove the old copy */
	conf_remove(context, "", "device_video_pclock");
	conf_remove(context, "", "device_video_hclock");
	conf_remove(context, "", "device_video_vclock");

	return 0;
}
Example #9
0
int main(int argc, char *argv[])
{
  const struct parsed_proto *pp;
  FILE *fout, *fhdr;
  char basename[256] = { 0, };
  char line[256];
  char fmt[256];
  char word[256];
  int noname = 0;
  const char *p2;
  char *p;
  int arg;
  int ret, ord;
  int l;

  for (arg = 1; arg < argc; arg++) {
    if (IS(argv[arg], "-n"))
      noname = 1;
    else if (IS(argv[arg], "-b") && arg < argc - 1)
      snprintf(basename, sizeof(basename), "%s", argv[++arg]);
    else
      break;
  }

  if (argc != arg + 2) {
    printf("usage:\n%s [-n] [-b <basename>] <.h> <.def>\n", argv[0]);
    return 1;
  }

  hdrfn = argv[arg++];
  fhdr = fopen(hdrfn, "r");
  my_assert_not(fhdr, NULL);

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

  if (basename[0] == 0) {
    p = strrchr(hdrfn, '.');
    my_assert_not(p, NULL);
    p2 = strrchr(hdrfn, '/');
    if (p2++ == NULL)
      p2 = hdrfn;
    l = p - p2;
    my_assert((unsigned int)l < 256, 1);
    memcpy(basename, p2, l);
    basename[l] = 0;
  }

  snprintf(fmt, sizeof(fmt), "%s_%%d", basename);

  fprintf(fout, "LIBRARY %s\n", basename);
  fprintf(fout, "EXPORTS\n");

  while (fgets(line, sizeof(line), fhdr))
  {
    p = sskip(line);
    if (*p == 0)
      continue;

    if (IS_START(p, "//"))
      continue;

    ret = 0;
    while (p != NULL && *p != 0) {
      p = next_word(word, sizeof(word), p);
      ret = sscanf(word, fmt, &ord);
      if (ret == 1)
        break;
    }
    if (ret != 1) {
      printf("scan for '%s' failed for '%s'\n", fmt, line);
      return 1;
    }

    snprintf(word, sizeof(word), fmt, ord);
    pp = proto_parse(fhdr, word, 0);
    if (pp == NULL)
      return 1;

    fputc(' ', fout);
    fputc(pp->is_fastcall ? '@' : ' ', fout);
    fprintf(fout, "%s", word);
    if (pp->is_stdcall)
      fprintf(fout, "@%-2d", pp->argc * 4);
    else
      fprintf(fout, "   ");
    fprintf(fout, " @%d", ord);
    if (noname)
      fprintf(fout, " NONAME");
    fprintf(fout, "\n");
  }

  fclose(fhdr);
  fclose(fout);
  return 0;
}
Example #10
0
File: rv2.c Project: NREL/Radiance
void
getview(				/* get/show/save view parameters */
	char  *s
)
{
	FILE  *fp;
	char  buf[128];
	char  *fname;
	int  change = 0;
	VIEW  nv = ourview;

	while (isspace(*s))
		s++;
	if (*s == '-') {			/* command line parameters */
		if (sscanview(&nv, s))
			newview(&nv);
		else
			error(COMMAND, "bad view option(s)");
		return;
	}
	if (nextword(buf, sizeof(buf), s) != NULL) {	/* write to a file */
		if ((fname = getpath(buf, NULL, 0)) == NULL ||
				(fp = fopen(fname, "a")) == NULL) {
			sprintf(errmsg, "cannot open \"%s\"", buf);
			error(COMMAND, errmsg);
			return;
		}
		fputs(progname, fp);
		fprintview(&ourview, fp);
		fputs(sskip(s), fp);
		putc('\n', fp);
		fclose(fp);
		return;
	}
	sprintf(buf, "view type (%c): ", ourview.type);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (buf[0] && buf[0] != ourview.type) {
		nv.type = buf[0];
		change++;
	}
	sprintf(buf, "view point (%.6g %.6g %.6g): ",
			ourview.vp[0], ourview.vp[1], ourview.vp[2]);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanvec(buf, nv.vp))
		change++;
	sprintf(buf, "view direction (%.6g %.6g %.6g): ",
			ourview.vdir[0]*ourview.vdist,
			ourview.vdir[1]*ourview.vdist,
			ourview.vdir[2]*ourview.vdist);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanvec(buf, nv.vdir)) {
		nv.vdist = 1.;
		change++;
	}
	sprintf(buf, "view up (%.6g %.6g %.6g): ",
			ourview.vup[0], ourview.vup[1], ourview.vup[2]);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanvec(buf, nv.vup))
		change++;
	sprintf(buf, "view horiz and vert size (%.6g %.6g): ",
			ourview.horiz, ourview.vert);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanf(buf, "%lf %lf", &nv.horiz, &nv.vert) == 2)
		change++;
	sprintf(buf, "fore and aft clipping plane (%.6g %.6g): ",
			ourview.vfore, ourview.vaft);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanf(buf, "%lf %lf", &nv.vfore, &nv.vaft) == 2)
		change++;
	sprintf(buf, "view shift and lift (%.6g %.6g): ",
			ourview.hoff, ourview.voff);
	(*dev->comout)(buf);
	(*dev->comin)(buf, NULL);
	if (buf[0] == CTRL('C')) return;
	if (sscanf(buf, "%lf %lf", &nv.hoff, &nv.voff) == 2)
		change++;
	if (change)
		newview(&nv);
}
Example #11
0
File: rv2.c Project: NREL/Radiance
void
setparam(				/* get/set program parameter */
	char  *s
)
{
	int  prev_newp = newparam;
	char  buf[128];
	
	if (s[0] == '\0') {
		(*dev->comout)(
		"aa ab ad ar as av aw b bv dc dv dj ds dt i lr lw me ma mg ms ps pt ss st u: ");
		(*dev->comin)(buf, NULL);
		s = buf;
	}
	switch (s[0]) {
	case 'u':			/* uncorrelated sampling */
		getparam(s+1, "uncorrelated sampling", 'b',
				(void *)&rand_samp);
		break;
	case 'l':			/* limit */
		switch (s[1]) {
		case 'w':			/* weight */
			getparam(s+2, "limit weight", 'r',
					(void *)&minweight);
			break;
		case 'r':			/* reflection */
			getparam(s+2, "limit reflection", 'i',
					(void *)&maxdepth);
			break;
		default:
			goto badparam;
		}
		break;
	case 'd':			/* direct */
		switch (s[1]) {
		case 'j':			/* jitter */
			getparam(s+2, "direct jitter", 'r',
					(void *)&dstrsrc);
			break;
		case 'c':			/* certainty */
			getparam(s+2, "direct certainty", 'r',
					(void *)&shadcert);
			break;
		case 't':			/* threshold */
			getparam(s+2, "direct threshold", 'r',
					(void *)&shadthresh);
			break;
		case 'v':			/* visibility */
			getparam(s+2, "direct visibility", 'b',
					(void *)&directvis);
			break;
		case 's':			/* sampling */
			getparam(s+2, "direct sampling", 'r',
					(void *)&srcsizerat);
			break;
		default:
			goto badparam;
		}
		break;
	case 'b':			/* back faces or black and white */
		switch (s[1]) {
		case 'v':			/* back face visibility */
			getparam(s+2, "back face visibility", 'b',
					(void *)&backvis);
			break;
		case '\0':			/* black and white */
		case ' ':
		case 'y': case 'Y': case 't': case 'T': case '1': case '+':
		case 'n': case 'N': case 'f': case 'F': case '0': case '-':
			getparam(s+1, "black and white", 'b',
					(void *)&greyscale);
			newparam = prev_newp;
			break;
		default:
			goto badparam;
		}
		break;
	case 'i':			/* irradiance */
		getparam(s+1, "irradiance", 'b',
				(void *)&do_irrad);
		break;
	case 'a':			/* ambient */
		switch (s[1]) {
		case 'v':			/* value */
			getparam(s+2, "ambient value", 'C',
					(void *)ambval);
			break;
		case 'w':			/* weight */
			getparam(s+2, "ambient value weight", 'i',
					(void *)&ambvwt);
			break;
		case 'a':			/* accuracy */
			if (getparam(s+2, "ambient accuracy", 'r',
					(void *)&ambacc))
				setambacc(ambacc);
			break;
		case 'd':			/* divisions */
			getparam(s+2, "ambient divisions", 'i',
					(void *)&ambdiv);
			break;
		case 's':			/* samples */
			getparam(s+2, "ambient super-samples", 'i',
					(void *)&ambssamp);
			break;
		case 'b':			/* bounces */
			getparam(s+2, "ambient bounces", 'i',
					(void *)&ambounce);
			break;
		case 'r':
			if (getparam(s+2, "ambient resolution", 'i',
					(void *)&ambres))
				setambres(ambres);
			break;
		default:
			goto badparam;
		}
		break;
	case 'm':			/* medium */
		switch (s[1]) {
		case 'e':			/* extinction coefficient */
			getparam(s+2, "extinction coefficient", 'C',
					(void *)cextinction);
			break;
		case 'a':			/* scattering albedo */
			getparam(s+2, "scattering albedo", 'C',
					(void *)salbedo);
			break;
		case 'g':			/* scattering eccentricity */
			getparam(s+2, "scattering eccentricity", 'r',
					(void *)&seccg);
			break;
		case 's':			/* sampling distance */
			getparam(s+2, "mist sampling distance", 'r',
					(void *)&ssampdist);
			break;
		default:
			goto badparam;
		}
		break;
	case 'p':			/* pixel */
		switch (s[1]) {
		case 's':			/* sample */
			if (getparam(s+2, "pixel sample", 'i',
					(void *)&psample))
				pdepth = 0;
			break;
		case 't':			/* threshold */
			if (getparam(s+2, "pixel threshold", 'r',
					(void *)&maxdiff))
				pdepth = 0;
			break;
		default:
			goto badparam;
		}
		newparam = prev_newp;
		break;
	case 's':			/* specular */
		switch (s[1]) {
		case 's':			/* sampling */
			getparam(s+2, "specular sampling", 'r',
					(void *)&specjitter);
			break;
		case 't':			/* threshold */
			getparam(s+2, "specular threshold", 'r',
					(void *)&specthresh);
			break;
		default:
			goto badparam;
		}
		break;
	case '\0':			/* nothing */
		break;
	default:;
badparam:
		*sskip(s) = '\0';
		sprintf(errmsg, "%s: unknown variable", s);
		error(COMMAND, errmsg);
		break;
	}
}
Example #12
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;
}