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: ra.c Source File

ra.c

Go to the documentation of this file.
00001 
00010 /*--------------------------------------------------------------------------
00011  *
00012  * Copyright (C) 2002-2005, Raphael Schneider
00013  * See the file COPYING for information on usage and redistribution.
00014  *
00015  * $Id: ra.c 810 2005-05-22 10:16:48Z rasch $
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();  /* set global variable ra_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         /* set global variable ra_i18n_codeset;
00102            do it after reading the config because on Win32, the
00103            place of the translation will be set when installing libRASCH */
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 } /* ra_lib_init() */
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 } /* set_endian_type() */
00137 
00138 
00148 void
00149 init_i18n(struct librasch *ra)
00150 {
00151         const char *l = NULL;
00152 
00153         /* when in debug mode, do not set language so messages are not translated */
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                         /* when the charset startes with a number, then add 'CP' so iconv
00169                            understand the charset */
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 } /* init_i18n() */
00182 
00183 
00189 LIBRAAPI int
00190 get_endian_type()
00191 {
00192         return ra_endian_type;
00193 } /* get_endian_type() */
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         /* set configuration to values which work when no config-file is found */
00215         init_config(&(ra->config));
00216 
00217 #ifdef WIN32
00218         /* Under Win32 we try first to get the configuration from the
00219            Registry (because Visual Studio Installer allows to change
00220            Registry settings during install). If it fails to get infos
00221            from the Resgistr, try to get infos from a librasch.conf file. */
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         /* TODO: think about config structure */
00240         node = doc->children->children;
00241         while (node)
00242         {
00243 #ifdef _DEBUG                   /* only needed for Win32 to handle debug-build plugins */
00244                 if (xmlStrcmp(node->name, (xmlChar *)"plugin-path-debug") == 0)
00245 #else
00246                 if (xmlStrcmp(node->name, (xmlChar *)"plugin-path") == 0)
00247 #endif /* _DEBUG */
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 } /* read_config() */
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 } /* init_config() */
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         /* Check that libRASCH is installed */
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  /* _DEBUG */
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 } /* read_win32_registry() */
00333 #endif  /* WIN32 */
00334 
00335 
00345 int
00346 find_config_file(char *fn)
00347 {
00348         FILE *fp = NULL;
00349         int found = 0;
00350 
00351         /* first check current-dir */
00352         sprintf(fn, ".%clibrasch.conf", SEPERATOR);
00353 
00354         fp = fopen(fn, "r");
00355 #ifdef LINUX
00356         if (!fp)
00357         {
00358                 /* if not found in the current directory then check on Linux first
00359                    the HOME directory */
00360                 sprintf(fn, "%s/librasch.conf", getenv("HOME"));
00361                 fp = fopen(fn, "r");
00362                 
00363         }
00364 #endif  /* LINUX */
00365         if (!fp)
00366         {
00367                 /* now check /etc under LINUX resp. system-dir under Windows */
00368 #ifdef LINUX
00369                 sprintf(fn, "/etc/librasch.conf");
00370 #else /* WINDOWS */
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 } /* find_config_file() */
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 } /* ra_lib_close() */
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 } /* ra_lib_get_error() */
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 } /* get_error_text() */
00495 #endif /* WIN32 */
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 } /* get_error_text() */
00509 #endif /* LINUX
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 } /* get_error_text_ra() */
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         /* get pointer to struct librasch */
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         /* if error == 0 -> os error */
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 } /* _ra_set_error() */
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 } /* ra_lib_handle_from_any_handle() */
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 } /* ra_meas_handle_from_any_handle() */
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 } /* ra_lib_use_plugin() */
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 } /* get_plugin() */
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 } /* get_plugin_by_name() */
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 } /* ra_plugin_get_by_num() */
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 } /* ra_plugin_get_by_name() */
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                 /* use plugin and (find_meas() is assigned) ? */
00878                 if (!p->info.use_plugin || !p->access.find_meas)
00879                 {
00880                         p = p->next;
00881                         continue;
00882                 }
00883 
00884                 /* look for signals handled by current plugin in dir */
00885                 (*p->access.find_meas) (dir_utf8, f);
00886 
00887                 /* next plugin */
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 } /* ra_meas_find_first() */
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 } /* ra_meas_find_next() */
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 } /* ra_meas_close_find() */
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                 /* use plugin and (open_meas() is assigned) ? */
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                 /* check if current plugin supports file */
01009                 if ((*p->access.check_meas)(file_utf8))
01010                 {
01011                         /* yes, correct plugin -> open it */
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                                 /* save pointer to overall ra struct */
01019                                 meas->ra = h;
01020                                 /* and save pointer to handling plugin */
01021                                 meas->p = p;
01022                                 /* get max. samplerate and calc channel scaling factors */
01023                                 calc_x_scales(meas);
01024                                 /* read evaluation */
01025                                 /* store given evaluation filename */
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);  /* first load eval (if avail.) */
01032                                 read_evaluation(mh);    /* then read original (if not alread in eval) */
01033 
01034                                 break;
01035                         }
01036                 }
01037 
01038                 /* try next plugin */
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 } /* ra_meas_open() */
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 } /* calc_x_scales() */
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         /* measurement will be handled by rasch-file plugin */
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         /* to be sure, check that new_meas() function exists in ra-raw plugin */
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         /* create measurement and set needed info */
01147         meas = (struct ra_meas *)mh;
01148         meas->handle_id = RA_HANDLE_MEAS;
01149         /* save pointer to overall lib struct */
01150         meas->ra = ra;
01151         /* and save pointer to handling plugin */
01152         meas->p = p;
01153         /* get max. samplerate and calc channel scaling factors */
01154         calc_x_scales(meas);
01155 
01156  error: 
01157         free(dir_utf8);
01158         free(name_utf8);
01159 
01160         return meas;
01161 } /* ra_meas_new() */
01162 
01163 
01164 
01173 LIBRAAPI int
01174 ra_meas_save(meas_handle mh)
01175 {
01176         /* (TODO: think about how to implement one save function (for measurement and evaluation))*/
01177         int ret = -1;
01178         unsigned short type = *((unsigned short *)mh);
01179         
01180         if (type == RA_HANDLE_MEAS) /* to be sure that correct handle is used */
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 } /* ra_meas_save() */
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         /* is close_meas() assigned ? */
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 } /* ra_meas_close() */
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         /* in-validate value so in case of error 'vh' has no value */
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 } /* ra_info_get() */
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 } /* check_handle_type() */
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         /* get infos about asked measurement info */
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 } /* get_lib_info() */
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         /* get infos about asked measurement info */
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         /* internal checks */
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 /*              _ra_set_error(pl, RA_ERR_INTERNAL_PLUGIN_ERROR, "libRASCH");
01457                 return -1; */
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 /*              _ra_set_error(pl, RA_ERR_INTERNAL_PLUGIN_ERROR, "libRASCH");
01464                 return -1; */
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 } /* get_plugin_info() */
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         /* get infos about asked measurement info */
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 }  /* get_meas_general_info() */
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 } /* get_session_info() */
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 } /* get_proc_info() */
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 } /* get_plugin_from_handle() */
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 } /* ra_info_get_by_name() */
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         /* in-validate value so in case of error 'vh' has no value */
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 } /* ra_info_get_by_idx() */
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         /* get infos about asked measurement info */
01794         meta_inf = get_meta_info(v->id);
01795 
01796         /* all var's ok? */
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 } /* ra_info_set() */
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 } /* ra_rec_get_first() */
01834 
01835 
01842 LIBRAAPI rec_handle
01843 ra_rec_get_next(rec_handle rh)
01844 {
01845         /* TODO: think about if "follows" is correct and insert link to user-manual (if written) */
01846         return ((struct ra_rec *) rh)->next;
01847 } /* ra_rec_get_next() */
01848 
01849 
01856 LIBRAAPI rec_handle
01857 ra_rec_get_first_child(rec_handle rh)
01858 {
01859         return ((struct