#include #include #include #include #include #define TS (4*1024*1024) #define PRINT(a) \ tag = (a); if (tag) { strncat(s, " ", TS-strlen(s)); strncat(s, tag, TS-strlen(s)); strncat(s, "\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\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"); level++; print_xml(fd, xid, tags); level--; fprintf(fd, "", 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\n\n"); xid = xmlMarkId(rid); num = xmlNodeGetNum(xid, "*"); for (i=0; i"); print_xml(fd, xid, tags); fprintf(fd, "\n\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 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 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\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, " ", 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 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 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, " \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, " ", 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; }