void
SectorBuilder::parse_object(const FileReader& reader)
{
  GameObjectHandle obj;

  if(reader.get_name() == "tilemap")
  {
    std::auto_ptr<TileMap> tilemap(new TileMap(reader));

    if (tilemap->get_name() == "interactive")
      m_sector.interactive_tilemap = tilemap.get();
    else if (tilemap->get_name() == "interactivebackground")
      m_sector.interactivebackground_tilemap = tilemap.get();

    obj.reset(tilemap.release());
  }
  else if (reader.get_name() == "navgraph-edge-ref")
  {
    // FIXME: Implement me
  }
  else if(reader.get_name() == "background")
  {
    // TODO
  }
  else if(reader.get_name() == "layer")
  {    
    parse_layer(reader);
  }
  else 
  {
    obj = ObjectFactory::create(reader);
    if (!obj)
    {
      std::cout << "Skipping unknown Object: " << reader.get_name() << "\n";
    }
  }

  if (obj)
  {
    std::string id_str;
    if (reader.read("id", id_str))
    {
      id_table[id_str] = obj;
    }

    std::string parent_str;
    if (reader.read("parent", parent_str))
    {
      if (!parent_str.empty())
        parent_table[obj] = parent_str;
    }

    m_sector.add(obj);
  }
}
Exemplo n.º 2
0
/* Load layer configurations from disk */
bool buxton_init_layers(void)
{
	bool ret = false;
	dictionary *ini;
	char *path;
	int nlayers = 0;

	path = DEFAULT_CONFIGURATION_FILE;

	ini = iniparser_load(path);
	if (ini == NULL) {
		buxton_log("Failed to load buxton conf file: %s\n", path);
		goto finish;
	}

	nlayers = iniparser_getnsec(ini);
	if (nlayers <= 0) {
		buxton_log("No layers defined in buxton conf file: %s\n", path);
		goto end;
	}

	_layers = hashmap_new(string_hash_func, string_compare_func);
	if (!_layers)
		goto end;

	for (int n = 0; n < nlayers; n++) {
		BuxtonLayer *layer;
		char *section_name;

		layer = malloc0(sizeof(BuxtonLayer));
		if (!layer)
			continue;

		section_name = iniparser_getsecname(ini, n);
		if (!section_name) {
			buxton_log("Failed to find section number: %d\n", n);
			continue;
		}

		if (!parse_layer(ini, section_name, layer)) {
			free(layer);
			buxton_log("Failed to load layer: %s\n", section_name);
			continue;
		}
		hashmap_put(_layers, layer->name, layer);
	}
	ret = true;

end:
	iniparser_freedict(ini);
finish:
	return ret;
}
Exemplo n.º 3
0
Arquivo: event.c Projeto: tomtix/osux
static int parse_sample_object(
    osux_event *ev, char **split, unsigned size)
{
    if (size < 4)
        return -OSUX_ERR_INVALID_EVENT_OBJECT;
    ev->offset = atoi(split[1]);
    ev->object.layer = parse_layer(split[2]);
    ev->object.filename = g_strdup(split[3]);
    ev->object.sample_volume = 100;
    if (size >= 5)
        ev->object.sample_volume = atoi(split[4]);
    return 0;
}
Exemplo n.º 4
0
Arquivo: event.c Projeto: tomtix/osux
static int parse_sprite_object(
    osux_event *ev, char **split, unsigned size)
{
    if (size != 6)
        return -OSUX_ERR_INVALID_EVENT_OBJECT;

    ev->object.layer = parse_layer(split[1]);
    ev->object.origin = parse_origin(split[2]);
    ev->object.filename = g_strdup(split[3]);
    ev->object.x = atoi(split[4]);
    ev->object.y = atoi(split[5]);

    return 0;
}
Exemplo n.º 5
0
Arquivo: event.c Projeto: tomtix/osux
static int parse_animation_object(
    osux_event *ev, char **split, unsigned size)
{
    if (size < 8)
        return -OSUX_ERR_INVALID_EVENT_OBJECT;
    ev->object.layer = parse_layer(split[1]);
    ev->object.origin = parse_origin(split[2]);
    ev->object.filename = g_strdup(split[3]);
    ev->object.x = atoi(split[4]);
    ev->object.y = atoi(split[5]);
    ev->object.anim_frame_count = atoi(split[6]);
    ev->object.anim_frame_delay = atoi(split[7]);
    ev->object.anim_loop = EVENT_LOOP_FOREVER;
    if (size == 9)
        ev->object.anim_loop = parse_loop(split[8]);
    return 0;
}
Exemplo n.º 6
0
static int nbyte_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
			    struct bstr *args)
{
	struct bstr *a;
	struct bstr *needle = args;
	unsigned long offset = 0, layer = TCF_LAYER_NETWORK;
	int offset_present = 0;
	struct tcf_em_nbyte nb;

