mirror of
				https://github.com/owntone/owntone-server.git
				synced 2025-10-30 00:05:05 -04:00 
			
		
		
		
	Replace old config code, remove old code
Activate the new confuse-based config code, add compatibility functions for the old config code.
This commit is contained in:
		
							parent
							
								
									a17e23010a
								
							
						
					
					
						commit
						e3ab6de328
					
				| @ -24,7 +24,7 @@ mt_daapd_SOURCES = main.c daapd.h webserver.c \ | ||||
| 	rxml.c rxml.h redblack.c redblack.h \
 | ||||
| 	scan-xml.c scan-wma.c scan-url.c \
 | ||||
| 	smart-parser.c smart-parser.h xml-rpc.c xml-rpc.h \
 | ||||
| 	ll.c ll.h conf.c conf.h util.c util.h \
 | ||||
| 	util.c util.h \
 | ||||
| 	plugin.c plugin.h db-sql-updates.c \
 | ||||
| 	io.h io.c io-errors.h io-plugin.h \
 | ||||
| 	db-sql.c db-sql.h db-sql-sqlite3.c db-sql-sqlite3.h\
 | ||||
| @ -32,4 +32,5 @@ mt_daapd_SOURCES = main.c daapd.h webserver.c \ | ||||
| 
 | ||||
| EXTRA_DIST = scan-mpc.c \
 | ||||
| 	scan-flac.c \
 | ||||
| 	conf.h \
 | ||||
| 	ff-plugins.h ff-dbstruct.h ff-plugin-events.h | ||||
|  | ||||
							
								
								
									
										1752
									
								
								src/conf.c
									
									
									
									
									
								
							
							
						
						
									
										1752
									
								
								src/conf.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -34,6 +34,7 @@ | ||||
| #define CONF_E_PATHEXPECTED 10 | ||||
| #define CONF_E_INTEXPECTED  11 | ||||
| #define CONF_E_BADCONFIG    12 | ||||
| #define CONF_E_NOTSUPP      13 | ||||
| 
 | ||||
| extern int conf_read(char *file); | ||||
| extern int conf_reload(void); | ||||
|  | ||||
							
								
								
									
										263
									
								
								src/conffile.c
									
									
									
									
									
								
							
							
						
						
									
										263
									
								
								src/conffile.c
									
									
									
									
									
								
							| @ -331,3 +331,266 @@ conffile_unload(void) | ||||
