TUM-Logo

libRASCH

 

Home
 

General

About libRASCH/News
Design
Screen shots
Sample programs (with source code)
License
 

Download

libRASCH
Tools
 

Documentation

User
Developer
 

Resources

Mailing list
Supported Formats
Plugins
Status
Links
 
Contact
About this site
 
Last updated
Tue Mar 27 23:03:52 2007
libRASCH: eval.c Source File

eval.c

Go to the documentation of this file.
00001 
00009 /*----------------------------------------------------------------------------
00010  *
00011  * Copyright (C) 2002-2005, Raphael Schneider
00012  * See the file COPYING for information on usage and redistribution.
00013  *
00014  * $Id: eval.c 794 2005-05-07 12:46:04Z rasch $
00015  *
00016  *--------------------------------------------------------------------------*/
00017 
00018 #include <string.h>
00019 #include <stdlib.h>
00020 #include <stdio.h>
00021 #include <errno.h>
00022 #include <time.h>
00023 #include <assert.h>
00024 #include <ctype.h>
00025 
00026 #ifndef WIN32
00027 #include <unistd.h>
00028 #endif
00029 
00030 #define _LIBRASCH_BUILD
00031 #include <ra_eval.h>
00032 #include <pl_general.h>
00033 #include <ra_linked_list.h>
00034 #include "eval.h"
00035 
00036 
00037 LIBRAAPI int
00038 ra_eval_edit_start(any_handle h)
00039 {
00040         return 0;
00041 } /* ra_eval_edit_start() */
00042 
00043 
00044 LIBRAAPI int
00045 ra_eval_edit_complete(any_handle h)
00046 {
00047         return 0;
00048 } /* ra_eval_edit_complete() */
00049 
00050 
00051 LIBRAAPI int
00052 ra_eval_edit_cancel(any_handle h)
00053 {
00054         return 0;
00055 } /* ra_eval_edit_cancel() */
00056 
00057 
00058 /* ------------------------------ attribute functions ------------------------------ */
00059 
00060 LIBRAAPI int
00061 ra_eval_attribute_list(any_handle h, value_handle vh)
00062 {
00063         int ret, i, num;
00064         struct eval_head *head = (struct eval_head *)h; 
00065         char **names;
00066         struct eval_attribute *curr;
00067 
00068         _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00069         ra_value_reset(vh);
00070 
00071         num = 0;
00072         names = NULL;
00073         curr = head->meas->eval.attribute;
00074         while (curr)
00075         {
00076                 if (curr->src_handle == h)
00077                 {
00078                         num++;
00079                         names = realloc(names, sizeof(char *) * num);
00080 
00081                         names[num-1] = (char *)malloc(sizeof(char) * MAX_ATTRIB_LEN);
00082                         strncpy(names[num-1], curr->name, MAX_ATTRIB_LEN);
00083                 }
00084                 curr = curr->next;
00085         }
00086 
00087         if (num > 0)
00088         {
00089                 ra_value_set_string_array(vh, (const char **)names, num);
00090 
00091                 for (i = 0; i < num; i++)
00092                         free(names[i]);
00093                 free(names);
00094         }
00095 
00096         return ret;
00097 } /* ra_eval_attribute_list() */
00098 
00099 
00108 LIBRAAPI int
00109 ra_eval_attribute_get(any_handle h, const char *id, value_handle vh)
00110 {
00111         int ret = -1;
00112         struct eval_head *head= (struct eval_head *)h;
00113         struct eval_attribute *curr;
00114 
00115         _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00116         ra_value_reset(vh);
00117 
00118         if ((curr = find_attribute(head, id)) == NULL)
00119         {
00120                 _ra_set_error(h, RA_ERR_UNKNOWN, "libRASCH");
00121                 return -1;
00122         }
00123 
00124         ret = ra_value_copy(vh, curr->value);
00125 
00126         return ret;
00127 } /* ra_eval_attribute_get() */
00128 
00129 
00138 LIBRAAPI int
00139 ra_eval_attribute_set(any_handle h, const char *id, value_handle vh)
00140 {
00141         int ret = -1;
00142         struct eval_head *head = (struct eval_head *)h;
00143         struct eval_attribute *curr;
00144 
00145         _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00146 
00147         if ((curr = find_attribute(head, id)) == NULL)
00148         {
00149                 curr = (struct eval_attribute *)calloc(1, sizeof(struct eval_attribute));
00150                 ra_list_add((void **)&(head->meas->eval.attribute), curr);
00151 
00152                 curr->src_handle = h;
00153                 strncpy(curr->name, id, MAX_ATTRIB_LEN-1);
00154                 curr->value = ra_value_malloc();
00155         }
00156 
00157         ret = ra_value_copy(curr->value, vh);
00158 
00159         return ret;
00160 } /* ra_eval_attribute_set() */
00161 
00162 
00170 LIBRAAPI int
00171 ra_eval_attribute_unset(any_handle h, const char *id)
00172 {
00173         int ret = -1;
00174         struct eval_head *head = (struct eval_head *)h;
00175         struct eval_attribute *curr;
00176 
00177         _ra_set_error(h, RA_ERR_NONE, "libRASCH");
00178 
00179         if ((curr = find_attribute(head, id)) == NULL)
00180         {
00181                 _ra_set_error(h, RA_ERR_UNKNOWN, "libRASCH");
00182                 return -1;
00183         }
00184 
00185         ra_value_free(curr->value);
00186         ret = ra_list_del((void **)&(head->meas->eval.attribute), curr);
00187 
00188         return ret;
00189 } /* ra_eval_attribute_unset() */
00190 
00191 
00192 struct eval_attribute *
00193 find_attribute(struct eval_head *h, const char *id)
00194 {
00195         struct eval_attribute *curr;
00196         
00197         curr = h->meas->eval.attribute;
00198         while (curr)
00199         {
00200                 if ((curr->src_handle == h) && (strncmp(curr->name, id, MAX_ATTRIB_LEN)))
00201                     break;
00202                 
00203                 curr = curr->next;
00204         }
00205 
00206         return curr;
00207 } /* find_attribute() */
00208 
00209 
00210 int
00211 delete_attributes(struct eval_head *h)
00212 {
00213         struct eval_attribute *a;
00214 
00215         a = h->meas->eval.attribute;
00216         while (a)
00217         {
00218                 if (a->src_handle == h)
00219                 {
00220                         ra_value_free(a->value);
00221                         ra_list_del((void **)&(h->meas->eval.attribute), a);
00222                         a = h->meas->eval.attribute;
00223                         continue;
00224                 }
00225 
00226                 a = a->next;
00227         }
00228 
00229         return 0;
00230 } /* delete_attributes() */
00231 
00232 
00233 /* ------------------------------ evaluation functions ------------------------------ */
00234 
00235 
00245 LIBRAAPI eval_handle
00246 ra_eval_add(meas_handle mh, const char *name, const char *desc, int original)
00247 {
00248         struct ra_meas *meas = (struct ra_meas *) mh;
00249         struct eval *e = NULL;
00250         char text[EVAL_MAX_DESC];
00251         struct tm *t;
00252         time_t tt;
00253         value_handle vh = NULL;
00254 
00255         _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00256 
00257         if (!mh)
00258                 return NULL;
00259         if (meas->handle_id != RA_HANDLE_MEAS)
00260         {
00261                 _ra_set_error(mh, RA_ERR_WRONG_HANDLE, "libRASCH");
00262                 return NULL;
00263         }
00264 
00265         /* if the new eval should be the original check if not already an original one is available */
00266         if (original)
00267         {
00268                 e = ra_eval_get_original(mh);
00269                 if (e)
00270                 {
00271                         _ra_set_error(mh, RA_ERR_EVAL_WRONG_TYPE, "libRASCH");
00272                         return NULL;
00273                 }
00274         }
00275 
00276         e = (struct eval *)calloc(1, sizeof(struct eval));
00277         ra_list_add((void **)&(meas->eval.evaluations), e);
00278 
00279         e->handle_id = RA_HANDLE_EVAL;
00280         e->meas = meas;
00281         e->original = original;
00282 
00283         time(&tt);
00284         t = gmtime(&tt);
00285         sprintf(text, "%02d.%02d.%4d  %02d:%02d:%02d", t->tm_mday,
00286                 t->tm_mon + 1, (t->tm_year + 1900), t->tm_hour, t->tm_min, t->tm_sec);
00287 
00288         vh = ra_value_malloc();
00289         ra_value_set_string(vh, text);
00290         if (ra_eval_attribute_set(e, "add-timestamp", vh) != 0)
00291                 goto error;
00292         if (ra_eval_attribute_set(e, "modify-timestamp", vh) != 0)
00293                 goto error;
00294 
00295         if (set_env(e) != 0)
00296                 goto error;
00297 
00298         /* set the new evaluation as the default evaluation */
00299         if (ra_eval_set_default(e) != 0)
00300                 goto error;
00301 
00302         if (name)
00303         {
00304                 ra_value_set_string(vh, name);
00305                 if (ra_eval_attribute_set(e, "name", vh) != 0)
00306                         goto error;
00307         }
00308         if (desc)
00309         {
00310                 ra_value_set_string(vh, desc);
00311                 if (ra_eval_attribute_set(e, "description", vh) != 0)
00312                         goto error;
00313         }       
00314         ra_value_free(vh);
00315 
00316         return e;
00317 
00318  error:
00319         if (e)
00320                 ra_list_del((void **)&(meas->eval.evaluations), e);
00321         if (vh)
00322                 ra_value_free(vh);
00323 
00324         return NULL;
00325 } /* ra_eval_add() */
00326 
00327 
00328 
00337 #ifdef LINUX
00338 int
00339 set_env(struct eval *e)
00340 {
00341         char t[EVAL_MAX_DESC];
00342         char fn[MAX_PATH_RA];
00343         FILE *f;
00344         value_handle vh;
00345 
00346         vh = ra_value_malloc();
00347 
00348         gethostname(t, EVAL_MAX_HOST);
00349         if (t[0] != '\0')
00350         {
00351                 ra_value_set_string(vh, t);
00352                 ra_eval_attribute_set(e, "add-host", vh);
00353         }
00354 
00355         if (getenv("LOGNAME") != NULL)
00356         {
00357                 ra_value_set_string(vh, getenv("LOGNAME"));
00358                 ra_eval_attribute_set(e, "add-user", vh);
00359         }
00360 
00361         sprintf(fn, "/proc/%d/status", getpid());
00362         f = fopen(fn, "r");
00363         if (f != NULL)
00364         {
00365                 char *p;
00366 
00367                 fgets(t, 200, f);
00368                 fclose(f);
00369 
00370                 p = strchr(t, '\t');
00371                 if ((p != NULL) && (p + 1 != '\0'))
00372                 {
00373                         char *newline;
00374 
00375                         p++;
00376                         newline = strchr(p, '\n');
00377                         if (newline)
00378                                 *newline = '\0';
00379                         ra_value_set_string(vh, p);
00380                         ra_eval_attribute_set(e, "add-program", vh);
00381                 }
00382         }
00383 
00384         ra_value_free(vh);
00385 
00386         return 0;
00387 } /* set_env() */
00388 
00389 #elif WIN32
00390 
00391 int
00392 set_env(struct eval *e)
00393 {
00394         char t[EVAL_MAX_DESC];
00395         char full_path[MAX_PATH_RA];
00396         char *pos, *cmd;
00397         long size;
00398         value_handle vh;
00399 
00400         vh = ra_value_malloc();
00401 
00402         size = EVAL_MAX_DESC;
00403         GetComputerName(t, &size);
00404         ra_value_set_string(vh, t);
00405         ra_eval_attribute_set(e, "add-host", vh);
00406         size = EVAL_MAX_DESC;
00407         GetUserName(t, &size);
00408         ra_value_set_string(vh, t);
00409         ra_eval_attribute_set(e, "add-user", vh);
00410 
00411         cmd = GetCommandLine();
00412         pos = strchr(cmd, ' ');
00413         if (pos == NULL)
00414                 strncpy(full_path, cmd, MAX_PATH_RA);
00415         else
00416                 strncpy(full_path, cmd, pos - cmd);
00417         pos = strrchr(full_path, '\\');
00418         if (pos == NULL)
00419                 pos = full_path;
00420         else
00421                 pos++;
00422         strncpy(t, pos, EVAL_MAX_PRG);
00423         pos = strchr(t, '\"');
00424         if (pos != NULL)
00425                 *pos = '\0';
00426         ra_value_set_string(vh, t);
00427         ra_eval_attribute_set(e, "add-program", vh);
00428 
00429         ra_value_free(vh);
00430 
00431         return 0;
00432 } /* set_env() */
00433 
00434 #else /* no matching system found -> do nothing */
00435 
00436 int
00437 set_env(struct eval *e)
00438 {
00439         return 0;
00440 } /* set_env() */
00441 #endif
00442 
00443 
00450 LIBRAAPI int
00451 ra_eval_delete(eval_handle eh)
00452 {
00453         int ret;
00454         value_handle vh;
00455         struct eval *e = (struct eval *)eh;
00456         struct eval_info *ei;
00457 
00458         _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00459 
00460         if (!eh)
00461                 return -1;
00462         if (e->handle_id != RA_HANDLE_EVAL)
00463         {
00464                 _ra_set_error(eh, RA_ERR_WRONG_HANDLE, "libRASCH");
00465                 return -1;
00466         }
00467 
00468         /* first delete all classes */
00469         vh = ra_value_malloc();
00470         while (1)
00471         {
00472                 const void **p;
00473                 long n;
00474 
00475                 ret = ra_class_get(eh, NULL, vh);
00476                 if (ret != 0)
00477                         break;
00478                 n = ra_value_get_num_elem(vh);
00479                 if (n <= 0)
00480                         break;
00481                 p = ra_value_get_voidp_array(vh);
00482                 ra_class_delete((class_handle)(p[0]));
00483         }
00484         ra_value_free(vh);
00485         if (ret != 0)
00486                 return -1;
00487 
00488         /* now delete all attributes associated with this evaluation */
00489         delete_attributes((struct eval_head *)e);
00490 
00491         /* and finally delete the evaluation entry */
00492         ei = &(e->meas->eval);
00493         ra_list_del((void **)&(ei->evaluations), e);
00494 
00495         return 0;
00496 } /* ra_eval_delete() */
00497 
00498 
00506 LIBRAAPI int
00507 ra_eval_get_all(meas_handle mh, value_handle vh)
00508 {
00509         struct ra_meas *meas = (struct ra_meas *)mh;
00510         void **p;
00511         int i, cnt;
00512         struct eval *curr;
00513 
00514         if ((!mh) || (!vh))
00515         {
00516                 if (mh)
00517                         _ra_set_error(mh, RA_ERR_INFO_MISSING, "libRASCH");
00518                 return -1;
00519         }
00520 
00521         ra_value_reset(vh);
00522         _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00523 
00524         if (meas->eval.evaluations == NULL)
00525                 return 0;
00526 
00527         cnt = ra_list_len(meas->eval.evaluations);
00528 
00529         p = (void **)calloc(cnt, sizeof(void *));
00530 
00531         curr = meas->eval.evaluations;
00532         for (i = 0; i < cnt; i++)
00533         {
00534                 if (curr == NULL)
00535                         break;
00536                 p[i] = curr;
00537                 curr = curr->next;
00538         }
00539         ra_value_set_voidp_array(vh, (const void **)p, cnt);
00540 
00541         free(p);
00542 
00543         return 0;
00544 } /* ra_eval_get_all() */
00545 
00546 
00553 LIBRAAPI eval_handle
00554 ra_eval_get_original(meas_handle mh)
00555 {
00556         struct ra_meas *meas = (struct ra_meas *)mh;
00557         struct eval *e = NULL;
00558 
00559         if (!mh)
00560                 return NULL;
00561         _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00562 
00563         e = meas->eval.evaluations;
00564         while (e)
00565         {
00566                 if (e->original)
00567                         break;
00568                 e = e->next;
00569         }
00570 
00571         return e;
00572 } /* ra_eval_get_original() */
00573 
00574 
00581 LIBRAAPI eval_handle
00582 ra_eval_get_default(meas_handle mh)
00583 {
00584         struct ra_meas *meas = (struct ra_meas *)mh;
00585         struct eval *e = NULL;
00586 
00587         _ra_set_error(mh, RA_ERR_NONE, "libRASCH");
00588         if (!mh)
00589                 return NULL;
00590 
00591         e = meas->eval.evaluations;
00592         while (e)
00593         {
00594                 if (e->def)
00595                         break;
00596                 e = e->next;
00597         }
00598 
00599         return e;
00600 } /* ra_eval_get_default() */
00601 
00602 
00609 LIBRAAPI int
00610 ra_eval_set_default(eval_handle eh)
00611 {
00612         struct eval *e, *e_prev;
00613                         
00614         if (!eh)
00615                 return -1;
00616         _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00617 
00618         e = (struct eval *)eh;
00619 
00620         e_prev = ra_eval_get_default(ra_meas_handle_from_any_handle(eh));
00621         if (e_prev)
00622                 e_prev->def = 0;
00623 
00624         e->def = 1;
00625 
00626         return 0;
00627 } /* ra_eval_set_default() */
00628 
00629 
00637 LIBRAAPI eval_handle
00638 ra_eval_get_handle(class_handle clh)
00639 {
00640         struct eval_class *c = (struct eval_class *)clh;
00641 
00642         if (!clh)
00643                 return NULL;
00644 
00645         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00646 
00647         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00648         {
00649                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00650                 return NULL;
00651         }
00652         
00653         return (eval_handle)(c->eval);
00654 } /* ra_eval_get_handle() */
00655 
00656 
00657 
00658 /* ------------------------------ event-class functions ------------------------------ */
00659 
00660 
00661 
00675 LIBRAAPI class_handle
00676 ra_class_add(eval_handle eh, const char *id, const char *name, const char *desc)
00677 {
00678         struct eval *e = (struct eval *)eh;
00679         struct eval_class *c = NULL;
00680         value_handle vh = NULL;
00681 
00682         if (!eh)
00683                 return NULL;
00684 
00685         if ((id == NULL) || (id[0] == '\0'))
00686         {
00687                 _ra_set_error(eh, RA_ERR_INFO_MISSING, "libRASCH");
00688                 return NULL;
00689         }
00690 
00691         _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00692 
00693         c = calloc(1, sizeof(struct eval_class));
00694         ra_list_add((void **)&(e->cl), c);
00695 
00696         c->handle_id = RA_HANDLE_EVAL_CLASS;
00697         c->id = get_class_id(id);
00698         strncpy(c->ascii_id, id, MAX_ID_LEN);
00699         c->meas = e->meas;
00700         c->eval = e;
00701 
00702         vh = ra_value_malloc();
00703         if (name)
00704         {
00705                 ra_value_set_string(vh, name);
00706                 if (ra_eval_attribute_set(c, "name", vh) != 0)
00707                         goto error;
00708         }
00709         if (desc)
00710         {
00711                 ra_value_set_string(vh, desc);
00712                 if (ra_eval_attribute_set(c, "description", vh) != 0)
00713                         goto error;
00714         }       
00715         ra_value_free(vh);
00716 
00717         return c;
00718 
00719  error:
00720         ra_class_delete(c);
00721 
00722         if (vh)
00723                 ra_value_free(vh);
00724 
00725         return NULL;
00726 } /* ra_class_add() */
00727 
00728 
00738 LIBRAAPI class_handle
00739 ra_class_add_predef(eval_handle eh, const char *id)
00740 {
00741         class_handle clh = NULL;
00742         value_handle vh_name, vh_desc;
00743 
00744         vh_name = ra_value_malloc();
00745         vh_desc = ra_value_malloc();
00746 
00747         if (fill_predef_class_info_ascii(id, vh_name, vh_desc) != 0)
00748                 goto error;
00749 
00750         clh = ra_class_add(eh, id, ra_value_get_string(vh_name), ra_value_get_string(vh_desc));
00751 
00752  error:
00753         ra_value_free(vh_name);
00754         ra_value_free(vh_desc);
00755 
00756         return clh;
00757 } /* ra_class_add_predef() */
00758 
00759 
00766 LIBRAAPI int
00767 ra_class_delete(class_handle clh)
00768 {
00769         struct eval_class *c = (struct eval_class *)clh;
00770         struct eval *e;
00771         struct eval_property *p;
00772         struct eval_summary *s;
00773 
00774         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00775 
00776         if (!clh)
00777                 return -1;
00778         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00779         {
00780                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00781                 return -1;
00782         }
00783 
00784         /* delete all properties associated with this class */
00785         while ((p = c->prop))
00786                 ra_prop_delete(p);
00787 
00788         /* delete all event-summaries associated with this class */
00789         while ((s = c->summaries))
00790                 ra_sum_delete(s);
00791 
00792         /* then delete all events associated with this event class */
00793         if (c->ev)
00794                 free(c->ev);
00795         
00796         /* now delete all attributes associated with this evaluation */
00797         delete_attributes((struct eval_head *)c);
00798         
00799         /* and finally delete the class entry */
00800         e = c->eval;
00801         ra_list_del((void **)&(e->cl), c);
00802 
00803         return 0;
00804 } /* ra_class_delete() */
00805 
00806 
00817 LIBRAAPI int
00818 ra_class_get(eval_handle eh, const char *id, value_handle vh)
00819 {
00820         struct eval *e = (struct eval *)eh;     
00821         struct eval_class *c;
00822         int num;
00823         void **vp;
00824 
00825         _ra_set_error(eh, RA_ERR_NONE, "libRASCH");
00826         ra_value_reset(vh);
00827 
00828         if (!eh)
00829                 return -1;
00830         if (e->handle_id != RA_HANDLE_EVAL)
00831         {
00832                 _ra_set_error(eh, RA_ERR_WRONG_HANDLE, "libRASCH");
00833                 return -1;
00834         }
00835         if (!vh)
00836         {
00837                 _ra_set_error(eh, RA_ERR_INFO_MISSING, "libRASCH");
00838                 return -1;
00839         }
00840 
00841         c = e->cl;
00842         num = 0;
00843         vp = NULL;
00844         while (c)
00845         {
00846                 int ok = 1;
00847 
00848                 if (id && (id[0] != '\0') && (strcmp(c->ascii_id, id) != 0))
00849                         ok = 0;
00850 
00851                 if (ok)
00852                 {
00853                         num++;
00854                         vp = (void **)realloc(vp, sizeof(void *) * num);
00855                         vp[num-1] = c;
00856                 }
00857 
00858                 c = c->next;
00859         }
00860 
00861         if (num > 0)
00862         {
00863                 ra_value_set_voidp_array(vh, (const void **)vp, num);
00864                 free(vp);
00865         }
00866 
00867         return 0;       
00868 } /* ra_class_get() */
00869 
00870 
00882 LIBRAAPI long
00883 ra_class_add_event(class_handle clh, long start, long end)
00884 {
00885         struct eval_class *c = (struct eval_class *)clh;
00886 
00887         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
00888 
00889         if (!clh)
00890                 return -1;
00891         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
00892         {
00893                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
00894                 return -1;
00895         }
00896 
00897         c->num_event++;
00898         c->ev = (struct eval_event *)realloc(c->ev, sizeof(struct eval_event) * c->num_event);
00899         c->last_id++;
00900         c->ev[c->num_event-1].id = c->last_id;
00901         c->ev[c->num_event-1].start = start;
00902         c->ev[c->num_event-1].end = end;
00903 
00904         add_prop_mem(c);
00905 
00906         return c->last_id;
00907 } /* ra_class_add_event() */
00908 
00909 
00910 int
00911 add_prop_mem(struct eval_class *c)
00912 {
00913         struct eval_property *p = c->prop;
00914         long total, added;
00915 
00916         while (p)
00917         {
00918                 /* check if memory needs to be allocated */
00919                 if (p->allocated_events >= c->num_event)
00920                 {
00921                         p = p->next;
00922                         continue;
00923                 }
00924 
00925                 /* memory is needed -> prepare variables */
00926                 added = (long)((double)p->allocated_events * EVENT_MEM_ADD);
00927                 if (added < 1)
00928                         added = 1;
00929 
00930                 total = p->allocated_events + added;
00931 
00932                 switch (p->value_type)
00933                 {
00934                 case RA_VALUE_TYPE_SHORT:
00935                         p->value.s = realloc(p->value.s, sizeof(short *) * total);
00936                         memset(p->value.s + p->allocated_events, 0, sizeof(short *) * added);
00937                         break;
00938                 case RA_VALUE_TYPE_LONG:
00939                         p->value.l = realloc(p->value.l, sizeof(long *) * total);
00940                         memset(p->value.l + p->allocated_events, 0, sizeof(long *) * added);
00941                         break;
00942                 case RA_VALUE_TYPE_DOUBLE:
00943                         p->value.d = realloc(p->value.d, sizeof(double *) * total);
00944                         memset(p->value.d + p->allocated_events, 0, sizeof(double *) * added);
00945                         break;
00946                 case RA_VALUE_TYPE_CHAR:
00947                         p->value.c = realloc(p->value.c, sizeof(char **) * total);
00948                         memset(p->value.c + p->allocated_events, 0, sizeof(char **) * added);
00949                         break;
00950                 case RA_VALUE_TYPE_SHORT_ARRAY:
00951                         p->value.sa = realloc(p->value.sa, sizeof(short **) * total);
00952                         memset(p->value.sa + p->allocated_events, 0, sizeof(short **) * added);
00953                         break;
00954                 case RA_VALUE_TYPE_LONG_ARRAY:
00955                         p->value.la = realloc(p->value.la, sizeof(long **) * total);
00956                         memset(p->value.la + p->allocated_events, 0, sizeof(long **) * added);
00957                         break;
00958                 case RA_VALUE_TYPE_DOUBLE_ARRAY:
00959                         p->value.da = realloc(p->value.da, sizeof(double **) * total);
00960                         memset(p->value.da + p->allocated_events, 0, sizeof(double **) * added);
00961                         break;
00962                 case RA_VALUE_TYPE_CHAR_ARRAY:
00963                         p->value.ca = realloc(p->value.ca, sizeof(char ***) * total);
00964                         memset(p->value.ca + p->allocated_events, 0, sizeof(char ***) * added);
00965                         break;
00966                 }
00967 
00968                 p->ch_map = realloc(p->ch_map, sizeof(short *) * total);
00969                 memset(p->ch_map + p->allocated_events, 0, sizeof(short *) * added);
00970 
00971                 p->num_entries = realloc(p->num_entries, sizeof(long) * total);
00972                 memset(p->num_entries + p->allocated_events, 0, sizeof(long) * added);
00973 
00974                 p->num_elements = realloc(p->num_elements, sizeof(long *) * total);
00975                 memset(p->num_elements + p->allocated_events, 0, sizeof(long *) * added);
00976 
00977                 /* the value of the allocated events has to be set at the end
00978                    because the old value is needed above*/
00979                 p->allocated_events = total;
00980                 
00981                 p = p->next;
00982         }
00983 
00984         return 0;
00985 } /* add_prop_mem() */
00986 
00987 
00995 LIBRAAPI int
00996 ra_class_del_event(class_handle clh, long event_id)
00997 {
00998         struct eval_class *c = (struct eval_class *)clh;
00999         long idx;
01000 
01001         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01002 
01003         if (!clh)
01004                 return -1;
01005         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01006         {
01007                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01008                 return -1;
01009         }
01010         if ((event_id < 0) || (event_id > c->last_id))
01011         {
01012                 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01013                 return -1;
01014         }
01015 
01016         idx = get_event_idx(c, event_id);
01017         if (idx < 0)
01018         {
01019                 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01020                 return -1;
01021         }
01022 
01023         del_prop_values(c, idx);
01024 
01025         if (idx == 0)
01026                 memmove(c->ev, c->ev + 1, sizeof(struct eval_event) * (c->num_event - 1));
01027         else if (idx < (c->num_event-1))
01028                 memmove(c->ev + idx, c->ev + idx+1, sizeof(struct eval_event) * (c->num_event - idx - 1));
01029 
01030         c->num_event--;
01031 
01032         c->ev = (struct eval_event *)realloc(c->ev, sizeof(struct eval_event) * c->num_event);
01033 
01034         return 0;
01035 } /* ra_class_del_event() */
01036 
01037 
01038 long
01039 get_event_idx(struct eval_class *c, long event_id)
01040 {
01041         long idx = -1;
01042         long l;
01043 
01044         for (l = 0; l < c->num_event; l++)
01045         {
01046                 if (c->ev[l].id == event_id)
01047                 {
01048                         idx = l;
01049                         break;
01050                 }
01051         }
01052 
01053         return idx;
01054 } /* get_event_idx() */
01055 
01056 
01057 int
01058 del_prop_values(struct eval_class *c, long idx)
01059 {
01060         long l, m;
01061         struct eval_property *p = c->prop;
01062 
01063         while (p)
01064         {
01065                 switch (p->value_type)
01066                 {
01067                 case RA_VALUE_TYPE_SHORT:
01068                         free(p->value.s[idx]);
01069                         if (idx < (c->num_event - 1))
01070                                 memmove(p->value.s + idx, p->value.s + idx+1, sizeof(short *) * (c->num_event - idx - 1));
01071                         p->value.s[c->num_event-1] = NULL;
01072                         break;
01073                 case RA_VALUE_TYPE_LONG:
01074                         free(p->value.l[idx]);
01075                         if (idx < (c->num_event - 1))
01076                                 memmove(p->value.l + idx, p->value.l + idx+1, sizeof(long *) * (c->num_event - idx - 1));
01077                         p->value.l[c->num_event-1] = NULL;
01078                         break;
01079                 case RA_VALUE_TYPE_DOUBLE:
01080                         free(p->value.d[idx]);
01081                         if (idx < (c->num_event - 1))
01082                                 memmove(p->value.d + idx, p->value.d + idx+1, sizeof(double *) * (c->num_event - idx - 1));
01083                         p->value.d[c->num_event-1] = NULL;
01084                         break;
01085                 case RA_VALUE_TYPE_CHAR:
01086                         for (l = 0; l < p->num_entries[idx]; l++)
01087                                 free(p->value.c[idx][l]);
01088                         free(p->value.c[idx]);
01089                         if (idx < (c->num_event - 1))
01090                                 memmove(p->value.c + idx, p->value.c + idx+1, sizeof(char **) * (c->num_event - idx - 1));
01091                         p->value.c[c->num_event-1] = NULL;
01092                         break;
01093                 case RA_VALUE_TYPE_SHORT_ARRAY:
01094                         for (l = 0; l < p->num_entries[idx]; l++)
01095                                 free(p->value.sa[idx][l]);
01096                         free(p->value.sa[idx]);
01097                         if (idx < (c->num_event - 1))
01098                                 memmove(p->value.sa + idx, p->value.sa + idx+1, sizeof(short **) * (c->num_event - idx - 1));
01099                         p->value.sa[c->num_event-1] = NULL;
01100                         break;
01101                 case RA_VALUE_TYPE_LONG_ARRAY:
01102                         for (l = 0; l < p->num_entries[idx]; l++)
01103                                 free(p->value.la[idx][l]);
01104                         free(p->value.la[idx]);
01105                         if (idx < (c->num_event - 1))
01106                                 memmove(p->value.la + idx, p->value.la + idx+1, sizeof(long **) * (c->num_event - idx - 1));
01107                         p->value.la[c->num_event-1] = NULL;
01108                         break;
01109                 case RA_VALUE_TYPE_DOUBLE_ARRAY:
01110                         for (l = 0; l < p->num_entries[idx]; l++)
01111                                 free(p->value.da[idx][l]);
01112                         free(p->value.da[idx]);
01113                         if (idx < (c->num_event - 1))
01114                                 memmove(p->value.da + idx, p->value.da + idx+1, sizeof(double **) * (c->num_event - idx - 1));
01115                         p->value.da[c->num_event-1] = NULL;
01116                         break;
01117                 case RA_VALUE_TYPE_CHAR_ARRAY:
01118                         for (l = 0; l < p->num_entries[idx]; l++)
01119                         {
01120                                 for (m = 0; m < p->num_elements[idx][l]; m++)
01121                                         free(p->value.ca[idx][l][m]);
01122                                 free(p->value.ca[idx][l]);
01123                         }
01124                         free(p->value.ca[idx]);
01125                         if (idx < (c->num_event - 1))
01126                                 memmove(p->value.ca + idx, p->value.ca + idx+1, sizeof(char ***) * (c->num_event - idx - 1));
01127                         p->value.ca[c->num_event-1] = NULL;
01128                         break;
01129                 }
01130 
01131                 free(p->ch_map[idx]);
01132                 free(p->num_elements[idx]);
01133                 
01134                 if (idx < (c->num_event - 1))
01135                 {
01136                         memmove(p->ch_map + idx, p->ch_map + idx+1, sizeof(short *) * (c->num_event - idx - 1));
01137                         memmove(p->num_entries + idx, p->num_entries + idx+1, sizeof(long) * (c->num_event - idx - 1));
01138                         memmove(p->num_elements + idx, p->num_elements + idx+1, sizeof(long *) * (c->num_event - idx - 1));
01139                 }
01140                 p->ch_map[c->num_event-1] = NULL;
01141                 p->num_entries[c->num_event-1] = 0;
01142                 p->num_elements[c->num_event-1] = NULL;
01143                 
01144                 p = p->next;
01145         }
01146 
01147         return 0;
01148 } /* del_prop_values() */
01149 
01150 
01161 LIBRAAPI int
01162 ra_class_get_event_pos(class_handle clh, long event_id, long *start, long *end)
01163 {
01164         struct eval_class *c= (struct eval_class *)clh;
01165         long idx;
01166 
01167         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01168 
01169         if (!clh)
01170                 return -1;
01171         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01172         {
01173                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01174                 return -1;
01175         }
01176         if ((event_id < 0) || (event_id > c->last_id))
01177         {
01178                 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01179                 return -1;
01180         }
01181 
01182         idx = get_event_idx(c, event_id);
01183         if (idx < 0)
01184         {
01185                 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01186                 return -1;
01187         }
01188 
01189         if (start)
01190                 *start = c->ev[idx].start;
01191         if (end)
01192                 *end = c->ev[idx].end;
01193 
01194         return 0;
01195 } /* ra_class_get_event_pos() */
01196 
01197 
01208 LIBRAAPI int
01209 ra_class_set_event_pos(class_handle clh, long event_id, long start, long end)
01210 {
01211         struct eval_class *c= (struct eval_class *)clh;
01212         long idx;
01213 
01214         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01215 
01216         if (!clh)
01217                 return -1;
01218         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01219         {
01220                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01221                 return -1;
01222         }
01223         if ((event_id < 0) || (event_id > c->last_id))
01224         {
01225                 _ra_set_error(clh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01226                 return -1;
01227         }
01228 
01229         idx = get_event_idx(c, event_id);
01230         if (idx < 0)
01231         {
01232                 _ra_set_error(clh, RA_ERR_WRONG_INPUT, "libRASCH");
01233                 return -1;
01234         }
01235 
01236         c->ev[idx].start = start;
01237         c->ev[idx].end = end;
01238 
01239         return 0;
01240 } /* ra_class_set_event_pos() */
01241 
01242 
01243 int
01244 comp_pos(const void* arg1, const void* arg2)
01245 {
01246         struct sort_pos *b1 = (struct sort_pos *)arg1;
01247         struct sort_pos *b2 = (struct sort_pos *)arg2;
01248 
01249         return (b1->pos - b2->pos);
01250 }  /* comp_pos() */
01251 
01252 
01253 
01268 LIBRAAPI int
01269 ra_class_get_events(class_handle clh, long start, long end, int complete, int sort, value_handle vh)
01270 {
01271         struct eval_class *c= (struct eval_class *)clh; 
01272         struct sort_pos *sp = NULL;
01273         long *ids, l, num;
01274 
01275         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01276         ra_value_reset(vh);
01277 
01278         if (!clh)
01279                 return -1;
01280         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01281         {
01282                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01283                 return -1;
01284         }
01285         if (!vh)
01286         {
01287                 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01288                 return -1;
01289         }
01290 
01291         if ((start <= 0) && (end < 0))
01292         {
01293                 num = c->num_event;
01294                 sp = (struct sort_pos *)malloc(sizeof(struct sort_pos) * num);
01295                 for (l = 0; l < num; l++)
01296                 {
01297                         sp[l].id = c->ev[l].id;
01298                         sp[l].pos = c->ev[l].start;
01299                 }
01300         }
01301         else
01302         {
01303                 num = 0;
01304                 for (l = 0; l < c->num_event; l++)
01305                 {
01306                         if ((c->ev[l].start < start) && complete)
01307                                 continue;
01308                         if ((end != -1) && ((c->ev[l].end > end) && complete))
01309                                 continue;
01310                         if ((end != -1) && (c->ev[l].end < start))
01311                                 continue;
01312                         if (c->ev[l].start > end)
01313                                 continue;
01314 
01315                         num++;
01316                         sp = (struct sort_pos *)realloc(sp, sizeof(struct sort_pos) * num);
01317                         sp[num-1].id = c->ev[l].id;
01318                         sp[num-1].pos = c->ev[l].start;
01319                 }
01320         }
01321         
01322         if ((num > 0) && sort)
01323                 qsort(sp, num, sizeof(struct sort_pos), comp_pos);
01324 
01325         if (num > 0)
01326         {
01327                 ids = (long *)malloc(sizeof(long) * num);
01328                 for (l = 0; l < num; l++)
01329                         ids[l] = sp[l].id;
01330 
01331                 ra_value_set_long_array(vh, ids, num);
01332 
01333                 free(ids);
01334                 free(sp);
01335         }
01336 
01337         return 0;
01338 } /* ra_class_get_events() */
01339 
01340 
01347 LIBRAAPI class_handle
01348 ra_class_get_handle(prop_handle ph)
01349 {
01350         struct eval_property *p = (struct eval_property *)ph;
01351 
01352         if (!ph)
01353                 return NULL;
01354 
01355         _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01356 
01357         if (p->handle_id != RA_HANDLE_EVAL_PROP)
01358         {
01359                 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01360                 return NULL;
01361         }
01362         
01363         return (class_handle)(p->evclass);
01364 } /* ra_class_get_handle() */
01365 
01366 
01367 /* ------------------------------ event-property functions ------------------------------ */
01368 
01369 
01370 LIBRAAPI prop_handle
01371 ra_prop_add(class_handle clh, const char *id, long value_type, long num_values, const char *name,
01372             const char *desc, const char *unit, int use_minmax, double min, double max)
01373 {
01374         struct eval_class *c = (struct eval_class *)clh;
01375         struct eval_property *p = NULL;
01376         value_handle vh = NULL;
01377 
01378         _ra_set_error(clh, RA_ERR_NONE, "libRASCH");
01379 
01380         if (!clh)
01381                 return NULL;
01382         if (c->handle_id != RA_HANDLE_EVAL_CLASS)
01383         {
01384                 _ra_set_error(clh, RA_ERR_WRONG_HANDLE, "libRASCH");
01385                 return NULL;
01386         }
01387         if (id == NULL)
01388         {
01389                 _ra_set_error(clh, RA_ERR_INFO_MISSING, "libRASCH");
01390                 return NULL;
01391         }
01392 
01393         p = calloc(1, sizeof(struct eval_property));
01394         ra_list_add((void **)&(c->prop), p);
01395 
01396         p->handle_id = RA_HANDLE_EVAL_PROP;
01397         p->id = get_prop_id(id);
01398         strncpy(p->ascii_id, id, MAX_ID_LEN);
01399         p->meas = c->meas;
01400         p->evclass = c;
01401         p->value_type = value_type;
01402 
01403         vh = ra_value_malloc();
01404         if (name)
01405         {
01406                 ra_value_set_string(vh, name);
01407                 if (ra_eval_attribute_set(p, "name", vh) != 0)
01408                         goto error;
01409         }
01410         if (desc)
01411         {
01412                 ra_value_set_string(vh, desc);
01413                 if (ra_eval_attribute_set(p, "description", vh) != 0)
01414                         goto error;
01415         }
01416         if (unit)
01417         {
01418                 ra_value_set_string(vh, unit);
01419                 if (ra_eval_attribute_set(p, "unit", vh) != 0)
01420                         goto error;
01421         }
01422         if (use_minmax)
01423         {
01424                 ra_value_set_long(vh, 1);
01425                 if (ra_eval_attribute_set(p, "use-minmax", vh) != 0)
01426                         goto error;
01427                 ra_value_set_double(vh, min);
01428                 if (ra_eval_attribute_set(p, "min", vh) != 0)
01429                         goto error;
01430                 ra_value_set_double(vh, max);
01431                 if (ra_eval_attribute_set(p, "max", vh) != 0)
01432                         goto error;
01433         }
01434         ra_value_free(vh);
01435 
01436         if (alloc_prop_mem(p) != 0)
01437                 goto error;
01438 
01439         return p;
01440 
01441  error:
01442         ra_prop_delete(p);
01443 
01444         if (vh)
01445                 ra_value_free(vh);
01446 
01447         return NULL;
01448 } /* ra_prop_add() */
01449 
01450 
01451 int
01452 alloc_prop_mem(struct eval_property *p)
01453 {
01454         struct eval_class *c = p->evclass;
01455         
01456         p->allocated_events = c->num_event;
01457         if (c->num_event <= 0)
01458                 return 0;
01459 
01460         switch (p->value_type)
01461         {
01462         case RA_VALUE_TYPE_SHORT:
01463                 p->value.s = calloc(c->num_event, sizeof(short *));
01464                 break;
01465         case RA_VALUE_TYPE_LONG:
01466                 p->value.l = calloc(c->num_event, sizeof(long *));
01467                 break;
01468         case RA_VALUE_TYPE_DOUBLE:
01469                 p->value.d = calloc(c->num_event, sizeof(double *));
01470                 break;
01471         case RA_VALUE_TYPE_CHAR:
01472                 p->value.c = calloc(c->num_event, sizeof(char **));
01473                 break;
01474         case RA_VALUE_TYPE_SHORT_ARRAY:
01475                 p->value.sa = calloc(c->num_event, sizeof(short **));
01476                 break;
01477         case RA_VALUE_TYPE_LONG_ARRAY:
01478                 p->value.la = calloc(c->num_event, sizeof(long **));
01479                         break;
01480         case RA_VALUE_TYPE_DOUBLE_ARRAY:
01481                 p->value.da = calloc(c->num_event, sizeof(double **));
01482                 break;
01483         case RA_VALUE_TYPE_CHAR_ARRAY:
01484                 p->value.ca = calloc(c->num_event, sizeof(char ***));
01485                 break;
01486         }
01487         
01488         p->ch_map = calloc(c->num_event, sizeof(short *));      
01489         p->num_entries = calloc(c->num_event, sizeof(long));
01490         p->num_elements = calloc(c->num_event, sizeof(long *));
01491         
01492         return 0;
01493 } /* alloc_prop_mem() */
01494 
01495 
01496 LIBRAAPI prop_handle
01497 ra_prop_add_predef(class_handle clh, const char *id)
01498 {
01499         prop_handle ph = NULL;
01500         value_handle vh_type, vh_len, vh_name, vh_desc, vh_unit;
01501         value_handle vh_use_minmax, vh_min, vh_max;
01502 
01503         vh_type = ra_value_malloc();
01504         vh_len = ra_value_malloc();
01505         vh_name = ra_value_malloc();
01506         vh_desc = ra_value_malloc();
01507         vh_unit = ra_value_malloc();
01508         vh_use_minmax = ra_value_malloc();
01509         vh_min = ra_value_malloc();
01510         vh_max = ra_value_malloc();
01511 
01512         if (fill_predef_prop_info_ascii(id, vh_type, vh_len, vh_name, vh_desc, vh_unit,
01513                                         vh_use_minmax, vh_min, vh_max) != 0)
01514         {
01515                 goto error;
01516         }
01517         
01518         /* add property */
01519         ph = ra_prop_add(clh, id, ra_value_get_long(vh_type), ra_value_get_long(vh_len),
01520                          ra_value_get_string(vh_name), ra_value_get_string(vh_desc), ra_value_get_string(vh_unit),
01521                          ra_value_get_long(vh_use_minmax), ra_value_get_double(vh_min), ra_value_get_double(vh_max));
01522 
01523  error:
01524         ra_value_free(vh_type);
01525         ra_value_free(vh_len);
01526         ra_value_free(vh_name);
01527         ra_value_free(vh_desc);
01528         ra_value_free(vh_unit);
01529         ra_value_free(vh_use_minmax);
01530         ra_value_free(vh_min);
01531         ra_value_free(vh_max);
01532 
01533         return ph;
01534 } /* ra_prop_add_predef() */
01535 
01536 
01537 LIBRAAPI int
01538 ra_prop_delete(prop_handle ph)
01539 {
01540         struct eval_property *p = (struct eval_property *)ph;   
01541         long l, m, n;
01542         struct eval_class *c;
01543 
01544         _ra_set_error(ph, RA_ERR_NONE, "libRASCH");
01545 
01546         if (!ph)
01547                 return -1;
01548         if (p->handle_id != RA_HANDLE_EVAL_PROP)
01549         {
01550                 _ra_set_error(ph, RA_ERR_WRONG_HANDLE, "libRASCH");
01551                 return -1;
01552         }
01553 
01554         /* delete allocated memory */
01555         switch (p->value_type)
01556         {
01557         case RA_VALUE_TYPE_SHORT:
01558                 for (l = 0; l < p->evclass->num_event; l++)
01559                 {
01560                         if (p->value.s[l])
01561                                 free(p->value.s[l]);
01562                 }
01563                 free(p->value.s);
01564                 break;
01565         case RA_VALUE_TYPE_LONG:
01566                 for (l = 0; l < p->evclass->num_event; l++)
01567                 {
01568                         if (p->value.l[l])
01569                                 free(p->value.l[l]);
01570                 }
01571                 free(p->value.l);
01572                 break;
01573         case RA_VALUE_TYPE_DOUBLE:
01574                 for (l = 0; l < p->evclass->num_event; l++)
01575                 {
01576                         if (p->value.d[l])
01577                                 free(p->value.d[l]);
01578                 }
01579                 free(p->value.d);
01580                 break;
01581         case RA_VALUE_TYPE_CHAR:
01582                 for (l = 0; l < p->evclass->num_event; l++)
01583                 {
01584                         if (p->value.c[l])
01585                         {
01586                                 for (m = 0; m < p->num_entries[l]; m++)
01587                                 {
01588                                         if (p->value.c[l][m])
01589                                                 free(p->value.c[l][m]);
01590                                 }
01591                                 free(p->value.c[l]);
01592                         }
01593                 }
01594                 free(p->value.c);
01595                 break;
01596         case RA_VALUE_TYPE_SHORT_ARRAY:
01597                 for (l = 0; l < p->evclass->num_event; l++)
01598                 {
01599                         if (p->value.sa[l])
01600                         {
01601                                 for (m = 0; m < p->num_entries[l]; m++)
01602                                 {
01603                                         if (p->value.sa[l][m])
01604                                                 free(p->value.sa[l][m]);
01605                                 }
01606                                 free(p->value.sa[l]);
01607                         }
01608                 }
01609                 free(p->value.sa);
01610                 break;
01611         case RA_VALUE_TYPE_LONG_ARRAY:
01612                 for (l = 0; l < p->evclass->num_event; l++)
01613                 {
01614                         if (p->value.la[l])
01615                         {
01616                                 for (m = 0; m < p->num_entries[l]; m++)
01617                                 {
01618                                         if (p->value.la[l][m])
01619                                                 free(p->value.la[l][m]);
01620                                 }
01621                                 free(p->value.la[l]);
01622                         }
01623                 }
01624                 free(p->value.la);
01625                 break;
01626         case RA_VALUE_TYPE_DOUBLE_ARRAY:
01627                 for (l = 0; l < p->evclass->num_event; l++)
01628                 {
01629                         if (p->value.da[l])
01630                         {
01631                                 for (m = 0; m < p->num_entries[l]; m++)
01632                                 {
01633                                         if (p->value.da[l][m])
01634                                                 free(p->value.da[l][m]);
01635                                 }
01636                                 free(p->value.da[l]);
01637                         }
01638                 }
01639                 free(p->value.da);
01640                 break;
01641         case R