X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fpnd_pxml.c;h=7632c055b3ba612275ec54b84b73bc63820c45e7;hb=5eb90829d7d555257f69265a99bc5ca987ce30ee;hp=35b21b35fe1f4adfdba0be49078c4a6bf8bbaee0;hpb=020f0555fd57745e14c1e388884c4f63272d8562;p=pandora-libraries.git diff --git a/lib/pnd_pxml.c b/lib/pnd_pxml.c index 35b21b3..7632c05 100644 --- a/lib/pnd_pxml.c +++ b/lib/pnd_pxml.c @@ -10,69 +10,79 @@ #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_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 ) { pnd_pxml_t *p = (pnd_pxml_t*) h; - if ( p -> title_en ) { - free ( p -> title_en ); - } - if ( p -> title_de ) { - free ( p -> title_de ); - } - if ( p -> title_it ) { - free ( p -> title_it ); - } - if ( p -> title_fr ) { - free ( p -> title_fr ); + int i; + if (p->titles) { + for (i = 0; i < p->titles_c; i++) + { + free(p->titles[i].language); + free(p->titles[i].string); + } + free(p->titles); } - if ( p -> unique_id ) { - free ( p -> unique_id ); + + if (p->descriptions) { + for (i = 0; i < p->descriptions_c; i++) + { + free(p->descriptions[i].language); + free(p->descriptions[i].string); + } + free(p->descriptions); } + if ( p -> standalone ) { free ( p -> standalone ); } if ( p -> icon ) { free ( p -> icon ); } - if ( p -> description_en ) { - free ( p -> description_en ); - } - if ( p -> description_de ) { - free ( p -> description_de ); - } - if ( p -> description_it ) { - free ( p -> description_it ); - } - if ( p -> description_fr ) { - free ( p -> description_fr ); - } if ( p -> previewpic1 ) { free ( p -> previewpic1 ); } @@ -167,25 +177,50 @@ void pnd_pxml_delete ( pnd_pxml_handle h ) { free ( p -> startdir ); } + free(p); /*very important!*/ + return; } 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. + */ pnd_pxml_t *p = (pnd_pxml_t*) h; - if ( p -> title_en ) { - free ( p -> title_en ); - p -> title_en = NULL; + char has_en_field = 0; + int i; + + if (!v) return; /*TODO: add error information? Make it possible to set the string to NULL?*/ + + for (i = 0; i < p->titles_c; i++) + { + if (strncmp("en", p->titles[i].language, 2) == 0) /*strict comparison; match "en_US", "en_GB" etc... All these are set.*/ + { + free(p->titles[i].string); + p->titles[i].string = strdup(v); + has_en_field = 1; + } } - if ( v ) { - p -> title_en = strdup ( v ); + if (!has_en_field) + { + p->titles_c++; + if (p->titles_c > p->titles_alloc_c) //we don't have enough strings allocated + { + p->titles_alloc_c <<= 1; + p->titles = (pnd_localized_string_t *)realloc((void*)p->titles, p->titles_alloc_c); + if (!p->titles) return; //errno = ENOMEM + } + p->titles[p->titles_c - 1].language = "en_US"; + p->titles[p->titles_c - 1].string = strdup(v); } return; } unsigned char pnd_is_pxml_valid_app ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; + //pnd_pxml_t *p = (pnd_pxml_t*) h; //unused atm // for now, lets just verify the exec-path is valid @@ -209,8 +244,14 @@ 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 ) ) { + return ( -1 ); // no unique-id present, so can't use it to name potential override files + } + SEARCHPATH_PRE { @@ -220,10 +261,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 ) ); } @@ -233,28 +276,61 @@ signed char pnd_pxml_merge_override ( pnd_pxml_handle h, char *searchpath ) { } 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 = 0xffff; /*Set to something Really Bad in the beginning*/ + char *best_match = NULL; + + for(i = 0; i < strings_c; i++) + { + // 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; + best_match = strings[i].string; + } + } + + 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_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_en ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> title_en ); + return pnd_pxml_get_app_name(h, "en"); } char *pnd_pxml_get_app_name_de ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> title_de ); + return pnd_pxml_get_app_name(h, "de"); } char *pnd_pxml_get_app_name_it ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> title_it ); + return pnd_pxml_get_app_name(h, "it"); } char *pnd_pxml_get_app_name_fr ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> title_fr ); + return pnd_pxml_get_app_name(h, "fr"); } char *pnd_pxml_get_unique_id ( pnd_pxml_handle h ) { @@ -272,24 +348,25 @@ char *pnd_pxml_get_icon ( pnd_pxml_handle h ) { return ( p -> icon ); } +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); +} + char *pnd_pxml_get_description_en ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> description_en ); + return pnd_pxml_get_app_description(h, "en"); } char *pnd_pxml_get_description_de ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> description_de ); + return pnd_pxml_get_app_description(h, "de"); } char *pnd_pxml_get_description_it ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> description_it ); + return pnd_pxml_get_app_description(h, "it"); } char *pnd_pxml_get_description_fr ( pnd_pxml_handle h ) { - pnd_pxml_t *p = (pnd_pxml_t*) h; - return ( p -> description_fr ); + return pnd_pxml_get_app_description(h, "fr"); } char *pnd_pxml_get_previewpic1 ( pnd_pxml_handle h ) { @@ -337,6 +414,16 @@ char *pnd_pxml_get_exec ( pnd_pxml_handle h ) { 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 ); +} + char *pnd_pxml_get_main_category ( pnd_pxml_handle h ) { pnd_pxml_t *p = (pnd_pxml_t*) h; return ( p -> main_category ); @@ -446,3 +533,54 @@ char *pnd_pxml_get_startdir ( pnd_pxml_handle h ) { pnd_pxml_t *p = (pnd_pxml_t*) h; return ( p -> startdir ); } + +char *pnd_pxml_get_mkdir ( pnd_pxml_handle h ) { + pnd_pxml_t *p = (pnd_pxml_t*) h; + return ( p -> mkdir_sp ); +} + +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 ); +}