00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 #include <stdlib.h>
00064 #include <stdio.h>
00065 #include <string.h>
00066
00067 #include <osl/macros.h>
00068 #include <osl/util.h>
00069 #include <osl/interface.h>
00070 #include <osl/generic.h>
00071
00072
00073
00074
00075
00076
00077
00088 void osl_generic_idump(FILE * file, osl_generic_p generic, int level) {
00089 int j, first = 1;
00090
00091
00092 for (j = 0; j < level; j++)
00093 fprintf(file,"|\t");
00094
00095 if (generic != NULL)
00096 fprintf(file, "+-- osl_generic_t\n");
00097 else
00098 fprintf(file, "+-- NULL generic\n");
00099
00100 while (generic != NULL) {
00101 if (!first) {
00102
00103 for (j = 0; j < level; j++)
00104 fprintf(file, "|\t");
00105 fprintf(file, "| osl_generic_t\n");
00106 }
00107 else {
00108 first = 0;
00109 }
00110
00111
00112 for(j = 0; j <= level + 1; j++)
00113 fprintf(file, "|\t");
00114 fprintf(file, "\n");
00115
00116 osl_interface_idump(file, generic->interface, level + 1);
00117
00118 if (generic->interface != NULL)
00119 generic->interface->idump(file, generic->data, level + 1);
00120
00121 generic = generic->next;
00122
00123
00124 if (generic != NULL) {
00125 for (j = 0; j <= level; j++)
00126 fprintf(file, "|\t");
00127 fprintf(file, "V\n");
00128 }
00129 }
00130
00131
00132 for (j = 0; j <= level; j++)
00133 fprintf(file, "|\t");
00134 fprintf(file, "\n");
00135 }
00136
00137
00145 void osl_generic_dump(FILE * file, osl_generic_p generic) {
00146 osl_generic_idump(file, generic, 0);
00147 }
00148
00149
00157 void osl_generic_print(FILE * file, osl_generic_p generic) {
00158 char * string;
00159
00160 if (generic == NULL)
00161 return;
00162
00163 while (generic != NULL) {
00164 if (generic->interface != NULL) {
00165 string = generic->interface->sprint(generic->data);
00166 if (string != NULL) {
00167 fprintf(file, "<%s>\n", generic->interface->URI);
00168 fprintf(file, "%s", string);
00169 fprintf(file, "</%s>\n", generic->interface->URI);
00170 free(string);
00171 }
00172 }
00173 generic = generic->next;
00174 if (generic != NULL)
00175 fprintf(file, "\n");
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00194 osl_generic_p osl_generic_sread(char * string, osl_interface_p registry) {
00195 osl_generic_p generic = NULL, new;
00196 char * content, * start;
00197 void * data;
00198
00199 while (registry != NULL) {
00200 content = osl_util_tag_content(string, registry->URI);
00201 if (content != NULL) {
00202 start = content;
00203 data = registry->sread(&content);
00204 if (data != NULL) {
00205 new = osl_generic_malloc();
00206 new->interface = osl_interface_nclone(registry, 1);
00207 new->data = data;
00208 osl_generic_add(&generic, new);
00209 }
00210 free(start);
00211 }
00212 registry = registry->next;
00213 }
00214
00215 return generic;
00216 }
00217
00218
00230 osl_generic_p osl_generic_read_one(FILE * file, osl_interface_p registry) {
00231 char * tag;
00232 char * content, * temp;
00233 osl_generic_p generic = NULL;
00234 osl_interface_p interface;
00235
00236 tag = osl_util_read_tag(file, NULL);
00237 if ((tag == NULL) || (strlen(tag) < 1) || (tag[0] == '/')) {
00238 OSL_debug("empty tag name or closing tag instead of an opening one");
00239 return NULL;
00240 }
00241
00242 content = osl_util_read_uptoendtag(file, tag);
00243 interface = osl_interface_lookup(registry, tag);
00244
00245 temp = content;
00246 if (interface == NULL) {
00247 OSL_warning("unsupported generic");
00248 fprintf(stderr, "[osl] Warning: unknown URI \"%s\".\n", tag);
00249 }
00250 else {
00251 generic = osl_generic_malloc();
00252 generic->interface = osl_interface_nclone(interface, 1);
00253 generic->data = interface->sread(&temp);
00254 }
00255
00256 free(content);
00257 free(tag);
00258 return generic;
00259 }
00260
00261
00271 osl_generic_p osl_generic_read(FILE * file, osl_interface_p registry) {
00272 char * generic_string;
00273 osl_generic_p generic_list;
00274
00275 generic_string = osl_util_read_uptotag(file, OSL_TAG_END_SCOP);
00276 generic_list = osl_generic_sread(generic_string, registry);
00277 free(generic_string);
00278 return generic_list;
00279 }
00280
00281
00282
00283
00284
00285
00286
00295 void osl_generic_add(osl_generic_p * list, osl_generic_p generic) {
00296 osl_generic_p tmp = *list, check;
00297
00298 if (generic != NULL) {
00299
00300 check = generic;
00301 while (check != NULL) {
00302 if ((check->interface == NULL) || (check->interface->URI == NULL))
00303 OSL_error("no interface or URI in a generic to add to a list");
00304
00305
00306 if (osl_generic_lookup(*list, check->interface->URI) != NULL)
00307 OSL_error("only one generic with a given URI is allowed");
00308 check = check->next;
00309 }
00310
00311 if (*list != NULL) {
00312 while (tmp->next != NULL)
00313 tmp = tmp->next;
00314 tmp->next = generic;
00315 }
00316 else {
00317 *list = generic;
00318 }
00319 }
00320 }
00321
00322
00331 osl_generic_p osl_generic_malloc() {
00332 osl_generic_p generic;
00333
00334 OSL_malloc(generic, osl_generic_p, sizeof(osl_generic_t));
00335 generic->interface = NULL;
00336 generic->data = NULL;
00337 generic->next = NULL;
00338
00339 return generic;
00340 }
00341
00342
00348 void osl_generic_free(osl_generic_p generic) {
00349 osl_generic_p next;
00350
00351 while (generic != NULL) {
00352 next = generic->next;
00353 if (generic->interface != NULL) {
00354 generic->interface->free(generic->data);
00355 osl_interface_free(generic->interface);
00356 }
00357 else {
00358 if (generic->data != NULL) {
00359 OSL_warning("unregistered interface, memory leaks are possible");
00360 free(generic->data);
00361 }
00362 }
00363 free(generic);
00364 generic = next;
00365 }
00366 }
00367
00368
00369
00370
00371
00372
00373
00381 osl_generic_p osl_generic_clone(osl_generic_p generic) {
00382 osl_generic_p clone = NULL, new;
00383 osl_interface_p interface;
00384 void * x;
00385
00386 while (generic != NULL) {
00387 if (generic->interface != NULL) {
00388 x = generic->interface->clone(generic->data);
00389 interface = osl_interface_clone(generic->interface);
00390 new = osl_generic_malloc();
00391 new->interface = interface;
00392 new->data = x;
00393 osl_generic_add(&clone, new);
00394 }
00395 else {
00396 OSL_warning("unregistered interface, cloning ignored");
00397 }
00398 generic = generic->next;
00399 }
00400
00401 return clone;
00402 }
00403
00404
00412 int osl_generic_count(osl_generic_p x) {
00413 int generic_number = 0;
00414
00415 while (x != NULL) {
00416 generic_number++;
00417 x = x->next;
00418 }
00419
00420 return generic_number;
00421 }
00422
00423
00433 int osl_generic_equal(osl_generic_p x1, osl_generic_p x2) {
00434 int x1_generic_number, x2_generic_number;
00435 int found, equal;
00436 osl_generic_p backup_x2 = x2;
00437
00438 if (x1 == x2)
00439 return 1;
00440
00441
00442 x1_generic_number = osl_generic_count(x1);
00443 x2_generic_number = osl_generic_count(x2);
00444 if (x1_generic_number != x2_generic_number)
00445 return 0;
00446
00447
00448 while (x1 != NULL) {
00449 x2 = backup_x2;
00450 found = 0;
00451 while ((x2 != NULL) && (found != 1)) {
00452 if (osl_interface_equal(x1->interface, x2->interface)) {
00453 if (x1->interface != NULL) {
00454 equal = x1->interface->equal(x1->data, x2->data);
00455 }
00456 else {
00457 OSL_warning("unregistered generic, "
00458 "cannot state generic equality");
00459 equal = 0;
00460 }
00461
00462 if (equal == 0)
00463 return 0;
00464 else
00465 found = 1;
00466 }
00467
00468 x2 = x2->next;
00469 }
00470
00471 if (found != 1)
00472 return 0;
00473
00474 x1 = x1->next;
00475 }
00476
00477 return 1;
00478 }
00479
00480
00489 int osl_generic_has_URI(osl_generic_p x, char * URI) {
00490
00491 if ((x == NULL) ||
00492 (x->interface == NULL) ||
00493 (x->interface->URI == NULL) ||
00494 (strcmp(x->interface->URI, URI)))
00495 return 0;
00496
00497 return 1;
00498 }
00499
00500
00510 void * osl_generic_lookup(osl_generic_p x, char * URI) {
00511 while (x != NULL) {
00512 if (osl_generic_has_URI(x, URI))
00513 return x->data;
00514
00515 x = x->next;
00516 }
00517
00518 return NULL;
00519 }
00520
00521
00530 osl_generic_p osl_generic_shell(void * data, osl_interface_p interface) {
00531 osl_generic_p generic = NULL;
00532
00533 if ((data == NULL) || (interface == NULL))
00534 OSL_warning("shell created with some empty elements inside");
00535
00536 generic = osl_generic_malloc();
00537 generic->data = data;
00538 generic->interface = interface;
00539 return generic;
00540 }