#include "pnd_pxml.h"
#include "pnd_pathiter.h"
#include "pnd_tinyxml.h"
+#include "pnd_logger.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_handle *h;
- 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 );
- if ( ! pnd_pxml_load ( fullpath, p ) ) {
+ if ( ! len ) {
+ return ( NULL );
+ }
+
+ b = (char*) malloc ( len + 1 );
+
+ if ( ! b ) {
+ fclose ( f );
return ( 0 );
}
- return ( p );
-}
+ fread ( b, 1, len, f );
-pnd_pxml_handle pnd_pxml_fetch_buffer ( char *filename, char *buffer ) {
+ fclose ( f );
- pnd_pxml_t *p = malloc ( sizeof(pnd_pxml_t) );
+ h = pnd_pxml_fetch_buffer ( fullpath, b );
+ free ( b );
- memset ( p, '\0', sizeof(pnd_pxml_t) );
+ return ( h );
+}
+
+pnd_pxml_handle *pnd_pxml_fetch_buffer ( char *filename, char *buffer ) {
+
+ 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 ) {
free(p->descriptions);
}
+ if ( p -> unique_id ) {
+ free ( p -> unique_id );
+ }
+ if ( p -> package_id ) {
+ free ( p -> package_id );
+ }
if ( p -> standalone ) {
free ( p -> standalone );
}
if ( p -> startdir ) {
free ( p -> startdir );
}
+ if ( p -> appdata_dirname ) {
+ free ( p -> appdata_dirname );
+ }
+ if ( p -> info_name ) {
+ free ( p -> info_name );
+ }
+ if ( p -> info_filename ) {
+ free ( p -> info_filename );
+ }
+ if ( p -> info_type ) {
+ free ( p -> info_type );
+ }
+ if ( p -> exec_no_x11 ) {
+ free ( p -> exec_no_x11 );
+ }
+ if ( p -> execargs ) {
+ free ( p -> execargs );
+ }
+ if ( p -> mkdir_sp ) {
+ free ( p -> mkdir_sp );
+ }
+ if ( p -> package_version_major ) {
+ free ( p -> package_version_major );
+ }
+ if ( p -> package_version_minor ) {
+ free ( p -> package_version_minor );
+ }
+ if ( p -> package_version_release ) {
+ free ( p -> package_version_release );
+ }
+ if ( p -> package_version_build ) {
+ free ( p -> package_version_build );
+ }
free(p); /*very important!*/
}
void pnd_pxml_set_app_name ( pnd_pxml_handle h, char *v ) {
- /*
+ /*
* Please do not use this function if it can be avoided; it is only here for compatibility.
* The function might fail on low memory, and there's no way for the user to know when this happens.
*/
// 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 ) ) {
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 ) );
}
}
SEARCHPATH_POST
+#endif
return ( retval );
}
char *pnd_pxml_get_best_localized_string(pnd_localized_string_t strings[], int strings_c, char *iso_lang)
{
int i;
- int similarity_weight = 0xff; /*Set to something Really Bad in the beginning*/
+ int similarity_weight = 0xffff; /*Set to something Really Bad in the beginning*/
char *best_match = NULL;
for(i = 0; i < strings_c; i++)
{
- int new_weight = abs(strcmp(strings[i].language, iso_lang));
+ // factor in the length -- if we're given 'en' and have a string 'en_US', thats better than 'de_something'; if we don't
+ // use length, then en_US and de_FO are same to 'en'.
+ int maxcount = strlen ( strings[i].language ) < strlen ( iso_lang ) ? strlen ( strings[i].language ) : strlen ( iso_lang );
+ int new_weight = abs(strncmp(strings[i].language, iso_lang, maxcount));
+ //pnd_log ( PND_LOG_DEFAULT, "looking for lang %s, looking at lang %s (weight %d, old %d): %s\n",
+ // iso_lang, strings [ i ].language, new_weight, similarity_weight, strings [ i ].string );
if (new_weight < similarity_weight)
{
similarity_weight = new_weight;
}
if ( best_match ) {
+ //pnd_log ( PND_LOG_DEFAULT, "best match: %s\n", best_match );
return strdup(best_match);
}
+ //pnd_log ( PND_LOG_DEFAULT, "best match: FAIL\n" );
+
return ( NULL );
}
+char *pnd_pxml_get_package_id ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> package_id );
+}
+
char *pnd_pxml_get_app_name ( pnd_pxml_handle h, char *iso_lang ) {
pnd_pxml_t *p = (pnd_pxml_t *) h;
return pnd_pxml_get_best_localized_string(p->titles, p->titles_c, iso_lang);
char *pnd_pxml_get_app_name_fr ( pnd_pxml_handle h ) {
return pnd_pxml_get_app_name(h, "fr");
}
-
char *pnd_pxml_get_unique_id ( pnd_pxml_handle h ) {
pnd_pxml_t *p = (pnd_pxml_t*) h;
return ( p -> unique_id );
}
+char *pnd_pxml_get_appdata_dirname ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> appdata_dirname );
+}
+
char *pnd_pxml_get_standalone ( pnd_pxml_handle h ) {
pnd_pxml_t *p = (pnd_pxml_t*) h;
return ( p -> standalone );
return ( p -> icon );
}
+// this guy's func name is 'out of sync' with the family of functions below; but since it
+// exists, rather than just remove it and break someones code, will add in the appropriate
+// function wrapper; the header only specifies the other guy (always did), so the header
+// was already on the right path.
char *pnd_pxml_get_app_description ( pnd_pxml_handle h, char *iso_lang ) {
pnd_pxml_t *p = (pnd_pxml_t *) h;
return pnd_pxml_get_best_localized_string(p->descriptions, p->descriptions_c, iso_lang);
return pnd_pxml_get_app_description(h, "fr");
}
+// wrapper added so family of function names is consistent; see comment for pnd_pxml_get_app_description() above
+char *pnd_pxml_get_description ( pnd_pxml_handle h, char *iso_lang) {
+ return ( pnd_pxml_get_app_description ( h, iso_lang ) );
+}
+
char *pnd_pxml_get_previewpic1 ( pnd_pxml_handle h ) {
pnd_pxml_t *p = (pnd_pxml_t*) h;
return ( p -> previewpic1 );
return ( p -> exec );
}
+char *pnd_pxml_get_execargs ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> execargs );
+}
+
char *pnd_pxml_get_exec_option_no_x11 ( pnd_pxml_handle h ) {
pnd_pxml_t *p = (pnd_pxml_t*) h;
return ( p -> exec_no_x11 );
pnd_pxml_t *p = (pnd_pxml_t*) h;
return ( p -> mkdir_sp );
}
+
+char *pnd_pxml_get_package_version_major ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> package_version_major );
+}
+
+char *pnd_pxml_get_package_version_minor ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> package_version_minor );
+}
+
+char *pnd_pxml_get_package_version_release ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> package_version_release );
+}
+
+char *pnd_pxml_get_package_version_build ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> package_version_build );
+}
+
+unsigned char pnd_pxml_is_affirmative ( char *v ) {
+
+ if ( ! v ) {
+ return ( 0 );
+ }
+
+ if ( ( v [ 0 ] == 'Y' ) ||
+ ( v [ 0 ] == 'y' ) ||
+ ( v [ 0 ] == '1' ) )
+ {
+ return ( 0 );
+ }
+
+ return ( 0 );
+}
+
+pnd_pxml_x11_req_e pnd_pxml_get_x11 ( char *pxmlvalue ) {
+
+ if ( ! pxmlvalue ) {
+ return ( pnd_pxml_x11_ignored );
+ } else if ( strcasecmp ( pxmlvalue, "req" ) == 0 ) {
+ return ( pnd_pxml_x11_required );
+ } else if ( strcasecmp ( pxmlvalue, "stop" ) == 0 ) {
+ return ( pnd_pxml_x11_stop );
+ } else if ( strcasecmp ( pxmlvalue, "ignore" ) == 0 ) {
+ return ( pnd_pxml_x11_ignored );
+ }
+
+ return ( pnd_pxml_x11_ignored ); // default
+}
+
+char *pnd_pxml_get_info_name ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> info_name );
+}
+
+char *pnd_pxml_get_info_type ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> info_type );
+}
+
+char *pnd_pxml_get_info_src ( pnd_pxml_handle h ) {
+ pnd_pxml_t *p = (pnd_pxml_t*) h;
+ return ( p -> info_filename );
+}