Example #1
0
int main(void){
	sqlite3 *db;
	char *err;	
	int rc = sqlite3_open("bucket.db", &db);
	if(rc){
		printf("Fehler!\n");
		sqlite3_close(db);
		return 1;
	}
	char st[] = "select * from bin_bucket where id = 123;";
	sqlite3_stmt *stmt;
	
	rc = sqlite3_prepare_v2(db, st, -1, &stmt, NULL);
	if (rc != SQLITE_OK){
		printf("SQL-Fehler!\n");
		sqlite3_close(db);
		return 1;
	}
	
	

		
	while( (rc = sqlite3_step(stmt)) != SQLITE_DONE){
		if (rc != SQLITE_ROW){
			printf("Step-Fehler\n");
			sqlite3_close(db);
			return 1;
		} else {
			printf("Neue Zeile:\n");
			int i;
			for (i=0; i<sqlite3_column_count(stmt); i++){
				printf("|%s|", sqlite3_column_text(stmt, i ));
			}
			printf("\n");
		}
	}
	rc = sqlite3_prepare_v2(db, st, -1, &stmt, NULL);
	printf("Anzahl der Ergebniszeilen: %d\n", count_rows(stmt));
	sqlite3_close(db);
	return 0;
}
Example #2
0
int main(int argc, char **argv)
{
  std::string app_name = base::basename(argv[0]);

  base::threading_init();
  
  TaskQueue tables;

  std::string source_password;
  std::string source_connstring;
  bool source_use_cleartext_plugin = false;
  bool source_is_utf8 = false;
  std::string source_charset;
  SourceType source_type = ST_MYSQL;

  std::string target_connstring;
  std::string target_password;
  bool target_use_cleartext_plugin = false;
  std::string log_level;
  std::string log_file;

  bool passwords_from_stdin = false;
  bool count_only = false;
  bool check_types_only = false;
  bool truncate_target = false;
  bool show_progress = false;
  bool abort_on_oversized_blobs = false;
  bool disable_triggers = false;
  bool reenable_triggers = false;
  bool disable_triggers_on_copy = true;
  bool resume = false;
  int thread_count = 1;
  long long bulk_insert_batch = 100;
  long long max_count = 0;

  std::string table_file;

  std::set<std::string> trigger_schemas;
  std::string source_rdbms_type = "unknown";

  bool log_level_set = false;
  int i = 1;
  while (i < argc)
  {
    char *argval = NULL;

    if (check_arg_with_value(argv, i, "--log-level", argval, true))
      log_level = argval;
    else if (check_arg_with_value(argv, i, "--log-file", argval, true))
      log_file = argval;
    else if (check_arg_with_value(argv, i, "--odbc-source", argval, true))
    {
      source_type = ST_ODBC;
      source_connstring = base::trim(argval, "\"");
    }
    else if (check_arg_with_value(argv, i, "--mysql-source", argval, true))
    {
      source_type = ST_MYSQL;
      source_connstring = base::trim(argval, "\"");
    }
    else if (check_arg_with_value(argv, i, "--pythondbapi-source", argval, true))
    {
      source_type = ST_PYTHON;
      source_connstring = base::trim(argval, "\"");
    }
    else if (check_arg_with_value(argv, i, "--source-password", argval, true))
      source_password = argval;
    else if (check_arg_with_value(argv, i, "--target-password", argval, true))
      target_password = argval;
    else if (strcmp(argv[i], "--force-utf8-for-source") == 0)
      source_is_utf8 = true;
    else if (check_arg_with_value(argv, i, "--source-charset", argval, true))
      source_charset = argval;
    else if (strcmp(argv[i], "--progress") == 0)
      show_progress = true;
    else if (strcmp(argv[i], "--truncate-target") == 0)
      truncate_target = true;
    else if (strcmp(argv[i], "--count-only") == 0)
    {
      // Count only will be allowed only if one of the trigger
      // operations has not been indicated first
      if ( !disable_triggers && !reenable_triggers)
        count_only = true;
    }
    else if (strcmp(argv[i], "--check-types-only") == 0)
      check_types_only = true;
    else if (strcmp(argv[i], "--passwords-from-stdin") == 0)
      passwords_from_stdin = true;
    else if (strcmp(argv[i], "--abort-on-oversized-blobs") == 0)
      abort_on_oversized_blobs = true;
    else if (strcmp(argv[i], "--dont-disable-triggers") == 0)
      disable_triggers_on_copy = false;
    else if (strcmp(argv[i], "--resume") == 0)
      resume = true;
    else if (check_arg_with_value(argv, i, "--disable-triggers-on", argval, true))
    {
      // disabling/enabling triggers are standalone operations and mutually exclusive
      // so here it ensures a request for trigger enabling was not found first
      if (!reenable_triggers && !count_only)
      {
        disable_triggers = true;
        trigger_schemas.insert(argval);
      }
    }
    else if (check_arg_with_value(argv, i, "--reenable-triggers-on", argval, true))
    {
      // disabling/enabling triggers are standalone operations and mutually exclusive
      // so here it ensures a request for trigger enabling was not found first
      if (!disable_triggers && !count_only)
      {
        reenable_triggers = true;
        trigger_schemas.insert(argval);
      }
    }
    else if (check_arg_with_value(argv, i, "--thread-count", argval, true))
    {
      thread_count = base::atoi<int>(argval, 0);
      if (thread_count < 1)
        thread_count = 1;
    }
    else if (check_arg_with_value(argv, i, "--bulk-insert-batch-size", argval, true))
    {
      bulk_insert_batch = base::atoi<int>(argval, 0);
      if (bulk_insert_batch < 1)
        bulk_insert_batch = 100;
    }
    else if (strcmp(argv[i], "--version") == 0)
    {
      const char *type = APP_EDITION_NAME;
      if (strcmp(APP_EDITION_NAME, "Community") == 0)
        type = "CE";

      printf("%s %s (%s) %i.%i.%i %s build %i\n"
             , base::basename(argv[0]).c_str()
             , type, APP_LICENSE_TYPE
             , APP_MAJOR_NUMBER
             , APP_MINOR_NUMBER
             , APP_RELEASE_NUMBER
             , APP_RELEASE_TYPE
             , APP_BUILD_NUMBER
            );
      exit(0);
    }
    else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0)
    {
      show_help();
      exit(0);
    }
    else if (check_arg_with_value(argv, i, "--target", argval, true))
    {
      target_connstring = base::trim(argval, "\"");
    }
    else if (check_arg_with_value(argv, i, "--table-file", argval, true))
      table_file = argval;
    else if (strcmp(argv[i], "--table") == 0)
    {
      TableParam param;

      if ((!count_only && i + 7 >= argc) || (count_only && i + 2 >= argc))
      {
        fprintf(stderr, "%s: Missing value for table copy specification\n", argv[0]);
        exit(1);
      }

      param.source_schema = argv[++i];
      param.source_table = argv[++i];
      if (!(count_only && !resume))
      {
        param.target_schema = argv[++i];
        param.target_table = argv[++i];
        if(std::strcmp(argv[++i], "-") != 0)
          param.source_pk_columns = base::split(argv[i], ",", -1);
        if(std::strcmp(argv[++i], "-") != 0)
          param.target_pk_columns = base::split(argv[i], ",", -1);
        param.select_expression = argv[++i];

        trigger_schemas.insert(param.target_schema);
      }

      param.copy_spec.resume = resume;
      param.copy_spec.max_count = max_count;

      param.copy_spec.type = CopyAll;

      tables.add_task(param);
    }
    else if (strcmp(argv[i], "--table-range") == 0)
    {
      TableParam param;

      if ((!count_only && i + 10 >= argc) || (count_only && i + 5 >= argc))
      {
        fprintf(stderr, "%s: Missing value for table copy specification\n", argv[0]);
        exit(1);
      }
      param.source_schema = argv[++i];
      param.source_table = argv[++i];
      if (!(count_only && !resume))
      {
        param.target_schema = argv[++i];
        param.target_table = argv[++i];
        if(std::strcmp(argv[++i], "-") != 0)
          param.source_pk_columns = base::split(argv[i], ",", -1);
        if(std::strcmp(argv[++i], "-") != 0)
          param.target_pk_columns = base::split(argv[i], ",", -1);
        param.select_expression = argv[++i];

        trigger_schemas.insert(param.target_schema);
      }
      param.copy_spec.range_key = argv[++i];
      param.copy_spec.range_start = base::atoi<long long>(argv[++i], 0ll);
      param.copy_spec.range_end = base::atoi<long long>(argv[++i], 0ll);
      param.copy_spec.type = CopyRange;

      tables.add_task(param);
    }
    else if (strcmp(argv[i], "--table-row-count") == 0)
    {
      TableParam param;

      if ((!count_only && i + 8 >= argc) || (count_only && i + 3 >= argc))
      {
        fprintf(stderr, "%s: Missing value for table copy specification\n", argv[0]);
        exit(1);
      }
      param.source_schema = argv[++i];
      param.source_table = argv[++i];
      if (!(count_only && !resume))
      {
        param.target_schema = argv[++i];
        param.target_table = argv[++i];
        if(std::strcmp(argv[++i], "-") != 0)
          param.source_pk_columns = base::split(argv[i], ",", -1);
        if(std::strcmp(argv[++i], "-") != 0)
          param.target_pk_columns = base::split(argv[i], ",", -1);
        param.select_expression = argv[++i];
      }
      param.copy_spec.row_count = base::atoi<long long>(argv[++i], 0ll);
      param.copy_spec.resume = resume;
      param.copy_spec.type = CopyCount;

      tables.add_task(param);
    }
    else if (check_arg_with_value(argv, i, "--source-rdbms-type", argval, false))
    	source_rdbms_type = argval;
    else if (strcmp(argv[i], "--table-where") == 0)
    {
      TableParam param;

      if ((!count_only && i + 8 >= argc) || (count_only && i + 4 >= argc))
      {
        fprintf(stderr, "%s: Missing value for table copy specification\n", argv[0]);
        exit(1);
      }
      param.source_schema = argv[++i];
      param.source_table = argv[++i];
      if (!(count_only && !resume))
      {
        param.target_schema = argv[++i];
        param.target_table = argv[++i];
        if(std::strcmp(argv[++i], "-") != 0)
          param.source_pk_columns = base::split(argv[i], ",", -1);
        if(std::strcmp(argv[++i], "-") != 0)
          param.target_pk_columns = base::split(argv[i], ",", -1);
        param.select_expression = argv[++i];
        param.copy_spec.where_expression = argv[++i];

        trigger_schemas.insert(param.target_schema);
      }
      else
      {
        param.select_expression = argv[++i];
        param.copy_spec.where_expression = argv[++i];
      }
      param.copy_spec.type = CopyWhere;

      tables.add_task(param);
    }
    else if (check_arg_with_value(argv, i, "--max-count", argval, true))
    {
      max_count = base::atoi<int>(argval, 0);
    }
    else if (strcmp(argv[i], "--source-use-cleartext") == 0)
      source_use_cleartext_plugin = true;
    else if (strcmp(argv[i], "--target-use-cleartext") == 0)
      target_use_cleartext_plugin = true;
    else
    {
      fprintf(stderr, "%s: Invalid option %s\n", argv[0], argv[i]);
      exit(1);
    }

    i++;
  }

  // Creates the log to the target file if any, if not
  // uses std_error
  base::Logger logger(true, log_file);

  if (!log_level.empty())
  {
      if (!set_log_level(log_level))
      {
        fprintf(stderr, "%s: invalid argument '%s' for option %s\n", argv[0], log_level.data(), "--log-level");
        exit(1);
      }
      else
        log_level_set = true;
  }

  // Set the log level from environment var WB_LOG_LEVEL if specified or set a default log level.
  if (!log_level_set)
  {
    const char* log_setting = getenv("WB_LOG_LEVEL");
    if (log_setting == NULL)
      log_setting = "info";
    else
      log_level_set = true;

    std::string level = base::tolower(log_setting);
    base::Logger::active_level(level);
  }

  // If needed, reads the tasks from the table definition file
  if (!table_file.empty())
  {
    if (!read_tasks_from_file(table_file, count_only, tables, trigger_schemas, resume, max_count))
    {
      fprintf(stderr, "Invalid table definitions format in file: %s\n", table_file.data());
      exit(1);
    }
  }

  // Not having the source connection data is an error unless
  // the standalone operations to disable or reenable triggers
  // are called
  if (source_connstring.empty() && !reenable_triggers && ! disable_triggers)
  {
    fprintf(stderr, "Missing source DB server\n");
    exit(1);
  }

  if (target_connstring.empty() && !(count_only && !resume))
  {
    fprintf(stderr, "Missing target DB server\n");
    exit(1);
  }

  // Table definitions will be required only if the standalone operations to
  // Reenable or disable triggers are not called
  if (tables.empty() && !reenable_triggers && ! disable_triggers)
  {
    log_warning("Missing table list specification\n");
    exit(0);
  }

  std::string source_host;
  std::string source_user;
  int source_port = -1;
  std::string source_socket;

  // Source connection is parsed only when NOT executing the
  // Standalone operatios on triggers
  if (source_type == ST_MYSQL && !reenable_triggers && ! disable_triggers)
  {
    if (!parse_mysql_connstring(source_connstring, source_user, source_password,
                                source_host, source_port, source_socket))
    {
      fprintf(stderr, "Invalid MySQL connection string %s for source database. Must be in format user[:pass]@host:port or user[:pass]@::socket\n", target_connstring.c_str());
      exit(1);
    }
  }

  std::string target_host;
  std::string target_user;
  int target_port = -1;
  std::string target_socket;
  if (!(count_only && !resume) && !parse_mysql_connstring(target_connstring, target_user, target_password,
                                             target_host, target_port, target_socket))
  {
    fprintf(stderr, "Invalid MySQL connection string %s for target database. Must be in format user[:pass]@host:port or user[:pass]@::socket\n", target_connstring.c_str());
    exit(1);
  }

  if (passwords_from_stdin)
  {
    char password[200];
    if (!fgets(password, sizeof(password), stdin))
    {
      log_error("Error reading passwords from stdin\n");
      exit(1);
    }

    if ((count_only && !resume)|| reenable_triggers || disable_triggers)
    {
      char *ptr = strtok(password, "\t\r\n");
      if (ptr)
      {
        if (count_only)
          source_password = ptr;
        else
          target_password = ptr;
      }
    }
    else
    {
      char *ptr = strtok(password, "\r\n");
      if (ptr)
      {
        ptr = strchr(password, '\t');
        if (ptr)
        {
          source_password = std::string(password, ptr-password);
          target_password = ptr+1;
        }
        else
          source_password = password;
      }
    }
  }

  static SQLHENV odbc_env;

  PyThreadState *state = NULL;
  if (source_type == ST_PYTHON)
  {
    Py_Initialize();
    PyEval_InitThreads();
    state = PyEval_SaveThread();
  }
  try
  {
    if (count_only)
    {
      boost::scoped_ptr<CopyDataSource> psource;

      if (source_type == ST_ODBC)
      {
        SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env);
        SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

        psource.reset(new ODBCCopyDataSource(odbc_env, source_connstring, source_password, source_is_utf8, source_rdbms_type));
      }
      else if (source_type == ST_MYSQL)
        psource.reset(new MySQLCopyDataSource(source_host, source_port, source_user, source_password, source_socket, source_use_cleartext_plugin));
      else
        psource.reset(new PythonCopyDataSource(source_connstring, source_password));

      boost::scoped_ptr<MySQLCopyDataTarget> ptarget;
      TableParam task;
      while(tables.get_task(task))
      {
        std::vector<std::string> last_pkeys;
        if (task.copy_spec.resume)
        {
          if(!ptarget.get())
            ptarget.reset(new MySQLCopyDataTarget(target_host, target_port, target_user, target_password, target_socket, target_use_cleartext_plugin, app_name, source_charset, source_rdbms_type));
          last_pkeys = ptarget->get_last_pkeys(task.target_pk_columns, task.target_schema, task.target_table);
        }
        count_rows(psource, task.source_schema, task.source_table, task.source_pk_columns, task.copy_spec, last_pkeys);
      }
    }
    else if (reenable_triggers || disable_triggers)
    {
      boost::scoped_ptr<MySQLCopyDataTarget> ptarget;
      ptarget.reset(new MySQLCopyDataTarget(target_host, target_port, target_user, target_password, target_socket, target_use_cleartext_plugin, app_name, source_charset, source_rdbms_type));

      if (disable_triggers)
        ptarget->backup_triggers(trigger_schemas);
      else
        ptarget->restore_triggers(trigger_schemas);
    }
    else
    {
      std::vector<CopyDataTask*> threads;

      boost::scoped_ptr<MySQLCopyDataTarget> ptarget_conn;
      MySQLCopyDataTarget *ptarget = NULL;
      CopyDataSource *psource = NULL;

      if (disable_triggers_on_copy)
      {
        ptarget_conn.reset(new MySQLCopyDataTarget(target_host, target_port, target_user, target_password, target_socket, target_use_cleartext_plugin, app_name, source_charset, source_rdbms_type));
        ptarget_conn->backup_triggers(trigger_schemas);
      }

      for (int index = 0; index < thread_count; index++)
      {
        if (source_type == ST_ODBC)
        {
          SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env);
          SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (void *) SQL_OV_ODBC3, 0);

          psource = new ODBCCopyDataSource(odbc_env, source_connstring, source_password, source_is_utf8, source_rdbms_type);
        }
        else if (source_type == ST_MYSQL)
          psource = new MySQLCopyDataSource(source_host, source_port, source_user, source_password, source_socket, source_use_cleartext_plugin);
        else
          psource = new PythonCopyDataSource(source_connstring, source_password);

        ptarget = new MySQLCopyDataTarget(target_host, target_port, target_user, target_password, target_socket, target_use_cleartext_plugin, app_name, source_charset, source_rdbms_type);

        psource->set_max_blob_chunk_size(ptarget->get_max_allowed_packet());
        psource->set_max_parameter_size((unsigned long)ptarget->get_max_long_data_size());
        psource->set_abort_on_oversized_blobs(abort_on_oversized_blobs);
        ptarget->set_truncate(truncate_target);
        if (max_count > 0)
          bulk_insert_batch = max_count;
        ptarget->set_bulk_insert_batch_size((int)bulk_insert_batch);

        if (check_types_only)
        {
          //XXXX
          delete psource;
        }
        else
        {
          threads.push_back(new CopyDataTask(base::strfmt("Task %d", index + 1), psource, ptarget, &tables, show_progress));
        }
      }

      // Waits for all the threads to complete
      for (size_t index = 0; index < threads.size(); index++)
        threads[index]->wait();

      // Finally destroys the threads and connections
      for (size_t index = 0; index < threads.size(); index++)
        delete threads[index];

      // Finally restores the triggers
      if (disable_triggers_on_copy)
        ptarget_conn->restore_triggers(trigger_schemas);
    }
  }
  catch (std::exception &e)
  {
    log_error("Exception: %s\n", e.what());
    if (source_type == ST_PYTHON)
    {
      PyEval_RestoreThread(state);
      Py_Finalize();
    }
    exit(1);
  }

  if (source_type == ST_PYTHON)
  {
    PyEval_RestoreThread(state);
    Py_Finalize();
  }

  printf("FINISHED\n");
  fflush(stdout);

  return 0;
}
Example #3
0
static fm_system* parse_files(FILE *afile, FILE *cfile)
{

    fm_system* system = (fm_system*)malloc(sizeof(fm_system));
    
	unsigned int i;
	unsigned int rows = count_rows(afile);
	unsigned int cols = count_cols(afile);

	fm_row *fm_rows = (fm_row *) malloc(sizeof(fm_row)*rows);
	fm_poly *fm_polys = (fm_poly *) malloc(sizeof(fm_poly)*rows*2);
	fm_poly_entry *fm_lesser_rows  = (fm_poly_entry *) malloc(sizeof(fm_poly_entry)*rows*cols);
	fm_poly_entry *fm_greater_rows = (fm_poly_entry *) malloc(sizeof(fm_poly_entry)*rows);

	if(fm_rows == NULL || fm_polys == NULL || fm_lesser_rows == NULL || fm_greater_rows == NULL) {
		fprintf(stderr, "Unable to allocate memory!\n");
		exit(1);
	}

	for(i = 0; i < rows; ++i) {
		fm_rows[i].lesser = &(fm_polys[i]);
		fm_rows[i].greater = &(fm_polys[rows+i]);

	    fm_rows[i].lesser->poly = &(fm_lesser_rows[i*cols]);
		fm_rows[i].lesser->poly_len = cols;

		fm_rows[i].greater->poly = &(fm_greater_rows[i]);
		fm_rows[i].greater->poly_len = 1;
	}

	long file_length = fsize(afile)+1;
	char *buffer = (char *) malloc(sizeof(char)*file_length);
	fread(buffer, sizeof(char), file_length, afile);
	rewind(afile);
	buffer[file_length-1] = '\0';

	long long read_integer;
	char *line_tok, *integer_tok, *line_save, *integer_save;
	unsigned int ctr_col = 0;
	unsigned int ctr_row = 0;

	for (line_tok = strtok_r(buffer+4*sizeof(char), "\n", &line_save); line_tok; line_tok = strtok_r(NULL, "\n", &line_save)) {
		//printf("line=%s\n", line_tok);
		for (integer_tok = strtok_r(line_tok, " \t", &integer_save); integer_tok; integer_tok = strtok_r(NULL, " \t", &integer_save)) {
				//printf("integer=%s\n", integer_tok);
				sscanf(integer_tok, "%lld", &read_integer);

				fm_rows[ctr_row].lesser->poly[ctr_col].numerator = read_integer;
				fm_rows[ctr_row].lesser->poly[ctr_col].denominator = 1;
				fm_rows[ctr_row].lesser->poly[ctr_col].index = ctr_col + 1;
				++ctr_col;
		}
        system->nbr_x = ctr_col;
        system->curr_nbr_x = ctr_col;
		ctr_col = 0;
		++ctr_row;
	}

	file_length = fsize(cfile)+1;
	buffer = (char *) malloc(sizeof(char)*file_length);
	fread(buffer, sizeof(char), file_length, cfile);
	rewind(cfile);
	buffer[file_length-1] = '\0';

	ctr_row = 0;

	for (line_tok = strtok_r(buffer+2*sizeof(char), " \t\n", &line_save); line_tok; line_tok = strtok_r(NULL, "\n", &line_save)) {
		printf("line=%s\n", line_tok);
		sscanf(line_tok, "%lld", &read_integer);

		fm_rows[ctr_row].greater->poly[0].numerator = read_integer;
		fm_rows[ctr_row].greater->poly[0].denominator = 1;
		fm_rows[ctr_row].greater->poly[0].index = 0;
		++ctr_row;
	}

//	free(buffer);
	
	system->rows = fm_rows;
	system->nbr_rows = count_rows(afile);
	
	return system;
}
int parse_config(FILE *cnf, ode_model_parameters *omp, main_options *cnf_options){
  /* This function parses the configuration file The configuration
   * file contains xml like expressions containing data, measurement
   * time points, etc.
   * We start by defining regular expressions for the field names
   * 
   */
  int D=0,U=0,C=0,F=0,T=0,N=0;
  int i,l;
  int n=10; // number of fields
  regex_t cpt[2*n]; // defines the patterns for the field names
  regex_t comment;
  int bsize=2048;
  char buffer[bsize];
  gsl_matrix *reference_data;
  gsl_matrix *sd_reference_data;
  omp->data_is_relative=0; // assume data to be absolute
  char *var_value, *var_value_newline;

  //comments in file
  regcomp(&comment,"#|//|%",REG_EXTENDED);

  regcomp(&cpt[0],"\\[time\\]",REG_EXTENDED);
  regcomp(&cpt[1],"\\[reference_input\\]",REG_EXTENDED);
  regcomp(&cpt[2],"\\[reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[3],"\\[sd_reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[4],"\\[input\\]",REG_EXTENDED);
  regcomp(&cpt[5],"\\[data\\]",REG_EXTENDED);
  regcomp(&cpt[6],"\\[sd_data\\]",REG_EXTENDED);
  regcomp(&cpt[7],"\\[prior_mu\\]",REG_EXTENDED);
  regcomp(&cpt[8],"\\[prior_inv(erse)?_cov(ariance)?\\]",REG_EXTENDED);
  regcomp(&cpt[9],"\\[output\\]",REG_EXTENDED);

  regcomp(&cpt[n+0],"\\[/time\\]",REG_EXTENDED);
  regcomp(&cpt[n+1],"\\[/reference_input\\]",REG_EXTENDED);
  regcomp(&cpt[n+2],"\\[/reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+3],"\\[/sd_reference_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+4],"\\[/input\\]",REG_EXTENDED);
  regcomp(&cpt[n+5],"\\[/data\\]",REG_EXTENDED);
  regcomp(&cpt[n+6],"\\[/sd_data\\]",REG_EXTENDED);
  regcomp(&cpt[n+7],"\\[/prior_mu\\]",REG_EXTENDED);
  regcomp(&cpt[n+8],"\\[/prior_inv(erse)?_cov(ariance)?\\]",REG_EXTENDED);
  regcomp(&cpt[n+9],"\\[/output\\]",REG_EXTENDED);

  /* now that we have several regular expressions, we parse the file
   * once to get the problem size: D,P,F,U,C; then we allocate mamory
   * and parse the file a second time to read the data, inputs and so
   * forth.
   */


  /* relevant interfaces:
   * count_rows(FILE *cnf, regex_t *end, regex_t *comment)
   * count_columns(const char *c)
   * read_columns(char *c, double *vector, const int length)
   * read_block(int rows, int columns, FILE *f, double *target, regex_t *comment)
   */

  while (!feof(cnf)){
    do fgets(buffer,bsize,cnf);
    while (regexec(&comment,buffer,0,NULL,0)==0);
    var_value=strchr(buffer,'='); // string looks like this: [var_name]=[var_value]
    if (var_value!=NULL) { // we have a variable definition
      var_value[0]='\0'; //mark the end of the variable name
      /*printf("var_name=%s\n",buffer);
        printf("var_value=%s\n",var_value+1);
       *printf("removing newline....\n");
       */
      var_value_newline=strchr(++var_value,'\n');
      if (var_value_newline!=NULL) var_value_newline[0]='\0';      
      printf("# [cfg] {%s} ← {%s}\n",buffer,var_value);
      
      if (strcmp(cnf_options->output_file,"sample.dat")==0 && strcmp(buffer,"output")==0) strcpy(cnf_options->output_file,var_value);
      else if (cnf_options->sample_size<0 && strcmp(buffer,"sample_size")==0) cnf_options->sample_size=strtol(var_value,NULL,0);
      else if (cnf_options->target_acceptance<0 && strcmp(buffer,"acceptance")==0) cnf_options->target_acceptance=strtod(var_value,NULL);
      else if (cnf_options->initial_stepsize<0 && strcmp(buffer,"step_size")==0) cnf_options->initial_stepsize=strtod(var_value,NULL);
      else if (strcmp(buffer,"t0")==0) {omp->t0=strtod(var_value,NULL); printf("# t0 = %f\n",omp->t0);}
    }
    else { 
      for (i=0;i<n;i++){
	if (regexec(&cpt[i],buffer,0,NULL,0)==0){
	  /* printf("found match with regular expression %i.\n",i); */
	  /* printf(buffer); */
	  switch (i){ // counting columns and/or rows
	  case 0: /*time*/
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    T=count_rows(cnf, &cpt[n+i], &comment);
	    break;
	  case 1: /* reference input */
	    omp->data_is_relative=1;
	    printf("data is relative.\n");
	    break;
	  case 4: /* inputs */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    U=count_columns(buffer);
	    C=count_rows(cnf, &cpt[n+i], &comment);
	    //	  printf("# input field has %i lines. (%i experimental conditions)\n",l,C);
	    break;
	  case 5: /* data */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    F=count_columns(buffer);
	    l=count_rows(cnf, &cpt[n+i], &comment);
	    printf("# data has %i (%i × %i) lines.\n",l,C,T);
	    break;
	  case 7: /* problem size */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    D=count_rows(cnf, &cpt[n+i], &comment);
	    break;
	  case 9: /* output structure */
	    do fgets(buffer,bsize,cnf);
	    while (regexec(&comment,buffer,0,NULL,0)==0);
	    N=count_columns(buffer);
	    F=count_rows(cnf, &cpt[n+i], &comment);
	  }// switch
	  break;
	}// if match
      }// for (regular expressions)
    }// while !EOF
  }
  printf("# file read once to determine the size of data and inputs.\n");
  printf("# D=%i\tN=%i\tF=%i\tU=%i\tC=%i\tT=%i\n",D,N,F,U,C,T);
  omp->D=D;
  /* now we must allocate the necessary memory and fill it with values
   */
  ode_model_parameters_alloc(omp, D, N, F, T, U, C);
  reference_data=gsl_matrix_alloc(T,F);
  sd_reference_data=gsl_matrix_alloc(T,F);
  printf("# memory allocated.\n");
  /* we reset the FILE structure and parse again, now reading the
   * values.
   */
  rewind(cnf);
  printf("# rewind.\n");
  while (!feof(cnf)){
    do fgets(buffer,bsize,cnf);
    while (regexec(&comment,buffer,0,NULL,0)==0);
    for (i=0;i<n;i++){
      if (    regexec(&cpt[i],buffer,0,NULL,0)==0){
        /* printf("found match with regular expression %i.\n",i); */
        /* printf(buffer); */
	switch (i){// reading the data
	case 0: /*time*/
	  read_block(T,1,cnf,omp->t->data,&comment);
	  printf("# measurement time(s) read.\n");
	  break;
	case 1: /* reference input */
	  //printf("# reading reference input.\n");
	  read_block(1,U,cnf,omp->reference_u->data,&comment);
	  printf("# reference input read.\n");
	  break;
	case 2: /* reference data */
	  read_block(T,F,cnf,reference_data->data,&comment);
	  printf("# reference data read.\n");
	  break;
	case 3: /* sd reference data */
	  read_block(T,F,cnf,sd_reference_data->data,&comment);
	  printf("# standard deviation of reference data read.\n");
	  break;
	case 4: /* inputs */
	  read_block(C,U,cnf,omp->input_u->data,&comment);
	  printf("# input read.\n");
	  break;
	case 5: /* data */
	  read_block(C*T,F,cnf,omp->Data->data,&comment);
	  printf("# data read.\n");
	  break;
	case 6: /* sd data */
	  read_block(C*T,F,cnf,omp->sdData->data,&comment);
	  printf("# standard deviation of data read.\n");
	  break;
	case 7:
	  read_block(D,1,cnf,omp->prior_mu->data,&comment);
	  printf("# prior mean read.\n");
	  break;
	case 8: /* prior inverse covariance */
	  read_block(D,D,cnf,omp->prior_inverse_cov->data,&comment);
	  printf("# prior inverse covariance matrix read.\n");
	  break;
	case 9: /* output structure */
	  read_block(F,N,cnf,omp->output_C->data,&comment);
	}// switch
	break;
      }// if match
    }// for (regular expressions)
  }// while !EOF
  printf("# configuration read.\n");
  /* now we take the ratios of data and reference data
   */

  if (omp->data_is_relative){
    printf("# calculating relative data (ratios)...");
    ratio_with_sd(omp->Data,omp->sdData,reference_data,sd_reference_data);
    printf("# done.\n");
  }

  //  omp->t0=0.0;

  // cleanup
  gsl_matrix_free(reference_data);
  gsl_matrix_free(sd_reference_data);
  for (i=0;i<2*n;i++)  regfree(&cpt[i]);

  return EXIT_SUCCESS;
}