/* open a file with name out_root.name.maf, or returns it if already open. This is a bit messy because in some cases (splitting by feature) there may be more output files than the OS can handle. But it would be computationally expensive to check and see which files are finished, assuming that the MAF is sorted. So, if it tries to open a file and fails, it the goes through the list of filehandles, finds an open one, closes it, and tries to open the new one again. Repeat until successful. Then, if a filehandle needs to be re-opened, it is opened with append. Again, if this is not successful, it looks for another file to close. If it can't find one the program reports an error and dies. Finally, close_outfiles below checks and makes sure that all files are closed with mafBlock_close_file in the end, so that they get the #eof closer. */ FILE *get_outfile(List *outfileList, Hashtable *outfileHash, String *name, char *out_root, int argc, char *argv[]) { int idx, i; FILE *outfile; char *fname = smalloc((strlen(out_root)+name->length+7)*sizeof(char)); sprintf(fname, "%s.%s.maf", out_root, name->chars); idx = ptr_to_int(hsh_get(outfileHash, fname)); if (idx == -1) { hsh_put(outfileHash, fname, int_to_ptr(lst_size(outfileList))); outfile = mafBlock_open_outfile(fname, argc, argv); while (outfile==NULL) { //too many files are open, close one first for (i=0; i<lst_size(outfileList); i++) { outfile = (FILE*)lst_get_ptr(outfileList, i); if (outfile != NULL) break; } if (i == lst_size(outfileList)) { die("ERROR: too many files open in maf_parse\n"); } else { phast_fclose(outfile); lst_set_ptr(outfileList, i, NULL); } outfile = mafBlock_open_outfile(fname, argc, argv); } lst_push_ptr(outfileList, (void*)outfile); sfree(fname); return outfile; } outfile = (FILE*)lst_get_ptr(outfileList, idx); if (outfile == NULL) { //has already been opened but then closed. outfile = phast_fopen_no_exit(fname, "a"); while (outfile == NULL) { for (i=0; i<lst_size(outfileList); i++) { outfile = (FILE*)lst_get_ptr(outfileList, i); if (outfile != NULL) break; } if (i == lst_size(outfileList)) { die("ERROR: too many files open in maf_parse\n"); } else { phast_fclose(outfile); lst_set_ptr(outfileList, i, NULL); } outfile = phast_fopen_no_exit(fname, "a"); } lst_set_ptr(outfileList, idx, (void*)outfile); } sfree(fname); return outfile; }
static error_t parse_opt (int key, char *arg, struct argp_state *state) { switch(key) { case 1001: // --locktime=NNNNN opt_locktime = arg; break; case 1002: // --nversion=NNNNN opt_version = arg; break; case 1003: // --blank opt_blank = true; break; case 1030: // --output-json opt_decode_json = true; break; case 1040: // --strict-free opt_strict_free = true; break; case 1010: { // --txin=TXID:VOUT char *colon = strchr(arg, ':'); if (!colon) return ARGP_ERR_UNKNOWN; if ((colon - arg) != 64) return ARGP_ERR_UNKNOWN; if (!is_digitstr(colon + 1)) return ARGP_ERR_UNKNOWN; char hexstr[65]; memcpy(hexstr, arg, 64); hexstr[64] = 0; if (!is_hexstr(hexstr, false)) return ARGP_ERR_UNKNOWN; opt_txin = clist_append(opt_txin, strdup(arg)); break; } case 1011: { // --delete-txin=INDEX if (!is_digitstr(arg)) return ARGP_ERR_UNKNOWN; opt_del_txin = clist_append(opt_del_txin, int_to_ptr(atoi(arg))); break; } case 1020: { // --txout=ADDRESS:AMOUNT char *colon = strchr(arg, ':'); if (!colon) return ARGP_ERR_UNKNOWN; unsigned int partlen = colon - arg; if (!is_digitstr(colon + 1)) return ARGP_ERR_UNKNOWN; char addrstr[partlen + 1]; memcpy(addrstr, arg, partlen); addrstr[partlen] = 0; cstring *payload = base58_decode_check(NULL, addrstr); bool payload_invalid = (!payload || (payload->len != 21)); cstr_free(payload, true); if (payload_invalid) return ARGP_ERR_UNKNOWN; opt_txout = clist_append(opt_txout, strdup(arg)); break; } case 1021: { // --delete-txout=INDEX if (!is_digitstr(arg)) return ARGP_ERR_UNKNOWN; opt_del_txout = clist_append(opt_del_txout, int_to_ptr(atoi(arg))); break; } case ARGP_KEY_ARG: if (opt_hexdata) return ARGP_ERR_UNKNOWN; opt_hexdata = arg; break; default: return ARGP_ERR_UNKNOWN; } return 0; }