	memset(&nb, 0, sizeof(nb));

#define PARSE_ERR(CARG, FMT, ARGS...) \
	em_parse_error(EINVAL, args, CARG, &nbyte_ematch_util, FMT ,##ARGS)

	if (args == NULL)
		return PARSE_ERR(args, "nbyte: missing arguments");

	if (needle->len <= 0)
		return PARSE_ERR(args, "nbyte: needle length is 0");

	for (a = bstr_next(args); a; a = bstr_next(a)) {
		if (!bstrcmp(a, "at")) {
			if (a->next == NULL)
				return PARSE_ERR(a, "nbyte: missing argument");
			a = bstr_next(a);

			offset = bstrtoul(a);
			if (offset == ULONG_MAX)
				return PARSE_ERR(a, "nbyte: invalid offset, " \
				    "must be numeric");

			offset_present = 1;
		} else if (!bstrcmp(a, "layer")) {
			if (a->next == NULL)
				return PARSE_ERR(a, "nbyte: missing argument");
			a = bstr_next(a);

			layer = parse_layer(a);
			if (layer == INT_MAX) {
				layer = bstrtoul(a);
				if (layer == ULONG_MAX)
					return PARSE_ERR(a, "nbyte: invalid " \
					    "layer");
			}

			if (layer > TCF_LAYER_MAX)
				return PARSE_ERR(a, "nbyte: illegal layer, " \
				    "must be in 0..%d", TCF_LAYER_MAX);
		} else
			return PARSE_ERR(a, "nbyte: unknown parameter");
	}

	if (offset_present == 0)
		return PARSE_ERR(a, "nbyte: offset required");

	nb.len = needle->len;
	nb.layer = (__u8) layer;
	nb.off = (__u16) offset;

	addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
	addraw_l(n, MAX_MSG, &nb, sizeof(nb));
	addraw_l(n, MAX_MSG, needle->data, needle->len);

#undef PARSE_ERR
	return 0;
}
Exemplo n.º 7
0
static DFBBoolean
parse_command_line( int argc, char *argv[] )
{
     int n;

     for (n = 1; n < argc; n++) {
          const char *arg = argv[n];

          if (strcmp (arg, "-h") == 0 || strcmp (arg, "--help") == 0) {
               print_usage (argv[0]);
               return DFB_FALSE;
          }

          if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) {
               fprintf (stderr, "dfbg version %s\n", DIRECTFB_VERSION);
               return DFB_FALSE;
          }

          if (strcmp (arg, "-l") == 0 || strcmp (arg, "--layer") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_layer( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-m") == 0 || strcmp (arg, "--mode") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_mode( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-f") == 0 || strcmp (arg, "--format") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_format( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-b") == 0 || strcmp (arg, "--buffer") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_buffermode( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-o") == 0 || strcmp (arg, "--opacity") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_opacity( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-L") == 0 || strcmp (arg, "--level") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_level( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-R") == 0 || strcmp (arg, "--rotate") == 0) {
               if (++n == argc) {
                    print_usage (argv[0]);
                    return DFB_FALSE;
               }

               if (!parse_rotation( argv[n] ))
                    return DFB_FALSE;

               continue;
          }

          if (strcmp (arg, "-t") == 0 || strcmp (arg, "--test-lock") == 0) {
               test_lock = DSLF_READ | DSLF_WRITE;

               continue;
          }

          if (strcmp (arg, "-tr") == 0 || strcmp (arg, "--test-lock-read") == 0) {
               test_lock = DSLF_READ;

               continue;
          }

          if (strcmp (arg, "-tw") == 0 || strcmp (arg, "--test-lock-write") == 0) {
               test_lock = DSLF_WRITE;

               continue;
          }

          print_usage (argv[0]);

          return DFB_FALSE;
     }

