GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 /* required for NULL */ 00003 #include <stdio.h> 00004 #include <stdlib.h> 00005 #include <string.h> 00006 #include <grass/gis.h> 00007 #include "pad.h" 00008 00009 static PAD *padlist; 00010 00011 static int free_item(ITEM * item) 00012 { 00013 LIST *list, *next; 00014 00015 if (item->name != NULL) 00016 G_free(item->name); 00017 for (list = item->list; list != NULL; list = next) { 00018 next = list->next; 00019 if (list->value) 00020 G_free(list->value); 00021 G_free(list); 00022 } 00023 G_free(item); 00024 00025 return 0; 00026 } 00027 00028 static ITEM *new_item(PAD * pad, const char *name) 00029 { 00030 ITEM *item; 00031 00032 item = (ITEM *) G_malloc((size_t) sizeof(ITEM)); 00033 if (item == NULL) 00034 return (ITEM *) NULL; 00035 00036 item->name = G_store(name); 00037 if (item->name == NULL) { 00038 G_free(item); 00039 return (ITEM *) NULL; 00040 } 00041 item->list = NULL; 00042 item->next = pad->items; 00043 if (item->next != NULL) 00044 item->next->prev = item; 00045 item->prev = NULL; 00046 pad->items = item; 00047 00048 return item; 00049 } 00050 00051 static int remove_value(ITEM * item, const char *value) 00052 { 00053 LIST **p = &item->list; 00054 LIST *l = *p; 00055 00056 for (l = *p; l; l = *p) { 00057 if (value && l->value && !strcmp(value, l->value)) { 00058 *p = l->next; 00059 if (l->value) 00060 G_free(l->value); 00061 G_free(l); 00062 } 00063 else 00064 p = &l->next; 00065 } 00066 00067 return 0; 00068 } 00069 00070 int append_item(PAD * pad, const char *name, const char *value, int replace) 00071 { 00072 ITEM *item; 00073 LIST *cur, *prev; 00074 LIST *list; 00075 00076 if (pad == NULL) 00077 return 0; 00078 00079 /* allocate a list struct and put value into it */ 00080 list = (LIST *) G_malloc((size_t) sizeof(LIST)); 00081 if (list == NULL) 00082 return 0; 00083 list->next = NULL; 00084 list->value = G_store(value); 00085 if (list->value == NULL) { 00086 G_free(list); 00087 return 0; 00088 } 00089 /* find the named item for the current pad */ 00090 item = find_item(pad, name); 00091 if (item == NULL) 00092 item = new_item(pad, name); 00093 if (item == NULL) 00094 return 0; 00095 00096 /* remove any existing occurences of the value */ 00097 if (replace) 00098 remove_value(item, value); 00099 00100 /* add the LIST at the end of the item LIST */ 00101 prev = NULL; 00102 for (cur = item->list; cur != NULL; cur = cur->next) 00103 prev = cur; 00104 00105 if (prev == NULL) 00106 item->list = list; 00107 else 00108 prev->next = list; 00109 00110 return 1; 00111 } 00112 00113 int delete_item(PAD * pad, const char *name) 00114 { 00115 ITEM *item; 00116 00117 item = find_item(pad, name); 00118 if (item == NULL) 00119 return 0; 00120 00121 if (item->prev == NULL) 00122 pad->items = item->next; 00123 else 00124 item->prev->next = item->next; 00125 00126 if (item->next != NULL) 00127 item->next->prev = item->prev; 00128 00129 /* free the item */ 00130 free_item(item); 00131 00132 return 1; 00133 } 00134 00135 ITEM *find_item(PAD * pad, const char *name) 00136 { 00137 ITEM *item; 00138 00139 if (pad != NULL) 00140 for (item = pad->items; item != NULL; item = item->next) 00141 if (strcmp(name, item->name) == 0) 00142 return item; 00143 return (ITEM *) NULL; 00144 } 00145 00146 PAD *pad_list(void) 00147 { 00148 return padlist; 00149 } 00150 00151 static int delink_pad(PAD * pad) 00152 { 00153 if (pad == NULL) 00154 return 1; 00155 00156 if (pad->prev == NULL) 00157 padlist = pad->next; 00158 else 00159 pad->prev->next = pad->next; 00160 00161 if (pad->next != NULL) 00162 pad->next->prev = pad->prev; 00163 00164 return 0; 00165 } 00166 00167 int create_pad(const char *name) 00168 { 00169 PAD *pad; 00170 00171 pad = (PAD *) G_malloc((size_t) sizeof(PAD)); 00172 if (pad == NULL) 00173 return 0; 00174 pad->name = G_store(name); 00175 if (pad->name == NULL) { 00176 G_free(pad); 00177 return 0; 00178 } 00179 pad->items = NULL; 00180 pad->next = padlist; 00181 if (pad->next != NULL) 00182 pad->next->prev = pad; 00183 pad->prev = NULL; 00184 padlist = pad; 00185 return 1; 00186 } 00187 00188 int delete_pad(PAD * pad) 00189 { 00190 ITEM *item, *next; 00191 00192 if (pad == NULL) 00193 return 0; 00194 00195 delink_pad(pad); 00196 00197 /* free the items */ 00198 for (item = pad->items; item != NULL; item = next) { 00199 next = item->next; 00200 free_item(item); 00201 } 00202 G_free(pad); 00203 00204 return 1; 00205 } 00206 00207 PAD *find_pad(const char *name) 00208 { 00209 PAD *pad; 00210 00211 for (pad = padlist; pad != NULL; pad = pad->next) 00212 if (strcmp(name, pad->name) == 0) 00213 return pad; 00214 return (PAD *) NULL; 00215 } 00216 00217 int invent_pad(char *name) 00218 { 00219 static int i = 0; 00220 00221 do 00222 sprintf(name, "%d", ++i); 00223 while (find_pad(name) != NULL); 00224 00225 return 0; 00226 }