00001
00009
00010
00011
00012
00013
00014
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 }
00042
00043
00044 LIBRAAPI int
00045 ra_eval_edit_complete(any_handle h)
00046 {
00047 return 0;
00048 }
00049
00050
00051 LIBRAAPI int
00052 ra_eval_edit_cancel(any_handle h)
00053 {
00054 return 0;
00055 }
00056
00057
00058
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 }
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 }
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 }
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 }
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 }
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 }
00231
00232
00233
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
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
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 }
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 }
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 }
00433
00434 #else
00435
00436 int
00437 set_env(struct eval *e)
00438 {
00439 return 0;
00440 }
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
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
00489 delete_attributes((struct eval_head *)e);
00490
00491
00492 ei = &(e->meas->eval);
00493 ra_list_del((void **)&(ei->evaluations), e);
00494
00495 return 0;
00496 }
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 }
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 }
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 }
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 }
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 }
00655
00656
00657
00658
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 }
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 }
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
00785 while ((p = c->prop))
00786 ra_prop_delete(p);
00787
00788
00789 while ((s = c->summaries))
00790 ra_sum_delete(s);
00791
00792
00793 if (c->ev)
00794 free(c->ev);
00795
00796
00797 delete_attributes((struct eval_head *)c);
00798
00799
00800 e = c->eval;
00801 ra_list_del((void **)&(e->cl), c);
00802
00803 return 0;
00804 }
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 }
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 }
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
00919 if (p->allocated_events >= c->num_event)
00920 {
00921 p = p->next;
00922 continue;
00923 }
00924
00925
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
00978
00979 p->allocated_events = total;
00980
00981 p = p->next;
00982 }
00983
00984 return 0;
00985 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
01365
01366
01367
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 }
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 }
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
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 }
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
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