static PyObject* setGlobals(PyObject *self, PyObject *args){ /* Sets the Primer3 global settings from a Python dictionary containing ** key: value pairs that correspond to the documented Primer3 ** global parameters. Also accepts a mispriming or mishybridization library ** organized as `seq_name`:`seq_value` key:value pairs. */ PyObject *global_args=NULL, *misprime_lib=NULL; PyObject *mishyb_lib=NULL; seq_lib *mp_lib, *mh_lib; if (pa != NULL) { // Free memory for previous global settings p3_destroy_global_settings(pa); pa = NULL; } // Allocate memory for global settings if ((pa = p3_create_global_settings()) == NULL) { PyErr_SetString(PyExc_IOError, "Could not allocate memory for p3 globals"); return NULL; } if (!PyArg_ParseTuple(args, "O!OO", &PyDict_Type, &global_args, &misprime_lib, &mishyb_lib)) { goto err_set_global; } if ((pdh_setGlobals(pa, global_args)) != 0) { goto err_set_global; } if ((misprime_lib != NULL) && (misprime_lib != Py_None)) { if ((mp_lib = pdh_createSeqLib(misprime_lib)) == NULL) { goto err_set_global; } pa->p_args.repeat_lib = mp_lib; } if ((mishyb_lib != NULL) && (mishyb_lib != Py_None)) { if ((mh_lib = pdh_createSeqLib(mishyb_lib))==NULL) { goto err_set_global; } pa->o_args.repeat_lib = mh_lib; } Py_RETURN_NONE; err_set_global: p3_destroy_global_settings(pa); pa = NULL; return NULL; }
int main(int argc, char *argv[]) { /* Setup the input data structures handlers */ int format_output = 0; int strict_tags = 0; int echo_settings = 0; int dump_args = 0 ; /* set to 1 if dumping arguments to choose_primers */ int io_version = 4; /* Some space for file names */ char p3_all_file[FILE_NAME_SIZE]; char p3_settings_file[FILE_NAME_SIZE]; p3_global_settings *global_pa; seq_args *sarg; read_boulder_record_results read_boulder_record_res = {0,0}; pr_append_str fatal_parse_err; pr_append_str nonfatal_parse_err; pr_append_str warnings; /* Some variables needed by getopt */ int opt, option_index = 0; struct option long_options[] = { {"about", no_argument, 0, 'a'}, {"format_output", no_argument, &format_output, 1}, {"strict_tags", no_argument, &strict_tags, 1}, {"p3_settings_file", required_argument, 0, 'p'}, {"echo_settings_file", no_argument, &echo_settings, 1}, {"io_version", required_argument, 0, 'i'}, {"2x_compat", no_argument, 0, '2'}, {"output", required_argument, 0, 'o'}, {"error", required_argument, 0, 'e'}, {0, 0, 0, 0} }; int about = 0, output = 0, error = 0, compat = 0, invalid_flag = 0; char output_file[FILE_NAME_SIZE], error_file[FILE_NAME_SIZE]; /* Retval will point to the return value from choose_primers(). */ p3retval *retval = NULL; int input_found=0; p3_all_file[0] = '\0'; p3_settings_file[0] = '\0'; init_pr_append_str(&fatal_parse_err); init_pr_append_str(&nonfatal_parse_err); init_pr_append_str(&warnings); /* Get the program name for correct error messages */ pr_release = libprimer3_release(); pr_program_name = argv[0]; p3_set_program_name(pr_program_name); /* We set up some signal handlers in case someone starts up the program * from the command line, wonders why nothing is happening, and then kills * the program. */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); /* Allocate the space for global settings and fill in default parameters */ global_pa = p3_create_global_settings(); if (!global_pa) { exit(-2); /* Out of memory. */ } if (dump_args) global_pa->dump = 1 ; /* Read in the flags provided with the program call */ opterr = 0; while ((opt = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1) { switch (opt) { case 'a': about = 1; break; case 'p': strncpy(p3_settings_file, optarg, FILE_NAME_SIZE - 1); break; case 'i': if (!strcmp(optarg, "3")) io_version = 3; else if (!strcmp(optarg, "4")) io_version = 4; else io_version = -1; break; case '2': compat = 1; break; case 'o': output = 1; strncpy(output_file, optarg, FILE_NAME_SIZE - 1); break; case 'e': error = 1; strncpy(error_file, optarg, FILE_NAME_SIZE - 1); break; case '?': invalid_flag = 1; break; } } /* Open the output and error files specified */ if (error == 1) { /* reassign stderr */ if (freopen(error_file, "w", stderr) == NULL) { fprintf(stderr, "Error creating file %s\n", error_file); exit(-1); } } if (output == 1) { /* reassign stdout */ if (freopen(output_file, "w", stdout) == NULL) { fprintf(stderr, "Error creating file %s\n", output_file); exit(-1); } } /* We do any printing after redirecting stdout and stderr */ if (about == 1) { printf("%s\n", pr_release); exit(0); } if ((io_version == -1) || (invalid_flag == 1)) { print_usage(); exit(-1); } if (compat == 1) { printf("PRIMER_ERROR=flag -2x_compat is no longer supported\n=\n"); exit(-1); } /* Check if an input file has been specified */ if (optind < argc) { if (optind + 1 != argc) { print_usage(); exit(-1); } if (freopen(argv[optind], "r", stdin) == NULL) { fprintf(stderr, "Error opening file %s\n", argv[optind]); exit(-1); } } /* Settings files have to be read in just below, and the functions need a temporary sarg */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Read data from the settings file until a "=" line occurs. Assign parameter * values for primer picking to pa and sa. */ if (p3_settings_file[0] != '\0') { read_p3_file(p3_settings_file, settings, echo_settings && !format_output, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &warnings, &read_boulder_record_res); /* Check if the thermodynamical alignment flag was given */ if (global_pa->thermodynamic_alignment == 1) read_thermodynamic_parameters(); } /* We also need to print out errors here because the loop erases all * errors at start */ /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } } /* The temporary sarg is not needed any more */ destroy_seq_args(sarg); sarg = NULL; /* Read the data from input stream record by record and process it if * there are no errors. This is where the work is done. */ while (1) { /* Create and initialize a seq_args data structure. sa (seq_args *) is * initialized here because Values are _not_ retained across different * input records. */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Reset all errors handlers and the return structure */ pr_set_empty(&fatal_parse_err); pr_set_empty(&nonfatal_parse_err); pr_set_empty(&warnings); retval = NULL; /* See read_boulder.h for documentation on read_boulder_record().*/ if (!read_boulder_record(stdin, &strict_tags, &io_version, !format_output, all_parameters, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &warnings, &read_boulder_record_res)) { break; /* There were no more boulder records */ } /* Check if the thermodynamical alignment flag was given and the path to the parameter files changed - we need to reread them */ if ((global_pa->thermodynamic_alignment == 1) && (thermodynamic_path_changed == 1)) read_thermodynamic_parameters(); input_found = 1; if ((global_pa->primer_task == pick_detection_primers) && (global_pa->pick_internal_oligo == 1)){ PR_ASSERT(global_pa->pick_internal_oligo); } /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } goto loop_wrap_up; } /* Print any warnings and continue processing */ if (!pr_is_empty(&warnings)) { if (format_output) { format_warning(stdout, sarg->sequence_name, warnings.data); } else { print_boulder_warning(warnings.data); } } if (read_boulder_record_res.file_flag && sarg->sequence_name == NULL) { /* We will not have a base name for the files */ if (format_output) { format_error(stdout, NULL, "Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } else { print_boulder_error("Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } goto loop_wrap_up; } /* Pick the primers - the central function */ p3_set_gs_primer_file_flag(global_pa, read_boulder_record_res.file_flag); retval = choose_primers(global_pa, sarg); if (NULL == retval) exit(-2); /* Out of memory. */ /* This is old code to make it compatible with version 3 input. In future versions it can be deleted! If it was necessary to use a left_input, right_input, or internal_oligo_input primer that was unacceptable, then add warnings. */ if (global_pa->pick_anyway && (io_version == 3 || format_output)) { if (sarg->left_input) { add_must_use_warnings(&retval->warnings, "Left primer", &retval->fwd.expl); } if (sarg->right_input) { add_must_use_warnings(&retval->warnings, "Right primer", &retval->rev.expl); } if (sarg->internal_input) { add_must_use_warnings(&retval->warnings, "Hybridization probe", &retval->intl.expl); } } /* End of the old code for compartibility. */ if (pr_is_empty(&retval->glob_err) && pr_is_empty(&retval->per_sequence_err)) { /* We need to test for errors before we call p3_print_oligo_lists. This function only works on retval as returned when there were no errors. */ if (read_boulder_record_res.file_flag) { /* Create files with left, right, and internal oligos. */ p3_print_oligo_lists(retval, sarg, global_pa, &retval->per_sequence_err, sarg->sequence_name); } } if (format_output) { print_format_output(stdout, &io_version, global_pa, sarg, retval, pr_release, read_boulder_record_res.explain_flag); } else { /* Use boulder output */ print_boulder(/* & */io_version, global_pa, sarg, retval, read_boulder_record_res.explain_flag); } loop_wrap_up: /* Here the failed loops join in again */ if (NULL != retval) { /* Check for errors and print them */ if (NULL != retval->glob_err.data) { fprintf(stderr, "%s: %s\n", pr_program_name, retval->glob_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } } destroy_p3retval(retval); /* This works even if retval is NULL */ retval = NULL; destroy_seq_args(sarg); sarg = NULL; } /* while (1) (processing boulder io records) ... End of the primary working loop */ /* To avoid being distracted when looking for leaks: */ if (global_pa->thermodynamic_alignment == 1) destroy_thal_structures(); p3_destroy_global_settings(global_pa); global_pa = NULL; destroy_seq_args(sarg); destroy_pr_append_str_data(&nonfatal_parse_err); destroy_pr_append_str_data(&fatal_parse_err); destroy_pr_append_str_data(&warnings); destroy_dpal_thal_arg_holder(); if (thermodynamic_params_path) free(thermodynamic_params_path); /* If it could not read input complain and die */ if (0 == input_found) { print_usage(); exit(-3); } return 0; }
int main(int argc, char *argv[]) { /* Setup the input data structures handlers */ int format_output = 0; int strict_tags = 0; int dump_args = 0 ; /* set to 1 if dumping arguments to choose_primers */ int io_version = 4; /* Some space for file names */ char *tmp_file_name = NULL; char p3_all_file[FILE_NAME_SIZE]; char p3_settings_file[FILE_NAME_SIZE]; p3_global_settings *global_pa; seq_args *sarg; read_boulder_record_results read_boulder_record_res = {0,0}; pr_append_str fatal_parse_err; pr_append_str nonfatal_parse_err; /* Retval will point to the return value from choose_primers(). */ p3retval *retval = NULL; int input_found=0; p3_all_file[0] = '\0'; p3_settings_file[0] = '\0'; init_pr_append_str(&fatal_parse_err); init_pr_append_str(&nonfatal_parse_err); /* Get the program name for correct error messages */ pr_program_name = argv[0]; p3_set_program_name(pr_program_name); /* We set up some signal handlers in case someone starts up the program * from the command line, wonders why nothing is happening, and then kills * the program. */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); /* Allocate the space for global settings and fill in default parameters */ global_pa = p3_create_global_settings(); if (!global_pa) { exit(-2); /* Out of memory. */ } if (dump_args) global_pa->dump = 1 ; /* Read in the flags provided with the program call */ while (--argc > 0) { argv++; if (!strcmp(*argv, "-format_output")) { format_output = 1; } else if (!strcmp(*argv, "-about")) { printf( "%s\n", pr_release); exit (0); } else if (!strcmp(*argv, "-2x_compat")) { printf( "PRIMER_ERROR=flag -2x_compat is no longer supported\n=\n"); exit (-1); } else if (!strcmp(*argv, "-io_version=3")) { io_version = 3; } else if (!strcmp(*argv, "-io_version=4")) { io_version = 4; } else if (!strncmp(*argv, "-p3_settings_file=", 18)) { tmp_file_name = strchr(*argv,'=') + 1; strncpy (p3_settings_file,tmp_file_name,FILE_NAME_SIZE-1); } else if (!strcmp(*argv, "-strict_tags")) { strict_tags = 1; } else { print_usage(); exit(-1); } } /* Settings files have to be read in just below, and the functions need a temporary sarg */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Read data from the settings file until a "=" line occurs. Assign parameter * values for primer picking to pa and sa. */ if (p3_settings_file[0] != '\0') { read_p3_file(p3_settings_file, settings, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &read_boulder_record_res); } /* We also need to print out errors here because the loop erases all * errors at start */ /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } } /* The temporary sarg is not needed any more */ destroy_seq_args(sarg); sarg = NULL; /* Read the data from input stream record by record and process it if * there are no errors. This is where the work is done. */ while (1) { /* Create and initialize a seq_args data structure. sa (seq_args *) is * initialized here because Values are _not_ retained across different * input records. */ if (!(sarg = create_seq_arg())) { exit(-2); } /* Reset all errors handlers and the return structure */ pr_set_empty(&fatal_parse_err); pr_set_empty(&nonfatal_parse_err); retval = NULL; /* See read_boulder.h for documentation on read_boulder_record().*/ if (!read_boulder_record(stdin, &strict_tags, &io_version, !format_output, all_parameters, global_pa, sarg, &fatal_parse_err, &nonfatal_parse_err, &read_boulder_record_res)) { break; /* There were no more boulder records */ } input_found = 1; if ((global_pa->primer_task == pick_detection_primers) && (global_pa->pick_internal_oligo == 1)){ PR_ASSERT(global_pa->pick_internal_oligo); } /* If there are fatal errors, write the proper message and exit */ if (fatal_parse_err.data != NULL) { if (format_output) { format_error(stdout, sarg->sequence_name, fatal_parse_err.data); } else { print_boulder_error(fatal_parse_err.data); } fprintf(stderr, "%s: %s\n", pr_program_name, fatal_parse_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } /* If there are nonfatal errors, write the proper message * and skip to the end of the loop */ if (!pr_is_empty(&nonfatal_parse_err)) { if (format_output) { format_error(stdout, sarg->sequence_name, nonfatal_parse_err.data); } else { print_boulder_error(nonfatal_parse_err.data); } goto loop_wrap_up; } if (read_boulder_record_res.file_flag && sarg->sequence_name == NULL) { /* We will not have a base name for the files */ if (format_output) { format_error(stdout, NULL, "Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } else { print_boulder_error("Need PRIMER_SEQUENCE_ID if PRIMER_FILE_FLAG is not 0"); } goto loop_wrap_up; } /* Pick the primers - the central function */ p3_set_gs_primer_file_flag(global_pa, read_boulder_record_res.file_flag); retval = choose_primers(global_pa, sarg); if (NULL == retval) exit(-2); /* Out of memory. */ /* This is old code to make it compatible with version 3 input. In future versions it can be deleted! If it was necessary to use a left_input, right_input, or internal_oligo_input primer that was unacceptable, then add warnings. */ if (global_pa->pick_anyway && (io_version == 3 || format_output)) { if (sarg->left_input) { add_must_use_warnings(&retval->warnings, "Left primer", &retval->fwd.expl); } if (sarg->right_input) { add_must_use_warnings(&retval->warnings, "Right primer", &retval->rev.expl); } if (sarg->internal_input) { add_must_use_warnings(&retval->warnings, "Hybridization probe", &retval->intl.expl); } } /* End of the old code for compartibility. */ if (pr_is_empty(&retval->glob_err) && pr_is_empty(&retval->per_sequence_err)) { /* We need to test for errors before we call p3_print_oligo_lists. This function only works on retval as returned when there were no errors. */ if (read_boulder_record_res.file_flag) { /* Create files with left, right, and internal oligos. */ p3_print_oligo_lists(retval, sarg, global_pa, &retval->per_sequence_err, sarg->sequence_name); } } if (format_output) { print_format_output(stdout, &io_version, global_pa, sarg, retval, pr_release, read_boulder_record_res.explain_flag); } else { /* Use boulder output */ print_boulder(/* & */io_version, global_pa, sarg, retval, read_boulder_record_res.explain_flag); } loop_wrap_up: /* Here the failed loops join in again */ if (NULL != retval) { /* Check for errors and print them */ if (NULL != retval->glob_err.data) { fprintf(stderr, "%s: %s\n", pr_program_name, retval->glob_err.data); destroy_p3retval(retval); destroy_seq_args(sarg); exit(-4); } } destroy_p3retval(retval); /* This works even if retval is NULL */ retval = NULL; destroy_seq_args(sarg); sarg = NULL; } /* while (1) (processing boulder io records) ... End of the primary working loop */ /* To avoid being distracted when looking for leaks: */ p3_destroy_global_settings(global_pa); global_pa = NULL; destroy_seq_args(sarg); destroy_pr_append_str_data(&nonfatal_parse_err); destroy_pr_append_str_data(&fatal_parse_err); destroy_dpal_thal_arg_holder(); /* If it could not read input complain and die */ if (0 == input_found) { print_usage(); exit(-3); } return 0; }