/* legacy interface to getdata() */ int GetData(const char *filename, const char *field_code, int first_frame, int first_samp, int num_frames, int num_samp, char return_type, void *data_out, int *error_code) { DIRFILE* D; int nread; dtrace("\"%s\", \"%s\", %i, %i, %i, %i, '%c', %p, %p", filename, field_code, first_frame, first_samp, num_frames, num_samp, return_type, data_out, error_code); D = _GD_GetDirfile(filename, GD_RDONLY, error_code); if (!D) { dreturn("%i", 0); return 0; } nread = (int)gd_getdata64(D, field_code, (off64_t)first_frame, (off64_t)first_samp, (size_t)num_frames, (size_t)num_samp, _GD_LegacyType(return_type), data_out); *error_code = _GD_CopyGlobalError(D); dreturn("%i", nread); return nread; }
static int _GD_CollectFragments(DIRFILE* D, int** f, int fragment, int nf) { int i; int *new_f; dtrace("%p, %p, %i, %i", D, f, fragment, nf); new_f = (int *)_GD_Realloc(D, *f, sizeof(int) * ++nf); if (new_f == NULL) { dreturn("%i", -1); return -1; } new_f[nf - 1] = fragment; for (i = 0; i < D->n_fragment; ++i) if (D->fragment[i].parent == fragment) { nf = _GD_CollectFragments(D, &new_f, i, nf); if (nf == -1) break; } *f = new_f; dreturn("%i", nf); return nf; }
unsigned int _GD_NEntries(DIRFILE *D, struct _gd_private_entry *p, int type, unsigned int flags) { int i; unsigned int u, n = 0; const int special = (type & GD_SPECIAL_ENTRY_BIT) ? type : 0; const gd_entype_t ctype = (type & GD_SPECIAL_ENTRY_BIT) ? GD_NO_ENTRY : (gd_entype_t)type; const int hidden = (flags & GD_ENTRIES_HIDDEN); const int noalias = (flags & GD_ENTRIES_NOALIAS); dtrace("%p, %p, 0x%X, 0x%X", D, p, type, flags); /* check for invalid type */ if (ctype && _GD_InvalidEntype(ctype)) { _GD_SetError(D, GD_E_BAD_ENTRY, GD_E_ENTRY_TYPE, NULL, type, NULL); dreturn("%u", 0); return 0; } if (p) { for (i = 0; i < p->n_meta; ++i) if (_GD_ListEntry(p->p.meta_entry[i], 1, hidden, noalias, special, ctype)) n++; } else { for (u = 0; u < D->n_entries; ++u) if (_GD_ListEntry(D->entry[u], 0, hidden, noalias, special, ctype)) n++; } dreturn("%u", n); return n; }
/* Create new affixes given the current affixes and the new parts indicated * on a /INCLUDE line */ static int _GD_SetFieldAffixes(DIRFILE *D, int me, const char *prefix_in, const char *suffix_in, int standards, int pedantic, const char *format_file, int line, char **prefix, char **suffix) { dtrace("%p, %i, \"%s\", \"%s\", %i, %i, \"%s\", %i, %p, %p", D, me, prefix_in, suffix_in, standards, pedantic, format_file, line, prefix, suffix); /* suffix first, for some reason */ if (suffix_in && suffix_in[0] != '\0') { if (_GD_ValidateField(suffix_in, standards, pedantic, 1, NULL)) { _GD_SetError(D, GD_E_FORMAT, GD_E_FORMAT_BAD_NAME, format_file, line, suffix_in); dreturn("%i", 1); return 1; } if (D->fragment[me].suffix == NULL) *suffix = _GD_Strdup(D, suffix_in); else { *suffix = (char*)_GD_Malloc(D, strlen(D->fragment[me].suffix) + strlen(suffix_in) + 1); if (*suffix) strcat(strcpy(*suffix, suffix_in), D->fragment[me].suffix); } } else if (D->fragment[me].suffix) *suffix = _GD_Strdup(D, D->fragment[me].suffix); if (D->error) { dreturn("%i", 1); return 1; } /* now the prefix */ if (prefix_in && prefix_in[0] != '\0') { if (_GD_ValidateField(prefix_in, standards, pedantic, 1, NULL)) { _GD_SetError(D, GD_E_FORMAT, GD_E_FORMAT_BAD_NAME, format_file, line, prefix_in); dreturn("%i", 1); return 1; } if (D->fragment[me].prefix == NULL) *prefix = _GD_Strdup(D, prefix_in); else { *prefix = (char*)_GD_Malloc(D, strlen(D->fragment[me].prefix) + strlen(prefix_in) + 1); if (*prefix) strcat(strcpy(*prefix, D->fragment[me].prefix), prefix_in); } } else if (D->fragment[me].prefix) *prefix = _GD_Strdup(D, D->fragment[me].prefix); dreturn("%i", D->error); return D->error; }
off64_t _GD_Bzip2Seek(struct _gd_raw_file* file, off64_t count, gd_type_t data_type, unsigned int mode __gd_unused) { struct gd_bzdata *ptr = (struct gd_bzdata *)file->edata; dtrace("%p, %lli, 0x%X, <unused>", file, (long long)count, data_type); count *= GD_SIZE(data_type); if (ptr->base > count) { /* a backwards seek -- reopen the file */ ptr->bzerror = 0; BZ2_bzReadClose(&ptr->bzerror, ptr->bzfile); ptr->bzfile = BZ2_bzReadOpen(&ptr->bzerror, ptr->stream, 0, 0, NULL, 0); if (ptr->bzfile == NULL || ptr->bzerror != BZ_OK) { fclose(ptr->stream); dreturn("%i", -1); return -1; } ptr->pos = ptr->end = 0; ptr->base = ptr->stream_end = 0; } /* seek forward the slow way */ while (ptr->base + ptr->end < count) { int n; ptr->bzerror = 0; n = BZ2_bzRead(&ptr->bzerror, ptr->bzfile, ptr->data, GD_BZIP_BUFFER_SIZE); if (ptr->bzerror == BZ_OK || ptr->bzerror == BZ_STREAM_END) { ptr->base += ptr->end; ptr->end = n; } else { dreturn("%i", -1); return -1; } /* eof */ if (ptr->bzerror != BZ_OK) { ptr->stream_end = 1; break; } } ptr->pos = (ptr->bzerror == BZ_STREAM_END && count >= ptr->base + ptr->end) ? ptr->end : count - ptr->base; dreturn("%lli", (long long)((ptr->base + ptr->pos) / GD_SIZE(data_type))); return (ptr->base + ptr->pos) / GD_SIZE(data_type); }
/* _GD_GetSPF: Get samples per frame for field */ unsigned int _GD_GetSPF(DIRFILE *D, gd_entry_t *E) { unsigned int spf = 0; dtrace("%p, %p", D, E); if (++D->recurse_level >= GD_MAX_RECURSE_LEVEL) { _GD_SetError(D, GD_E_RECURSE_LEVEL, GD_E_RECURSE_CODE, NULL, 0, E->field); dreturn("%u", 0); D->recurse_level--; return 0; } switch(E->field_type) { case GD_RAW_ENTRY: if (!E->e->calculated) _GD_CalculateEntry(D, E, 1); if (!D->error) spf = E->EN(raw,spf); break; case GD_LINCOM_ENTRY: case GD_MULTIPLY_ENTRY: case GD_DIVIDE_ENTRY: case GD_RECIP_ENTRY: case GD_BIT_ENTRY: case GD_PHASE_ENTRY: case GD_LINTERP_ENTRY: case GD_POLYNOM_ENTRY: case GD_SBIT_ENTRY: case GD_WINDOW_ENTRY: case GD_MPLEX_ENTRY: if (_GD_BadInput(D, E, 0, 1)) break; spf = _GD_GetSPF(D, E->e->entry[0]); break; case GD_INDEX_ENTRY: spf = 1; break; case GD_CONST_ENTRY: case GD_CARRAY_ENTRY: case GD_STRING_ENTRY: case GD_ALIAS_ENTRY: case GD_NO_ENTRY: _GD_InternalError(D); } D->recurse_level--; dreturn("%u", spf); return spf; }
static int _GD_ContainsFragment(int* f, int nf, int fragment) { int i; dtrace("%p, %i, %i", f, nf, fragment); for (i = 0; i < nf; ++i) if (f[i] == fragment) { dreturn("%i", 1); return 1; } dreturn("%i", 0); return 0; }
off64_t _GD_AsciiSeek(struct _gd_raw_file* file, off64_t count, gd_type_t data_type __gd_unused, unsigned int mode) { char line[64]; dtrace("%p, %lli, <unused>, 0x%X", file, (long long)count, mode); if (count < file->pos) { rewind((FILE *)file->edata); file->pos = 0; } for (; count > file->pos; ++file->pos) if (fgets(line, 64, (FILE *)file->edata) == NULL) break; if (mode & GD_FILE_WRITE && count > file->pos) { strcpy(line, "0\n"); for (; count > file->pos; ++file->pos) fputs(line, (FILE *)file->edata); } dreturn("%lli", (long long)file->pos); return file->pos; }
int WindowEntry::SetThreshold(const char *threshold) { int r = 0; dtrace("\"%s\"", threshold); SetScalar(0, threshold); if (D != NULL) { r = gd_alter_entry(D->D, E.field, &E, 0); if (!r) { switch(E.u.window.windop) { case GD_WINDOP_EQ: case GD_WINDOP_NE: r = gd_get_constant(D->D, threshold, GD_INT64, &E.u.window.threshold.i); break; case GD_WINDOP_SET: case GD_WINDOP_CLR: r = gd_get_constant(D->D, threshold, GD_UINT64, &E.u.window.threshold.u); break; default: r = gd_get_constant(D->D, threshold, GD_FLOAT64, &E.u.window.threshold.r); break; } } } dreturn("%i", r); return r; }
int _GD_Bzip2Open(int dirfd, struct _gd_raw_file* file, int swap __gd_unused, unsigned int mode __gd_unused) { dtrace("%i, %p, <unused>, <unused>", dirfd, file); file->edata = _GD_Bzip2DoOpen(dirfd, file); if (file->edata == NULL) { dreturn("%i", 1); return 1; } file->mode = GD_FILE_READ; file->idata = 0; dreturn("%i", 0); return 0; }
int gd_alter_frameoffset64(DIRFILE* D, off64_t offset, int fragment, int move) { int i; dtrace("%p, %lli, %i, %i", D, (long long)offset, fragment, move); if (D->flags & GD_INVALID) {/* don't crash */ _GD_SetError(D, GD_E_BAD_DIRFILE, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if ((D->flags & GD_ACCMODE) != GD_RDWR) { _GD_SetError(D, GD_E_ACCMODE, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if (fragment < GD_ALL_FRAGMENTS || fragment >= D->n_fragment) { _GD_SetError(D, GD_E_BAD_INDEX, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if (offset < 0) { _GD_SetError(D, GD_E_RANGE, GD_E_OUT_OF_RANGE, NULL, 0, NULL); dreturn("%i", -1); return -1; } _GD_ClearError(D); if (fragment == GD_ALL_FRAGMENTS) { for (i = 0; i < D->n_fragment; ++i) { _GD_ShiftFragment(D, offset, i, move); if (D->error) break; } } else _GD_ShiftFragment(D, offset, fragment, move); dreturn("%i", (D->error) ? -1 : 0); return (D->error) ? -1 : 0; }
int gd_discard(DIRFILE* D) { int ret; dtrace("%p", D); ret = _GD_ShutdownDirfile(D, 0, 0); dreturn("%i", ret); return ret; }
int gd_close(DIRFILE *D) { int ret; dtrace("%p", D); ret = _GD_ShutdownDirfile(D, 1, 0); dreturn("%i", ret); return ret; }
static struct gd_bzdata *_GD_Bzip2DoOpen(int dirfd, struct _gd_raw_file* file) { int fd; struct gd_bzdata *ptr; dtrace("%i, %p", dirfd, file); if ((ptr = (struct gd_bzdata *)malloc(sizeof(struct gd_bzdata))) == NULL) { dreturn("%p", NULL); return NULL; } if ((fd = gd_OpenAt(file->D, dirfd, file->name, O_RDONLY, 0666)) == -1) { free(ptr); dreturn("%p", NULL); return NULL; } if ((ptr->stream = fdopen(fd, "rb")) == NULL) { close(fd); free(ptr); dreturn("%p", NULL); return NULL; } ptr->bzerror = ptr->stream_end = 0; ptr->bzfile = BZ2_bzReadOpen(&ptr->bzerror, ptr->stream, 0, 0, NULL, 0); if (ptr->bzfile == NULL || ptr->bzerror != BZ_OK) { fclose(ptr->stream); free(ptr); dreturn("%p", NULL); return NULL; } ptr->pos = ptr->end = 0; ptr->base = 0; dreturn("%p", ptr); return ptr; }
int gd_include(DIRFILE* D, const char* file, int fragment_index, unsigned long flags) { int new_fragment; dtrace("%p, \"%s\", %i, 0x%lX", D, file, fragment_index, flags); new_fragment = gd_include_affix(D, file, fragment_index, NULL, NULL, flags); dreturn("%i", new_fragment); return new_fragment; }
off64_t gd_frameoffset64(DIRFILE* D, int fragment) { dtrace("%p, %i", D, fragment); if (D->flags & GD_INVALID) {/* don't crash */ _GD_SetError(D, GD_E_BAD_DIRFILE, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if (fragment < 0 || fragment >= D->n_fragment) { _GD_SetError(D, GD_E_BAD_INDEX, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } _GD_ClearError(D); dreturn("%lli", (long long)D->fragment[fragment].frame_offset); return D->fragment[fragment].frame_offset; }
static const char* _GD_TypeName(DIRFILE* D, gd_type_t data_type) { const char* ptr; dtrace("%p, 0x%X", D, data_type); switch(data_type) { case GD_UINT8: ptr = "UINT8"; break; case GD_INT8: ptr = "INT8"; break; case GD_UINT16: ptr = "UINT16"; break; case GD_INT16: ptr = "INT16"; break; case GD_UINT32: ptr = "UINT32"; break; case GD_INT32: ptr = "INT32"; break; case GD_UINT64: ptr = "UINT64"; break; case GD_INT64: ptr = "INT64"; break; case GD_FLOAT32: ptr = "FLOAT32"; break; case GD_FLOAT64: ptr = "FLOAT64"; break; case GD_COMPLEX64: ptr = "COMPLEX64"; break; case GD_COMPLEX128: ptr = "COMPLEX128"; break; default: _GD_InternalError(D); ptr = ""; break; } dreturn("\"%s\"", ptr); return ptr; }
static void _GD_ScanFormat(char* fmt, gd_type_t data_type) { dtrace("%p, 0x%X", fmt, data_type); switch(data_type) { case GD_UINT8: #ifndef NO_8BIT_INT_PREFIX strcpy(fmt, "%" SCNu8); break; #endif case GD_UINT16: strcpy(fmt, "%" SCNu16); break; case GD_INT8: #ifndef NO_8BIT_INT_PREFIX strcpy(fmt, "%" SCNi8); break; #endif case GD_INT16: strcpy(fmt, "%" SCNi16); break; case GD_UINT32: strcpy(fmt, "%" SCNu32); break; case GD_INT32: strcpy(fmt, "%" SCNi32); break; case GD_UINT64: strcpy(fmt, "%" SCNu64); break; case GD_INT64: strcpy(fmt, "%" SCNi64); break; case GD_FLOAT32: strcpy(fmt, "%f"); break; case GD_FLOAT64: strcpy(fmt, "%lf"); break; case GD_COMPLEX64: strcpy(fmt, "%f;%f"); break; case GD_COMPLEX128: strcpy(fmt, "%lf;%lf"); break; default: fmt[0] = 0; break; } dreturn("[\"%s\"]", fmt); }
static size_t _GD_StringEscapeise(FILE *stream, const char *in, int meta, int permissive, int standards) { const char* HexDigit = "0123456789ABCDEF"; size_t len = 0; dtrace("%p, \"%s\", %i, %i", stream, in, permissive, standards); if (in == NULL || in[0] == '\0') { fputs("\"\"", stream); dreturn("%i", 2); return 2; } if (!permissive && standards < 6) { fputs(in, stream); dreturn("%" PRNsize_t, strlen(in)); return strlen(in); } for (; *in != '\0'; ++in) { if (*in == '"') { fputs("\\\"", stream); len += 2; fputc('\\', stream); } else if (*in == '\\' || *in == '#' || *in == '"' || *in == ' ') { fputc('\\', stream); fputc(*in, stream); len += 2; } else if (*in < 0x20 #if CHAR_MIN != 0 && *in >= 0x00 #endif ) { fputs("\\x", stream); fputc(HexDigit[*in >> 8], stream); fputc(HexDigit[*in & 0xF], stream); len += 4; } else if (meta && *in == '/')
int WindowEntry::SetWindOp(WindOpType windop) { int ret = 0; dtrace("0x%X", (unsigned)windop); E.u.window.windop = (gd_windop_t)windop; if (D != NULL) ret = gd_alter_entry(D->D, E.field, &E, 0); dreturn("%i", ret); return ret; }
int _GD_ShutdownDirfile(DIRFILE* D, int flush_meta, int keep_dirfile) { unsigned int i; dtrace("%p, %i, %i", D, flush_meta, keep_dirfile); if (D == NULL) { dreturn("%i", 0); return 0; } _GD_ClearError(D); /* Flush */ if (flush_meta) _GD_FlushMeta(D, GD_ALL_FRAGMENTS, 0); for(i = 0; i < D->n_entries; ++i) if (D->entry[i]->field_type == GD_RAW_ENTRY) _GD_Flush(D, D->entry[i], 0, 1); if (D->error) { dreturn("%i", 1); return -1; } #ifndef GD_NO_DIR_OPEN /* close the directory */ for (i = 0; i < (unsigned int)D->ndir; ++i) close(D->dir[i].fd); #endif _GD_FreeD(D, keep_dirfile); dreturn("%i", 0); return 0; }
/* _GD_CopyGlobalError: Copy the last error message to the global error buffer. */ static int _GD_CopyGlobalError(DIRFILE* D) { dtrace("%p", D); _GD_GlobalErrors.suberror = D->suberror; _GD_GlobalErrors.error_line = D->error_line; free(_GD_GlobalErrors.error_file); _GD_GlobalErrors.error_file = (D->error_file) ? strdup(D->error_file) : NULL; free(_GD_GlobalErrors.error_string); _GD_GlobalErrors.error_string = (D->error_string) ? strdup(D->error_string) : NULL; dreturn("%i", D->error); return _GD_GlobalErrors.error = D->error; }
int _GD_AsciiOpen(int fd, struct _gd_raw_file* file, int swap __gd_unused, unsigned int mode) { dtrace("%i, %p, <unused>, %u", fd, file, mode); if (!(mode & GD_FILE_TEMP)) { if (file->mode & mode) { dreturn("%i", 0); return 0; } else if (file->edata != NULL) fclose((FILE*)file->edata); file->idata = gd_OpenAt(file->D, fd, file->name, ((mode & GD_FILE_WRITE) ? (O_RDWR | O_CREAT) : O_RDONLY) | O_BINARY, 0666); if (file->idata < 0) { dreturn("%i", -1); return -1; } } else file->idata = fd; file->edata = fdopen(file->idata, (mode & GD_FILE_WRITE) ? "rb+" : "rb"); if (file->edata == NULL) { close(file->idata); file->idata = -1; dreturn("%i", -1); return -1; } file->mode = mode | GD_FILE_READ; file->pos = 0; dreturn("%i", 0); return 0; }
int WindowEntry::SetThreshold(gd_triplet_t threshold) { int ret = 0; dtrace("{%g,%llX,%lli}", threshold.r, (unsigned long long)threshold.u, (long long)threshold.i); E.u.window.threshold = threshold; if (D != NULL) ret = gd_alter_entry(D->D, E.field, &E, 0); dreturn("%i", ret); return ret; }
void BytecodeAssembler::_return(BasicType bt) { switch (bt) { case T_BOOLEAN: case T_CHAR: case T_BYTE: case T_SHORT: case T_INT: ireturn(); break; case T_FLOAT: freturn(); break; case T_DOUBLE: dreturn(); break; case T_LONG: lreturn(); break; case T_OBJECT: case T_ARRAY: areturn(); break; case T_VOID: _return(); break; default: ShouldNotReachHere(); } }
off64_t gd_nframes64(DIRFILE* D) { off64_t nf; dtrace("%p", D); _GD_ClearError(D); if (D->flags & GD_INVALID) {/* don't crash */ _GD_SetError(D, GD_E_BAD_DIRFILE, 0, NULL, 0, NULL); dreturn("%i", 0); return 0; } if (D->reference_field == NULL) { dreturn("%i", 0); return 0; } if (!_GD_Supports(D, D->reference_field, GD_EF_NAME | GD_EF_SIZE)) { dreturn("%i", 0); return 0; } if ((*_gd_ef[D->reference_field->e->u.raw.file[0].subenc].name)(D, (const char*)D->fragment[D->reference_field->fragment_index].enc_data, D->reference_field->e->u.raw.file, D->reference_field->e->u.raw.filebase, 0, 0)) { dreturn("%i", 0); return 0; } nf = (*_gd_ef[D->reference_field->e->u.raw.file[0].subenc].size)( D->fragment[D->reference_field->fragment_index].dirfd, D->reference_field->e->u.raw.file, D->reference_field->EN(raw,data_type), _GD_FileSwapBytes(D, D->reference_field->fragment_index)); if (nf < 0) { _GD_SetError(D, GD_E_RAW_IO, 0, D->reference_field->e->u.raw.file[0].name, errno, NULL); dreturn("%lli", 0LL); return 0; } nf /= D->reference_field->EN(raw,spf); nf += D->fragment[D->reference_field->fragment_index].frame_offset; dreturn("%lli", (unsigned long long)nf); return nf; }
static const char *_GD_WindopName(DIRFILE *D, gd_windop_t op) { const char *ptr; dtrace("%p, %i", D, op); switch(op) { case GD_WINDOP_EQ: ptr = "EQ"; break; case GD_WINDOP_GE: ptr = "GE"; break; case GD_WINDOP_GT: ptr = "GT"; break; case GD_WINDOP_LE: ptr = "LE"; break; case GD_WINDOP_LT: ptr = "LT"; break; case GD_WINDOP_NE: ptr = "NE"; break; case GD_WINDOP_SET: ptr = "SET"; break; case GD_WINDOP_CLR: ptr = "CLR"; break; default: _GD_InternalError(D); ptr = ""; break; } dreturn("\"%s\"", ptr); return ptr; }
static const char* _GD_OldTypeName(DIRFILE* D, gd_type_t data_type) { const char* ptr; dtrace("%p, 0x%X", D, data_type); switch(data_type) { case GD_UINT8: ptr = "c"; break; case GD_UINT16: ptr = "u"; break; case GD_INT16: ptr = "s"; break; case GD_UINT32: ptr = "U"; break; case GD_INT32: ptr = "S"; break; case GD_FLOAT32: ptr = "f"; break; case GD_FLOAT64: ptr = "d"; break; default: _GD_InternalError(D); ptr = ""; break; } dreturn("\"%s\"", ptr); return ptr; }
/* Include a format file fragment -- returns the mew fragment index, or * -1 on error */ int _GD_Include(DIRFILE *D, const char *ename, const char *format_file, int linenum, char **ref_name, int me, const char *prefix_in, const char *suffix_in, int *standards, unsigned long *flags, int resolve) { int i; int old_standards = *standards; int old_pedantic = *flags & GD_PEDANTIC; int dirfd = -1; char *temp_buf1, *temp_buf2, *sname; char *base, *prefix = NULL, *suffix = NULL; void *ptr = NULL; FILE* new_fp = NULL; time_t mtime = 0; struct stat statbuf; dtrace("%p, \"%s\", \"%s\", %p, %i, %i, \"%s\", \"%s\", %p, %p, %i", D, ename, format_file, ref_name, linenum, me, prefix_in, suffix_in, standards, flags, resolve); if (++D->recurse_level >= GD_MAX_RECURSE_LEVEL) { _GD_SetError(D, GD_E_RECURSE_LEVEL, GD_E_RECURSE_INCLUDE, format_file, linenum, ename); D->recurse_level--; dreturn("%i", 0); return 0; } if (_GD_SetFieldAffixes(D, me, prefix_in, suffix_in, old_standards, old_pedantic, format_file, linenum, &prefix, &suffix)) { free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } /* isolate filename */ temp_buf2 = _GD_Strdup(D, ename); if (temp_buf2 == NULL) { free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } base = _GD_Strdup(D, basename(temp_buf2)); if (base == NULL) { free(temp_buf2); free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } free(temp_buf2); /* isolate relative path */ temp_buf2 = _GD_Strdup(D, ename); if (temp_buf2 == NULL) { free(base); free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } sname = _GD_Strdup(D, dirname(temp_buf2)); if (base == NULL) { free(temp_buf2); free(base); free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } free(temp_buf2); /* Open the containing directory */ dirfd = _GD_GrabDir(D, D->fragment[me].dirfd, ename); if (dirfd == -1 && D->error == GD_E_OK) _GD_SetError(D, GD_E_OPEN_FRAGMENT, errno, format_file, linenum, ename); if (D->error) { free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } temp_buf1 = _GD_MakeFullPath(D, dirfd, base, 1); if (temp_buf1 == NULL) { _GD_ReleaseDir(D, dirfd); free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } /* Try to open the file */ i = gd_OpenAt(D, dirfd, base, (((D->flags & GD_ACCMODE) == GD_RDWR) ? O_RDWR : O_RDONLY) | ((*flags & GD_CREAT) ? O_CREAT : 0) | ((*flags & GD_TRUNC) ? O_TRUNC : 0) | ((*flags & GD_EXCL) ? O_EXCL : 0) | O_BINARY, 0666); if (i < 0) { _GD_SetError(D, GD_E_OPEN_FRAGMENT, errno, format_file, linenum, temp_buf1); free(prefix); free(suffix); free(base); free(temp_buf1); D->recurse_level--; dreturn("%i", -1); return -1; } new_fp = fdopen(i, ((D->flags & GD_ACCMODE) == GD_RDWR) ? "rb+" : "rb"); /* If opening the file failed, set the error code and abort parsing. */ if (new_fp == NULL) { _GD_SetError(D, GD_E_OPEN_FRAGMENT, errno, format_file, linenum, temp_buf1); free(prefix); free(suffix); free(base); free(temp_buf1); D->recurse_level--; dreturn("%i", -1); return -1; } /* fstat the file and record the mtime */ if (fstat(i, &statbuf) == 0) mtime = statbuf.st_mtime; /* If we got here, we managed to open the included file; parse it */ ptr = _GD_Realloc(D, D->fragment, (++D->n_fragment) * sizeof(struct gd_fragment_t)); if (ptr == NULL) { D->n_fragment--; fclose(new_fp); free(prefix); free(suffix); free(base); free(temp_buf1); D->recurse_level--; dreturn("%i", -1); return -1; } D->fragment = (struct gd_fragment_t *)ptr; D->fragment[D->n_fragment - 1].bname = base; D->fragment[D->n_fragment - 1].cname = temp_buf1; D->fragment[D->n_fragment - 1].ename = _GD_Strdup(D, ename); D->fragment[D->n_fragment - 1].enc_data = NULL; D->fragment[D->n_fragment - 1].modified = 0; D->fragment[D->n_fragment - 1].parent = me; D->fragment[D->n_fragment - 1].dirfd = dirfd; D->fragment[D->n_fragment - 1].encoding = *flags & GD_ENCODING; D->fragment[D->n_fragment - 1].byte_sex = #ifdef WORDS_BIGENDIAN (*flags & GD_LITTLE_ENDIAN) ? GD_LITTLE_ENDIAN : GD_BIG_ENDIAN #else (*flags & GD_BIG_ENDIAN) ? GD_BIG_ENDIAN : GD_LITTLE_ENDIAN #endif ; D->fragment[D->n_fragment - 1].ref_name = NULL; D->fragment[D->n_fragment - 1].frame_offset = D->fragment[me].frame_offset; D->fragment[D->n_fragment - 1].protection = GD_PROTECT_NONE; D->fragment[D->n_fragment - 1].prefix = prefix; D->fragment[D->n_fragment - 1].suffix = suffix; D->fragment[D->n_fragment - 1].mtime = mtime; D->fragment[D->n_fragment - 1].vers = (*flags & GD_PEDANTIC) ? 1ULL << *standards : 0; /* compute the (relative) subdirectory name */ if (sname[0] == '.' && sname[1] == '\0') { /* dirname is the same as the parent fragment's */ D->fragment[D->n_fragment - 1].sname = (D->fragment[me].sname) ? _GD_Strdup(D, D->fragment[me].sname) : NULL; free(sname); } else if (D->fragment[me].sname && _GD_AbsPath(sname)) { /* have both a relative dirname and the parent's sname; squish them * together */ D->fragment[D->n_fragment - 1].sname = (char*)_GD_Malloc(D, strlen(sname) + strlen(D->fragment[me].sname) + 2); if (D->fragment[D->n_fragment - 1].sname) sprintf(D->fragment[D->n_fragment - 1].sname, "%s%c%s", D->fragment[me].sname, GD_DIRSEP, sname); free(sname); } else /* just save the sname */ D->fragment[D->n_fragment - 1].sname = sname; /* catch alloc errors */ if (D->error) { D->n_fragment--; fclose(new_fp); free(prefix); free(suffix); D->recurse_level--; dreturn("%i", -1); return -1; } *ref_name = _GD_ParseFragment(new_fp, D, D->n_fragment - 1, standards, flags, resolve); fclose(new_fp); /* prevent /VERSION leak in DSV >= 9 */ if ((old_standards >= 9 && old_pedantic) || *standards >= 9) { if (*standards != old_standards) { *standards = old_standards; D->flags |= GD_MULTISTANDARD; } if (!old_pedantic) *flags &= ~GD_PEDANTIC; } D->recurse_level--; dreturn("%i", D->n_fragment - 1); return D->n_fragment - 1; }
int gd_uninclude(DIRFILE* D, int fragment_index, int del) { int parent, j, nf; unsigned int i, o, old_count; int *f = NULL; dtrace("%p, %i, %i", D, fragment_index, del); _GD_ClearError(D); if (D->flags & GD_INVALID) {/* don't crash */ _GD_SetError(D, GD_E_BAD_DIRFILE, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if ((D->flags & GD_ACCMODE) == GD_RDONLY) { _GD_SetError(D, GD_E_ACCMODE, 0, NULL, 0, NULL); dreturn("%i", -1); return -1; } if (fragment_index <= 0 || fragment_index >= D->n_fragment) { _GD_SetError(D, GD_E_BAD_INDEX, 0, NULL, fragment_index, NULL); dreturn("%i", -1); return -1; } parent = D->fragment[fragment_index].parent; if (D->fragment[parent].protection & GD_PROTECT_FORMAT) { _GD_SetError(D, GD_E_PROTECTED, GD_E_PROTECTED_FORMAT, NULL, 0, D->fragment[parent].cname); dreturn("%i", -1); return -1; } /* find all affected fragments */ nf = _GD_CollectFragments(D, &f, fragment_index, 0); if (D->error) { free(f); dreturn("%i", -1); return -1; } /* close affected raw fields */ for (i = 0; i < D->n_entries; ++i) if (D->entry[i]->field_type == GD_RAW_ENTRY && _GD_ContainsFragment(f, nf, D->entry[i]->fragment_index)) { _GD_Flush(D, D->entry[i], 0, 1); } /* flush the fragment's metadata, if requested */ if (!del) for (j = 0; j < nf; ++j) _GD_FlushMeta(D, f[j], 0); if (D->error) { free(f); dreturn("%i", -1); return -1; } /* Nothing from now on may fail */ /* delete the fragments, if requested */ if (del) for (j = 0; j < nf; ++j) gd_UnlinkAt(D, D->fragment[f[j]].dirfd, D->fragment[f[j]].bname, 0); /* delete fields from the fragment -- memory use is not sufficient to warrant * resizing D->entry */ old_count = D->n_entries; for (i = o = 0; i < old_count; ++i) if (_GD_ContainsFragment(f, nf, D->entry[i]->fragment_index)) { if (D->entry[i]->e->n_meta >= 0) D->n_entries--; _GD_FreeE(D, D->entry[i], 1); } else D->entry[o++] = D->entry[i]; /* Flag the parent as modified */ D->fragment[parent].modified = 1; D->flags &= ~GD_HAVE_VERSION; /* delete the fragments -- again, don't bother resizing D->fragment */ for (j = 0; j < nf; ++j) { _GD_ReleaseDir(D, D->fragment[f[j]].dirfd); free(D->fragment[f[j]].cname); free(D->fragment[f[j]].ename); free(D->fragment[f[j]].bname); free(D->fragment[f[j]].ref_name); memcpy(D->fragment + f[j], D->fragment + D->n_fragment - 1, sizeof(struct gd_fragment_t)); D->n_fragment--; /* Relocate all fields of the fragment we just moved */ for (i = 0; i < D->n_entries; ++i) if (D->entry[i]->fragment_index == D->n_fragment) D->entry[i]->fragment_index = f[j]; } /* Clear the cache of all fields */ /* FIXME: Should probably just clear affected fields */ for (i = 0; i < D->n_entries; ++i) { D->entry[i]->e->calculated = 0; for (j = 0; j < GD_MAX_LINCOM; ++j) D->entry[i]->e->entry[j] = NULL; D->entry[i]->e->value_list_validity = 0; D->entry[i]->e->entry_list_validity = 0; } /* Invalidate the field lists */ D->value_list_validity = 0; D->entry_list_validity = 0; free(f); dreturn("%i", 0); return 0; }