     return DFB_TRUE;
}
Exemplo n.º 8
0
static tmx_map *parse_root_map(xmlTextReaderPtr reader, const char *filename) {
	tmx_map *res = NULL;
	int curr_depth;
	const char *name;
	char *value;

	name = (char*) xmlTextReaderConstName(reader);
	curr_depth = xmlTextReaderDepth(reader);

	if (strcmp(name, "map")) {
		tmx_err(E_XDATA, "xml parser: root is not a 'map' element");
		return NULL;
	}

	if (!(res = alloc_map())) return NULL;

	/* parses each attribute */
	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"orientation"))) { /* orientation */
		if (res->orient = parse_orient(value), res->orient == O_NONE) {
			tmx_err(E_XDATA, "xml parser: unsupported 'orientation' '%s'", value);
			goto cleanup;
		}
		tmx_free_func(value);
	} else {
		tmx_err(E_MISSEL, "xml parser: missing 'orientation' attribute in the 'map' element");
		goto cleanup;
	}

	value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"renderorder"); /* renderorder */
	if (res->renderorder = parse_renderorder(value), res->renderorder == R_NONE) {
		tmx_err(E_XDATA, "xml parser: unsupported 'renderorder' '%s'", value);
		goto cleanup;
	}
	tmx_free_func(value);

	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"height"))) { /* height */
		res->height = atoi(value);
		tmx_free_func(value);
	} else {
		tmx_err(E_MISSEL, "xml parser: missing 'height' attribute in the 'map' element");
		goto cleanup;
	}

	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"width"))) { /* width */
		res->width = atoi(value);
		tmx_free_func(value);
	} else {
		tmx_err(E_MISSEL, "xml parser: missing 'width' attribute in the 'map' element");
		goto cleanup;
	}

	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"tileheight"))) { /* tileheight */
		res->tile_height = atoi(value);
		tmx_free_func(value);
	} else {
		tmx_err(E_MISSEL, "xml parser: missing 'tileheight' attribute in the 'map' element");
		goto cleanup;
	}

	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"tilewidth"))) { /* tilewidth */
		res->tile_width = atoi(value);
		tmx_free_func(value);
	} else {
		tmx_err(E_MISSEL, "xml parser: missing 'tilewidth' attribute in the 'map' element");
		goto cleanup;
	}

	if ((value = (char*)xmlTextReaderGetAttribute(reader, (xmlChar*)"backgroundcolor"))) { /* backgroundcolor */
		res->backgroundcolor = get_color_rgb(value);
		tmx_free_func(value);
	}

	/* Parse each child */
	do {
		if (xmlTextReaderRead(reader) != 1) goto cleanup; /* error_handler has been called */

		if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
			name = (char*)xmlTextReaderConstName(reader);
			if (!strcmp(name, "tileset")) {
				if (!parse_tileset(reader, &(res->ts_head), filename)) goto cleanup;
			} else if (!strcmp(name, "layer")) {
				if (!parse_layer(reader, &(res->ly_head), res->height, res->width, L_LAYER, filename)) goto cleanup;
			} else if (!strcmp(name, "objectgroup")) {
				if (!parse_layer(reader, &(res->ly_head), res->height, res->width, L_OBJGR, filename)) goto cleanup;
			} else if (!strcmp(name, "imagelayer")) {
				if (!parse_layer(reader, &(res->ly_head), res->height, res->width, L_IMAGE, filename)) goto cleanup;
			} else if (!strcmp(name, "properties")) {
				if (!parse_properties(reader, &(res->properties))) goto cleanup;
			} else {
				/* Unknow element, skip its tree */
				if (xmlTextReaderNext(reader) != 1) goto cleanup;
			}
		}
	} while (xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT ||
	         xmlTextReaderDepth(reader) != curr_depth);
	return res;
cleanup:
	tmx_map_free(res);
	return NULL;
}
Exemplo n.º 9
0
static int cmp_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
                          struct bstr *args)
{
    struct bstr *a;
    int align, opnd = 0;
    unsigned long offset = 0, layer = TCF_LAYER_NETWORK, mask = 0, value = 0;
    int offset_present = 0, value_present = 0;
    struct tcf_em_cmp cmp;

