int main(const int argc, char* argv[]) { FILE *image; enum exe_type et; if (argc < 2) { fprintf(stderr, "Synopsis: %s file.exe [...]\n", argv[0]); return 0; } #ifdef ENABLE_DEBUG if (!strcmp(argv[1], "--pretend") && argc >= 3) { pretending = 1; argv[1] = argv[2]; /* we won't be using argv[2+] anyway */ } #endif image = fopen(argv[1], "r"); et = detect_format(image); /* image can be NULL here */ if (et == EXE_ERROR) perror("I/O error while reading executable"); if (image) fclose(image); if (et < EXE_ERROR) { char* const handler = read_conf(et); if (handler) doexec(handler, argv); } return 127; }
int main(int argc, char **argv) { scram_fd **in, *out; int n_input, i; bam_seq_t **s; char imode[10], *in_f = "", omode[10], *out_f = ""; int level = '\0'; // nul terminate string => auto level int c, verbose = 0; int s_opt = 0, S_opt = 0, embed_ref = 0; char *ref_fn = NULL; int start, end; char ref_name[1024] = {0}; refs_t *refs = NULL; /* Parse command line arguments */ while ((c = getopt(argc, argv, "u0123456789hvs:S:V:r:XI:O:R:")) != -1) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': level = c; break; case 'u': level = '0'; break; case 'h': usage(stdout); return 0; case 'v': verbose++; break; case 's': s_opt = atoi(optarg); break; case 'S': S_opt = atoi(optarg); break; case 'V': cram_set_option(NULL, CRAM_OPT_VERSION, optarg); break; case 'r': ref_fn = optarg; break; case 'X': embed_ref = 1; break; case 'I': in_f = parse_format(optarg); break; case 'O': out_f = parse_format(optarg); break; case 'R': { char *cp = strchr(optarg, ':'); if (cp) { *cp = 0; switch (sscanf(cp+1, "%d-%d", &start, &end)) { case 1: end = start; break; case 2: break; default: fprintf(stderr, "Malformed range format\n"); return 1; } } else { start = INT_MIN; end = INT_MAX; } strncpy(ref_name, optarg, 1023); break; } case '?': fprintf(stderr, "Unrecognised option: -%c\n", optopt); usage(stderr); return 1; } } /* Open output file */ sprintf(omode, "w%s%c", out_f, level); if (!(out = scram_open("-", omode))) { fprintf(stderr, "Failed to open bam file %s\n", argv[optind+1]); return 1; } /* Open multiple input files */ sprintf(imode, "r%s%c", in_f, level); n_input = argc - optind; if (!n_input) { fprintf(stderr, "No input files specified.\n"); return 1; } if (!(in = malloc(n_input * sizeof(*in)))) return 1; if (!(s = malloc(n_input * sizeof(*s)))) return 1; for (i = 0; i < n_input; i++, optind++) { s[i] = NULL; if (*in_f == 0) sprintf(imode, "r%s%c", detect_format(argv[optind]), level); if (!(in[i] = scram_open(argv[optind], imode))) { fprintf(stderr, "Failed to open bam file %s\n", argv[optind]); return 1; } if (i && !hdr_compare(scram_get_header(in[0]), scram_get_header(in[i]))) { fprintf(stderr, "Incompatible reference sequence list.\n"); fprintf(stderr, "Currently the @SQ lines need to be identical" " in all files.\n"); return 1; } if (!refs && scram_get_refs(in[i])) refs = scram_get_refs(in[i]); if (refs && scram_set_option(in[i], CRAM_OPT_SHARED_REF, refs)) return 1; } /* Set any format specific options */ if (refs) scram_set_option(out, CRAM_OPT_SHARED_REF, refs); if (scram_set_option(out, CRAM_OPT_VERBOSITY, verbose)) return 1; if (s_opt) if (scram_set_option(out, CRAM_OPT_SEQS_PER_SLICE, s_opt)) return 1; if (S_opt) if (scram_set_option(out, CRAM_OPT_SLICES_PER_CONTAINER, S_opt)) return 1; if (embed_ref) if (scram_set_option(out, CRAM_OPT_EMBED_REF, embed_ref)) return 1; /* Copy header and refs from in to out, for writing purposes */ // FIXME: do proper merging of @PG lines // FIXME: track mapping of old PG aux name to new PG aux name per seq scram_set_header(out, sam_hdr_dup(scram_get_header(in[0]))); // Needs doing after loading the header. if (ref_fn) if (scram_set_option(out, CRAM_OPT_REFERENCE, ref_fn)) return 1; if (scram_get_header(in[0])) { if (scram_write_header(out)) return 1; } /* Do the actual file format conversion */ fprintf(stderr, "Opening and loading initial seqs\n"); for (i = 0; i < n_input; i++) { if (scram_get_seq(in[i], &s[i]) < 0) { if (scram_close(in[i])) return 1; in[i] = NULL; free(s[i]); continue; } } fprintf(stderr, "Merging...\n"); for (;;) { int64_t best_val = INT64_MAX; int best_j = 0, j; for (j = 0; j < n_input; j++) { bam_seq_t *b = s[j]; uint64_t x; if (!in[j]) continue; x = (((uint64_t)bam_ref(b))<<33) | (bam_pos(b)<<2) | (bam_strand(b)<<1) | !(bam_flag(b) & BAM_FREAD1); if (best_val > x) { best_val = x; best_j = j; } } if (best_val == INT64_MAX) { // all closed break; } if (-1 == scram_put_seq(out, s[best_j])) return 1; if (scram_get_seq(in[best_j], &s[best_j]) < 0) { if (scram_close(in[best_j])) return 1; in[best_j] = NULL; free(s[best_j]); } } for (i = 0; i < n_input; i++) { if (!in[i]) continue; scram_close(in[i]); if (s[i]) free(s[i]); } /* Finally tidy up and close files */ if (scram_close(out)) return 1; free(in); free(s); return 0; }
void setArguments(){ /* * Verification os file in */ if (fileIn == NULL){ fprintf(stderr, "There is no input file.\n"); exit(-1); } /* * Verification o number of bits. * Number default: 1. */ if (nbBits == -1){ nbBits = 1; } else{ if(nbBits>8 || nbBits <1){ fprintf(stderr, "Not possible to pattern a message with this number of bits\n"); exit(-1); } } /* * Verification of pattern * Default pattern: Direct. */ if(pattern == NULL){ pattern = "DIRECT"; patternInt = 1; } else{ flag = validatePattern(); switch (flag){ case -1: fprintf(stderr, "Not a valid pattern\n"); exit(-1); case 1: patternInt = flag; //Direct Pattern break; case 2: patternInt = flag; //Inverse break; case 3: fprintf(stderr, "External spiral pattern not implemented\n"); exit(-3); case 4: fprintf(stderr, "Internal spiral pattern not implemented\n"); exit(-4); } } /** * Setting and validation os Channels * Default: Red,Green,Blue */ if (channels == NULL){ firstChannel = 2; secondChannel = 1; thirdChannel = 0; }else{ setChannels(); } /** * Validation of Magic Number * Default: 48454C50 */ if(magicHexa == NULL){ magicHexa = "48454C50"; magic = hex_to_str(magicHexa); // magic = "HELP" }else{ magic = hex_to_str(magicHexa); } /** * Validation of Output * Default: Standart (Console) */ if(fileOut != NULL){ isStandard = false; } else { isStandard = true; fileOut = "output.txt"; } /** * Validation of the format of input * If there is no format, the program will detect. * If the format of the image its different of the argument or it is not a format accepted, * the program ends/error. */ img = cvLoadImage(fileIn, 1); // Second parameter == 1 (RGB) || == 0 (GREY) if (img){ //Try to load the image by OpenCv if(formatIn == NULL){ int format = detect_format(fileIn); if (format == -1){ fprintf(stderr, "Not possible to detect format\n"); exit(-1); } } else { flag = validateFormat(); switch (flag) { case 0: //Accepted break; case -1: fprintf(stderr, "%s is not a format accepted\n", formatIn); exit(-1); case -2: fprintf(stderr, "This format is not the format of the image\n"); exit(-2); case -3: fprintf(stderr, "Not a format valid\n"); exit(-2); } } }else{ fprintf(stderr, "Could not open the file\n"); exit(-3); } }
int main(int argc, char **argv) { scram_fd *in, *out; bam_seq_t *s; char imode[10], *in_f = "", omode[10], *out_f = ""; int level = '\0'; // nul terminate string => auto level int c, verbose = 0; int s_opt = 0, S_opt = 0, embed_ref = 0, ignore_md5 = 0, decode_md = 0; char *ref_fn = NULL; int start, end, multi_seq = -1, no_ref = 0; int use_bz2 = 0, use_arith = 0, use_lzma = 0; char ref_name[1024] = {0}; refs_t *refs; int nthreads = 1; t_pool *p = NULL; int max_reads = -1; enum quality_binning binning = BINNING_NONE; /* Parse command line arguments */ while ((c = getopt(argc, argv, "u0123456789hvs:S:V:r:xXeI:O:R:!MmjJZt:BN:")) != -1) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': level = c; break; case 'u': level = '0'; break; case 'h': usage(stdout); return 0; case 'v': verbose++; break; case 's': s_opt = atoi(optarg); break; case 'S': S_opt = atoi(optarg); break; case 'm': decode_md = 1; break; case 'V': if (cram_set_option(NULL, CRAM_OPT_VERSION, optarg)) return 1; break; case 'r': ref_fn = optarg; break; case 'X': fprintf(stderr, "-X is deprecated in favour of -e.\n"); case 'e': embed_ref = 1; break; case 'x': no_ref = 1; break; case 'I': in_f = parse_format(optarg); break; case 'O': out_f = parse_format(optarg); break; case 'R': { char *cp = strchr(optarg, ':'); if (cp) { *cp = 0; switch (sscanf(cp+1, "%d-%d", &start, &end)) { case 1: end = start; break; case 2: break; default: fprintf(stderr, "Malformed range format\n"); return 1; } } else { start = INT_MIN; end = INT_MAX; } strncpy(ref_name, optarg, 1023); break; } case '!': ignore_md5 = 1; break; case 'M': multi_seq = 1; break; case 'j': #ifdef HAVE_LIBBZ2 use_bz2 = 1; #else fprintf(stderr, "Warning: bzip2 support is not compiled into this" " version.\nPlease recompile.\n"); #endif break; case 'J': use_arith = 1; break; case 'Z': #ifdef HAVE_LIBLZMA use_lzma = 1; #else fprintf(stderr, "Warning: lzma support is not compiled into this" " version.\nPlease recompile.\n"); #endif break; case 't': nthreads = atoi(optarg); if (nthreads < 1) { fprintf(stderr, "Number of threads needs to be >= 1\n"); return 1; } break; case 'B': binning = BINNING_ILLUMINA; break; case 'N': // For debugging max_reads = atoi(optarg); break; case '?': fprintf(stderr, "Unrecognised option: -%c\n", optopt); usage(stderr); return 1; } } if (argc - optind > 2) { fprintf(stderr, "Usage: scramble [input_file [output_file]]\n"); return 1; } /* Open up input and output files */ sprintf(imode, "r%s%c", in_f, level); if (argc - optind > 0) { if (*in_f == 0) sprintf(imode, "r%s%c", detect_format(argv[optind]), level); if (!(in = scram_open(argv[optind], imode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind]); return 1; } } else { if (!(in = scram_open("-", imode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind]); return 1; } } if (!in->is_bam && ref_fn) { cram_load_reference(in->c, ref_fn); if (!in->c->refs && !embed_ref) { fprintf(stderr, "Unable to find an appropriate reference.\n" "Please specify a valid reference with " "-r ref.fa option.\n"); return 1; } } sprintf(omode, "w%s%c", out_f, level); if (argc - optind > 1) { if (*out_f == 0) sprintf(omode, "w%s%c", detect_format(argv[optind+1]), level); if (!(out = scram_open(argv[optind+1], omode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind+1]); return 1; } } else { if (!(out = scram_open("-", omode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind+1]); return 1; } } /* Set any format specific options */ scram_set_refs(out, refs = scram_get_refs(in)); scram_set_option(out, CRAM_OPT_VERBOSITY, verbose); if (s_opt) if (scram_set_option(out, CRAM_OPT_SEQS_PER_SLICE, s_opt)) return 1; if (S_opt) if (scram_set_option(out, CRAM_OPT_SLICES_PER_CONTAINER, S_opt)) return 1; if (embed_ref) if (scram_set_option(out, CRAM_OPT_EMBED_REF, embed_ref)) return 1; if (use_bz2) if (scram_set_option(out, CRAM_OPT_USE_BZIP2, use_bz2)) return 1; if (use_arith) if (scram_set_option(out, CRAM_OPT_USE_ARITH, use_arith)) return 1; if (use_lzma) if (scram_set_option(out, CRAM_OPT_USE_LZMA, use_lzma)) return 1; if (binning != BINNING_NONE) if (scram_set_option(out, CRAM_OPT_BINNING, binning)) return 1; if (no_ref) if (scram_set_option(out, CRAM_OPT_NO_REF, no_ref)) return 1; if (multi_seq) if (scram_set_option(out, CRAM_OPT_MULTI_SEQ_PER_SLICE, multi_seq)) return 1; if (decode_md) { if (no_ref) { fprintf(stderr, "Cannot use -m in conjunction with -x.\n"); return 1; } if (scram_set_option(in, CRAM_OPT_DECODE_MD, decode_md)) return 1; } if (nthreads > 1) { if (NULL == (p = t_pool_init(nthreads*2, nthreads))) return 1; if (scram_set_option(in, CRAM_OPT_THREAD_POOL, p)) return 1; if (scram_set_option(out, CRAM_OPT_THREAD_POOL, p)) return 1; } if (ignore_md5) if (scram_set_option(in, CRAM_OPT_IGNORE_MD5, ignore_md5)) return 1; /* Copy header and refs from in to out, for writing purposes */ scram_set_header(out, scram_get_header(in)); // Needs doing after loading the header. if (ref_fn) { if (scram_set_option(out, CRAM_OPT_REFERENCE, ref_fn)) return 1; } else { // Attempt to fill out a cram->refs[] array from @SQ headers scram_set_option(out, CRAM_OPT_REFERENCE, NULL); } if (scram_get_header(out)) { char *arg_list = stringify_argv(argc, argv); if (!arg_list) return 1; if (sam_hdr_add_PG(scram_get_header(out), "scramble", "VN", PACKAGE_VERSION, "CL", arg_list, NULL)) return 1; if (scram_write_header(out)) return 1; free(arg_list); } /* Support for sub-range queries, currently implemented for CRAM only */ if (*ref_name != 0) { cram_range r; int refid; if (in->is_bam) { fprintf(stderr, "Currently the -R option is only implemented for CRAM indices\n"); return 1; } cram_index_load(in->c, argv[optind]); refid = sam_hdr_name2ref(in->c->header, ref_name); if (refid == -1 && *ref_name != '*') { fprintf(stderr, "Unknown reference name '%s'\n", ref_name); return 1; } r.refid = refid; r.start = start; r.end = end; if (scram_set_option(in, CRAM_OPT_RANGE, &r)) return 1; } /* Do the actual file format conversion */ s = NULL; while (scram_get_seq(in, &s) >= 0) { if (-1 == scram_put_seq(out, s)) { fprintf(stderr, "Failed to encode sequence\n"); return 1; } if (max_reads >= 0) if (--max_reads == 0) break; } if (max_reads == -1) { switch(scram_eof(in)) { case 0: fprintf(stderr, "Failed to decode sequence\n"); return 1; case 2: fprintf(stderr, "Warning: no end-of-file block identified. " "File may be truncated.\n"); break; case 1: default: // expected case break; } } /* Finally tidy up and close files */ if (scram_close(in)) return 1; if (scram_close(out)) return 1; if (p) t_pool_destroy(p, 0); if (s) free(s); return 0; }
int main(int argc, char **argv) { scram_fd *in; bam_seq_t *s; char imode[10], *in_f = ""; int level = '\0'; // nul terminate string => auto level int c; char *ref_fn = NULL; int start, end, ignore_md5 = 0; char ref_name[1024] = {0}; bam_flagstat_t st; int nthreads = 1; memset(&st, 0, sizeof(st)); /* Parse command line arguments */ while ((c = getopt(argc, argv, "hI:R:r:!t:")) != -1) { switch (c) { case 'h': usage(stdout); return 0; case 'r': ref_fn = optarg; break; case 'I': in_f = parse_format(optarg); break; case 'R': { char *cp = strchr(optarg, ':'); if (cp) { *cp = 0; switch (sscanf(cp+1, "%d-%d", &start, &end)) { case 1: end = start; break; case 2: break; default: fprintf(stderr, "Malformed range format\n"); return 1; } } else { start = INT_MIN; end = INT_MAX; } strncpy(ref_name, optarg, 1023); break; } case '!': ignore_md5 = 1; break; case 't': nthreads = atoi(optarg); if (nthreads < 1) { fprintf(stderr, "Number of threads needs to be >= 1\n"); return 1; } break; case '?': fprintf(stderr, "Unrecognised option: -%c\n", optopt); usage(stderr); return 1; } } if (argc - optind > 2) { fprintf(stderr, "Usage: scramble [input_file [output_file]]\n"); return 1; } /* Open up input and output files */ sprintf(imode, "r%s%c", in_f, level); if (argc - optind > 0) { if (*in_f == 0) sprintf(imode, "r%s%c", detect_format(argv[optind]), level); if (!(in = scram_open(argv[optind], imode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind]); return 1; } } else { if (!(in = scram_open("-", imode))) { fprintf(stderr, "Failed to open file %s\n", argv[optind]); return 1; } } if (!in->is_bam && ref_fn) cram_load_reference(in->c, ref_fn); if (nthreads > 1) if (scram_set_option(in, CRAM_OPT_NTHREADS, nthreads)) return 1; if (ignore_md5) if (scram_set_option(in, CRAM_OPT_IGNORE_MD5, ignore_md5)) return 1; /* Support for sub-range queries, currently implemented for CRAM only */ if (*ref_name != 0) { cram_range r; int refid; if (in->is_bam) { fprintf(stderr, "Currently the -R option is only implemented for CRAM indices\n"); return 1; } cram_index_load(in->c, argv[optind]); refid = sam_hdr_name2ref(in->c->header, ref_name); if (refid == -1 && *ref_name != '*') { fprintf(stderr, "Unknown reference name '%s'\n", ref_name); return 1; } r.refid = refid; r.start = start; r.end = end; if (scram_set_option(in, CRAM_OPT_RANGE, &r)) return 1; } /* Do the actual file format conversion */ s = NULL; while (scram_get_seq(in, &s) >= 0) { int w = s->flag & BAM_FQCFAIL ? 1 : 0; ++st.n_reads[w]; if (s->flag & BAM_FPAIRED) { ++st.n_pair_all[w]; if (s->flag & BAM_FPROPER_PAIR) ++st.n_pair_good[w]; if (s->flag & BAM_FREAD1) ++st.n_read1[w]; if (s->flag & BAM_FREAD2) ++st.n_read2[w]; if ((s->flag & BAM_FMUNMAP) && !(s->flag & BAM_FUNMAP)) ++st.n_sgltn[w]; if (!(s->flag & BAM_FUNMAP) && !(s->flag & BAM_FMUNMAP)) { ++st.n_pair_map[w]; if (s->mate_ref != s->ref) { ++st.n_diffchr[w]; if (s->map_qual >= 5) ++st.n_diffhigh[w]; } } } if (!(s->flag & BAM_FUNMAP)) ++st.n_mapped[w]; if (s->flag & BAM_FDUP) ++st.n_dup[w]; } if (s) free(s); if (!scram_eof(in)) return 1; if (scram_close(in)) return 1; printf("%lld + %lld in total (QC-passed reads + QC-failed reads)\n", st.n_reads[0], st.n_reads[1]); printf("%lld + %lld duplicates\n", st.n_dup[0], st.n_dup[1]); printf("%lld + %lld mapped (%.2f%%:%.2f%%)\n", st.n_mapped[0], st.n_mapped[1], (float)st.n_mapped[0] / st.n_reads[0] * 100.0, (float)st.n_mapped[1] / st.n_reads[1] * 100.0); printf("%lld + %lld paired in sequencing\n", st.n_pair_all[0], st.n_pair_all[1]); printf("%lld + %lld read1\n", st.n_read1[0], st.n_read1[1]); printf("%lld + %lld read2\n", st.n_read2[0], st.n_read2[1]); printf("%lld + %lld properly paired (%.2f%%:%.2f%%)\n", st.n_pair_good[0], st.n_pair_good[1], (float)st.n_pair_good[0] / st.n_pair_all[0] * 100.0, (float)st.n_pair_good[1] / st.n_pair_all[1] * 100.0); printf("%lld + %lld with itself and mate mapped\n", st.n_pair_map[0], st.n_pair_map[1]); printf("%lld + %lld singletons (%.2f%%:%.2f%%)\n", st.n_sgltn[0], st.n_sgltn[1], (float)st.n_sgltn[0] / st.n_pair_all[0] * 100.0, (float)st.n_sgltn[1] / st.n_pair_all[1] * 100.0); printf("%lld + %lld with mate mapped to a different chr\n", st.n_diffchr[0], st.n_diffchr[1]); printf("%lld + %lld with mate mapped to a different chr (mapQ>=5)\n", st.n_diffhigh[0], st.n_diffhigh[1]); return 0; }
static int read_spec(struct mtree_reader *r, char *s) { struct mtree_entry *entry; char name[MAXPATHLEN]; char *slash, *file, *word, *next; int ret; int skip = 0; /* Try to detect the format if it isn't known yet. */ if (r->path_last == -1 && detect_format(r, s) == -1) return (-1); if (r->path_last != 1) { /* * Path is surely in the first field, either because we know * the format or there is just one single field. */ read_word(s, &file, &next); assert(file != NULL); if (IS_DOTDOT(file)) { /* Only change the parent, keywords are ignored. */ if (r->parent == NULL) { mtree_reader_set_error(r, EINVAL, "`..' not allowed, no parent directory"); return (-1); } r->parent = r->parent->parent; return (0); } } entry = mtree_entry_create_empty(); if (entry == NULL) { mtree_reader_set_error(r, errno, NULL); return (-1); } if (r->path_last != 1) { if (next != NULL) { /* Read keyword that follow the path. */ ret = read_keywords(r, next, &entry->data, 1); if (ret == -1) { mtree_entry_free(entry); return (-1); } } } else { /* Path is at the end, read the keywords first. */ for (file = NULL; file == NULL;) { read_word(s, &word, &next); assert(word != NULL); if (next != NULL) { ret = read_keyword(r, word, &entry->data, 1); if (ret == -1) { mtree_entry_free(entry); return (-1); } s = next; } else file = word; } assert(file != NULL); if (IS_DOTDOT(file)) { mtree_reader_set_error(r, EINVAL, "`..' not allowed in " "this format"); mtree_entry_free(entry); return (-1); } } /* Copy /set values to the entry. */ mtree_entry_data_copy_keywords(&entry->data, &r->defaults, r->defaults.keywords, 0); /* * See if we should skip this file. */ if (SKIP_TYPE(r->options, entry->data.type)) { /* * With directories in version 1.0 format, we'll have to worry * about potentially setting the directory as the current * parent, other types can be skipped immediately. */ if (entry->data.type != MTREE_ENTRY_DIR || r->path_last == 1) goto skip; else skip = 1; } /* Save the file path and name. */ if (strnunvis(name, sizeof(name), file) == -1) { mtree_reader_set_error(r, ENAMETOOLONG, "File name too long: `%s'", file); mtree_entry_free(entry); return (-1); } if ((slash = strchr(name, '/')) != NULL) { /* * If the name contains a slash, it is a relative path. * These do not change the working directory. */ if (skip) goto skip; ret = mtree_cleanup_path(name, &entry->path, &entry->name); if (ret == -1) { mtree_reader_set_error(r, errno, NULL); mtree_entry_free(entry); return (-1); } } else { entry->name = strdup(name); if (entry->name == NULL) { mtree_reader_set_error(r, errno, NULL); mtree_entry_free(entry); return (-1); } entry->parent = r->parent; entry->path = create_v1_path(entry); if (entry->path == NULL) { mtree_reader_set_error(r, errno, NULL); mtree_entry_free(entry); return (-1); } } /* * We may want to skip this entry if a filter told us to skip * children of a directory, which is a parent of this entry. * * There is also no need to worry about changing the parent if * this happens. */ if (!skip && r->skip_trie != NULL) { char *tok; char *endptr; for (tok = strtok_r(name, "/", &endptr); tok != NULL; tok = strtok_r(NULL, "/", &endptr)) { if (mtree_trie_find(r->skip_trie, tok) != NULL) { mtree_entry_free(entry); return (0); } } } /* * Mark the current entry as the current directory. This only applies * to classic (1.0) entries and must be done after keywords are read. */ if (slash == NULL && entry->data.type == MTREE_ENTRY_DIR) r->parent = entry; if (skip) goto skip; if (r->filter != NULL) { int result; /* Apply filter. */ result = r->filter(entry, r->filter_data); if (result & MTREE_ENTRY_SKIP_CHILDREN) { if (entry->data.type == MTREE_ENTRY_DIR) { struct mtree_entry *found, *start; if (r->skip_trie == NULL) { r->skip_trie = mtree_trie_create(NULL); if (r->skip_trie == NULL) { mtree_reader_set_error(r, errno, NULL); return (-1); } } if (mtree_trie_insert(r->skip_trie, entry->path, TRIE_ITEM) == -1) { mtree_reader_set_error(r, errno, NULL); return (-1); } strcpy(name, entry->path); strcat(name, "/"); /* * Remove children that are already in the * list. */ start = r->entries; for (;;) { found = mtree_entry_find_prefix(start, name); if (found == NULL) break; start = found->next; r->entries = mtree_entry_unlink( r->entries, found); mtree_entry_free(found); } } } if (result & MTREE_ENTRY_SKIP) goto skip; } r->entries = mtree_entry_prepend(r->entries, entry); return (0); skip: /* * Skipping directory which is the current parent would make its files * end up in a wrong directory. * * Keep such entries in a list of `loose' entries instead, these will * be deleted when all the work is done. */ if (entry == r->parent) r->loose = mtree_entry_prepend(r->loose, entry); else mtree_entry_free(entry); return (0); }