00001
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <errno.h>
00023 #include <assert.h>
00024 #include <locale.h>
00025
00026 #ifdef WIN32
00027 #include <windows.h>
00028 #endif
00029
00030 #define _LIBRASCH_BUILD
00031 #include <ra_priv.h>
00032 #include <ra_version.h>
00033 #include <ra.h>
00034 #include <ra_error_txt.h>
00035 #include <handle_plugin.h>
00036 #include <pl_general.h>
00037 #include <ra_file.h>
00038 #include <ra_endian.h>
00039
00040 #include <libxml/tree.h>
00041 #include <libxml/parser.h>
00042
00043
00047 int ra_print_debug_infos;
00048
00052 int ra_in_error;
00053
00057 int ra_endian_type;
00058
00062 char ra_i18n_codeset[MAX_I18N_LEN];
00063
00064
00070 LIBRAAPI ra_handle
00071 ra_lib_init(void)
00072 {
00073 int ret = 0;
00074 struct librasch *ra;
00075
00076 if (getenv("LIBRASCH_DEBUG"))
00077 ra_print_debug_infos = 1;
00078 else
00079 ra_print_debug_infos = 0;
00080 ra_in_error = 0;
00081
00082 set_endian_type();
00083
00084 ra = malloc(sizeof(*ra));
00085 if (ra == NULL)
00086 return NULL;
00087 memset(ra, 0, sizeof(*ra));
00088 ra->handle_id = RA_HANDLE_LIB;
00089 _ra_set_error(ra, RA_ERR_NONE, "libRASCH");
00090
00091 ra->hf.get_plugin = get_plugin_by_name;
00092 if ((ret = read_config(ra)) != 0)
00093 {
00094 if (ret == -1)
00095 _ra_set_error(ra, RA_WARN_NO_CONFIG_FILE, "libRASCH");
00096 else
00097 _ra_set_error(ra, RA_ERR_READ_CONFIG, "libRASCH");
00098 return (ra_handle)ra;
00099 }
00100
00101
00102
00103
00104 init_i18n(ra);
00105
00106 close_plugins(ra->pl_head);
00107 if (read_plugins(ra) != 0)
00108 {
00109 _ra_set_error(ra, RA_ERR_LOAD_PLUGINS, "libRASCH");
00110 return (ra_handle)ra;
00111 }
00112
00113 return (ra_handle)ra;
00114 }
00115
00116
00123 void
00124 set_endian_type()
00125 {
00126 short s;
00127 char *t;
00128
00129 s = 'U'*256 + 'N';
00130
00131 t = (char *)&s;
00132 if (*t == 'N')
00133 ra_endian_type = RA_LITTLE_ENDIAN;
00134 else
00135 ra_endian_type = RA_BIG_ENDIAN;
00136 }
00137
00138
00148 void
00149 init_i18n(struct librasch *ra)
00150 {
00151 const char *l = NULL;
00152
00153
00154 if (ra_print_debug_infos)
00155 return;
00156
00157 l = setlocale(LC_MESSAGES, "");
00158 if(l)
00159 {
00160 char *p = NULL;
00161 char *buf;
00162
00163 buf = malloc(strlen(l)+1);
00164 strcpy(buf, l);
00165 p = strrchr(buf, '.');
00166 if (p)
00167 {
00168
00169
00170 if ((*(p+1) >= '0') && (*(p+1) <= '9') && (strlen(p+1) < (MAX_I18N_LEN-3)))
00171 sprintf(ra_i18n_codeset, "CP%s", p+1);
00172 else
00173 strncpy(ra_i18n_codeset, p+1, MAX_I18N_LEN);
00174 }
00175 else
00176 ra_i18n_codeset[0] = '\0';
00177 free(buf);
00178 }
00179 bindtextdomain(PACKAGE, ra->config.po_dir);
00180 textdomain(PACKAGE);
00181 }
00182
00183
00189 LIBRAAPI int
00190 get_endian_type()
00191 {
00192 return ra_endian_type;
00193 }
00194
00195
00206 int
00207 read_config(struct librasch *ra)
00208 {
00209 char fn[MAX_PATH_RA];
00210 xmlDocPtr doc;
00211 xmlNodePtr node;
00212 xmlChar *c;
00213
00214
00215 init_config(&(ra->config));
00216
00217 #ifdef WIN32
00218
00219
00220
00221
00222 if (read_win32_registry(ra) == 0)
00223 return 0;
00224 #endif
00225
00226 if (!find_config_file(fn))
00227 return -1;
00228
00229 if (ra_print_debug_infos)
00230 fprintf(stderr, gettext("config-file: %s\n"), fn);
00231 if ((doc = xmlParseFile(fn)) == NULL)
00232 return -2;
00233 if (!doc->children || (xmlStrcmp(doc->children->name, (xmlChar *)"librasch-config") != 0))
00234 {
00235 xmlFreeDoc(doc);
00236 return -2;
00237 }
00238
00239
00240 node = doc->children->children;
00241 while (node)
00242 {
00243 #ifdef _DEBUG
00244 if (xmlStrcmp(node->name, (xmlChar *)"plugin-path-debug") == 0)
00245 #else
00246 if (xmlStrcmp(node->name, (xmlChar *)"plugin-path") == 0)
00247 #endif
00248 {
00249 c = xmlNodeGetContent(node);
00250 if (c != NULL)
00251 {
00252 strncpy(ra->config.plugin_dir, (const char *)c, EVAL_MAX_NAME);
00253 if (ra_print_debug_infos)
00254 fprintf(stderr, gettext("config plugin-dir: %s\n"), c);
00255 xmlFree(c);
00256 }
00257 }
00258 else if (xmlStrcmp(node->name, (xmlChar *)"po-path") == 0)
00259 {
00260 c = xmlNodeGetContent(node);
00261 if (c != NULL)
00262 {
00263 strncpy(ra->config.po_dir, (const char *)c, EVAL_MAX_NAME);
00264 if (ra_print_debug_infos)
00265 fprintf(stderr, gettext("po-dir: %s\n"), ra->config.po_dir);
00266 xmlFree(c);
00267 }
00268 }
00269 node = node->next;
00270 }
00271
00272 xmlFreeDoc(doc);
00273
00274 return 0;
00275 }
00276
00277
00285 void
00286 init_config(struct config_info *conf)
00287 {
00288 char curr_dir[MAX_PATH_RA];
00289
00290 sprintf(curr_dir, ".%c", SEPERATOR);
00291 strcpy(conf->plugin_dir, curr_dir);
00292
00293 strncpy(conf->po_dir, LOCALEDIR, MAX_PATH_RA);
00294 }
00295
00296
00304 #ifdef WIN32
00305 int
00306 read_win32_registry(struct librasch *ra)
00307 {
00308 int ret = -1;
00309 HKEY key;
00310 DWORD size, type;
00311
00312
00313 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\libRASCH", 0, KEY_READ, &key) != ERROR_SUCCESS)
00314 return -1;
00315
00316 size = MAX_PATH_RA;
00317 type = REG_SZ;
00318 #ifdef _DEBUG
00319 if (RegQueryValueEx(key, "plugin_path_debug", 0, &type, (LPBYTE)(ra->config.plugin_dir), &size) == ERROR_SUCCESS)
00320 ret = 0;
00321 #else
00322 if (RegQueryValueEx(key, "plugin_path", 0, &type, (LPBYTE)(ra->config.plugin_dir), &size) == ERROR_SUCCESS)
00323 ret = 0;
00324 #endif
00325
00326 if (RegQueryValueEx(key, "po_path", 0, &type, (LPBYTE)(ra->config.po_dir), &size) == ERROR_SUCCESS)
00327 ret = 0;
00328
00329 RegCloseKey(key);
00330
00331 return ret;
00332 }
00333 #endif
00334
00335
00345 int
00346 find_config_file(char *fn)
00347 {
00348 FILE *fp = NULL;
00349 int found = 0;
00350
00351
00352 sprintf(fn, ".%clibrasch.conf", SEPERATOR);
00353
00354 fp = fopen(fn, "r");
00355 #ifdef LINUX
00356 if (!fp)
00357 {
00358
00359
00360 sprintf(fn, "%s/librasch.conf", getenv("HOME"));
00361 fp = fopen(fn, "r");
00362
00363 }
00364 #endif
00365 if (!fp)
00366 {
00367
00368 #ifdef LINUX
00369 sprintf(fn, "/etc/librasch.conf");
00370 #else
00371 GetWindowsDirectory(fn, MAX_PATH_RA);
00372 strcat(fn, "\\librasch.conf");
00373 #endif
00374 fp = fopen(fn, "r");
00375 }
00376
00377 if (fp)
00378 {
00379 found = 1;
00380 fclose(fp);
00381 }
00382
00383 return found;
00384 }
00385
00386
00393 LIBRAAPI void
00394 ra_lib_close(ra_handle h)
00395 {
00396 struct librasch *ra = (struct librasch *)h;
00397
00398 close_plugins(ra->pl_head);
00399
00400 if (ra->error_from)
00401 {
00402 free(ra->error_from);
00403 ra->error_from = NULL;
00404 }
00405
00406 free(ra);
00407 }
00408
00409
00422 LIBRAAPI long
00423 ra_lib_get_error(ra_handle h, char *text, int len)
00424 {
00425 struct librasch *ra = (struct librasch *)h;
00426
00427 if (!h || (ra->error_number == 0))
00428 return 0;
00429
00430 if (text && len > 0)
00431 {
00432 char *t;
00433 int len_use;
00434
00435 if (ra->error_from)
00436 len_use = len - strlen(ra->error_from) - 2;
00437 else
00438 len_use = len;
00439
00440 if (len_use <= 0)
00441 {
00442 strncpy(text, ra->error_from, len);
00443 text[len-1] = '\0';
00444 return ra->error_number;
00445 }
00446
00447 t = malloc(len_use);
00448
00449 get_error_text(ra->error_number, t, len_use);
00450
00451 if (ra->error_from)
00452 sprintf(text, "%s: %s", ra->error_from, t);
00453 else
00454 strcpy(text, t);
00455
00456 free(t);
00457
00458 utf8_to_local_inplace(text, len);
00459 }
00460
00461 return ra->error_number;
00462 }
00463
00464
00473 #ifdef WIN32
00474 void
00475 get_error_text(long err, char *text, int len)
00476 {
00477 text[0] = '\0';
00478
00479 if (err > 0)
00480 get_error_text_ra(err, text, len);
00481 else
00482 {
00483 LPVOID msg_buf;
00484
00485 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
00486 NULL, -err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msg_buf, 0, NULL))
00487 {
00488 return;
00489 }
00490
00491 strncpy(text, (LPCTSTR)msg_buf, len);
00492 LocalFree(msg_buf);
00493 }
00494 }
00495 #endif
00496
00497
00498 #ifdef LINUX
00499 void
00500 get_error_text(long err, char *text, int len)
00501 {
00502 text[0] = '\0';
00503
00504 if (err > 0)
00505 get_error_text_ra(err, text, len);
00506 else
00507 strerror_r(-err, text, len);
00508 }
00509 #endif
00510
00511
00520 void
00521 get_error_text_ra(long err, char *text, int len)
00522 {
00523 const char *c;
00524
00525 if (err <= 0)
00526 return;
00527
00528 if (err <= ra_num_error_text)
00529 {
00530 c = ra_error_text[err-1];
00531
00532 strncpy(text, (c[0]=='\0' ? "" : gettext(c)), len);
00533 }
00534 else if ((err > RA_WARNING) && ((err - RA_WARNING) <= ra_num_warning_text))
00535 {
00536 c = ra_warning_text[err - RA_WARNING - 1];
00537
00538 strncpy(text, (c[0]=='\0' ? "" : gettext(c)), len);
00539 }
00540 }
00541
00542
00555 LIBRAAPI void
00556 _ra_set_error_int(any_handle h, long error, const char *error_from, const char *file, int line)
00557 {
00558 struct librasch *ra;
00559
00560 if (ra_in_error)
00561 {
00562 fprintf(stderr, gettext("circular set_error-calling, this should NOT happen\n"));
00563 return;
00564 }
00565
00566 ra_in_error = 1;
00567
00568 if (!h)
00569 return;
00570
00571
00572 ra = (struct librasch *)ra_lib_handle_from_any_handle(h);
00573 if (!ra)
00574 {
00575 ra_in_error = 0;
00576 return;
00577 }
00578
00579 if (ra->error_from)
00580 {
00581 free(ra->error_from);
00582 ra->error_from = NULL;
00583 }
00584 if (error_from || file)
00585 {
00586 ra->error_from = malloc(strlen(error_from)+strlen(file)+4+10);
00587 ra->error_from[0] = '\0';
00588 if (error_from)
00589 strcat(ra->error_from, error_from);
00590 if (file)
00591 {
00592 char t[20];
00593
00594 if (error_from)
00595 strcat(ra->error_from, " (");
00596 strcat(ra->error_from, file);
00597
00598 sprintf(t, ":%d", line);
00599 strcat(ra->error_from, t);
00600 if (error_from)
00601 strcat(ra->error_from, ")");
00602 }
00603 }
00604
00605
00606 if (error == 0)
00607 {
00608 #ifdef LINUX
00609 ra->error_number = -errno;
00610 #endif
00611 #ifdef WIN32
00612 ra->error_number = GetLastError();
00613 ra->error_number = -ra->error_number;
00614 #endif
00615 }
00616 else
00617 ra->error_number = error;
00618
00619 if (ra_print_debug_infos && (ra->error_number != RA_ERR_NONE))
00620 {
00621 char t[1000];
00622 long err_num;
00623
00624 err_num = ra_lib_get_error(ra, t, 1000);
00625 fprintf(stderr, "%s:%d - %s (%ld)\n", file, line, t, err_num);
00626 }
00627
00628 ra_in_error = 0;
00629 }
00630
00631
00638 LIBRAAPI ra_handle
00639 ra_lib_handle_from_any_handle(any_handle h)
00640 {
00641 unsigned short type = *((unsigned short *)h);
00642 struct ra_meas *meas;
00643 ra_handle ra = NULL;
00644
00645 switch (type)
00646 {
00647 case RA_HANDLE_LIB:
00648 ra = h;
00649 break;
00650 case RA_HANDLE_MEAS:
00651 case RA_HANDLE_REC:
00652 case RA_HANDLE_EVAL:
00653 case RA_HANDLE_EVAL_CLASS:
00654 case RA_HANDLE_EVAL_PROP:
00655 case RA_HANDLE_EVAL_SUMMARY:
00656 meas = ra_meas_handle_from_any_handle(h);
00657 if (meas)
00658 ra = meas->ra;
00659 break;
00660 case RA_HANDLE_PLUGIN:
00661 ra = ((struct plugin_struct *)h)->ra;
00662 break;
00663 case RA_HANDLE_PROC:
00664 ra = ((struct proc_info *)h)->ra;
00665 break;
00666 case RA_HANDLE_VIEW:
00667 ra = ((struct view_info *)h)->ra;
00668 break;
00669 case RA_HANDLE_FIND:
00670 default:
00671 break;
00672 }
00673
00674 return ra;
00675 }
00676
00677
00684 LIBRAAPI meas_handle
00685 ra_meas_handle_from_any_handle(any_handle h)
00686 {
00687 unsigned short type = *((unsigned short *)h);
00688 struct ra_rec *rec;
00689 struct eval *eval;
00690 struct eval_class *cl;
00691 struct eval_property *prop;
00692 struct eval_summary *sum;
00693 meas_handle mh = NULL;
00694
00695 if (h == NULL)
00696 return NULL;
00697
00698 switch (type)
00699 {
00700 case RA_HANDLE_MEAS:
00701 mh = h;
00702 break;
00703 case RA_HANDLE_REC:
00704 rec = (struct ra_rec *)h;
00705 mh = rec->meas;
00706 break;
00707 case RA_HANDLE_EVAL:
00708 eval = (struct eval *)h;
00709 mh = eval->meas;
00710 break;
00711 case RA_HANDLE_EVAL_CLASS:
00712 cl = (struct eval_class *)h;
00713 mh = cl->meas;
00714 break;
00715 case RA_HANDLE_EVAL_PROP:
00716 prop = (struct eval_property *)h;
00717 mh = prop->meas;
00718 break;
00719 case RA_HANDLE_EVAL_SUMMARY:
00720 sum = (struct eval_summary *)h;
00721 mh = sum->meas;
00722 break;
00723 default:
00724 _ra_set_error(h, RA_ERR_UNKNOWN_HANDLE, "libRASCH");
00725 break;
00726 }
00727
00728 return mh;
00729 }
00730
00731
00740 LIBRAAPI int
00741 ra_lib_use_plugin(ra_handle h, int plugin_index, int use_it)
00742 {
00743 struct librasch *ra = (struct librasch *)h;
00744 struct plugin_struct *p = get_plugin(ra, plugin_index);
00745
00746 if (!p)
00747 {
00748 _ra_set_error(h, RA_ERR_UNKNOWN_PLUGIN, "libRASCH");
00749 return -1;
00750 }
00751
00752 p->info.use_plugin = use_it;
00753
00754 return 0;
00755 }
00756
00757
00765 struct plugin_struct *
00766 get_plugin(struct librasch *ra, int number)
00767 {
00768 struct plugin_struct *p = ra->pl_head;
00769 int cnt = number;
00770
00771 while (p && cnt--)
00772 p = p->next;
00773
00774 return p;
00775 }
00776
00777
00785 struct plugin_struct *
00786 get_plugin_by_name(struct librasch *ra, const char *name)
00787 {
00788 struct plugin_struct *p = ra->pl_head;
00789 while (p && (strcmp(p->info.name, name) != 0))
00790 p = p->next;
00791 return p;
00792 }
00793
00794
00803 LIBRAAPI plugin_handle
00804 ra_plugin_get_by_num(ra_handle h, int plugin_num, int search_all)
00805 {
00806 struct librasch *ra = (struct librasch *)h;
00807 struct plugin_struct *p = get_plugin(ra, plugin_num);
00808
00809 if (p && !search_all && !p->info.use_plugin)
00810 {
00811 _ra_set_error(h, RA_ERR_UNKNOWN_PLUGIN, "libRASCH");
00812 p = NULL;
00813 }
00814
00815 return p;
00816 }
00817
00818
00827 LIBRAAPI plugin_handle
00828 ra_plugin_get_by_name(ra_handle h, const char *name, int search_all)
00829 {
00830 struct librasch *ra = (struct librasch *)h;
00831 struct plugin_struct *p = NULL;
00832 char *name_utf8;
00833
00834 if (!h)
00835 {
00836 _ra_set_error(h, RA_ERR_ERROR_INTERNAL, "libRASCH");
00837 return NULL;
00838 }
00839
00840 name_utf8 = malloc(strlen(name) * 2);
00841 local_to_utf8(name, name_utf8, strlen(name) * 2);
00842 p = get_plugin_by_name(ra, name_utf8);
00843 free(name_utf8);
00844
00845 if (p && !search_all && !p->info.use_plugin)
00846 {
00847 _ra_set_error(h, RA_ERR_UNKNOWN_PLUGIN, "libRASCH");
00848 p = NULL;
00849 }
00850
00851 return p;
00852 }
00853
00854
00864 LIBRAAPI ra_find_handle
00865 ra_meas_find_first(ra_handle h, const char *dir, struct ra_find_struct *rfs)
00866 {
00867 char *dir_utf8;
00868 struct plugin_struct *p = ((struct librasch *)h)->pl_head;
00869 struct find_meas *f = calloc(1, sizeof(struct find_meas));
00870 f->handle_id = RA_HANDLE_FIND;
00871
00872 dir_utf8 = malloc(strlen(dir) * 2);
00873 local_to_utf8(dir, dir_utf8, strlen(dir) * 2);
00874
00875 while (p)
00876 {
00877
00878 if (!p->info.use_plugin || !p->access.find_meas)
00879 {
00880 p = p->next;
00881 continue;
00882 }
00883
00884
00885 (*p->access.find_meas) (dir_utf8, f);
00886
00887
00888 p = p->next;
00889 }
00890
00891 free(dir_utf8);
00892
00893 if (f->num <= 0)
00894 {
00895 free(f);
00896 f = NULL;
00897 }
00898 else
00899 {
00900 strcpy(rfs->name, f->names[f->curr]);
00901 utf8_to_local_inplace(rfs->name, MAX_PATH_RA);
00902 f->curr++;
00903 }
00904
00905 return (ra_find_handle) f;
00906 }
00907
00908
00917 LIBRAAPI int
00918 ra_meas_find_next(ra_find_handle h, struct ra_find_struct *rfs)
00919 {
00920 struct find_meas *f = (struct find_meas *)h;
00921 f->handle_id = RA_HANDLE_FIND;
00922
00923 if (!f || (f->curr >= f->num))
00924 return 0;
00925
00926 strcpy(rfs->name, f->names[f->curr]);
00927 utf8_to_local_inplace(rfs->name, MAX_PATH_RA);
00928 f->curr++;
00929
00930 return 1;
00931 }
00932
00933
00941 LIBRAAPI void
00942 ra_meas_close_find(ra_find_handle h)
00943 {
00944 int i;
00945 struct find_meas *f = (struct find_meas *)h;
00946
00947 if (f == NULL)
00948 return;
00949
00950 if (f->names != NULL)
00951 {
00952 for (i = 0; i < f->num; i++)
00953 {
00954 if (f->names[i] != NULL)
00955 ra_free_mem(f->names[i]);
00956 }
00957 ra_free_mem(f->names);
00958 }
00959 free(f);
00960 }
00961
00962
00975 LIBRAAPI meas_handle
00976 ra_meas_open(ra_handle h, const char *file, const char *eval_file, int fast)
00977 {
00978 struct librasch *ra = (struct librasch *)h;
00979 struct plugin_struct *p;
00980 meas_handle mh = NULL;
00981 struct ra_meas *meas = NULL;
00982 char *file_utf8;
00983 char *eval_file_utf8 = NULL;
00984
00985 if (!ra)
00986 return NULL;
00987
00988 p = ra->pl_head;
00989
00990 file_utf8 = malloc(strlen(file) * 2);
00991 local_to_utf8(file, file_utf8, strlen(file) * 2);
00992 if (eval_file != NULL)
00993 {
00994 eval_file_utf8 = malloc(strlen(eval_file) * 2);
00995 local_to_utf8(eval_file, eval_file_utf8, strlen(eval_file) * 2);
00996 }
00997
00998 while (p)
00999 {
01000
01001 if (!p->info.use_plugin || !p->access.open_meas
01002 || !p->access.check_meas)
01003 {
01004 p = p->next;
01005 continue;
01006 }
01007
01008
01009 if ((*p->access.check_meas)(file_utf8))
01010 {
01011
01012 mh = (*p->access.open_meas)(h, file_utf8);
01013 if (mh)
01014 {
01015 meas = (struct ra_meas *)mh;
01016 meas->handle_id = RA_HANDLE_MEAS;
01017
01018
01019 meas->ra = h;
01020
01021 meas->p = p;
01022
01023 calc_x_scales(meas);
01024
01025
01026 if (eval_file != NULL)
01027 strncpy(meas->eval.filename, eval_file_utf8, MAX_PATH_RA);
01028 else
01029 meas->eval.filename[0] = '\0';
01030
01031 load_eval(mh, eval_file_utf8);
01032 read_evaluation(mh);
01033
01034 break;
01035 }
01036 }
01037
01038
01039 p = p->next;
01040 }
01041 free(file_utf8);
01042 free(eval_file_utf8);
01043
01044 if (meas == NULL)
01045 _ra_set_error(ra, RA_ERR_UNSUP_FORMAT, "libRASCH");
01046
01047 return meas;
01048 }
01049
01050
01058 int
01059 calc_x_scales(struct ra_meas *meas)
01060 {
01061 value_handle vh;
01062 rec_handle rh;
01063 int i;
01064
01065 vh = ra_value_malloc();
01066 rh = ra_rec_get_first(meas, 0);
01067
01068 if (ra_info_get(rh, RA_INFO_REC_GEN_NUM_CHANNEL_L, vh) == 0)
01069 meas->num_ch = ra_value_get_long(vh);
01070
01071 if (meas->num_ch <= 0)
01072 {
01073 meas->max_samplerate = 1.0;
01074 ra_value_free(vh);
01075
01076 return 0;
01077 }
01078
01079 meas->x_scale = malloc(sizeof(double) * meas->num_ch);
01080 memset(meas->x_scale, 0, sizeof(double) * meas->num_ch);
01081
01082 meas->max_samplerate = 0.0;
01083 for (i = 0; i < meas->num_ch; i++)
01084 {
01085 ra_value_set_number(vh, i);
01086 if (ra_info_get(rh, RA_INFO_REC_CH_SAMPLERATE_D, vh) != 0)
01087 continue;
01088
01089 meas->x_scale[i] = ra_value_get_double(vh);
01090 if (meas->max_samplerate < meas->x_scale[i])
01091 meas->max_samplerate = meas->x_scale[i];
01092 }
01093 ra_value_free(vh);
01094
01095 for (i = 0; i < meas->num_ch; i++)
01096 meas->x_scale[i] /= meas->max_samplerate;
01097
01098 return 0;
01099 }
01100
01101
01113 LIBRAAPI meas_handle
01114 ra_meas_new(ra_handle h, const char *dir, const char *name)
01115 {
01116 struct librasch *ra = (struct librasch *)h;
01117 plugin_handle pl;
01118 struct plugin_struct *p;
01119 meas_handle mh = NULL;
01120 struct ra_meas *meas = NULL;
01121 char *dir_utf8;
01122 char *name_utf8;
01123
01124
01125 pl = ra_plugin_get_by_name(h, "rasch-file", 0);
01126 if (!pl)
01127 return NULL;
01128 p = (struct plugin_struct *)pl;
01129
01130
01131 if (!p->access.new_meas)
01132 {
01133 _ra_set_error(h, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01134 return NULL;
01135 }
01136
01137 dir_utf8 = malloc(strlen(dir) * 2);
01138 local_to_utf8(dir, dir_utf8, strlen(dir) * 2);
01139 name_utf8 = malloc(strlen(name) * 2);
01140 local_to_utf8(name, name_utf8, strlen(name) * 2);
01141
01142 mh = (*p->access.new_meas)(dir_utf8, name_utf8);
01143 if (!mh)
01144 goto error;
01145
01146
01147 meas = (struct ra_meas *)mh;
01148 meas->handle_id = RA_HANDLE_MEAS;
01149
01150 meas->ra = ra;
01151
01152 meas->p = p;
01153
01154 calc_x_scales(meas);
01155
01156 error:
01157 free(dir_utf8);
01158 free(name_utf8);
01159
01160 return meas;
01161 }
01162
01163
01164
01173 LIBRAAPI int
01174 ra_meas_save(meas_handle mh)
01175 {
01176
01177 int ret = -1;
01178 unsigned short type = *((unsigned short *)mh);
01179
01180 if (type == RA_HANDLE_MEAS)
01181 {
01182 struct plugin_struct *p = ((struct ra_meas *)mh)->p;
01183
01184 if (p->access.save_meas)
01185 ret = (*p->access.save_meas)(mh);
01186 else
01187 _ra_set_error(mh, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01188 }
01189 else
01190 _ra_set_error(mh, RA_ERR_WRONG_HANDLE, "libRASCH");
01191
01192 return ret;
01193 }
01194
01195
01202 LIBRAAPI void
01203 ra_meas_close(meas_handle mh)
01204 {
01205 long l;
01206 struct ra_meas *meas = (struct ra_meas *) mh;
01207 struct plugin_struct *p = NULL;
01208
01209 if (!mh)
01210 return;
01211 p = meas->p;
01212
01213 free_eval_infos(&(meas->eval));
01214
01215
01216 if (p->access.close_meas)
01217 (*p->access.close_meas) (mh);
01218
01219 if (meas->sessions)
01220 {
01221 for (l = 0; l < meas->num_sessions; l++)
01222 free_session_rec(meas->sessions[l].root_rec);
01223 ra_free_mem(meas->sessions);
01224 meas->num_sessions = 0;
01225 }
01226
01227 if (meas->x_scale)
01228 free(meas->x_scale);
01229
01230 ra_free_mem(meas);
01231 }
01232
01233
01243 LIBRAAPI int
01244 ra_info_get(any_handle h, int id, value_handle vh)
01245 {
01246 unsigned short type;
01247 struct plugin_struct *p;
01248
01249
01250 ra_value_reset(vh);
01251
01252 if (!h || (id < 0) || !vh)
01253 return -1;
01254
01255 if (check_handle_type(h, id) != 0)
01256 return -1;
01257
01258 type = *((unsigned short *)h);
01259
01260 if (type == RA_HANDLE_LIB)
01261 return get_lib_info((ra_handle)h, id, vh);
01262
01263 if (type == RA_HANDLE_PLUGIN)
01264 return get_plugin_info((plugin_handle)h, id, vh);
01265
01266 if ((type == RA_HANDLE_MEAS) && (id > RA_INFO_MEASUREMENT_START) && (id < RA_INFO_MEASUREMENT_END))
01267 return get_meas_general_info((meas_handle)h, id, vh);
01268
01269 if ((id > RA_INFO_EVALUATION) && (id < RA_INFO_EVALUATION_END))
01270 return eval_get_info(h, id, vh);
01271
01272 if ((id > RA_INFO_SESSION_START) && (id < RA_INFO_SESSION_END))
01273 return get_session_info(h, id, vh);
01274
01275 if ((id > RA_INFO_PROCESSING_START) && (id < RA_INFO_PROCESSING_END))
01276 return get_proc_info(h, id, vh);
01277
01278 p = get_plugin_from_handle(h);
01279 if (!p)
01280 return -1;
01281
01282 if (p->access.get_info_id)
01283 return (*p->access.get_info_id)(h, id, vh);
01284 else
01285 _ra_set_error(h, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01286
01287 return -1;
01288 }
01289
01290
01298 int
01299 check_handle_type(any_handle h, int id)
01300 {
01301 int ret = -1;
01302 unsigned short type = *((unsigned short *)h);
01303
01304 switch (type)
01305 {
01306 case RA_HANDLE_LIB:
01307 if ((id > RA_INFO_LIB_START) && (id < RA_INFO_LIB_END))
01308 ret = 0;
01309 break;
01310 case RA_HANDLE_MEAS:
01311 if ((id > RA_INFO_MEASUREMENT_START) && (id < RA_INFO_OBJECT_END))
01312 ret = 0;
01313 break;
01314 case RA_HANDLE_REC:
01315 if ((id > RA_INFO_RECORDING_START) && (id < RA_INFO_RECORDING_END))
01316 ret = 0;
01317 break;
01318 case RA_HANDLE_FIND:
01319 if ((id > RA_INFO_MEASUREMENT_START) && (id < RA_INFO_OBJECT_END))
01320 ret = 0;
01321 break;
01322 case RA_HANDLE_EVAL:
01323 if ((id > RA_INFO_EVAL_START) && (id < RA_INFO_EVAL_END))
01324 ret = 0;
01325 break;
01326 case RA_HANDLE_EVAL_CLASS:
01327 if ((id > RA_INFO_CLASS_START) && (id < RA_INFO_CLASS_END))
01328 ret = 0;
01329 break;
01330 case RA_HANDLE_EVAL_PROP:
01331 if ((id > RA_INFO_PROP_START) && (id < RA_INFO_PROP_END))
01332 ret = 0;
01333 break;
01334 case RA_HANDLE_EVAL_SUMMARY:
01335 if ((id > RA_INFO_SUM_START) && (id < RA_INFO_SUM_END))
01336 ret = 0;
01337 break;
01338 case RA_HANDLE_PLUGIN:
01339 if ((id > RA_INFO_PLUGIN_START) && (id < RA_INFO_PLUGIN_END))
01340 ret = 0;
01341 break;
01342 case RA_HANDLE_PROC:
01343 if ((id > RA_INFO_PROCESSING_START) && (id < RA_INFO_PROCESSING_END))
01344 ret = 0;
01345 break;
01346 case RA_HANDLE_VIEW:
01347 _ra_set_error(h, RA_ERR_UNSUPPORTED, "libRASCH");
01348 break;
01349 default:
01350 _ra_set_error(h, RA_ERR_UNKNOWN_HANDLE, "libRASCH");
01351 break;
01352 }
01353
01354 return ret;
01355 }
01356
01357
01366 int
01367 get_lib_info(ra_handle ra, int id, value_handle vh)
01368 {
01369 int ret = 0;
01370 long cnt;
01371 struct plugin_struct *p;
01372 struct meta_info *meta_inf;
01373 char t[1000];
01374
01375
01376 meta_inf = get_meta_info(id);
01377
01378 if (!ra || !meta_inf || (id <= RA_INFO_LIB_START) || (id >= RA_INFO_LIB_END))
01379 {
01380 _ra_set_error(ra, RA_ERR_UNKNOWN_INFO, "libRASCH");
01381 return -1;
01382 }
01383 set_meta_info(vh, meta_inf->name, meta_inf->desc, meta_inf->id);
01384
01385 switch (id)
01386 {
01387 case RA_INFO_NUM_PLUGINS_L:
01388 p = ((struct librasch *)ra)->pl_head;
01389 cnt = 0;
01390 while (p)
01391 {
01392 cnt++;
01393 p = p->next;
01394 }
01395 ra_value_set_long(vh, cnt);
01396 break;
01397 case RA_INFO_VERSION_C:
01398 sprintf(t, "%d.%d.%d%s", LIBRASCH_MAJ_VERSION, LIBRASCH_MIN_VERSION, LIBRASCH_PATCH_LEVEL, LIBRASCH_EXTRA_VERSION);
01399 ra_value_set_string_utf8(vh, t);
01400 break;
01401 default:
01402 _ra_set_error(ra, RA_ERR_UNKNOWN_INFO, "libRASCH");
01403 ret = -1;
01404 break;
01405 }
01406
01407 return ret;
01408 }
01409
01410
01419 int
01420 get_plugin_info(plugin_handle pl, int id, value_handle vh)
01421 {
01422 int ret = 0;
01423 struct ra_value *v = (struct ra_value *)vh;
01424 struct plugin_struct *p = (struct plugin_struct *)pl;
01425 struct meta_info *meta_inf;
01426 const char *c;
01427
01428
01429 meta_inf = get_meta_info(id);
01430
01431 if (!pl || !meta_inf || (id <= RA_INFO_PLUGIN_START) || (id >= RA_INFO_PLUGIN_END))
01432 {
01433 _ra_set_error(pl, RA_ERR_UNKNOWN_INFO, "libRASCH");
01434 return -1;
01435 }
01436
01437 if (((id >= RA_INFO_PL_RES_NAME_C) && (id <= RA_INFO_PL_RES_DEFAULT_L))
01438 && ((v->number < 0) || (v->number >= p->info.num_results)))
01439 {
01440 _ra_set_error(pl, RA_ERR_UNKNOWN_INFO, "libRASCH");
01441 return -1;
01442 }
01443
01444 if (((id >= RA_INFO_PL_OPT_NAME_C) && (id <= RA_INFO_PL_OPT_TYPE_L))
01445 && ((v->number < 0) || (v->number >= p->info.num_options)))
01446 {
01447 _ra_set_error(pl, RA_ERR_UNKNOWN_INFO, "libRASCH");
01448 return -1;
01449 }
01450
01451
01452 if (((id >= RA_INFO_PL_RES_NAME_C) && (id <= RA_INFO_PL_RES_DEFAULT_L)) && (p->info.res == NULL))
01453 {
01454 fprintf(stderr, gettext("critical error - get_plugin_info() in ra.c:\ntried to get result-infos but mem was not set\nplugin used: %s\n"), p->info.name);
01455 exit(-1);
01456
01457
01458 }
01459 if (((id >= RA_INFO_PL_OPT_NAME_C) && (id <= RA_INFO_PL_OPT_TYPE_L)) && (p->info.opt == NULL))
01460 {
01461 fprintf(stderr, gettext("critical error - get_plugin_info() in ra.c:\ntried to get option-infos but mem was not set\nplugin used: %s\n"), p->info.name);
01462 exit(-1);
01463
01464
01465 }
01466
01467 set_meta_info(vh, meta_inf->name, meta_inf->desc, meta_inf->id);
01468
01469 switch (id)
01470 {
01471 case RA_INFO_PL_NAME_C:
01472 ra_value_set_string_utf8(vh, p->info.name);
01473 break;
01474 case RA_INFO_PL_DESC_C:
01475 ra_value_set_string_utf8(vh, p->info.desc);
01476 break;
01477 case RA_INFO_PL_FILE_C:
01478 ra_value_set_string_utf8(vh, p->info.file);
01479 break;
01480 case RA_INFO_PL_USE_IT_L:
01481 ra_value_set_long(vh, p->info.use_plugin);
01482 break;
01483 case RA_INFO_PL_TYPE_L:
01484 ra_value_set_long(vh, p->info.type);
01485 break;
01486 case RA_INFO_PL_VERSION_C:
01487 ra_value_set_string_utf8(vh, p->info.version);
01488 break;
01489 case RA_INFO_PL_BUILD_TS_C:
01490 ra_value_set_string_utf8(vh, p->info.build_ts);
01491 break;
01492 case RA_INFO_PL_LICENSE_L:
01493 ra_value_set_long(vh, p->info.license);
01494 break;
01495 case RA_INFO_PL_NUM_OPTIONS_L:
01496 ra_value_set_long(vh, p->info.num_options);
01497 break;
01498 case RA_INFO_PL_OPT_NAME_C:
01499 c = p->info.opt[v->number].name;
01500 ra_value_set_string_utf8(vh, (c[0]=='\0' ? "" : gettext(c)));
01501 break;
01502 case RA_INFO_PL_OPT_DESC_C:
01503 c = p->info.opt[v->number].desc;
01504 ra_value_set_string_utf8(vh, (c[0]=='\0' ? "" : gettext(c)));
01505 break;
01506 case RA_INFO_PL_OPT_TYPE_L:
01507 ra_value_set_long(vh, p->info.opt[v->number].type);
01508 break;
01509 case RA_INFO_PL_NUM_RESULTS_L:
01510 ra_value_set_long(vh, p->info.num_results);
01511 break;
01512 case RA_INFO_PL_RES_NAME_C:
01513 c = p->info.res[v->number].name;
01514 ra_value_set_string_utf8(vh, (c[0]=='\0' ? "" : gettext(c)));
01515 break;
01516 case RA_INFO_PL_RES_DESC_C:
01517 c = p->info.res[v->number].desc;
01518 ra_value_set_string_utf8(vh, (c[0]=='\0' ? "" : gettext(c)));
01519 break;
01520 case RA_INFO_PL_RES_TYPE_L:
01521 ra_value_set_long(vh, p->info.res[v->number].type);
01522 break;
01523 case RA_INFO_PL_RES_DEFAULT_L:
01524 ra_value_set_long(vh, p->info.res[v->number].def);
01525 break;
01526 default:
01527 _ra_set_error(pl, RA_ERR_UNKNOWN_INFO, "libRASCH");
01528 ret = -1;
01529 break;
01530 }
01531
01532 return ret;
01533 }
01534
01535
01544 int
01545 get_meas_general_info(meas_handle mh, int id, value_handle vh)
01546 {
01547 int ret = 0;
01548 struct ra_meas *meas = (struct ra_meas *)mh;
01549 struct ra_value *v = (struct ra_value *)vh;
01550 struct meta_info *meta_inf;
01551
01552
01553 meta_inf = get_meta_info(id);
01554
01555 if (!meas || !meta_inf || (id <= RA_INFO_MEASUREMENT_START) || (id >= RA_INFO_MEASUREMENT_END))
01556 {
01557 _ra_set_error(mh, RA_ERR_UNKNOWN_INFO, "libRASCH");
01558 return -1;
01559 }
01560
01561 set_meta_info(vh, meta_inf->name, meta_inf->desc, meta_inf->id);
01562
01563 if (id == RA_INFO_NUM_SESSIONS_L)
01564 ra_value_set_long(vh, meas->num_sessions);
01565 else if (id == RA_INFO_MAX_SAMPLERATE_D)
01566 ra_value_set_double(vh, meas->max_samplerate);
01567 else if (id == RA_INFO_CH_XSCALE_D)
01568 {
01569 if (v->number >= meas->num_ch)
01570 {
01571 _ra_set_error(mh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01572 return -1;
01573 }
01574
01575 ra_value_set_double(vh, meas->x_scale[v->number]);
01576 }
01577 else
01578 {
01579 struct plugin_struct *p = get_plugin_from_handle(mh);
01580 if (!p)
01581 return -1;
01582
01583 if (p->access.get_info_id)
01584 ret = (*p->access.get_info_id)(mh, id, vh);
01585 else
01586 _ra_set_error(mh, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01587 }
01588
01589 return ret;
01590 }
01591
01592
01601 int
01602 get_session_info(any_handle h, int id, value_handle vh)
01603 {
01604 int ret = 0;
01605 struct ra_meas * meas;
01606 struct ra_value *v = (struct ra_value *)vh;
01607
01608 if ((id <= RA_INFO_SESSION_START) || (id >= RA_INFO_SESSION_END))
01609 return -1;
01610
01611 meas = (struct ra_meas *)ra_meas_handle_from_any_handle(h);
01612 if (!meas)
01613 return -1;
01614
01615 if (v->number >= meas->num_sessions)
01616 return -1;
01617
01618 switch (id)
01619 {
01620 case RA_INFO_SES_NAME_C:
01621 ra_value_set_string_utf8(vh, meas->sessions[v->number].name);
01622 break;
01623 case RA_INFO_SES_DESC_C:
01624 ra_value_set_string_utf8(vh, meas->sessions[v->number].desc);
01625 break;
01626 default:
01627 ret = -1;
01628 break;
01629 }
01630
01631 return ret;
01632 }
01633
01634
01643 int
01644 get_proc_info(any_handle h, int id, value_handle vh)
01645 {
01646 int ret = 0;
01647 struct proc_info *proc;
01648
01649 if ((id <= RA_INFO_PROCESSING_START) || (id >= RA_INFO_PROCESSING_END))
01650 return -1;
01651
01652 proc = (struct proc_info *)h;
01653 if (!proc)
01654 return -1;
01655
01656 switch (id)
01657 {
01658 case RA_INFO_PROC_NUM_RES_SETS_L:
01659 ra_value_set_long(vh, proc->num_result_sets);
01660 break;
01661 case RA_INFO_PROC_NUM_RES_L:
01662 ra_value_set_long(vh, proc->num_results);
01663 break;
01664 default:
01665 ret = -1;
01666 break;
01667 }
01668
01669 return ret;
01670 }
01671
01672
01679 struct plugin_struct *
01680 get_plugin_from_handle(any_handle h)
01681 {
01682 struct plugin_struct *p = NULL;
01683 unsigned short type = *((unsigned short *)h);
01684
01685 switch (type)
01686 {
01687 case RA_HANDLE_MEAS:
01688 p = ((struct ra_meas *)h)->p;
01689 break;
01690 case RA_HANDLE_REC:
01691 p = ((struct ra_rec *)h)->meas->p;
01692 break;
01693 case RA_HANDLE_EVAL:
01694 p = ((struct eval *)h)->meas->p;
01695 break;
01696 case RA_HANDLE_EVAL_CLASS:
01697 p = ((struct eval_class *)h)->meas->p;
01698 break;
01699 case RA_HANDLE_EVAL_PROP:
01700 p = ((struct eval_property *)h)->meas->p;
01701 break;
01702 case RA_HANDLE_EVAL_SUMMARY:
01703 p = ((struct eval_summary *)h)->meas->p;
01704 break;
01705 }
01706
01707 if (!p)
01708 _ra_set_error(h, RA_ERR_ERROR, "libRASCH");
01709
01710 return p;
01711 }
01712
01713
01723 LIBRAAPI int
01724 ra_info_get_by_name(any_handle h, const char *name, value_handle vh)
01725 {
01726 char *name_utf8;
01727
01728 name_utf8 = malloc(strlen(name) * 2);
01729 local_to_utf8(name, name_utf8, strlen(name) * 2);
01730
01731 if (find_ra_info_by_name(vh, name_utf8) != 0)
01732 return -1;
01733
01734 return ra_info_get(h, ra_value_get_info(vh), vh);
01735 }
01736
01737
01748 LIBRAAPI int
01749 ra_info_get_by_idx(any_handle h, int info_type, int idx, value_handle vh)
01750 {
01751 struct plugin_struct *p;
01752
01753
01754 ra_value_reset(vh);
01755
01756 if ((h == NULL) || (idx < 0) || (vh == NULL))
01757 {
01758 _ra_set_error(h, RA_ERR_UNKNOWN_INFO, "libRASCH");
01759 return -1;
01760 }
01761
01762 p = get_plugin_from_handle(h);
01763 if (!p)
01764 return -1;
01765
01766 if (p->access.get_info_idx)
01767 return (*p->access.get_info_idx)(h, info_type, idx, vh);
01768 else
01769 _ra_set_error(h, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01770
01771 return -1;
01772 }
01773
01774
01782 LIBRAAPI int
01783 ra_info_set(any_handle h, value_handle vh)
01784 {
01785 struct meta_info *meta_inf;
01786 struct ra_value *v = (struct ra_value *)vh;
01787 struct plugin_struct *p;
01788
01789 p = get_plugin_from_handle(h);
01790 if (!p)
01791 return -1;
01792
01793
01794 meta_inf = get_meta_info(v->id);
01795
01796
01797 if ((v == NULL) || (meta_inf == NULL))
01798 {
01799 _ra_set_error(h, RA_ERR_UNKNOWN_INFO, "libRASCH");
01800 return -1;
01801 }
01802
01803 set_meta_info(vh, meta_inf->name, meta_inf->desc, meta_inf->id);
01804
01805 if (p->access.set_info)
01806 return (*p->access.set_info)(h, vh);
01807 else
01808 _ra_set_error(h, RA_ERR_PL_API_NOT_AVAIL, "libRASCH");
01809
01810 return -1;
01811 }
01812
01813
01821 LIBRAAPI rec_handle
01822 ra_rec_get_first(meas_handle mh, long session)
01823 {
01824 struct ra_meas *meas = (struct ra_meas *) mh;
01825
01826 if (!meas || (session < 0) || (session > meas->num_sessions))
01827 {
01828 _ra_set_error(mh, RA_ERR_OUT_OF_RANGE, "libRASCH");
01829 return NULL;
01830 }
01831
01832 return meas->sessions[session].root_rec;
01833 }
01834
01835
01842 LIBRAAPI rec_handle
01843 ra_rec_get_next(rec_handle rh)
01844 {
01845
01846 return ((struct ra_rec *) rh)->next;
01847 }
01848
01849
01856 LIBRAAPI rec_handle
01857 ra_rec_get_first_child(rec_handle rh)
01858 {
01859 return ((struct