| { | ||||
|   cfg_free(cfg); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Wrappers for old configfile handling */ | ||||
| #include "conf.h" | ||||
| 
 | ||||
| int | ||||
| conf_read(char *file) | ||||
| { | ||||
|   return conffile_load(file); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_close(void) | ||||
| { | ||||
|   conffile_unload(); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_get_int(char *section, char *key, int dflt) | ||||
| { | ||||
|   cfg_t *lib; | ||||
| 
 | ||||
|   if ((strcmp(section, "general") == 0) | ||||
|       && (strcmp(key, "port") == 0)) | ||||
|     { | ||||
|       lib = cfg_getnsec(cfg, "library", 0); | ||||
|       return cfg_getint(lib, "port"); | ||||
|     } | ||||
| 
 | ||||
|   /* Return default for everything else */ | ||||
|   return dflt; | ||||
| } | ||||
| 
 | ||||
| int conf_get_string(char *section, char *key, char *dflt, char *out, int *size) | ||||
| { | ||||
|   cfg_t *lib; | ||||
|   size_t len; | ||||
|   char *val = NULL; | ||||
| 
 | ||||
|   if (strcmp(section, "general") == 0) | ||||
|     { | ||||
|       if (strcmp(key, "admin_pw") == 0) | ||||
| 	{ | ||||
| 	  val = cfg_getstr(cfg_getsec(cfg, "general"), "admin_password"); | ||||
| 	} | ||||
|       else if (strcmp(key, "password") == 0) | ||||
| 	{ | ||||
| 	  lib = cfg_getnsec(cfg, "library", 0); | ||||
| 	  val = cfg_getstr(lib, "password"); | ||||
| 	} | ||||
|       else if (strcmp(key, "extensions") == 0) | ||||
| 	{ | ||||
| 	  val = ".mp3,.m4a,.m4p,.ogg,.flac,.mpc"; | ||||
| 	} | ||||
|       else if (strcmp(key, "runas") == 0) | ||||
| 	{ | ||||
| 	  val = cfg_getstr(cfg_getsec(cfg, "general"), "uid"); | ||||
| 	} | ||||
|       else if (strcmp(key, "db_type") == 0) | ||||
| 	{ | ||||
| 	  val = "sqlite3"; | ||||
| 	} | ||||
|       else if (strcmp(key, "db_parms") == 0) | ||||
| 	{ | ||||
| 	  val = "/var/cache/mt-daapd"; | ||||
| 	} | ||||
|       /* web_root now static */ | ||||
|       else if (strcmp(key, "web_root") == 0) | ||||
| 	{ | ||||
| 	  val = "/usr/share/mt-daapd/admin-root"; | ||||
| 	} | ||||
|     } | ||||
|   else if (strcmp(section, "plugins") == 0) | ||||
|     { | ||||
|       /* plugin_dir now static, going away */ | ||||
|       if (strcmp(key, "plugin_dir") == 0) | ||||
| 	{ | ||||
| 	  val = "/usr/lib/mt-daapd/plugins"; | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   /* Default value */ | ||||
|   if (val == NULL) | ||||
|     val = dflt; | ||||
| 
 | ||||
|   if (val == NULL) | ||||
|     { | ||||
|       *size = 0; | ||||
|       return 0; | ||||
|     } | ||||
| 
 | ||||
|   len = strlen(val) + 1; | ||||
|   if (len <= *size) | ||||
|     { | ||||
|       strcpy(out, val); | ||||
|       *size = len; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       *size = len; | ||||
|       return CONF_E_OVERFLOW; | ||||
|     } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| conf_alloc_string(char *section, char *key, char *dflt) | ||||
| { | ||||
|   char *val; | ||||
|   int len; | ||||
|   int ret; | ||||
| 
 | ||||
|   len = 256; | ||||
|   val = (char *)malloc(len); | ||||
|   if (!val) | ||||
|     return NULL; | ||||
| 
 | ||||
|   memset(val, 0, len); | ||||
| 
 | ||||
|   ret = conf_get_string(section, key, dflt, val, &len); | ||||
|   if (ret != 0) | ||||
|     return NULL; | ||||
| 
 | ||||
|   if (len == 0) | ||||
|     { | ||||
|       free(val); | ||||
|       val = NULL; | ||||
|     } | ||||
| 
 | ||||
|   return val; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_get_array(char *section, char *key, char ***argvp) | ||||
| { | ||||
|   cfg_t *lib; | ||||
|   int nelem; | ||||
|   char *opt; | ||||
|   char **a; | ||||
|   int i; | ||||
| 
 | ||||
|   lib = cfg_getnsec(cfg, "library", 0); | ||||
| 
 | ||||
|   if (strcmp(section, "general") == 0) | ||||
|     { | ||||
|       if (strcmp(key, "mp3_dir") == 0) | ||||
| 	{ | ||||
| 	  nelem = cfg_size(lib, "directories"); | ||||
| 	  if (nelem == 0) | ||||
| 	    return 0; | ||||
| 
 | ||||
| 	  opt = "directories"; | ||||
| 	} | ||||
|       else if (strcmp(key, "compdirs") == 0) | ||||
| 	{ | ||||
| 	  nelem = cfg_size(lib, "compilations"); | ||||
| 	  if (nelem == 0) | ||||
| 	    return 0; | ||||
| 
 | ||||
| 	  opt = "compilations"; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  return 0; | ||||
| 	} | ||||
|     } | ||||
|   else | ||||
|     return 0; | ||||
| 
 | ||||
|   a = (char **)malloc((nelem + 1) * sizeof(char *)); | ||||
|   if (!a) | ||||
|     return 0; | ||||
| 
 | ||||
|   memset(a, 0, (nelem + 1) * sizeof(char *)); | ||||
| 
 | ||||
|   for (i = 0; i < nelem; i++) | ||||
|     { | ||||
|       a[i] = strdup(cfg_getnstr(lib, opt, i)); | ||||
|     } | ||||
| 
 | ||||
|   *argvp = a; | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| conf_dispose_array(char **argv) | ||||
| { | ||||
|   int i; | ||||
| 
 | ||||
|   for (i = 0; argv[i]; i++) | ||||
|     free(argv[i]); | ||||
| 
 | ||||
|   free(argv); | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| conf_get_servername(void) | ||||
| { | ||||
|   cfg_t *lib; | ||||
| 
 | ||||
|   lib = cfg_getnsec(cfg, "library", 0); | ||||
|   return strdup(cfg_getstr(lib, "name")); | ||||
| } | ||||
| 
 | ||||
| /* Not supported */ | ||||
| 
 | ||||
| int | ||||
| conf_reload(void) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return CONF_E_NOTSUPP; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_set_int(char *section, char *key, int value, int verify) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return CONF_E_NOTSUPP; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_set_string(char *section, char *key, char *value, int verify) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return CONF_E_NOTSUPP; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_iswritable(void) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_isset(char *section, char *key) | ||||
| { | ||||
|   /* Not pertinent */ | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_write(void) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return CONF_E_NOTSUPP; | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| conf_get_filename(void) | ||||
| { | ||||
|   return "NOT SUPPORTED"; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| conf_xml_dump(WS_CONNINFO *pwsc) | ||||
| { | ||||
|   /* Not supported */ | ||||
|   return CONF_E_NOTSUPP; | ||||
| } | ||||
|  | ||||
							
								
								
									
										384
									
								
								src/ll.c
									
									
									
									
									
								
							
							
						
						
									
										384
									
								
								src/ll.c
									
									
									
									
									
								
							| @ -1,384 +0,0 @@ | ||||
| /*
 | ||||
|  * Rock stupid char* indexed linked lists | ||||
|  * | ||||
|  * Copyright (C) 2006 Ron Pedde (rpedde@users.sourceforge.net) | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| 
 | ||||
| #ifdef HAVE_CONFIG_H | ||||
| #  include "config.h" | ||||
| #endif | ||||
| 
 | ||||
| #include <pthread.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| #include "daapd.h" | ||||
| #include "ll.h" | ||||
| #include "err.h" | ||||
| 
 | ||||
| 
 | ||||
| /** Internal functions  */ | ||||
| 
 | ||||
| int _ll_add_item(LL *pl, char *key, void *vpval, int ival, int type); | ||||
| int _ll_update_item(LL_ITEM *pli, void *vpval, int ival, int type); | ||||
| void _ll_dump(LL *pl, int depth); | ||||
| 
 | ||||
| /**
 | ||||
|  * create a ll | ||||
|  * | ||||
|  * @param ppl pointer to a LL *.  Returns valid handle on LL_E_SUCCESS | ||||
|  * @returns LL_E_SUCCESS on success, error code otherwise | ||||
|  */ | ||||
| int ll_create(LL **ppl) { | ||||
|     *ppl = (LL *)malloc(sizeof(struct _LL)); | ||||
|     if(!*ppl) | ||||
|         return LL_E_MALLOC; | ||||
| 
 | ||||
|     memset(*ppl,0x0,sizeof(struct _LL)); | ||||
| 
 | ||||
|     /* set default flags */ | ||||
|     (*ppl)->flags = LL_FLAG_NODUPS | LL_FLAG_INHERIT; | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * destroy a ll, recusively, if neccesary | ||||
|  * | ||||
|  * @param pl ll to destroy | ||||
|  * @returns LL_E_SUCCESS | ||||
|  */ | ||||
| int ll_destroy(LL *pl) { | ||||
|     LL_ITEM *current,*last; | ||||
| 
 | ||||
|     last = &(pl->itemlist); | ||||
|     current = pl->itemlist.next; | ||||
| 
 | ||||
|     while(current) { | ||||
|         switch(current->type) { | ||||
|         case LL_TYPE_LL: | ||||
|             ll_destroy(current->value.as_ll); | ||||
|             break; | ||||
|         case LL_TYPE_STRING: | ||||
|             free(current->value.as_string); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         free(current->key); | ||||
|         last = current; | ||||
|         current = current->next; | ||||
|         free(last); | ||||
|     } | ||||
| 
 | ||||
|     free(pl); | ||||
| 
 | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_add_item | ||||
|  */ | ||||
| int ll_add_string(LL *pl, char *key, char *cval) { | ||||
|     return _ll_add_item(pl,key,cval,0,LL_TYPE_STRING); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_add_item | ||||
|  */ | ||||
| int ll_add_int(LL *pl, char *key, int ival) { | ||||
|     return _ll_add_item(pl,key,NULL,ival,LL_TYPE_INT); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_add_item | ||||
|  */ | ||||
| int ll_add_ll(LL *pl, char *key, LL *pnew) { | ||||
|     int result; | ||||
| 
 | ||||
|     result = _ll_add_item(pl,key,(void*)pnew,0,LL_TYPE_LL); | ||||
|     if(result == LL_E_SUCCESS) { | ||||
|         if(pl->flags & LL_FLAG_INHERIT) { | ||||
|             pnew->flags = pl->flags; | ||||
|         } | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| int ll_del_item(LL *pl, char *key) { | ||||
|     LL_ITEM *phead, *ptail; | ||||
| 
 | ||||
|     ptail = &pl->itemlist; | ||||
|     phead = pl->itemlist.next; | ||||
| 
 | ||||
|     while(phead) { | ||||
|         if((pl->flags & LL_FLAG_HONORCASE) && | ||||
|            (strcmp(phead->key,key)==0)) | ||||
|             break; | ||||
|         if((!(pl->flags & LL_FLAG_HONORCASE) && | ||||
|             (strcasecmp(phead->key,key)==0))) | ||||
|             break; | ||||
| 
 | ||||
|         ptail=phead; | ||||
|         phead=phead->next; | ||||
|     } | ||||
| 
 | ||||
|     if(phead) { | ||||
|         /* found the item... */ | ||||
|         if(pl->tailptr == phead) | ||||
|             pl->tailptr = ptail; | ||||
|         ptail->next = phead->next; | ||||
|     } else { | ||||
|         /* no matching item */ | ||||
|         return LL_E_NOKEY; | ||||
|     } | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * add an item to a ll | ||||
|  */ | ||||
| int _ll_add_item(LL *pl, char *key, void* vpval, int ival, int type) { | ||||
|     LL_ITEM *pli; | ||||
| 
 | ||||
|     if(!key) { | ||||
|         DPRINTF(E_LOG,L_MISC,"_ll_add_item: passed null key\n"); | ||||
|         return LL_E_BADPARAM; | ||||
|     } | ||||
| 
 | ||||
|     if(pl->flags & LL_FLAG_NODUPS) { | ||||
|         if(ll_fetch_item(pl,key)) | ||||
|             return LL_E_DUP; | ||||
|     } | ||||
| 
 | ||||
|     pli=(LL_ITEM *)malloc(sizeof(LL_ITEM)); | ||||
|     if(!pli) { | ||||
|         return LL_E_MALLOC; | ||||
|     } | ||||
| 
 | ||||
|     pli->type = type; | ||||
|     pli->key = strdup(key); | ||||
| 
 | ||||
|     switch(type) { | ||||
|     case LL_TYPE_INT: | ||||
|         pli->value.as_int = ival; | ||||
|         break; | ||||
|     case LL_TYPE_LL: | ||||
|         pli->value.as_ll = (LL *)vpval; | ||||
|         break; | ||||
|     case LL_TYPE_STRING: | ||||
|         if(!vpval) { | ||||
|             DPRINTF(E_LOG,L_MISC,"_ll_add_item: passed null value\n"); | ||||
|             free(pli); | ||||
|             return LL_E_BADPARAM; | ||||
|         } | ||||
|         pli->value.as_string = strdup((char*)vpval); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     if(pl->flags & LL_FLAG_HEADINSERT) { | ||||
|         pli->next = pl->itemlist.next; | ||||
|         pl->itemlist.next = pli; | ||||
|     } else { | ||||
|         pli->next = NULL; | ||||
|         if(pl->tailptr) { | ||||
|             pl->tailptr->next = pli; | ||||
|         } else { | ||||
|             pl->itemlist.next = pli; | ||||
|         } | ||||
|         pl->tailptr = pli; | ||||
|     } | ||||
| 
 | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_update_item | ||||
|  */ | ||||
| int ll_update_string(LL_ITEM *pli, char *cval) { | ||||
|     return _ll_update_item(pli,cval,0,LL_TYPE_STRING); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_update_item | ||||
|  */ | ||||
| int ll_update_int(LL_ITEM *pli, int ival) { | ||||
|     return _ll_update_item(pli,NULL,ival,LL_TYPE_INT); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * thin wrapper for _ll_update_item. | ||||
|  * | ||||
|  * NOTE: There is a reasonable case to be made about | ||||
|  * what should happen to flags on an update.  We'll just | ||||
|  * leave that to the caller, though. | ||||
|  */ | ||||
| int ll_update_ll(LL_ITEM *pli, LL *pnew) { | ||||
|     int result; | ||||
| 
 | ||||
|     result = _ll_update_item(pli,(void*)pnew,0,LL_TYPE_LL); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * update an item, given an item pointer | ||||
|  */ | ||||
| int _ll_update_item(LL_ITEM *pli, void* vpval, int ival, int type) { | ||||
| 
 | ||||
|     /* dispose of what used to be there*/ | ||||
|     switch(pli->type) { | ||||
|     case LL_TYPE_LL: | ||||
|         ll_destroy(pli->value.as_ll); | ||||
|         break; | ||||
|     case LL_TYPE_STRING: | ||||
|         free(pli->value.as_string); | ||||
|         break; | ||||
|     case LL_TYPE_INT: /* fallthrough */ | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     pli->type = type; | ||||
| 
 | ||||
|     switch(pli->type) { | ||||
|     case LL_TYPE_INT: | ||||
|         pli->value.as_int = ival; | ||||
|         break; | ||||
|     case LL_TYPE_LL: | ||||
|         pli->value.as_ll = (LL *)vpval; | ||||
|         break; | ||||
|     case LL_TYPE_STRING: | ||||
|         pli->value.as_string = strdup((char*)vpval); | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * internal function to get the ll item associated with | ||||
|  * a specific key, using the case sensitivity specified | ||||
|  * by the ll flags.  This assumes that the lock is held! | ||||
|  * | ||||
|  * @param pl ll to fetch item from | ||||
|  * @param key key name to fetch | ||||
|  * @returns pointer to llitem, or null if not found | ||||
|  */ | ||||
| LL_ITEM *ll_fetch_item(LL *pl, char *key) { | ||||
|     LL_ITEM *current; | ||||
| 
 | ||||
|     if(!pl) | ||||
|         return NULL; | ||||
| 
 | ||||
|     current = pl->itemlist.next; | ||||
|     while(current) { | ||||
|         if(pl->flags & LL_FLAG_HONORCASE) { | ||||
|             if(!strcmp(current->key,key)) | ||||
|                 return current; | ||||
|         } else { | ||||
|             if(!strcasecmp(current->key,key)) | ||||
|                 return current; | ||||
|         } | ||||
|         current = current->next; | ||||
|     } | ||||
| 
 | ||||
|     return current; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * set flags | ||||
|  * | ||||
|  * @param pl ll to set flags for | ||||
|  * @returns LL_E_SUCCESS | ||||
|  */ | ||||
| int ll_set_flags(LL *pl, unsigned int flags) { | ||||
|     pl->flags = flags; | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * get flags | ||||
|  * | ||||
|  * @param pl ll to get flags from | ||||
|  * @returns LL_E_SUCCESS | ||||
|  */ | ||||
| int ll_get_flags(LL *pl, unsigned int *flags) { | ||||
|     *flags = pl->flags; | ||||
|     return LL_E_SUCCESS; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Dump a linked list | ||||
|  * | ||||
|  * @parm pl linked list to dump | ||||
|  */ | ||||
| void ll_dump(LL *pl) { | ||||
|     _ll_dump(pl,0); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Internal support function for dumping linked list that | ||||
|  * carries depth. | ||||
|  * | ||||
|  * @param pl linked list to dump | ||||
|  * @param depth depth of list | ||||
|  */ | ||||
| 
 | ||||
| void _ll_dump(LL *pl, int depth) { | ||||
|     LL_ITEM *pli; | ||||
|     pli = pl->itemlist.next; | ||||
|     while(pli) { | ||||
|         switch(pli->type) { | ||||
|         case LL_TYPE_INT: | ||||
|             printf("%*s%s (int): %d\n",depth*2,"",pli->key,pli->value.as_int); | ||||
|             break; | ||||
|         case LL_TYPE_STRING: | ||||
|             printf("%*s%s (string): %s\n",depth*2,"",pli->key,pli->value.as_string); | ||||
|             break; | ||||
|         case LL_TYPE_LL: | ||||
|             printf("%*s%s (list)\n",depth*2,"",pli->key); | ||||
|             _ll_dump(pli->value.as_ll,depth+1); | ||||
|             break; | ||||
|         } | ||||
|         pli = pli->next; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * Given an item (or NULL for first item), fetch | ||||
|  * the next item | ||||
|  * | ||||
|  * @param pl ll to fetch from | ||||
|  * @param prev last item we fetched | ||||
|  */ | ||||
| LL_ITEM *ll_get_next(LL *pl, LL_ITEM *prev) { | ||||
|     if(!pl) | ||||
|         return NULL; | ||||
| 
 | ||||
|     if(!prev) | ||||
|         return pl->itemlist.next; | ||||
| 
 | ||||
|     return prev->next; | ||||
| } | ||||
							
								
								
									
										81
									
								
								src/ll.h
									
									
									
									
									
								
							
							
						
						
									
										81
									
								
								src/ll.h
									
									
									
									
									
								
							| @ -1,81 +0,0 @@ | ||||
| /*
 | ||||
|  * Rock stupid char* indexed linked lists | ||||
|  * | ||||
|  * Copyright (C) 2006 Ron Pedde (rpedde@users.sourceforge.net) | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _LL_H_ | ||||
| #define _LL_H_ | ||||
| 
 | ||||
| #define LL_TYPE_INT     0 | ||||
| #define LL_TYPE_STRING  1 | ||||
| #define LL_TYPE_LL      2 | ||||
| 
 | ||||
| 
 | ||||
| #define LL_E_SUCCESS   0 | ||||
| #define LL_E_MALLOC    1 | ||||
| #define LL_E_NOKEY     2 | ||||
| #define LL_E_DUP       3 | ||||
| #define LL_E_BADPARAM  4 | ||||
| 
 | ||||
| #define LL_FLAG_HONORCASE  1 /** Make keys case sensitive */ | ||||
| #define LL_FLAG_HEADINSERT 2 /** Insert at head, rather than tail */ | ||||
| #define LL_FLAG_NODUPS     4 /** Do not allow duplicates */ | ||||
| #define LL_FLAG_INHERIT    8 /** Set child flags based on parent flags */ | ||||
| 
 | ||||
| typedef struct _LLITEM { | ||||
|     int type; | ||||
|     char *key; | ||||
|     union { | ||||
|         int as_int; | ||||
|         char *as_string; | ||||
|         struct _LL *as_ll; | ||||
|     } value; | ||||
|     struct _LLITEM *next; | ||||
| } LL_ITEM, *LL_ITEMHANDLE; | ||||
| 
 | ||||
| typedef struct _LL { | ||||
|     unsigned int flags; | ||||
|     struct _LLITEM *tailptr; | ||||
|     struct _LLITEM itemlist; | ||||
| } LL, *LL_HANDLE; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| extern int ll_create(LL **ppl); | ||||
| extern int ll_destroy(LL *pl); | ||||
| 
 | ||||
| extern int ll_add_string(LL *pl, char *key, char *cval); | ||||
| extern int ll_add_int(LL *pl, char *key, int ival); | ||||
| extern int ll_add_ll(LL *pl, char *key, LL *pnew); | ||||
| 
 | ||||
| extern int ll_update_string(LL_ITEM *pli, char *cval); | ||||
| extern int ll_update_int(LL_ITEM *pli, int ival); | ||||
| extern int ll_update_ll(LL_ITEM *pli, LL *pnew); | ||||
| 
 | ||||
| extern int ll_set_flags(LL *pl, unsigned int flags); | ||||
| extern int ll_get_flags(LL *pl, unsigned int *flags); | ||||
| 
 | ||||
| extern int ll_del_item(LL *pl, char *key); | ||||
| 
 | ||||
| extern LL_ITEM *ll_fetch_item(LL *pl, char *key); | ||||
| extern LL_ITEM *ll_get_next(LL *pl, LL_ITEM *prev); | ||||
| 
 | ||||
| extern void ll_dump(LL *pl); | ||||
| 
 | ||||
| #endif /* _LL_H_ */ | ||||
| 
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user