test_pie/external/rply/etc/convert.c

131 lines
5.0 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "rply.h"
/* internal function prototypes */
static void error(const char *fmt, ...);
static void help(void);
static void parse_arguments(int argc, char **argv,
e_ply_storage_mode *storage_mode,
const char **iname, const char **oname);
static void setup_callbacks(p_ply iply, p_ply oply);
/* given a format mode, an input file name and an output file name,
* convert input file to output in given format mode */
int main(int argc, char **argv) {
const char *value = NULL;
e_ply_storage_mode storage_mode = PLY_LITTLE_ENDIAN;
const char *iname = NULL, *oname = NULL;
p_ply iply = NULL, oply = NULL;
/* parse command line arguments */
parse_arguments(argc, argv, &storage_mode, &iname, &oname);
/* open input file and make sure we parsed its header */
iply = ply_open(iname, NULL, 0, NULL);
if (!iply) error("Unable to open file '%s'", iname);
if (!ply_read_header(iply)) error("Failed reading '%s' header", iname);
/* create output file */
oply = ply_create(oname, storage_mode, NULL, 0, NULL);
if (!oply) error("Unable to create file '%s'", oname);
/* create elements and properties in output file and
* setup callbacks for them in input file */
setup_callbacks(iply, oply);
/* pass comments and obj_infos from input to output */
value = NULL;
while ((value = ply_get_next_comment(iply, value)))
if (!ply_add_comment(oply, value))
error("Failed adding comments");
value = NULL;
while ((value = ply_get_next_obj_info(iply, value)))
if (!ply_add_obj_info(oply, value))
error("Failed adding comments");
/* write output header */
if (!ply_write_header(oply)) error("Failed writing '%s' header", oname);
/* read input file generating callbacks that pass data to output file */
if (!ply_read(iply)) error("Conversion failed");
/* close up, we are done */
if (!ply_close(iply)) error("Error closing file '%s'", iname);
if (!ply_close(oply)) error("Error closing file '%s'", oname);
return 0;
}
/* prints an error message and exits */
static void error(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
/* prints the help message and exits */
static void help(void) {
error("Usage:\n"
" convert <option> <input> <output>\n"
"Options:\n"
" -a, --ascii: convert to ascii format\n"
" -b, --big-endian: convert to big-endian format\n"
" -l, --little-endian: convert to little-endian format\n");
}
/* parse command line parameters */
static void parse_arguments(int argc, char **argv,
e_ply_storage_mode *storage_mode,
const char **iname, const char **oname) {
if (argc < 4) help();
if (strcmp(argv[1], "--ascii") == 0 ||
strcmp(argv[1], "-a") == 0)
*storage_mode = PLY_ASCII;
else if (strcmp(argv[1], "--little-endian") == 0 ||
strcmp(argv[1], "-l") == 0)
*storage_mode = PLY_LITTLE_ENDIAN;
else if (strcmp(argv[1], "--big-endian") == 0 ||
strcmp(argv[1], "-b") == 0)
*storage_mode = PLY_BIG_ENDIAN;
else help();
*iname = argv[2];
*oname = argv[3];
}
/* read callback */
static int callback(p_ply_argument argument) {
void *pdata;
/* just pass the value from the input file to the output file */
ply_get_argument_user_data(argument, &pdata, NULL);
ply_write((p_ply) pdata, ply_get_argument_value(argument));
return 1;
}
/* prepares the conversion */
static void setup_callbacks(p_ply iply, p_ply oply) {
p_ply_element element = NULL;
/* iterate over all elements in input file */
while ((element = ply_get_next_element(iply, element))) {
p_ply_property property = NULL;
long ninstances = 0;
const char *element_name;
ply_get_element_info(element, &element_name, &ninstances);
/* add this element to output file */
if (!ply_add_element(oply, element_name, ninstances))
error("Unable to add output element '%s'", element_name);
/* iterate over all properties of current element */
while ((property = ply_get_next_property(element, property))) {
const char *property_name;
e_ply_type type, length_type, value_type;
ply_get_property_info(property, &property_name, &type,
&length_type, &value_type);
/* setup input callback for this property */
if (!ply_set_read_cb(iply, element_name, property_name, callback,
oply, 0))
error("Unable to setup input callback for property '%s'",
property_name);
/* add this property to output file */
if (!ply_add_property(oply, property_name, type, length_type,
value_type))
error("Unable to add output property '%s'", property_name);
}
}
}