7 #include "pnd_logger.h"
9 #include "pnd_container.h"
10 #include "pnd_discovery.h"
11 #include "../lib/pnd_pathiter.h"
17 mm_category_t g_categories [ MAX_CATS ];
18 unsigned char g_categorycount = 0;
20 mm_catmap_t g_catmaps [ MAX_CATS ];
21 unsigned char g_catmapcount = 0;
23 extern pnd_conf_handle g_conf;
25 unsigned char category_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ) {
28 // check category list; if found, append app to the end of it.
29 // if not found, add it to the category list and plop the app in there.
30 // app's are just app-refs, which contain links to the disco-t list -- thus removal is only in one place, and
31 // an app can be in multiple categories if we like..
34 // find or create category
37 if ( ( c = category_query ( catname ) ) ) {
38 // category was found..
40 // category wasn't found..
41 pnd_log ( PND_LOG_DEFAULT, "New category '%s'\n", catname );
42 g_categories [ g_categorycount ].catname = strdup ( catname );
43 g_categories [ g_categorycount ].refs = NULL;
44 c = &(g_categories [ g_categorycount ]);
49 return ( 1 ); // create cat, but skip app
52 // alloc and populate appref
54 mm_appref_t *ar = malloc ( sizeof(mm_appref_t) );
59 bzero ( ar, sizeof(mm_appref_t) );
64 // plug it into category
65 // and sort it on insert!
67 ar -> next = c -> refs;
70 // if no refs at all, or new guy has no title, just stick it in at head
71 if ( c -> refs && ar -> ref -> title_en ) {
72 mm_appref_t *iter = c -> refs;
73 mm_appref_t *last = NULL;
77 if ( iter -> ref -> title_en ) {
78 if ( strcmp ( ar -> ref -> title_en, iter -> ref -> title_en ) < 0 ) {
79 // new guy is smaller than the current guy!
83 // since new guy must have a name by here, we're bigger than any guy who does not have a name
92 // smaller than the current guy, so stitch in
97 ar -> next = c -> refs;
101 // we're the biggest, just append to last
106 ar -> next = c -> refs;
115 mm_category_t *category_query ( char *catname ) {
118 for ( i = 0; i < g_categorycount; i++ ) {
120 if ( strcasecmp ( g_categories [ i ].catname, catname ) == 0 ) {
121 return ( &(g_categories [ i ]) );
129 void category_dump ( void ) {
132 // WHY AREN'T I SORTING ON INSERT?
135 for ( i = 0; i < g_categorycount; i++ ) {
136 pnd_log ( PND_LOG_DEFAULT, "Category %u: '%s' * %u\n", i, g_categories [ i ].catname, g_categories [ i ].refcount );
137 mm_appref_t *ar = g_categories [ i ].refs;
140 pnd_log ( PND_LOG_DEFAULT, " Appref %s\n", IFNULL(ar -> ref -> title_en,"No Name") );
149 void category_freeall ( void ) {
151 mm_appref_t *iter, *next;
153 for ( i = 0; i < g_categorycount; i++ ) {
155 iter = g_categories [ i ].refs;
163 g_categories [ i ].refs = NULL;
172 unsigned char category_map_setup ( void ) {
174 char *searchpath = pnd_box_get_head ( g_conf );
176 if ( ! searchpath ) {
180 // look through conf for useful keys
181 while ( searchpath ) {
182 char *k = pnd_box_get_key ( searchpath );
184 // does this key look like a category mapping key?
185 if ( strncasecmp ( k, "categories.@", 12 ) == 0 ) {
188 // iterate across 'words' in v, assigning catmaps to them
191 //pnd_log ( pndn_debug, "target(%s) from(%s)\n", k, buffer );
193 category_push ( k, NULL, 0 );
194 g_catmaps [ g_catmapcount ].target = category_query ( k );
195 g_catmaps [ g_catmapcount ].from = strdup ( buffer );
201 } // if key looks like catmap
203 searchpath = pnd_box_get_next ( searchpath );
204 } // while each conf key
209 mm_category_t *category_map_query ( char *cat ) {
212 for ( i = 0; i < g_catmapcount; i++ ) {
213 if ( strcasecmp ( g_catmaps [ i ].from, cat ) == 0 ) {
214 return ( g_catmaps [ i ].target );
221 unsigned char category_meta_push ( char *catname, pnd_disco_t *app, pnd_conf_handle ovrh ) {
224 // do we honour cat mapping at all?
225 if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_on", 0 ) ) {
227 // is this guy mapped?
228 cat = category_map_query ( catname );
231 return ( category_push ( cat -> catname, app, ovrh ) );
234 // not mapped.. but default?
235 if ( pnd_conf_get_as_int_d ( g_conf, "categories.map_default_on", 0 ) ) {
236 char *def = pnd_conf_get_as_char ( g_conf, "categories.map_default_cat" );
238 return ( category_push ( def, app, ovrh ) );
242 } // cat map is desired?
244 // not default, just do it
245 return ( category_push ( catname, app, ovrh ) );