You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1075 lines
28 KiB

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <xml.h>
#define TS (4*1024*1024)
#define PRINT(a) \
tag = (a); if (tag) { strncat(s, " <tag>", TS-strlen(s)); strncat(s, tag, TS-strlen(s)); strncat(s, "</tag>\n", TS-strlen(s)); }
static unsigned int tags_level = 0;
static unsigned int print_tags = 0;
char *
getCommandLineOption(int argc, char **argv, char const *option)
{
int slen = strlen(option);
char *rv = 0;
int i;
for (i=0; i<argc; i++)
{
if (strncmp(argv[i], option, slen) == 0)
{
rv = "";
i++;
if (i<argc) rv = argv[i];
}
}
return rv;
}
void
show_help()
{
printf("Usage: metdata [options]\n");
printf("Updates the metadata of a FlightGear aircraft configuration.\n");
printf("\nOptions:\n");
printf(" -i, --input <file>\t\taircraft configuration file to update\n");
printf("\n");
exit(-1);
}
char *strlwr(char *str)
{
unsigned char *p = (unsigned char *)str;
while (*p) {
*p = tolower((unsigned char)*p);
p++;
}
return str;
}
void print_xml(FILE *fd, void *id, char *tags)
{
static int level = 1;
void *xid = xmlMarkId(id);
unsigned int num;
num = xmlNodeGetNum(xid, "*");
if (num == 0)
{
char *s;
s = xmlGetString(xid);
if (s)
{
fprintf(fd, "%s", s);
free(s);
}
}
else
{
unsigned int i, q;
for (i=0; i<num; i++)
{
if (xmlNodeGetPos(id, xid, "*", i) != 0)
{
unsigned int anum, a;
char name[256];
xmlNodeCopyName(xid, (char *)&name, 256);
if (tags_level == 1 && !strcmp(name, "sim")) tags_level++;
fprintf(fd, "\n");
for(q=0; q<level; q++) fprintf(fd, " ");
fprintf(fd, "<%s", name);
anum = xmlAttributeGetNum(xid);
for (a=0; a<anum; a++)
{
char name[256], attrib[256];
if (xmlAttributeCopyName(xid, (char *)&name, 256, a) != 0)
{
xmlAttributeCopyString(xid, name, (char *)&attrib, 256);
fprintf(fd, " %s=\"%s\"", name, attrib);
}
}
fprintf(fd, ">");
level++;
print_xml(fd, xid, tags);
level--;
fprintf(fd, "</%s>", name);
if (tags_level == 2 && !strcmp(name, "aero")) {
fprintf(fd, "\n%s\n", tags);
}
}
else printf("error\n");
}
fprintf(fd, "\n");
for(q=1; q<level; q++) fprintf(fd, " ");
}
}
void
updateFile(char *fname, char *tags)
{
char bfname[4096];
FILE *fd = NULL;
void *rid;
snprintf(bfname, 4096, "%s.bak", fname);
rename(fname, bfname);
rid = xmlOpen(bfname);
if (rid)
{
fd = fopen(fname, "w");
if (!fd)
{
xmlClose(rid);
rid = NULL;
rename(bfname, fname);
}
}
if (rid)
{
unsigned int i, num;
void *xid;
fprintf(fd, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
xid = xmlMarkId(rid);
num = xmlNodeGetNum(xid, "*");
for (i=0; i<num; i++)
{
if (xmlNodeGetPos(rid, xid, "*", i) != 0)
{
unsigned int anum, a;
char name[256];
xmlNodeCopyName(xid, (char *)&name, 256);
if (strcmp(name, "PropertyList")) break;
tags_level++;
fprintf(fd, "<%s", name);
anum = xmlAttributeGetNum(xid);
for (a=0; a<anum; a++)
{
char name[256], attrib[256];
if (xmlAttributeCopyName(xid, (char *)&name, 256, a) != 0)
{
xmlAttributeCopyString(xid, name, (char *)&attrib, 256);
fprintf(fd, " %s=\"%s\"", name, attrib);
}
}
fprintf(fd, ">");
print_xml(fd, xid, tags);
fprintf(fd, "\n</%s>\n", name);
}
}
free(xid);
xmlClose(rid);
fclose(fd);
}
}
const char*
vendor_tag(char *desc)
{
char *p = strlwr(desc);
if (strstr(p, "boeing")) return "boeing";
if (strstr(p, "airbus")) return "airbus";
if (strstr(p, "antonov")) return "antonov";
if (strstr(p, "tupolev")) return "tupolev";
if (strstr(p, "ilyoushin")) return "ilyoushin";
if (strstr(p, "bombardier")) return "bombardier";
if (strstr(p, "fokker")) return "fokker";
if (strstr(p, "lockheed")) return "lockheed";
if (strstr(p, "general-dynamics")) return "general-dynamics";
if (strstr(p, "general dynamics")) return "general-dynamics";
if (strstr(p, "mig")) return "mikoyan-gurevich";
if (strstr(p, "mikoyan gurevich")) return "mikoyan-gurevich";
if (strstr(p, "mikoyan-gurevich")) return "mikoyan-gurevich";
if (strstr(p, "sukoi")) return "sukoi";
if (strstr(p, "cessna")) return "cessna";
if (strstr(p, "fairchild")) return "fairchild";
if (strstr(p, "dassult")) return "dassult";
if (strstr(p, "dornier")) return "dornier";
if (strstr(p, "arado")) return "arado";
if (strstr(p, "schleicher")) return "schleicher";
if (strstr(p, "avro")) return "avro";
if (strstr(p, "saab")) return "saab";
if (strstr(p, "dassault")) return "dassault";
if (strstr(p, "aermacchi")) return "aermacchi";
if (strstr(p, "arsenal")) return "arsenal";
if (strstr(p, "rockwell")) return "rockwell";
if (strstr(p, "northrop")) return "northrop";
if (strstr(p, "grumman")) return "grumman";
if (strstr(p, "mc donnell") && strstr(p, "douglas")) return "mc-donnell-douglas";
if (strstr(p, "douglas")) return "douglas";
if (strstr(p, "mc donnell")) return "mc-donnell";
if (strstr(p, "mc-donnell")) return "mc-donnell";
// if (strstr(p, "jaguar")) return "jaguar";
if (strstr(p, "junkers")) return "junkers";
if (strstr(p, "kawasaki")) return "kawasaki";
if (strstr(p, "de havilland")) return "de-havilland";
if (strstr(p, "de-havilland")) return "de-havilland";
if (strstr(p, "diamond")) return "diamond";
if (strstr(p, "bell")) return "bell";
if (strstr(p, "hughes")) return "hughes";
if (strstr(p, "kamov")) return "kamov";
if (strstr(p, "mil")) return "mil";
if (strstr(p, "eurocopter")) return "eurocopter";
if (strstr(p, "alouette")) return "alouette";
if (strstr(p, "aerospatiale")) return "aerospatiale";
if (strstr(p, "sikorsky")) return "sikorsky";
if (strstr(p, "bernard")) return "bernard";
if (strstr(p, "bleriot")) return "bleriot";
if (strstr(p, "bristol")) return "bristol";
if (strstr(p, "breguet")) return "breguet";
if (strstr(p, "wright")) return "wright";
if (strstr(p, "breda")) return "breda";
if (strstr(p, "rutan")) return "rutan";
if (strstr(p, "vought")) return "vought";
if (strstr(p, "fiat")) return "fiat";
if (strstr(p, "focke wulf")) return "focke-wulf";
if (strstr(p, "focke-wulf")) return "focke-wulf";
if (strstr(p, "gloster")) return "gloster";
if (strstr(p, "hawker")) return "hawker";
if (strstr(p, "heinkel")) return "heinkel";
if (strstr(p, "messerschmitt")) return "messerschmitt";
if (strstr(p, "north american")) return "north-american";
if (strstr(p, "north-american")) return "north-american";
if (strstr(p, "piaggio")) return "piaggio";
if (strstr(p, "pilatus")) return "pilatus";
if (strstr(p, "supermarine")) return "supermarine";
if (strstr(p, "beechcraft")) return "beechcraft";
if (strstr(p, "beech")) return "beechcraft";
if (strstr(p, "vickers")) return "vickers";
if (strstr(p, "westland")) return "westland";
if (strstr(p, "yakovlev")) return "yakovlev";
if (strstr(p, "schweizer")) return "schweizer";
/* educated guess */
if (strstr(p, "b7")) return "boeing";
if (strstr(p, "airbus")) return "airbus";
if (strstr(p, "an-")) return "antonov";
if (strstr(p, "tu-")) return "tupolev";
if (strstr(p, "il-")) return "ilyoushin";
if (strstr(p, "su-")) return "sukoi";
if (strstr(p, "dc-")) return "douglas";
if (strstr(p, "md-")) return "mc-donnell-douglas";
if (strstr(p, "ju-")) return "junkers";
if (strstr(p, "ec-")) return "eurocopter";
if (strstr(p, "he-")) return "heinkel";
if (strstr(p, "as-")) return "aerospatiale";
if (strstr(p, "me-")) return "messerschmitt";
if (strstr(p, "fw-")) return "focke-wulf";
if (strstr(p, "yak-")) return "yakovlev";
if (strstr(p, "sgs-")) return "schweizer";
if (strstr(p, "ask-")) return "schleicher";
if (strstr(p, "mirage")) return "dassault";
return NULL;
}
/* -- JSBSim ---------------------------------------------------------------- */
const char*
jsb_wing_tag(void *xid, void *path)
{
void *xlid, *xmid, *xeid;
double aero_z = 0.0;
double eye_z = 0.0;
int i, num;
xeid = xmlNodeGet(xid, "/fdm_config/propulsion/engine/thruster");
if (xeid)
{
char *rv = NULL;
char *file = xmlAttributeGetString(xeid, "file");
char *fname = calloc(1, strlen(path)+strlen("Engines/")+
strlen(file)+strlen(".xml")+1);
if (fname)
{
void *xfid;
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), "Engines/", strlen("Engines/"));
memcpy(fname+strlen(path)+strlen("Engines/"), file, strlen(file));
memcpy(fname+strlen(path)+strlen("Engines/")+strlen(file), ".xml", strlen(".xml"));
xfid = xmlOpen(fname);
if (xfid)
{
if (xmlNodeTest(xfid, "rotor")) rv = "helicopter";
xmlClose(xfid);
}
free(fname);
}
xmlFree(file);
xmlFree(xeid);
if (rv) return rv;
}
xmid = xmlNodeGet(xid, "/fdm_config/metrics");
if (!xmid) return NULL;
xlid = xmlMarkId(xmid);
num = xmlNodeGetNum(xmid, "location");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xmid, xlid, "location", i) != 0)
{
if (!xmlAttributeCompareString(xlid, "name", "AERORP")) {
aero_z = xmlNodeGetDouble(xlid, "z");
} else if (!xmlAttributeCompareString(xlid, "name", "EYEPOINT")) {
eye_z = xmlNodeGetDouble(xlid, "z");
}
}
}
xmlFree(xlid);
xmlFree(xmid);
if (aero_z > eye_z) return "high-wing";
else return "low-wing";
}
const char*
jsb_gear_tag(void *xid)
{
void *xcid, *xgid = xmlNodeGet(xid, "/fdm_config/ground_reactions");
double nose_x = 0.0;
double main_x = 0.0;
int bogeys = 0;
int i, num;
if (!xgid) return NULL;
xcid = xmlMarkId(xgid);
num = xmlNodeGetNum(xgid, "contact");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xgid, xcid, "contact", i) != 0)
{
if (!xmlAttributeCompareString(xcid, "type", "BOGEY"))
{
if (xmlNodeGetDouble(xcid, "location/y") == 0.0) {
nose_x = xmlNodeGetDouble(xcid, "location/x");
} else {
main_x = xmlNodeGetDouble(xcid, "location/x");
}
bogeys++;
}
}
}
xmlFree(xcid);
xmlFree(xgid);
if (bogeys == 0) return "skids";
else if (bogeys < 3 || main_x < nose_x) return "tail-dragger";
return "tricycle";
}
const char*
jsb_gear_retract_tag(void *xid)
{
int r = xmlNodeGetInt(xid, "/fdm_config/ground_reactions/contact/retractable");
if (r) return "retractable-gear";
else return "fixed-gear";
}
const char*
jsb_gear_steering_tag(void *xid)
{
void *xcid, *xgid = xmlNodeGet(xid, "/fdm_config/ground_reactions");
char *rv = NULL;
int found = 0;
int i, num;
if (!xgid) return NULL;
xcid = xmlMarkId(xgid);
num = xmlNodeGetNum(xgid, "contact");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xgid, xcid, "contact", i) != 0)
{
if (!xmlAttributeCompareString(xcid, "type", "BOGEY"))
{
if (xmlNodeGetDouble(xcid, "location/y") == 0.0)
{
double m = xmlNodeGetDouble(xcid, "max_steer");
int c = xmlNodeGetInt(xcid, "castered");
if (c || (m == 360.0 && !c)) {
rv = "castering";
break;
} else if (m > 0.0) {
// rv = "normal-steering";
break;
}
else {
// rv = "no-steering";
}
}
}
}
}
xmlFree(xcid);
xmlFree(xgid);
return rv;
}
const char*
jsb_engines_tag(void *xid)
{
void *xeid, *xpid = xmlNodeGet(xid, "/fdm_config/propulsion");
const char* rv = NULL;
int engines = 0;
int i, num;
char *main;
if (!xpid) return rv;
xeid = xmlMarkId(xpid);
num = xmlNodeGetNum(xpid, "engine");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xpid, xeid, "engine", i) != 0)
{
if (i == 0)
{
main = xmlAttributeGetString(xeid, "file");
engines++;
}
else if (!xmlAttributeCompareString(xeid, "file", main)) {
engines++;
}
}
}
xmlFree(main);
xmlFree(xeid);
xmlFree(xpid);
switch (engines)
{
case 0:
rv = "glider";
break;
case 1:
rv = "single-engine";
break;
case 2:
rv = "twin-engine";
break;
case 3:
rv = "three-engine";
break;
case 4:
rv = "four-engine";
break;
default:
break;
}
return rv;
}
const char*
jsb_engine_tag(void *xid, char *path)
{
void *xeid = xmlNodeGet(xid, "/fdm_config/propulsion/engine");
char *engine, *fname;
const char *rv = NULL;
if (!xeid) return rv;
engine = xmlAttributeGetString(xeid, "file");
fname = calloc(1, strlen(path)+strlen("Engines/")+
strlen(engine)+strlen(".xml")+1);
if (fname)
{
void *xfid;
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), "Engines/", strlen("Engines/"));
memcpy(fname+strlen(path)+strlen("Engines/"), engine, strlen(engine));
memcpy(fname+strlen(path)+strlen("Engines/")+strlen(engine), ".xml", strlen(".xml"));
xfid = xmlOpen(fname);
if (xfid)
{
if (xmlNodeTest(xfid, "turbine_engine")) rv = "jet";
else if (xmlNodeTest(xfid, "turboprop_engine")) rv = "turboprop";
else if (xmlNodeTest(xfid, "piston_engine")) rv = "piston";
else if (xmlNodeTest(xfid, "electric_engine")) rv = "electric";
else if (xmlNodeTest(xfid, "rocket_engine")) rv = "rocket";
xmlClose(xfid);
}
else {
printf("JSBSim engine file not found: %s\n", fname);
}
free(fname);
}
else {
printf("Unable to allocate memory\n");
}
xmlFree(engine);
xmlFree(xeid);
return rv;
}
const char*
jsb_propulsion_tag(void *xid, char *path)
{
void *xeid = xmlNodeGet(xid, "fdm_config/propulsion/engine");
char *file, *fname;
const char *rv = NULL;
if (!xeid) return rv;
file = xmlAttributeGetString(xeid, "file");
fname = calloc(1, strlen(path)+strlen("Engines/")+
strlen(file)+strlen(".xml")+1);
if (fname)
{
void *xfid;
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), "Engines/", strlen("Engines/"));
memcpy(fname+strlen(path)+strlen("Engines/"), file, strlen(file));
memcpy(fname+strlen(path)+strlen("Engines/")+strlen(file), ".xml", strlen(".xml"));
xfid = xmlOpen(fname);
if (xfid)
{
if (xmlNodeGetInt(xfid, "turbine_engine/augmented")) {
rv = "afterburner";
}
else if (xmlNodeGetInt(xfid, "piston_engine/numboostspeeds")) {
rv = "supercharged";
}
xmlClose(xfid);
}
else {
printf("JSBSim engine file not found: %s\n", fname);
}
free(fname);
}
xmlFree(xeid);
xmlFree(file);
return rv;
}
const char*
jsb_thruster_tag(void *xid, char *path)
{
void *xeid = xmlNodeGet(xid, "/fdm_config/propulsion/engine/thruster");
char *file, *fname;
const char *rv = NULL;
if (!xeid) return rv;
file = xmlAttributeGetString(xeid, "file");
fname = calloc(1, strlen(path)+strlen("Engines/")+
strlen(file)+strlen(".xml")+1);
if (fname)
{
void *xfid;
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), "Engines/", strlen("Engines/"));
memcpy(fname+strlen(path)+strlen("Engines/"), file, strlen(file));
memcpy(fname+strlen(path)+strlen("Engines/")+strlen(file), ".xml", strlen(".xml"));
xfid = xmlOpen(fname);
if (xfid)
{
if (xmlNodeTest(xfid, "propeller"))
{
double min = xmlNodeGetDouble(xfid, "propeller/minpitch");
double max = xmlNodeGetDouble(xfid, "propeller/maxpitch");
if (min == max) rv = "fixed-pitch";
else rv = "variable-pitch";
}
xmlClose(xfid);
}
else {
printf("JSBSim thruster file not found: %s\n", fname);
}
free(fname);
}
else {
printf("Unable to allocate memory\n");
}
xmlFree(file);
xmlFree(xeid);
return rv;
}
void
update_metadata_jsb(char *sfname, char *path, char *aero, char *desc)
{
const char *tag;
char *s, *fname;
void *xid;
fname = calloc(1, strlen(path)+strlen(aero)+strlen(".xml")+1);
if (!fname)
{
printf("Unable to allocate memory\n");
return;
}
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), aero, strlen(aero));
memcpy(fname+strlen(path)+strlen(aero), ".xml", strlen(".xml"));
xid = xmlOpen(fname);
if (!xid)
{
printf("JSBSim aero file not found: '%s'\n", fname);
return;
}
s = malloc(65*1024);
if (s)
{
sprintf(s, " <tags>\n");
PRINT("auto-generated");
PRINT(vendor_tag(desc ? desc : aero));
PRINT(strlwr(desc ? desc : aero));
PRINT(jsb_wing_tag(xid, path));
PRINT(jsb_gear_tag(xid));
PRINT(jsb_gear_retract_tag(xid));
PRINT(jsb_gear_steering_tag(xid));
PRINT(jsb_engines_tag(xid));
PRINT(jsb_engine_tag(xid, path));
PRINT(jsb_propulsion_tag(xid, path));
PRINT(jsb_thruster_tag(xid, path));
s = strncat(s, " </tags>", TS-strlen(s));
if (print_tags) {
printf( "%s\n", s);
} else {
updateFile(sfname, s);
}
free(s);
}
xmlClose(xid);
free(fname);
}
/* -- Yasim ----------------------------------------------------------------- */
const char*
yasim_wing_tag(void *xid)
{
void *xaid = xmlNodeGet(xid, "/airplane");
void *xwid, *xcid;
int n_wings;
double wing_z = 0.0;
double eye_z = 0.0;
if (xmlNodeTest(xaid, "rotor")) {
return "helicopter";
}
xwid = xmlNodeGet(xaid, "wing");
if (xwid)
{
wing_z = xmlAttributeGetDouble(xwid, "z");
xmlFree(xwid);
}
xcid = xmlNodeGet(xaid, "cockpit");
if (xcid)
{
eye_z = xmlAttributeGetDouble(xcid, "z");
xmlFree(xcid);
}
n_wings = xmlNodeGetNum(xaid, "mstab");
xmlFree(xaid);
// if (n_wings == 2) return "triplane";
// if (n_wings == 1) return "biplane";
if (wing_z > eye_z) return "high-wing";
return "low-wing";
}
const char*
yasim_gear_tag(void *xid)
{
void *xaid = xmlNodeGet(xid, "/airplane");
void *xgid = xmlMarkId(xaid);
double nose_x = 0.0;
double main_x = 0.0;
int gears = 0;
int i, num;
num = xmlNodeGetNum(xaid, "gear");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xaid, xgid, "gear", i) != 0)
{
if (xmlAttributeGetDouble(xgid, "y") == 0.0) {
nose_x = xmlAttributeGetDouble(xgid, "x");
} else {
main_x = xmlAttributeGetDouble(xgid, "x");
}
gears++;
}
}
xmlFree(xgid);
xmlFree(xaid);
if (gears == 0) return "skids";
else if (gears < 3 || main_x > nose_x) return "tail-dragger";
return "tricycle";
}
const char*
yasim_gear_retract_tag(void *xid)
{
void *xaid = xmlNodeGet(xid, "/airplane");
void *xgid = xmlMarkId(xaid);
char *rv = "fixed-gear";
int found = 0;
int i, num;
num = xmlNodeGetNum(xaid, "gear");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xaid, xgid, "gear", i) != 0)
{
void *xgcid = xmlMarkId(xgid);
int j, cnum = xmlNodeGetNum(xgid, "control-input");
for (j=0; j<cnum; ++j)
{
if (xmlNodeGetPos(xgid, xgcid, "control-input", j))
{
if (!xmlAttributeCompareString(xgcid, "control", "EXTEND")) {
rv = "retractable-gear";
found = 1;
break;
}
}
}
xmlFree(xgcid);
}
}
xmlFree(xgid);
xmlFree(xaid);
return rv;
}
const char*
yasim_gear_steering_tag(void *xid)
{
void *xaid = xmlNodeGet(xid, "/airplane");
void *xgid = xmlMarkId(xaid);
char *rv = NULL;
int found = 0;
int i, num;
num = xmlNodeGetNum(xaid, "gear");
for (i=0; i<num; ++i)
{
if (xmlNodeGetPos(xaid, xgid, "gear", i) != 0)
{
void *xgcid = xmlMarkId(xgid);
int j, cnum = xmlNodeGetNum(xgid, "control-input");
for (j=0; j<cnum; ++j)
{
if (xmlNodeGetPos(xgid, xgcid, "control-input", j))
{
if (!xmlAttributeCompareString(xgcid, "control", "STEER")) {
// rv = "normal-steering";
found = 1;
break;
}
else if (!xmlAttributeCompareString(xgcid, "control", "CASTERING")) {
rv = "castering";
found = 1;
break;
}
}
}
xmlFree(xgcid);
}
}
xmlFree(xgid);
xmlFree(xaid);
return rv;
}
const char*
yasim_engines_tag(void *xid)
{
void *xeid = xmlNodeGet(xid, "/airplane");
const char* rv = "multi-engine";
int engines = 0;
if (xmlNodeTest(xeid, "propeller")) {
engines = xmlNodeGetNum(xeid, "propeller");
}
else if (xmlNodeTest(xeid, "jet")) {
engines = xmlNodeGetNum(xeid, "jet");
}
else if (xmlNodeTest(xeid, "rotor")) {
engines = 1;
}
switch (engines)
{
case 0:
rv = "glider";
break;
case 1:
rv = "single-engine";
break;
case 2:
rv = "twin-engine";
break;
case 3:
rv = "three-engine";
break;
case 4:
rv = "four-engine";
break;
default:
break;
}
xmlFree(xeid);
return rv;
}
const char*
yasim_engine_tag(void *xid, char *path)
{
const char* rv = NULL;
if (xmlNodeTest(xid, "/airplane/propeller/piston-engine")) {
rv = "piston";
}
else if (xmlNodeTest(xid, "/airplane/propeller/turbine-engine")) {
rv = "turboprop";
}
else if (xmlNodeTest(xid, "/airplane/jet")) {
rv = "jet";
}
return rv;
}
const char*
yasim_propulsion_tag(void *xid, char *path)
{
const char* rv = NULL;
void *xpid;
if ((xpid = xmlNodeGet(xid, "/airplane/jet")) != NULL)
{
if (xmlAttributeGetDouble(xpid, "afterburner") > 0.0) {
rv = "afterburner";
}
xmlFree(xpid);
}
else if ((xpid = xmlNodeGet(xid, "/airplane/propeller/piston-engine")) != NULL)
{
if (xmlAttributeGetInt(xpid, "supercharger") > 0) {
rv = "supercharger";
}
xmlFree(xpid);
}
return rv;
}
const char*
yasim_thruster_tag(void *xid, char *path)
{
const char* rv = NULL;
void *xtid;
xtid = xmlNodeGet(xid, "/airplane/propeller/control-input");
if (xtid)
{
if (!xmlAttributeCompareString(xtid, "control", "ADVANCE")) {
rv = "variable-pitch";
} else rv = "fixed-pitch";
xmlFree(xtid);
}
return rv;
}
void
update_metadata_yasim(char *sfname, char *path, char *aero, char *desc)
{
const char *tag;
char *s, *fname;
void *xid;
fname = calloc(1, strlen(path)+strlen(aero)+strlen(".xml")+1);
if (!fname)
{
printf("Unable to allocate memory\n");
return;
}
memcpy(fname, path, strlen(path));
memcpy(fname+strlen(path), aero, strlen(aero));
memcpy(fname+strlen(path)+strlen(aero), ".xml", strlen(".xml"));
xid = xmlOpen(fname);
if (!xid)
{
printf("Yasim aero file not found: '%s'\n", fname);
return;
}
s = malloc(65*1024);
if (s)
{
sprintf(s, " <tags>\n");
PRINT("auto-generated");
PRINT(vendor_tag(desc ? desc : aero));
PRINT(strlwr(desc ? desc : aero));
PRINT(yasim_wing_tag(xid));
PRINT(yasim_gear_tag(xid));
PRINT(yasim_gear_retract_tag(xid));
PRINT(yasim_gear_steering_tag(xid));
PRINT(yasim_engines_tag(xid));
PRINT(yasim_engine_tag(xid, path));
PRINT(yasim_propulsion_tag(xid, path));
PRINT(yasim_thruster_tag(xid, path));
s = strncat(s, " </tags>", TS-strlen(s));
if (print_tags) {
printf( "%s\n", s);
} else {
updateFile(sfname, s);
}
free(s);
}
xmlClose(xid);
free(fname);
}
/* -------------------------------------------------------------------------- */
void
update_metadata(const char *fname)
{
void *xsid, *xid = xmlOpen(fname);
if (!xid)
{
printf("File not found: '%s'\n", fname);
return;
}
xsid = xmlNodeGet(xid, "/PropertyList/sim");
if (!xsid)
{
printf("path '/PropertyList/sim' not found in '%s'\n", fname);
xmlClose(xid);
return;
}
if (xmlNodeTest(xsid, "tags") == 0)
{
char *desc = NULL, *str = NULL;
char *path, *pend;
pend = strrchr(fname, '/');
if (!pend) pend = strrchr(fname, '\\');
if (!pend) path = strdup("./");
else
{
pend++;
path = calloc(1, pend-fname+1);
memcpy(path, fname, pend-fname);
}
desc = xmlNodeGetString(xsid, "description");
str = xmlNodeGetString(xsid, "aero");
if (!xmlNodeCompareString(xsid, "flight-model", "jsb")) {
update_metadata_jsb(fname, path, str, desc);
}
else if (!xmlNodeCompareString(xsid, "flight-model", "yasim")) {
update_metadata_yasim(fname, path, str, desc);
}
else
{
str = xmlNodeGetString(xsid, "flight-model");
printf("The '%s' flightmodel is unsupported at this time\n", str);
}
xmlFree(xsid);
xmlFree(desc);
xmlFree(str);
free(path);
}
else {
printf("'%s' already contains metadata tags\n", fname);
}
xmlClose(xid);
}
int
main(int argc, char **argv)
{
const char *setFile;
if (argc == 1 || getCommandLineOption(argc, argv, "-h") ||
getCommandLineOption(argc, argv, "--help")) {
show_help();
}
if (getCommandLineOption(argc, argv, "-p") ||
getCommandLineOption(argc, argv, "--print")) {
print_tags = 1;
}
setFile = getCommandLineOption(argc, argv, "-i");
if (!setFile) {
setFile = getCommandLineOption(argc, argv, "-input");
}
if (!setFile) {
show_help();
}
printf("%s\n", setFile);
update_metadata(setFile);
printf("\n");
return 0;
}