From: skeezix Date: Mon, 1 Mar 2010 03:52:09 +0000 (-0500) Subject: Large change, to support multiple applications within a single PXML.xml file. X-Git-Tag: Release-2010-05/1~93 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0b54a848982a5985c285e42ac5057745503d1a49;p=pandora-libraries.git Large change, to support multiple applications within a single PXML.xml file. genpxml script was updated to generate properly formed new XML test apps were updated to comply pnd_run will attempt to run all subapps right now, for lack of a better idea :) pndnotifyd will generate all the icons and .desktop files for all subapps, and it should all work --- diff --git a/apps/pnd_info.c b/apps/pnd_info.c index a2acb4b..86908bf 100644 --- a/apps/pnd_info.c +++ b/apps/pnd_info.c @@ -78,36 +78,45 @@ int main ( int argc, char *argv[] ) { } pnd_pxml_handle h = NULL; + pnd_pxml_handle *apps = NULL; if ( pnd_pnd_seek_pxml ( f ) ) { if ( pnd_pnd_accrue_pxml ( f, pxmlbuf, pxmlbuflen ) ) { - h = pnd_pxml_fetch_buffer ( "pnd_run", pxmlbuf ); + apps = pnd_pxml_fetch_buffer ( "pnd_run", pxmlbuf ); } } fclose ( f ); - if ( ! h ) { + if ( ! apps ) { printf ( "ERROR: Couldn't pull PXML.xml from the pndfile.\n" ); exit ( 0 ); } - // display sections - for ( i = 0; i < sections; i++ ) { - char *t; + // iterate across apps + while ( *apps ) { + h = *apps; + + // display sections + for ( i = 0; i < sections; i++ ) { + char *t; + + if ( strcasecmp ( section [ i ], "description" ) == 0 ) { - if ( strcasecmp ( section [ i ], "description" ) == 0 ) { + printf ( "Section: %s\n", section [ i ] ); - printf ( "Section: %s\n", section [ i ] ); + if ( ( t = pnd_pxml_get_description_en ( h ) ) ) { + printf ( "%s\n", t ); + } else { + printf ( "Not supplied by PXML.xml in the pnd-file\n" ); + } - if ( ( t = pnd_pxml_get_description_en ( h ) ) ) { - printf ( "%s\n", t ); - } else { - printf ( "Not supplied by PXML.xml in the pnd-file\n" ); } - } + } // for - } // for + // next + apps++; + } // while return ( 0 ); } // main diff --git a/apps/pnd_run.c b/apps/pnd_run.c index c012ac6..5baabd4 100644 --- a/apps/pnd_run.c +++ b/apps/pnd_run.c @@ -139,40 +139,49 @@ int main ( int argc, char *argv[] ) { } pnd_pxml_handle h = NULL; + pnd_pxml_handle *apps = NULL; if ( pnd_pnd_seek_pxml ( f ) ) { if ( pnd_pnd_accrue_pxml ( f, pxmlbuf, pxmlbuflen ) ) { - h = pnd_pxml_fetch_buffer ( "pnd_run", pxmlbuf ); + apps = pnd_pxml_fetch_buffer ( "pnd_run", pxmlbuf ); } } fclose ( f ); - if ( ! h ) { + if ( ! apps ) { printf ( "ERROR: Couldn't pull PXML.xml from the pndfile.\n" ); exit ( 0 ); } - // attempt to invoke - unsigned int options = 0; - if ( no_x11 ) { - options |= PND_EXEC_OPTION_NOX11; - } + // attempt to invoke.. all of the subapps? just first one? - unsigned int clock = 200; - if ( pnd_pxml_get_clockspeed ( h ) ) { - clock = atoi ( pnd_pxml_get_clockspeed ( h ) ); - } + while ( *apps ) { + h = *apps; - if ( ! pnd_apps_exec ( pnd_run, pndfile, - pnd_pxml_get_unique_id ( h ), - pnd_pxml_get_exec ( h ), - pnd_pxml_get_startdir ( h ), - clock, - options ) - ) - { - printf ( "ERROR: PXML.xml data is bad\n" ); - } + unsigned int options = 0; + if ( no_x11 ) { + options |= PND_EXEC_OPTION_NOX11; + } + + unsigned int clock = 200; + if ( pnd_pxml_get_clockspeed ( h ) ) { + clock = atoi ( pnd_pxml_get_clockspeed ( h ) ); + } + + if ( ! pnd_apps_exec ( pnd_run, pndfile, + pnd_pxml_get_unique_id ( h ), + pnd_pxml_get_exec ( h ), + pnd_pxml_get_startdir ( h ), + clock, + options ) + ) + { + printf ( "ERROR: PXML.xml data is bad\n" ); + } + + // next + apps++; + } // while return ( 0 ); } // main diff --git a/apps/pndnotifyd.c b/apps/pndnotifyd.c index b9b350e..07769e5 100644 --- a/apps/pndnotifyd.c +++ b/apps/pndnotifyd.c @@ -661,7 +661,7 @@ void process_discoveries ( pnd_box_handle applist, char *emitdesktoppath, char * // check if icon already exists (from a previous extraction say); if so, we needn't // do it again char existingpath [ FILENAME_MAX ]; - sprintf ( existingpath, "%s/%s.png", emiticonpath, d -> unique_id ); + sprintf ( existingpath, "%s/%s#%u.png", emiticonpath, d -> unique_id, d -> subapp_number ); struct stat dirs; if ( stat ( existingpath, &dirs ) == 0 ) { diff --git a/apps/pndvalidator.c b/apps/pndvalidator.c index 4307b31..b21ab46 100644 --- a/apps/pndvalidator.c +++ b/apps/pndvalidator.c @@ -68,33 +68,44 @@ int main ( int argc, char *argv[] ) { // actually do useful work // - pnd_pxml_handle pxmlh; + pnd_pxml_handle *pxmlapps; - pxmlh = pnd_pxml_get_by_path ( fullpath ); + pxmlapps = pnd_pxml_get_by_path ( fullpath ); - if ( ! pxmlh ) { + if ( ! pxmlapps ) { printf ( "ERROR: PXML could not be extracted meaningfully.\n" ); return ( 0 ); } - printf ( "Got back a meaningful PXML structure.\n" ); + printf ( "Got back a meaningful list of PXMLs.\n" ); - /* check the content - */ + pnd_pxml_handle h = *pxmlapps; + + while ( h ) { + + /* check the content + */ - // check for required fields + // check for required fields - // exec-path? + // exec-path? - // app name? + // app name? - // unique ID + // unique ID - // package-name (shortname) + // package-name (shortname) + + // free up that particular pxml_handle within the return-list + + // next + pxmlapps++; + h = pxmlapps; + } // while /* done! */ - pnd_pxml_delete ( pxmlh ); + pnd_pxml_delete ( pxmlapps ); return ( 0 ); } diff --git a/include/pnd_discovery.h b/include/pnd_discovery.h index e4b11b4..b8aaa2b 100644 --- a/include/pnd_discovery.h +++ b/include/pnd_discovery.h @@ -49,6 +49,7 @@ typedef struct { char *object_path; // directory containing pnd or PXML.xml (does not include filename) char *object_filename; // filename within object_path of the app: the PXML.xml or awesomeapp.pnd file itself unsigned int pnd_icon_pos; // offset to the byte after end of PXML in a pnd file (should be icon if present) + unsigned char subapp_number; // # of app within PXML (ie: 0, 1, 2, 3, up to the number of apps within the PXML) // strdup'd from PXML -- hey, who was the idiot who thought it was a reat idea not to just re-use the pxml-struct? char *title_en; char *desc_en; diff --git a/include/pnd_pxml.h b/include/pnd_pxml.h index 01e32d5..2ef0e80 100644 --- a/include/pnd_pxml.h +++ b/include/pnd_pxml.h @@ -12,14 +12,16 @@ extern "C" { #define PXML_TAGHEAD "" /* case insensitive */ +#define PXML_MAXAPPS 20 /* max number of 's within a single PXML */ + // use this handle to interact with PXML; this hides the mechanics of parsing a PXML file so that // it can be upgraded with impacting applications typedef void* pnd_pxml_handle; /* pxml_fetch() will return NULL on fail, otherwise a valid handle which may be further queried */ -pnd_pxml_handle pnd_pxml_fetch ( char *fullpath ); -pnd_pxml_handle pnd_pxml_fetch_buffer ( char *filename, char *buffer ); +pnd_pxml_handle *pnd_pxml_fetch ( char *fullpath ); +pnd_pxml_handle *pnd_pxml_fetch_buffer ( char *filename, char *buffer ); void pnd_pxml_delete ( pnd_pxml_handle h ); /* overrides() allow for customization of a PXML that persists; ie: An application might be sitting @@ -101,6 +103,7 @@ typedef struct typedef struct { + unsigned char subapp_number; // 0 for 'only app'; 1+ for # .. first is 1. pnd_localized_string_t *titles; int titles_c; int titles_alloc_c; diff --git a/include/pnd_pxml_names.h b/include/pnd_pxml_names.h index 39f72d2..c476c21 100644 --- a/include/pnd_pxml_names.h +++ b/include/pnd_pxml_names.h @@ -8,6 +8,9 @@ extern "C" { /* ...*/ #define PND_PXML_ATTRNAME_UID "id" +/* */ +#define PND_PXML_APP "application" + /* */ #define PND_PXML_ENAME_TITLE "title" #define PND_PXML_ATTRNAME_TITLELANG "lang" diff --git a/include/pnd_tinyxml.h b/include/pnd_tinyxml.h index efa4371..81965d3 100644 --- a/include/pnd_tinyxml.h +++ b/include/pnd_tinyxml.h @@ -6,8 +6,7 @@ extern "C" { #endif -unsigned char pnd_pxml_load ( const char* pFilename, pnd_pxml_t *app ); -unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int length, pnd_pxml_t *app ); +unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int length, pnd_pxml_t **apps ); #ifdef __cplusplus } diff --git a/include/pnd_utility.h b/include/pnd_utility.h index f9dce27..3be73d2 100644 --- a/include/pnd_utility.h +++ b/include/pnd_utility.h @@ -19,11 +19,8 @@ char *pnd_expand_tilde ( char *freeable_buffer ); // arbtrary execute function; fire and forget really void pnd_exec_no_wait_1 ( char *fullpath, char *arg1 ); -// pnd_pxml_get_always() will work against a PXML.xml file or a foo.pnd app-bundle and return -// the resulting PXML structure, or fail; ie: It should be handy to avoid the user having to -// do the 'what type is this, and if-this-or-that' themselves. -// NOTE: Does _NOT_ automatically pick up PXML-overrides; you can call that function if you want -pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ); +// NOTE: Does _NOT_ automatically pick up PXML-overrides; you can call that function if you want +pnd_pxml_handle *pnd_pxml_get_by_path ( char *fullpath ); // determine_mountpoint() will examine a path, and return the mountpoint that this path // is sitting on; returns 1 on success, meaning the target was populated. diff --git a/lib/pnd_desktop.c b/lib/pnd_desktop.c index 199825f..51992c4 100644 --- a/lib/pnd_desktop.c +++ b/lib/pnd_desktop.c @@ -11,6 +11,7 @@ #include "pnd_pndfiles.h" #include "pnd_conf.h" #include "pnd_desktop.h" +#include "pnd_logger.h" unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t *p ) { char filename [ FILENAME_MAX ]; @@ -23,24 +24,28 @@ unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t // validation if ( ! p -> unique_id ) { + pnd_log ( PND_LOG_DEFAULT, "Can't emit dotdesktop for %s, missing unique-id\n", targetpath ); return ( 0 ); } if ( ! p -> exec ) { + pnd_log ( PND_LOG_DEFAULT, "Can't emit dotdesktop for %s, missing exec\n", targetpath ); return ( 0 ); } if ( ! targetpath ) { + pnd_log ( PND_LOG_DEFAULT, "Can't emit dotdesktop for %s, missing target path\n", targetpath ); return ( 0 ); } if ( ! pndrun ) { + pnd_log ( PND_LOG_DEFAULT, "Can't emit dotdesktop for %s, missing pnd_run.sh\n", targetpath ); return ( 0 ); } // set up - sprintf ( filename, "%s/%s.desktop", targetpath, p -> unique_id ); + sprintf ( filename, "%s/%s#%u.desktop", targetpath, p -> unique_id, p -> subapp_number ); // emit @@ -195,7 +200,7 @@ unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) { } // determine filename for target - sprintf ( buffer, "%s/%s.png", targetpath, p -> unique_id ); // target + sprintf ( buffer, "%s/%s#%u.png", targetpath, p -> unique_id, p -> subapp_number ); // target /* first.. open the source file, by type of application: * are we looking through a pnd file or a dir? diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index 73ed18e..88a1126 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -47,6 +47,8 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, { unsigned char valid = pnd_object_type_unknown; pnd_pxml_handle pxmlh = 0; + pnd_pxml_handle *pxmlapps = NULL; + pnd_pxml_handle *pxmlappiter; unsigned int pxml_close_pos = 0; unsigned char logit = pnd_log_do_buried_logging(); @@ -84,7 +86,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, //printf ( "PXML: disco callback encountered '%s'\n", fpath ); // pick up the PXML if we can - pxmlh = pnd_pxml_fetch ( (char*) fpath ); + pxmlapps = pnd_pxml_fetch ( (char*) fpath ); } else if ( valid == pnd_object_type_pnd ) { // PND ... ?? @@ -147,7 +149,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, #endif // by now, we have <PXML> .. </PXML>, try to parse.. - pxmlh = pnd_pxml_fetch_buffer ( (char*) fpath, pxmlbuf ); + pxmlapps = pnd_pxml_fetch_buffer ( (char*) fpath, pxmlbuf ); // done with file fclose ( f ); @@ -155,7 +157,19 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, } // pxmlh is useful? - if ( pxmlh ) { + if ( ! pxmlapps ) { + return ( 0 ); // continue tree walk + } + + // iterate across apps in the PXML + pxmlappiter = pxmlapps; + while ( 1 ) { + pxmlh = *pxmlappiter; + pxmlappiter++; + + if ( ! pxmlh ) { + break; // all done + } // look for any overrides, if requested pnd_pxml_merge_override ( pxmlh, disco_overrides ); @@ -166,6 +180,8 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, char *fixpxml; char *z; + pnd_log ( PND_LOG_DEFAULT, "Setting up discovered app %u\n", ((pnd_pxml_t*) pxmlh) -> subapp_number ); + p = pnd_box_allocinsert ( disco_box, (char*) fpath, sizeof(pnd_disco_t) ); // base paths @@ -181,6 +197,9 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, p -> object_filename = strdup ( fixpxml + 1 ); } + // subapp-number + p -> subapp_number = ((pnd_pxml_t*) pxmlh) -> subapp_number; + // png icon path p -> pnd_icon_pos = pxml_close_pos; @@ -250,7 +269,10 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, // ditch pxml pnd_pxml_delete ( pxmlh ); - } // got a pxmlh + } // while pxmlh is good + + // free up the applist + free ( pxmlapps ); return ( 0 ); // continue the tree walk } diff --git a/lib/pnd_pxml.c b/lib/pnd_pxml.c index 6f981a2..09a7fb6 100644 --- a/lib/pnd_pxml.c +++ b/lib/pnd_pxml.c @@ -11,30 +11,47 @@ #include "pnd_pathiter.h" #include "pnd_tinyxml.h" -pnd_pxml_handle pnd_pxml_fetch ( char *fullpath ) { +pnd_pxml_handle *pnd_pxml_fetch ( char *fullpath ) { + FILE *f; + char *b; + unsigned int len; - pnd_pxml_t *p = malloc ( sizeof(pnd_pxml_t) ); + f = fopen ( fullpath, "r" ); - memset ( p, '\0', sizeof(pnd_pxml_t) ); + if ( ! f ) { + return ( 0 ); + } + + fseek ( f, 0, SEEK_END ); + + len = ftell ( f ); + + fseek ( f, 0, SEEK_SET ); + + b = (char*) malloc ( len ); - if ( ! pnd_pxml_load ( fullpath, p ) ) { + if ( ! b ) { + fclose ( f ); return ( 0 ); } - return ( p ); -} + fread ( b, 1, len, f ); + + fclose ( f ); -pnd_pxml_handle pnd_pxml_fetch_buffer ( char *filename, char *buffer ) { + return ( pnd_pxml_fetch_buffer ( fullpath, b ) ); +} - pnd_pxml_t *p = malloc ( sizeof(pnd_pxml_t) ); +pnd_pxml_handle *pnd_pxml_fetch_buffer ( char *filename, char *buffer ) { - memset ( p, '\0', sizeof(pnd_pxml_t) ); + pnd_pxml_t **p = malloc ( sizeof(pnd_pxml_t*) * PXML_MAXAPPS ); + memset ( p, '\0', sizeof(pnd_pxml_t*) * PXML_MAXAPPS ); if ( ! pnd_pxml_parse ( filename, buffer, strlen ( buffer ), p ) ) { return ( 0 ); } - return ( p ); + return ( (pnd_pxml_handle*) p ); } void pnd_pxml_delete ( pnd_pxml_handle h ) { @@ -226,6 +243,8 @@ signed char pnd_pxml_merge_override ( pnd_pxml_handle h, char *searchpath ) { // the pxml includes a unique-id; use this value to attempt to find an // override in the given searchpath signed char retval = 0; + +#if 0 // TODO: Unfinished entirely now pnd_pxml_handle mergeh; if ( ! pnd_pxml_get_unique_id ( h ) ) { @@ -241,10 +260,12 @@ signed char pnd_pxml_merge_override ( pnd_pxml_handle h, char *searchpath ) { strncat ( buffer, ".xml", FILENAME_MAX ); //printf ( " Path to seek merges: '%s'\n", buffer ); + // TODO: handle multiple subapps! mergeh = pnd_pxml_fetch ( buffer ); if ( mergeh ) { + // TODO: handle all the various data bits if ( pnd_pxml_get_app_name_en ( mergeh ) ) { pnd_pxml_set_app_name ( h, pnd_pxml_get_app_name_en ( mergeh ) ); } @@ -254,6 +275,7 @@ signed char pnd_pxml_merge_override ( pnd_pxml_handle h, char *searchpath ) { } SEARCHPATH_POST +#endif return ( retval ); } diff --git a/lib/pnd_tinyxml.cpp b/lib/pnd_tinyxml.cpp index b11d450..59f7e4d 100644 --- a/lib/pnd_tinyxml.cpp +++ b/lib/pnd_tinyxml.cpp @@ -1,44 +1,15 @@ +#include <stdio.h> #include "tinyxml/tinyxml.h" #include "../include/pnd_pxml.h" #include "pnd_tinyxml.h" +#include "pnd_logger.h" //Easily change the tag names if required (globally in this file): #include "pnd_pxml_names.h" extern "C" { -unsigned char pnd_pxml_load ( const char* pFilename, pnd_pxml_t *app ) { - FILE *f; - char *b; - unsigned int len; - - f = fopen ( pFilename, "r" ); - - if ( ! f ) { - return ( 0 ); - } - - fseek ( f, 0, SEEK_END ); - - len = ftell ( f ); - - fseek ( f, 0, SEEK_SET ); - - b = (char*) malloc ( len ); - - if ( ! b ) { - fclose ( f ); - return ( 0 ); - } - - fread ( b, 1, len, f ); - - fclose ( f ); - - return ( pnd_pxml_parse ( pFilename, b, len, app ) ); -} - char *pnd_pxml_get_attribute(TiXmlElement *elem, const char *name) { const char *value = elem->Attribute(name); @@ -48,43 +19,45 @@ char *pnd_pxml_get_attribute(TiXmlElement *elem, const char *name) return NULL; } -unsigned char pnd_pxml_parse_titles(const TiXmlHandle hRoot, pnd_pxml_t *app) -{ - TiXmlElement *pElem; - app->titles_alloc_c = 4; //TODO: adjust this based on how many titles a PXML usually has. Power of 2. +unsigned char pnd_pxml_parse_titles(const TiXmlHandle hRoot, pnd_pxml_t *app) { + TiXmlElement *pElem; + app->titles_alloc_c = 4; //TODO: adjust this based on how many titles a PXML usually has. Power of 2. - app->titles = (pnd_localized_string_t *)malloc(sizeof(pnd_localized_string_t) * app->titles_alloc_c); - if (!app->titles) return (0); //errno = NOMEM + app->titles = (pnd_localized_string_t *)malloc(sizeof(pnd_localized_string_t) * app->titles_alloc_c); + if (!app->titles) return (0); //errno = NOMEM - //Go through all title tags and load them. - for (pElem = hRoot.FirstChild(PND_PXML_ENAME_TITLE).Element(); pElem; - pElem = pElem->NextSiblingElement(PND_PXML_ENAME_TITLE)) - { + //Go through all title tags and load them. + for (pElem = hRoot.FirstChild(PND_PXML_ENAME_TITLE).Element(); pElem; + pElem = pElem->NextSiblingElement(PND_PXML_ENAME_TITLE)) + { - if ( ! pElem->GetText() ) { - continue; - } + if ( ! pElem->GetText() ) { + continue; + } - char *text = strdup(pElem->GetText()); - if (!text) continue; + char *text = strdup(pElem->GetText()); + if (!text) continue; - char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_TITLELANG); - if (!lang) continue; + char *lang = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_TITLELANG); + if (!lang) continue; - app->titles_c++; - if (app->titles_c > app->titles_alloc_c) //we don't have enough strings allocated - { - app->titles_alloc_c <<= 1; - app->titles = (pnd_localized_string_t *)realloc((void*)app->titles, app->titles_alloc_c); - if (!app->titles) return (0); //errno = ENOMEM - } + app->titles_c++; + if (app->titles_c > app->titles_alloc_c) //we don't have enough strings allocated + { + app->titles_alloc_c <<= 1; + app->titles = (pnd_localized_string_t *)realloc((void*)app->titles, app->titles_alloc_c); + if (!app->titles) return (0); //errno = ENOMEM + } - pnd_localized_string_t *title = &app->titles[app->titles_c - 1]; - title->language = lang; - title->string = text; - } + pnd_localized_string_t *title = &app->titles[app->titles_c - 1]; + title->language = lang; + title->string = text; - return (1); + pnd_log ( PND_LOG_DEFAULT, (char*)" Title/Lang: %s/%s\n", text, lang ); + + } + + return ( 1 ); } unsigned char pnd_pxml_parse_descriptions(const TiXmlHandle hRoot, pnd_pxml_t *app) @@ -128,231 +101,298 @@ unsigned char pnd_pxml_parse_descriptions(const TiXmlHandle hRoot, pnd_pxml_t *a return (1); } -unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int length, pnd_pxml_t *app ) { - //Load the XML document - TiXmlDocument doc; - doc.Parse(buffer); +unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int length, pnd_pxml_t **apps ) { - TiXmlElement *pElem = NULL; + //Load the XML document + TiXmlDocument doc; + doc.Parse(buffer); - //Find the root element - TiXmlHandle hDoc(&doc); - TiXmlHandle hRoot(0); + unsigned char appwrappermode = 0; // >=1 -> using <application>...</application> wrapper + unsigned char appcount = 0; + pnd_pxml_t *app = NULL; - pElem = hDoc.FirstChild("PXML").Element(); - if (!pElem) return (0); - hRoot = TiXmlHandle(pElem); + TiXmlElement *pElem = NULL; + TiXmlElement *appElem = NULL; - //Get unique ID first. - app->unique_id = pnd_pxml_get_attribute(hRoot.Element(), PND_PXML_ATTRNAME_UID); + //Find the root element + TiXmlHandle hDoc(&doc); + TiXmlHandle hRoot(0); - //Everything related to the title: - pnd_pxml_parse_titles(hRoot, app); + pElem = hDoc.FirstChild("PXML").Element(); + if (!pElem) return (0); - //Everything description-related: - pnd_pxml_parse_descriptions(hRoot, app); + // new Strategy; really, we want multiple app support within a PXML, without the lameness of + // multiple <PXML>..</PXML> within a single PXML.xml file. As such, we should have an app within + // an <application>..</application> wrapper level, with the ID on that. Further, the icon and + // .desktop filenames can have a # appended which is the application-count-# within the PXML, + // so that they can have their own .desktop and icon without collisions, but still use the + // same unique-id if they want to. + // To avoid breaking existing PXML's (even though we're pre-launch), can detect if ID + // is present in PXML line or not; if not, assume application mode? + hRoot = TiXmlHandle(pElem); - //Everything launcher-related in one tag: - if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_EXEC).Element()) ) - { - app->background = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECBG); //if this returns NULL, the struct is filled with NULL. No need to check. - app->standalone = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECSTAL); - app->exec = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECCMD); - app->startdir = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECWD); - app->exec_no_x11 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECNOX11); - } + if ( hRoot.FirstChild(PND_PXML_APP).Element() != NULL ) { + appwrappermode = 1; + appElem = hRoot.FirstChild(PND_PXML_APP).Element(); + hRoot = TiXmlHandle ( appElem ); + } - //The app icon: - if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_ICON).Element()) ) + // until we run out of applications in the PXML.. + while ( 1 ) { + + pnd_log ( PND_LOG_DEFAULT, (char*)" App #%u inside of PXML %s\n", appcount, pFilename ); + + // create the buffer to hold the pxml + apps [ appcount ] = (pnd_pxml_t*) malloc ( sizeof(pnd_pxml_t) ); + memset ( apps [ appcount ], '\0', sizeof(pnd_pxml_t) ); + + // due to old code, just make life easier a minute.. + app = apps [ appcount ]; + if ( appwrappermode ) { + app -> subapp_number = appcount; + } else { + app -> subapp_number = 0; + } + + //Get unique ID first. + if ( appwrappermode ) { + app->unique_id = pnd_pxml_get_attribute(appElem, PND_PXML_ATTRNAME_UID); + pnd_log ( PND_LOG_DEFAULT, (char*)" Subapp #%u has unique_id %s\n", appcount, app -> unique_id ); + } else { + app->unique_id = pnd_pxml_get_attribute(hRoot.Element(), PND_PXML_ATTRNAME_UID); + pnd_log ( PND_LOG_DEFAULT, (char*)" Only-app #%u has unique_id %s\n", appcount, app -> unique_id ); + } + + //Everything related to the title: + pnd_pxml_parse_titles(hRoot, app); + + //Everything description-related: + pnd_pxml_parse_descriptions(hRoot, app); + + //Everything launcher-related in one tag: + if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_EXEC).Element()) ) + { + app->background = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECBG); //if this returns NULL, the struct is filled with NULL. No need to check. + app->standalone = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECSTAL); + app->exec = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECCMD); + app->startdir = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECWD); + app->exec_no_x11 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECNOX11); + } + + //The app icon: + if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_ICON).Element()) ) { + app->icon = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ICONSRC); + } + + //The preview pics: + if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_PREVPICS).Element()) ) + { + //TODO: Change this if pnd_pxml_t gains the feature of more pics than 2. + if ( (pElem = pElem->FirstChildElement(PND_PXML_ENAME_PREVPIC)) ) + { + app->previewpic1 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_PREVPICSRC); + + if ( (pElem = pElem->NextSiblingElement(PND_PXML_ENAME_PREVPIC)) ) { - app->icon = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ICONSRC); + app->previewpic2 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_PREVPICSRC); } - - //The preview pics: - if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_PREVPICS).Element()) ) + } + } //previewpic + + //The author info: + if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_AUTHOR).Element()) ) + { + app->author_name = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHORNAME); + app->author_website = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHORWWW); + //TODO: Uncomment this if the author gets email support. + //app->author_email = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHOREMAIL)); + } + + //The version info: + if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_VERSION).Element()) ) + { + app->version_major = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERMAJOR); + app->version_minor = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERMINOR); + app->version_release = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERREL); + app->version_build = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERBUILD); + } + + //The OS version info: + if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_OSVERSION).Element()) ) + { + app->osversion_major = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERMAJOR); + app->osversion_minor = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERMINOR); + app->osversion_release = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERREL); + app->osversion_build = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERBUILD); + } + + int i; //For now, we need to keep track of the index of categories. + //Categories: + if ( (pElem = hRoot.FirstChildElement(PND_PXML_NODENAME_CATS).Element()) ) //First, enter the "categories" node. + { + i = 0; + + //Goes through all the top-level categories and their sub-categories. i helps limit these to 2. + for (pElem = pElem->FirstChildElement(PND_PXML_ENAME_CAT); pElem && i < 2; + pElem = pElem->NextSiblingElement(PND_PXML_ENAME_CAT), i++) + { + //TODO: Fix pnd_pxml_t so that there can be more than 2 category 'trees' and more than 2 subcategories. Then this can be removed. + switch (i) { - //TODO: Change this if pnd_pxml_t gains the feature of more pics than 2. - if ( (pElem = pElem->FirstChildElement(PND_PXML_ENAME_PREVPIC)) ) - { - app->previewpic1 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_PREVPICSRC); - - if ( (pElem = pElem->NextSiblingElement(PND_PXML_ENAME_PREVPIC)) ) - { - app->previewpic2 = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_PREVPICSRC); - } - } - } //previewpic + case 0: //first category counts as the main cat for now + app->main_category = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CATNAME); + break; - //The author info: - if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_AUTHOR).Element()) ) - { - app->author_name = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHORNAME); - app->author_website = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHORWWW); - //TODO: Uncomment this if the author gets email support. - //app->author_email = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_AUTHOREMAIL)); + case 1: //...second as the alternative + app->altcategory = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CATNAME); } - //The version info: - if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_VERSION).Element()) ) + TiXmlElement *pSubCatElem; //the sub-elements for a main category. + int j = 0; //the subcategory index within this category + + //Goes through all the subcategories within this category. j helps limit these to 2. + for (pSubCatElem = pElem->FirstChildElement(PND_PXML_ENAME_SUBCAT); pSubCatElem && j < 2; + pSubCatElem = pSubCatElem->NextSiblingElement(PND_PXML_ENAME_SUBCAT), j++) { - app->version_major = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERMAJOR); - app->version_minor = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERMINOR); - app->version_release = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERREL); - app->version_build = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_VERBUILD); + char *subcat = pnd_pxml_get_attribute(pSubCatElem, PND_PXML_ATTRNAME_SUBCATNAME); + if (!(subcat)) continue; + + //TODO: This is ugly. Fix pnd_pxml_t so that there can be more than 2 category 'trees' and more than 2 subcategories. Then this can be removed. + switch (j | (i << 1)) + { + case 0: + app->subcategory1 = subcat; + break; + case 1: + app->subcategory2 = subcat; + break; + case 2: + app->altsubcategory1 = subcat; + break; + case 3: + app->altsubcategory2 = subcat; + } } - - //The OS version info: - if ( (pElem = hRoot.FirstChild(PND_PXML_ENAME_OSVERSION).Element()) ) + } + } + + //All file associations: + //Step into the associations node + if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_ASSOCS).Element()) ) + { + i = 0; + //Go through all associations. i serves as index; since the format only supports 3 associations we need to keep track of the number. + for (pElem = pElem->FirstChildElement(PND_PXML_ENAME_ASSOC); pElem && i < 3; + pElem = pElem->NextSiblingElement(PND_PXML_ENAME_ASSOC), i++) + { + char *name = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCNAME); + char *filetype = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCFTYPE); + char *paramter = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCARGS); + + if (!(name && filetype && paramter)) continue; + + switch(i) //TODO: same problem here: only 3 associations supported { - app->osversion_major = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERMAJOR); - app->osversion_minor = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERMINOR); - app->osversion_release = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERREL); - app->osversion_build = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_OSVERBUILD); + case 0: + { + app->associationitem1_name = name; + app->associationitem1_filetype = filetype; + app->associationitem1_parameter = paramter; + break; } - - int i; //For now, we need to keep track of the index of categories. - //Categories: - if ( (pElem = hRoot.FirstChildElement(PND_PXML_NODENAME_CATS).Element()) ) //First, enter the "categories" node. + case 1: { - i = 0; - - //Goes through all the top-level categories and their sub-categories. i helps limit these to 2. - for (pElem = pElem->FirstChildElement(PND_PXML_ENAME_CAT); pElem && i < 2; - pElem = pElem->NextSiblingElement(PND_PXML_ENAME_CAT), i++) - { - //TODO: Fix pnd_pxml_t so that there can be more than 2 category 'trees' and more than 2 subcategories. Then this can be removed. - switch (i) - { - case 0: //first category counts as the main cat for now - app->main_category = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CATNAME); - break; - - case 1: //...second as the alternative - app->altcategory = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CATNAME); - } - - TiXmlElement *pSubCatElem; //the sub-elements for a main category. - int j = 0; //the subcategory index within this category - - //Goes through all the subcategories within this category. j helps limit these to 2. - for (pSubCatElem = pElem->FirstChildElement(PND_PXML_ENAME_SUBCAT); pSubCatElem && j < 2; - pSubCatElem = pSubCatElem->NextSiblingElement(PND_PXML_ENAME_SUBCAT), j++) - { - char *subcat = pnd_pxml_get_attribute(pSubCatElem, PND_PXML_ATTRNAME_SUBCATNAME); - if (!(subcat)) continue; - - //TODO: This is ugly. Fix pnd_pxml_t so that there can be more than 2 category 'trees' and more than 2 subcategories. Then this can be removed. - switch (j | (i << 1)) - { - case 0: - app->subcategory1 = subcat; - break; - case 1: - app->subcategory2 = subcat; - break; - case 2: - app->altsubcategory1 = subcat; - break; - case 3: - app->altsubcategory2 = subcat; - } - } - } + app->associationitem2_name = name; + app->associationitem2_filetype = filetype; + app->associationitem2_parameter = paramter; + break; } - - //All file associations: - //Step into the associations node - if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_ASSOCS).Element()) ) + case 2: { - i = 0; - //Go through all associations. i serves as index; since the format only supports 3 associations we need to keep track of the number. - for (pElem = pElem->FirstChildElement(PND_PXML_ENAME_ASSOC); pElem && i < 3; - pElem = pElem->NextSiblingElement(PND_PXML_ENAME_ASSOC), i++) - { - char *name = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCNAME); - char *filetype = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCFTYPE); - char *paramter = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_ASSOCARGS); - - if (!(name && filetype && paramter)) continue; - - switch(i) //TODO: same problem here: only 3 associations supported - { - case 0: - { - app->associationitem1_name = name; - app->associationitem1_filetype = filetype; - app->associationitem1_parameter = paramter; - break; - } - case 1: - { - app->associationitem2_name = name; - app->associationitem2_filetype = filetype; - app->associationitem2_parameter = paramter; - break; - } - case 2: - { - app->associationitem3_name = name; - app->associationitem3_filetype = filetype; - app->associationitem3_parameter = paramter; - } - } - } + app->associationitem3_name = name; + app->associationitem3_filetype = filetype; + app->associationitem3_parameter = paramter; } - - //Performance related things (aka: Clockspeed XD): - pElem = hRoot.FirstChild(PND_PXML_ENAME_CLOCK).Element(); - if (pElem) - { - app->clockspeed = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CLOCKFREQ); } - - // Package - pElem = hRoot.FirstChild ( PND_PXML_ENAME_PACKAGE ).Element(); - if ( pElem ) { - app -> package_name = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_PACKAGE_NAME ); - app -> package_release_date = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_PACKAGE_DATE ); + } + } + + //Performance related things (aka: Clockspeed XD): + pElem = hRoot.FirstChild(PND_PXML_ENAME_CLOCK).Element(); + if (pElem) + { + app->clockspeed = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_CLOCKFREQ); + } + + // Package + pElem = hRoot.FirstChild ( PND_PXML_ENAME_PACKAGE ).Element(); + if ( pElem ) { + app -> package_name = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_PACKAGE_NAME ); + app -> package_release_date = pnd_pxml_get_attribute ( pElem, PND_PXML_ATTRNAME_PACKAGE_DATE ); + } + + // mkdir request + if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_MKDIR).Element()) ) { + + // seek <dir> + if ( (pElem = pElem->FirstChildElement(PND_PXML_ENAME_MKDIR)) ) { + char *t; + + if ( ( t = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_MKDIRPATH) ) ) { + // first <dir>, so just replace it wholesale; we use strdup so we can free() easily later, consistently. Mmm, leak seems imminent. + app -> mkdir_sp = strdup ( t ); } - // mkdir request - if ( (pElem = hRoot.FirstChild(PND_PXML_NODENAME_MKDIR).Element()) ) { - - // seek <dir> - if ( (pElem = pElem->FirstChildElement(PND_PXML_ENAME_MKDIR)) ) { - char *t; - - if ( ( t = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_MKDIRPATH) ) ) { - // first <dir>, so just replace it wholesale; we use strdup so we can free() easily later, consistently. Mmm, leak seems imminent. - app -> mkdir_sp = strdup ( t ); - } - - while ( ( pElem = pElem -> NextSiblingElement ( PND_PXML_ENAME_MKDIR ) ) ) { + while ( ( pElem = pElem -> NextSiblingElement ( PND_PXML_ENAME_MKDIR ) ) ) { - if ( ( t = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_MKDIRPATH) ) ) { - char *foo = (char*) malloc ( strlen ( app -> mkdir_sp ) + strlen ( t ) + 1 /*:*/ + 1 /*\0*/ ); + if ( ( t = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_MKDIRPATH) ) ) { + char *foo = (char*) malloc ( strlen ( app -> mkdir_sp ) + strlen ( t ) + 1 /*:*/ + 1 /*\0*/ ); - if ( foo ) { - sprintf ( foo, "%s:%s", app -> mkdir_sp, t ); - free ( app -> mkdir_sp ); - app -> mkdir_sp = foo; - } // assuming we got ram, lets cat it all together + if ( foo ) { + sprintf ( foo, "%s:%s", app -> mkdir_sp, t ); + free ( app -> mkdir_sp ); + app -> mkdir_sp = foo; + } // assuming we got ram, lets cat it all together - } // got another elem? + } // got another elem? - } // while + } // while - } // found a <dir> + } // found a <dir> #if 0 - if ( app -> mkdir_sp ) { - printf ( "mkdir: %s\n", app -> mkdir_sp ); - } + if ( app -> mkdir_sp ) { + printf ( "mkdir: %s\n", app -> mkdir_sp ); + } #endif - } // mkdir + } // mkdir - return (1); + // if in <application> mode, do we find another app? + if ( appwrappermode ) { + appElem = appElem -> NextSiblingElement ( PND_PXML_APP ); + if ( ! appElem ) { + pnd_log ( PND_LOG_DEFAULT, (char*)" No more applications within PXML\n" ); + break; // no more applications + } + // got another application.. + //pnd_log ( PND_LOG_DEFAULT, " Found another applications within PXML\n" ); + appwrappermode++; + hRoot = TiXmlHandle ( appElem ); + + appcount++; + + if ( appcount == PXML_MAXAPPS ) { + return ( 1 ); // thats all we can handle; we're not going to auto-extend this + } + + } else { + break; // single-app old PXML + } + + } // while finding apps + + return (1); } } // extern C diff --git a/lib/pnd_utility.c b/lib/pnd_utility.c index 5009b51..6c521b9 100644 --- a/lib/pnd_utility.c +++ b/lib/pnd_utility.c @@ -173,9 +173,9 @@ void pnd_exec_no_wait_1 ( char *fullpath, char *arg1 ) { return; } -pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) { +pnd_pxml_handle *pnd_pxml_get_by_path ( char *fullpath ) { unsigned char valid = pnd_object_type_unknown; - pnd_pxml_handle pxmlh = 0; + pnd_pxml_handle *pxmlapps = 0; // WARN: this is way too close to callback in pnd_disco .. should be refactored! @@ -192,7 +192,7 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) { // potentially a valid application if ( valid == pnd_object_type_directory ) { - pxmlh = pnd_pxml_fetch ( (char*) fullpath ); + pxmlapps = pnd_pxml_fetch ( (char*) fullpath ); } else if ( valid == pnd_object_type_pnd ) { FILE *f; @@ -214,7 +214,7 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) { } // by now, we have <PXML> .. </PXML>, try to parse.. - pxmlh = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf ); + pxmlapps = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf ); // done with file fclose ( f ); @@ -223,7 +223,7 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) { // .. - return ( pxmlh ); + return ( pxmlapps ); } unsigned char pnd_determine_mountpoint ( char *fullpath, char *r_mountpoint, unsigned char mountpoint_len ) { diff --git a/test/rawpxmltest.c b/test/rawpxmltest.c index 26e3a96..06545ba 100644 --- a/test/rawpxmltest.c +++ b/test/rawpxmltest.c @@ -15,58 +15,66 @@ int main (int argc, char **argv) return 1; } - pnd_pxml_handle h = pnd_pxml_fetch(argv[1]); + pnd_pxml_handle *apps = pnd_pxml_fetch(argv[1]); + pnd_pxml_handle h; - if (!h) - { - printf("Could not load file \"%s\"\n", argv[1]); - return 1; - } + while ( *apps ) { + h = *apps; + + if (!h) + { + printf("Could not load file \"%s\"\n", argv[1]); + return 1; + } + + char *data; //for all values - char *data; //for all values + if ( (data = pnd_pxml_get_app_name_en(h)) ) printf("Appname(en): %s\n", data); + if ( (data = pnd_pxml_get_app_name_de(h)) ) printf("Appname(de): %s\n", data); + if ( (data = pnd_pxml_get_app_name_it(h)) ) printf("Appname(it): %s\n", data); + if ( (data = pnd_pxml_get_app_name_fr(h)) ) printf("Appname(fr): %s\n", data); - if ( (data = pnd_pxml_get_app_name_en(h)) ) printf("Appname(en): %s\n", data); - if ( (data = pnd_pxml_get_app_name_de(h)) ) printf("Appname(de): %s\n", data); - if ( (data = pnd_pxml_get_app_name_it(h)) ) printf("Appname(it): %s\n", data); - if ( (data = pnd_pxml_get_app_name_fr(h)) ) printf("Appname(fr): %s\n", data); + if ( (data = pnd_pxml_get_unique_id(h)) ) printf("UID: %s\n", data); - if ( (data = pnd_pxml_get_unique_id(h)) ) printf("UID: %s\n", data); + if ( (data = pnd_pxml_get_standalone(h)) ) printf("Standalone: %s\n", data); - if ( (data = pnd_pxml_get_standalone(h)) ) printf("Standalone: %s\n", data); + if ( (data = pnd_pxml_get_icon(h)) ) printf("Icon: %s\n", data); - if ( (data = pnd_pxml_get_icon(h)) ) printf("Icon: %s\n", data); + if ( (data = pnd_pxml_get_description_en(h)) ) printf("Description(en): %s\n", data); + if ( (data = pnd_pxml_get_description_de(h)) ) printf("Description(de): %s\n", data); + if ( (data = pnd_pxml_get_description_it(h)) ) printf("Description(it): %s\n", data); + if ( (data = pnd_pxml_get_description_fr(h)) ) printf("Description(fr): %s\n", data); - if ( (data = pnd_pxml_get_description_en(h)) ) printf("Description(en): %s\n", data); - if ( (data = pnd_pxml_get_description_de(h)) ) printf("Description(de): %s\n", data); - if ( (data = pnd_pxml_get_description_it(h)) ) printf("Description(it): %s\n", data); - if ( (data = pnd_pxml_get_description_fr(h)) ) printf("Description(fr): %s\n", data); + if ( (data = pnd_pxml_get_previewpic1(h)) ) printf("Pic1: %s\n", data); + if ( (data = pnd_pxml_get_previewpic2(h)) ) printf("Pic2: %s\n", data); - if ( (data = pnd_pxml_get_previewpic1(h)) ) printf("Pic1: %s\n", data); - if ( (data = pnd_pxml_get_previewpic2(h)) ) printf("Pic2: %s\n", data); + if ( (data = pnd_pxml_get_author_name(h)) ) printf("Author name: %s\n", data); + if ( (data = pnd_pxml_get_author_website(h)) ) printf("Author website: %s\n", data); - if ( (data = pnd_pxml_get_author_name(h)) ) printf("Author name: %s\n", data); - if ( (data = pnd_pxml_get_author_website(h)) ) printf("Author website: %s\n", data); + if ( (data = pnd_pxml_get_version_major(h)) ) printf("Version major: %s\n", data); + if ( (data = pnd_pxml_get_version_minor(h)) ) printf("Version minor: %s\n", data); + if ( (data = pnd_pxml_get_version_release(h)) ) printf("Version release: %s\n", data); + if ( (data = pnd_pxml_get_version_build(h)) ) printf("Version build: %s\n", data); - if ( (data = pnd_pxml_get_version_major(h)) ) printf("Version major: %s\n", data); - if ( (data = pnd_pxml_get_version_minor(h)) ) printf("Version minor: %s\n", data); - if ( (data = pnd_pxml_get_version_release(h)) ) printf("Version release: %s\n", data); - if ( (data = pnd_pxml_get_version_build(h)) ) printf("Version build: %s\n", data); + if ( (data = pnd_pxml_get_osversion_major(h)) ) printf("OSVersion major: %s\n", data); + if ( (data = pnd_pxml_get_osversion_minor(h)) ) printf("OSVersion minor: %s\n", data); + if ( (data = pnd_pxml_get_osversion_release(h)) ) printf("OSVersion release: %s\n", data); + if ( (data = pnd_pxml_get_osversion_build(h)) ) printf("OSVersion build: %s\n", data); - if ( (data = pnd_pxml_get_osversion_major(h)) ) printf("OSVersion major: %s\n", data); - if ( (data = pnd_pxml_get_osversion_minor(h)) ) printf("OSVersion minor: %s\n", data); - if ( (data = pnd_pxml_get_osversion_release(h)) ) printf("OSVersion release: %s\n", data); - if ( (data = pnd_pxml_get_osversion_build(h)) ) printf("OSVersion build: %s\n", data); + if ( (data = pnd_pxml_get_exec(h)) ) printf("Application exec: %s\n", data); - if ( (data = pnd_pxml_get_exec(h)) ) printf("Application exec: %s\n", data); + if ( (data = pnd_pxml_get_main_category(h)) ) printf("Category 1: %s\n", data); + if ( (data = pnd_pxml_get_subcategory1(h)) ) printf("Category 1 sub 1: %s\n", data); + if ( (data = pnd_pxml_get_subcategory2(h)) ) printf("Category 1 sub 2: %s\n", data); + if ( (data = pnd_pxml_get_altcategory(h)) ) printf("Category 2: %s\n", data); + if ( (data = pnd_pxml_get_altsubcategory1(h)) ) printf("Category 2 sub 1: %s\n", data); + if ( (data = pnd_pxml_get_altsubcategory2(h)) ) printf("Category 2 sub 2: %s\n", data); - if ( (data = pnd_pxml_get_main_category(h)) ) printf("Category 1: %s\n", data); - if ( (data = pnd_pxml_get_subcategory1(h)) ) printf("Category 1 sub 1: %s\n", data); - if ( (data = pnd_pxml_get_subcategory2(h)) ) printf("Category 1 sub 2: %s\n", data); - if ( (data = pnd_pxml_get_altcategory(h)) ) printf("Category 2: %s\n", data); - if ( (data = pnd_pxml_get_altsubcategory1(h)) ) printf("Category 2 sub 1: %s\n", data); - if ( (data = pnd_pxml_get_altsubcategory2(h)) ) printf("Category 2 sub 2: %s\n", data); + pnd_pxml_delete(h); - pnd_pxml_delete(h); + // next + apps++; + } // while return 0; } diff --git a/testdata/apps/sampleappX/PXML.xml b/testdata/apps/sampleappX/PXML.xml new file mode 100644 index 0000000..29e18fd --- /dev/null +++ b/testdata/apps/sampleappX/PXML.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<PXML xmlns="http://openpandora.org/namespaces/PXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PXML_schema.xsd"> + + <application id="jeff.sample.X"> + <title lang="en_US">Sample App X - Fullscreen + + This is the English Description of the file. + + + + + Sample App X - Windowed + + This is the English Description of the file. + + + + + Sample App X - Other ID + + This is the English Description of the file. + + + + diff --git a/testdata/apps/sampleappX/PXML.xml.bak2 b/testdata/apps/sampleappX/PXML.xml.bak2 new file mode 100644 index 0000000..fa62c13 --- /dev/null +++ b/testdata/apps/sampleappX/PXML.xml.bak2 @@ -0,0 +1,145 @@ + + + + + Sample App X1 + Sample App X1 - German + + + + This is the English Description of the file. + This would be the German description. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ......kfujl........ + ......qwe......fwer..... + + + + + + Sample App X2 + Sample App X2 - German + + + + This is the English Description of the file. + This would be the German description. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ......kfujl........ + ......qwe......fwer..... + + + + + + Sample App X3 + Sample App X3 - German + + + + This is the English Description of the file. + This would be the German description. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ......kfujl........ + ......qwe......fwer..... + + + + + diff --git a/testdata/apps/sampleappX/program.exe b/testdata/apps/sampleappX/program.exe new file mode 100644 index 0000000..e69de29 diff --git a/testdata/apps/sampleappX/zeldaicon.png b/testdata/apps/sampleappX/zeldaicon.png new file mode 100644 index 0000000..140a393 Binary files /dev/null and b/testdata/apps/sampleappX/zeldaicon.png differ diff --git a/testdata/scripts/genpxml.sh b/testdata/scripts/genpxml.sh index ade9c7f..d54f683 100755 --- a/testdata/scripts/genpxml.sh +++ b/testdata/scripts/genpxml.sh @@ -12,38 +12,44 @@ loc=$(dirname "$0") echo ' - - '$BASENAMEnoex' - '$BASENAMEnoex' - German (lol!) + + + + + '$BASENAMEnoex' + '$BASENAMEnoex' - German (lol!) - + - en_US Automatically generated pxml from'$(pwd)' exe='$BASENAME' - de_DE Automatisch generiertes pxml aus'$(pwd)' exe='$BASENAME' + en_US Automatically generated pxml from'$(pwd)' exe='$BASENAME' + de_DE Automatisch generiertes pxml aus'$(pwd)' exe='$BASENAME' - ' + ' #add all images in the folder as preview pics for image in $(file -i -0 * | grep -a image | cut -d" " -f1) do -echo "" +echo " " done -echo ' - - - - - - - - - - - - - - - - - +echo ' + + + + + + + + + + + + + + + + + + + + ' \ No newline at end of file