    memset(&cmp, 0, sizeof(cmp));

#define PARSE_ERR(CARG, FMT, ARGS...) \
	em_parse_error(EINVAL, args, CARG, &cmp_ematch_util, FMT ,##ARGS)

    if (args == NULL)
        return PARSE_ERR(args, "cmp: missing arguments");

    if (!bstrcmp(args, "u8"))
        align = TCF_EM_ALIGN_U8;
    else if (!bstrcmp(args, "u16"))
        align = TCF_EM_ALIGN_U16;
    else if (!bstrcmp(args, "u32"))
        align = TCF_EM_ALIGN_U32;
    else
        return PARSE_ERR(args, "cmp: invalid alignment");

    for (a = bstr_next(args); a; a = bstr_next(a)) {
        if (!bstrcmp(a, "at")) {
            if (a->next == NULL)
                return PARSE_ERR(a, "cmp: missing argument");
            a = bstr_next(a);

            offset = bstrtoul(a);
            if (offset == ULONG_MAX)
                return PARSE_ERR(a, "cmp: invalid offset, " \
                                 "must be numeric");

            offset_present = 1;
        } else if (!bstrcmp(a, "layer")) {
            if (a->next == NULL)
                return PARSE_ERR(a, "cmp: missing argument");
            a = bstr_next(a);

            layer = parse_layer(a);
            if (layer == INT_MAX) {
                layer = bstrtoul(a);
                if (layer == ULONG_MAX)
                    return PARSE_ERR(a, "cmp: invalid " \
                                     "layer");
            }

            if (layer > TCF_LAYER_MAX)
                return PARSE_ERR(a, "cmp: illegal layer, " \
                                 "must be in 0..%d", TCF_LAYER_MAX);
        } else if (!bstrcmp(a, "mask")) {
            if (a->next == NULL)
                return PARSE_ERR(a, "cmp: missing argument");
            a = bstr_next(a);

            mask = bstrtoul(a);
            if (mask == ULONG_MAX)
                return PARSE_ERR(a, "cmp: invalid mask");
        } else if (!bstrcmp(a, "trans")) {
            cmp.flags |= TCF_EM_CMP_TRANS;
        } else if (!bstrcmp(a, "eq") || !bstrcmp(a, "gt") ||
                   !bstrcmp(a, "lt")) {

            if (!bstrcmp(a, "eq"))
                opnd = TCF_EM_OPND_EQ;
            else if (!bstrcmp(a, "gt"))
                opnd = TCF_EM_OPND_GT;
            else if (!bstrcmp(a, "lt"))
                opnd = TCF_EM_OPND_LT;

            if (a->next == NULL)
                return PARSE_ERR(a, "cmp: missing argument");
            a = bstr_next(a);

            value = bstrtoul(a);
            if (value == ULONG_MAX)
                return PARSE_ERR(a, "cmp: invalid value");

            value_present = 1;
        } else
            return PARSE_ERR(a, "nbyte: unknown parameter");
    }

    if (offset_present == 0 || value_present == 0)
        return PARSE_ERR(a, "cmp: offset and value required");

    cmp.val = (__u32) value;
    cmp.mask = (__u32) mask;
    cmp.off = (__u16) offset;
    cmp.align = (__u8) align;
    cmp.layer = (__u8) layer;
    cmp.opnd = (__u8) opnd;

    addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
    addraw_l(n, MAX_MSG, &cmp, sizeof(cmp));

#undef PARSE_ERR
    return 0;
}
Exemplo n.º 10
0
int parse_command_line(int argc, char *argv[])
{
    char pl_desc[256];
    char pw_desc[256];
    int i;
    struct
    {
	struct Option *cell;
	struct Option *units;
	struct Option *pl;	/* page length */
	struct Option *pw;	/* page width */
	struct Option *outfile;
	struct Option *nv;
	struct Option *nsteps;
    } parms;
    struct
    {
	struct Flag *f;
	struct Flag *m;
	struct Flag *h;
	struct Flag *q;
	struct Flag *e;
	struct Flag *n;
	struct Flag *N;
	struct Flag *i;		/* use quant rules for fp map, 
				   i.e. read it as int */
	struct Flag *C;		/*  report for fp ranges in Cats file 
				   (fp maps only) */
    } flags;

    parms.cell = G_define_standard_option(G_OPT_R_MAPS);
    parms.cell->description = _("Raster map(s) to report on");

    parms.units = G_define_option();
    parms.units->key = "units";
    parms.units->type = TYPE_STRING;
    parms.units->required = NO;
    parms.units->multiple = YES;
    parms.units->description = _("Units");
    parms.units->descriptions =
	_("mi;miles;me;meters;k;kilometers;a;acres;"
	  "h;hectares;c;cell counts;p;percent cover");
    parms.units->options = "mi,me,k,a,h,c,p";
    parms.units->guisection = _("Output settings");

    parms.nv = G_define_option();
    parms.nv->key = "null";
    parms.nv->type = TYPE_STRING;
    parms.nv->required = NO;
    parms.nv->multiple = NO;
    parms.nv->answer = "*";
    parms.nv->description = _("Character representing no data cell value");
    parms.nv->guisection = _("Formatting");

    parms.pl = G_define_option();
    parms.pl->key = "pl";
    parms.pl->type = TYPE_INTEGER;
    parms.pl->required = NO;
    sprintf(pl_desc, _("Page length (default: %d lines)"),
	    DEFAULT_PAGE_LENGTH);
    parms.pl->description = pl_desc;
    parms.pl->guisection = _("Formatting");

    parms.pw = G_define_option();
    parms.pw->key = "pw";
    parms.pw->type = TYPE_INTEGER;
    parms.pw->required = NO;
    sprintf(pw_desc, _("Page width (default: %d characters)"),
	    DEFAULT_PAGE_WIDTH);
    parms.pw->description = pw_desc;
    parms.pw->guisection = _("Formatting");

    parms.outfile = G_define_standard_option(G_OPT_F_OUTPUT);
    parms.outfile->key = "output";
    parms.outfile->required = NO;
    parms.outfile->label =
	_("Name for output file to hold the report");
    parms.outfile->description =
	_("If no output given report is printed to standard output");
    parms.outfile->guisection = _("Output settings");

    parms.nsteps = G_define_option();
    parms.nsteps->key = "nsteps";
    parms.nsteps->type = TYPE_INTEGER;
    parms.nsteps->required = NO;
    parms.nsteps->multiple = NO;
    parms.nsteps->answer = "255";
    parms.nsteps->description =
	_("Number of fp subranges to collect stats from");
    parms.nsteps->guisection = _("FP maps");

    flags.h = G_define_flag();
    flags.h->key = 'h';
    flags.h->description = _("Suppress page headers");
    flags.h->guisection = _("Formatting");

    flags.f = G_define_flag();
    flags.f->key = 'f';
    flags.f->description = _("Use formfeeds between pages");
    flags.f->guisection = _("Formatting");

    flags.e = G_define_flag();
    flags.e->key = 'e';
    flags.e->description = _("Scientific format");
    flags.e->guisection = _("Formatting");

    flags.n = G_define_flag();
    flags.n->key = 'n';
    flags.n->description = _("Filter out all no data cells");

    flags.N = G_define_flag();
    flags.N->key = 'N';
    flags.N->description = _("Filter out cells where all maps have no data");

    flags.C = G_define_flag();
    flags.C->key = 'C';
    flags.C->description = _("Report for cats fp ranges (fp maps only)");
    flags.C->guisection = _("FP maps");

    flags.i = G_define_flag();
    flags.i->key = 'i';
    flags.i->description =
	_("Read fp map as integer (use map's quant rules)");
    flags.i->guisection = _("FP maps");

    /* hidden feature.
     * if first arg is >file just run r.stats into this file and quit
     * if first arg is <file, run report from stats in file
     * (this feature is for the interactive version of this program -
     *  to get more than one report without re-running r.stats)
     */
    stats_flag = EVERYTHING;
    if (argc > 1) {
	if (argv[1][0] == '<' || argv[1][0] == '>') {
	    stats_file = argv[1] + 1;
	    if (argv[1][0] == '<')
		stats_flag = REPORT_ONLY;
	    else {
		unlink(stats_file);
		stats_flag = STATS_ONLY;
	    }
	    argc--;
	    argv++;
	}
    }

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    use_formfeed = flags.f->answer;
    with_headers = !flags.h->answer;
    e_format = flags.e->answer;
    no_nulls = flags.n->answer;
    no_nulls_all = flags.N->answer;
    cat_ranges = flags.C->answer;
    as_int = flags.i->answer;

    for (i = 0; parms.cell->answers[i]; i++)
	parse_layer(parms.cell->answers[i]);
    if (parms.units->answers)
	for (i = 0; parms.units->answers[i]; i++)
	    parse_units(parms.units->answers[i]);

    sscanf(parms.nsteps->answer, "%d", &nsteps);
    if (nsteps <= 0) {
	G_warning(_("nsteps has to be > 0; using nsteps=255"));
	nsteps = 255;
    }

    if (parms.pl->answer) {
	if (sscanf(parms.pl->answer, "%d", &page_length) != 1 ||
	    page_length < 0) {
	    G_fatal_error(_("Illegal page length"));
	}
    }

    if (parms.pw->answer) {
	if (sscanf(parms.pw->answer, "%d", &page_width) != 1 ||
	    page_width < 1) {
	    G_fatal_error(_("Illegal page width"));
	}
    }
    if (parms.outfile->answer) {
	if (freopen(parms.outfile->answer, "w", stdout) == NULL) {
	    perror(parms.outfile->answer);
	    exit(EXIT_FAILURE);
	}
    }
    no_data_str = parms.nv->answer;

    return 0;
}
Exemplo n.º 11
0
int parse_command_line(int argc, char *argv[])
{
    int i;
    char *desc;
    struct
    {
	struct Option *cell;
	struct Option *units;
	struct Option *pl;	/* page length */
	struct Option *pw;	/* page width */
	struct Option *outfile;
	struct Option *nv;
	struct Option *nsteps;
        struct Option *sort;
    } parms;
    struct
    {
	struct Flag *f;
	struct Flag *m;
	struct Flag *h;
	struct Flag *q;
	struct Flag *e;
	struct Flag *n;
	struct Flag *N;
	struct Flag *i;		/* use quant rules for fp map, 
				   i.e. read it as int */
	struct Flag *C;		/*  report for fp ranges in Cats file 
				   (fp maps only) */
    } flags;

    parms.cell = G_define_standard_option(G_OPT_R_MAPS);
    parms.cell->description = _("Name of raster map(s) to report on");

    parms.units = G_define_option();
    parms.units->key = "units";
    parms.units->type = TYPE_STRING;
    parms.units->required = NO;
    parms.units->multiple = YES;
    parms.units->description = _("Units to report");
    desc = NULL;
    G_asprintf(&desc,
	       "mi;%s;me;%s;k;%s;a;%s;h;%s;c;%s;p;%s",
	       _("area in square miles"),
	       _("area in square meters"),
	       _("area in square kilometers"),
	       _("area in acres"),
	       _("area in hectares"),
	       _("number of cells"),
	       _("percent cover"));
    parms.units->descriptions = desc;
    parms.units->options = "mi,me,k,a,h,c,p";
    parms.units->guisection = _("Statistics");

    parms.outfile = G_define_standard_option(G_OPT_F_OUTPUT);
    parms.outfile->required = NO;
    parms.outfile->label =
	_("Name for output file to hold the report");
    parms.outfile->description =
	_("If no output file given report is printed to standard output");

    parms.nv = G_define_standard_option(G_OPT_M_NULL_VALUE);
    parms.nv->answer = "*";
    parms.nv->guisection = _("Formatting");

    parms.pl = G_define_option();
    parms.pl->key = "page_length";
    parms.pl->type = TYPE_INTEGER;
    parms.pl->required = NO;
    parms.pl->description = _("Page length");
    parms.pl->answer = DEFAULT_PAGE_LENGTH;
    parms.pl->guisection = _("Formatting");

    parms.pw = G_define_option();
    parms.pw->key = "page_width";
    parms.pw->type = TYPE_INTEGER;
    parms.pw->required = NO;
    parms.pw->description = _("Page width");
    parms.pw->answer = DEFAULT_PAGE_WIDTH;
    parms.pw->guisection = _("Formatting");

		    parms.nsteps = G_define_option();
    parms.nsteps->key = "nsteps";
    parms.nsteps->type = TYPE_INTEGER;
    parms.nsteps->required = NO;
    parms.nsteps->multiple = NO;
    parms.nsteps->answer = "255";
    parms.nsteps->description =
	_("Number of floating-point subranges to collect stats from");
    parms.nsteps->guisection = _("Floating point");

    parms.sort = G_define_option();
    parms.sort->key = "sort";
    parms.sort->type = TYPE_STRING;
    parms.sort->required = NO;
    parms.sort->multiple = NO;
    parms.sort->label = _("Sort output statistics by cell counts");
    parms.sort->description = _("Default: sorted by categories or intervals");
    parms.sort->options = "asc,desc";
    G_asprintf((char **)&(parms.sort->descriptions),
               "asc;%s;desc;%s",
               _("Sort by cell counts in ascending order"),
               _("Sort by cell counts in descending order"));
    parms.sort->guisection = _("Formatting");

    flags.h = G_define_flag();
    flags.h->key = 'h';
    flags.h->description = _("Suppress page headers");
    flags.h->guisection = _("Formatting");

    flags.f = G_define_flag();
    flags.f->key = 'f';
    flags.f->description = _("Use formfeeds between pages");
    flags.f->guisection = _("Formatting");

    flags.e = G_define_flag();
    flags.e->key = 'e';
    flags.e->description = _("Scientific format");
    flags.e->guisection = _("Formatting");

    flags.n = G_define_flag();
    flags.n->key = 'n';
    flags.n->description = _("Do not report no data value");
    flags.n->guisection = _("No data");

    flags.N = G_define_flag();
    flags.N->key = 'a';
    flags.N->description = _("Do not report cells where all maps have no data");
    flags.N->guisection = _("No data");

    flags.C = G_define_flag();
    flags.C->key = 'c';
    flags.C->description = _("Report for cats floating-point ranges (floating-point maps only)");
    flags.C->guisection = _("Floating point");

    flags.i = G_define_flag();
    flags.i->key = 'i';
    flags.i->description =
	_("Read floating-point map as integer (use map's quant rules)");
    flags.i->guisection = _("Floating point");

    /* hidden feature.
     * if first arg is >file just run r.stats into this file and quit
     * if first arg is <file, run report from stats in file
     * (this feature is for the interactive version of this program -
     *  to get more than one report without re-running r.stats)
     */
    stats_flag = EVERYTHING;
    if (argc > 1) {
	if (argv[1][0] == '<' || argv[1][0] == '>') {
	    stats_file = argv[1] + 1;
	    if (argv[1][0] == '<')
		stats_flag = REPORT_ONLY;
	    else {
		unlink(stats_file);
		stats_flag = STATS_ONLY;
	    }
	    argc--;
	    argv++;
	}
    }

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    use_formfeed = flags.f->answer;
    with_headers = !flags.h->answer;
    e_format = flags.e->answer;
    no_nulls = flags.n->answer;
    no_nulls_all = flags.N->answer;
    cat_ranges = flags.C->answer;
    as_int = flags.i->answer;

    for (i = 0; parms.cell->answers[i]; i++)
	parse_layer(parms.cell->answers[i]);
    if (parms.units->answers)
	for (i = 0; parms.units->answers[i]; i++)
	    parse_units(parms.units->answers[i]);

    sscanf(parms.nsteps->answer, "%d", &nsteps);
    if (nsteps <= 0) {
	G_warning(_("nsteps has to be > 0; using nsteps=255"));
	nsteps = 255;
    }

    if (sscanf(parms.pl->answer, "%d", &page_length) != 1 ||
        page_length < 0) {
      G_fatal_error(_("Illegal page length"));
    }

    if (sscanf(parms.pw->answer, "%d", &page_width) != 1 ||
        page_width < 1) {
      G_fatal_error(_("Illegal page width"));
    }

    if (parms.outfile->answer) {
	if (freopen(parms.outfile->answer, "w", stdout) == NULL) {
	    perror(parms.outfile->answer);
	    exit(EXIT_FAILURE);
	}
    }
    no_data_str = parms.nv->answer;

    /* determine sorting method */
    do_sort = SORT_DEFAULT; /* sort by cats by default */
    if (parms.sort->answer) {
        switch(parms.sort->answer[0]) {
        case 'a':
            do_sort = SORT_ASC;
            break;
        case 'd':
            do_sort = SORT_DESC;
            break;
        default:
            G_debug(1, "Sorting by '%s' not supported", parms.sort->answer);
            break;
        }
    }

    return 0;
}