bool PDBFileObject::GetDouble(const char *name, double *val) { bool retval = false; if(AutoOpen()) { syment *ep; if((ep = PD_inquire_entry(pdb, (char *)name, 0, NULL)) != NULL) { debug4 << "PDBFileObject::GetDouble: var="<< name << ", type=" << PD_entry_type(ep) << endl; if(strcmp(PD_entry_type(ep), "double") == 0) { retval = (PD_read(pdb, (char *)name, (void *)val) == TRUE); } else if(strcmp(PD_entry_type(ep), "float") == 0) { float tmp; retval = (PD_read(pdb, (char *)name, (void *)&tmp) == TRUE); if(retval) *val = (double)tmp; } } } return retval; }
/*------------------------------------------------------------------------- * Function: lite_PD_copy_syment * * Purpose: Make and return a copy of the given syment. * * Return: Success: a new syment * * Failure: * * Programmer: Adapted from PACT PDB * Mar 6, 1996 11:39 AM EST * * Modifications: * Eric Brugger, Tue Dec 8 15:16:07 PST 1998 * Remove unnecessary calls to lite_SC_mark, since reference count now * set when allocated. * *------------------------------------------------------------------------- */ syment * lite_PD_copy_syment (syment *osym) { int i, n; char *ntype; syment *nsym; symblock *nsp, *osp; dimdes *ndims; if (osym == NULL) return(NULL); nsym = FMAKE(syment, "PD_COPY_SYMENT:nsym"); n = PD_n_blocks(osym); osp = PD_entry_blocks(osym); nsp = FMAKE_N(symblock, n, "PD_COPY_SYMENT:blocks"); for (i = 0; i < n; i++) nsp[i] = osp[i]; ntype = lite_SC_strsavef(PD_entry_type(osym), "char*:PD_COPY_SYMENT:type"); ndims = lite_PD_copy_dims(PD_entry_dimensions(osym)); PD_entry_blocks(nsym) = nsp; PD_entry_type(nsym) = ntype; PD_entry_dimensions(nsym) = ndims; PD_entry_number(nsym) = PD_entry_number(osym); PD_entry_indirects(nsym) = PD_entry_indirects(osym); return(nsym); }
bool PDBFileObject::GetInteger(const char *name, int *val) { bool retval = false; if(AutoOpen()) { syment *ep; if((ep = PD_inquire_entry(pdb, (char *)name, 0, NULL)) != NULL) { debug4 << "PDBFileObject::GetInteger: var="<< name << ", type=" << PD_entry_type(ep) << endl; if(strcmp(PD_entry_type(ep), "integer") == 0 || strcmp(PD_entry_type(ep), "int") == 0) { // // Get the integer as an array in case there is more than 1 // integer. This way, we don't clobber memory when we read // the integer if it happens to be an array of integers. // int *vals = 0, nvals = 0; if(GetIntegerArray(name, &vals, &nvals) && nvals > 0) { *val = vals[0]; delete [] vals; retval = true; } } else if(strcmp(PD_entry_type(ep), "short") == 0) { short tmp; retval = (PD_read(pdb, (char *)name, (void *)&tmp) == TRUE); if(retval) *val = (short)tmp; } else if(strcmp(PD_entry_type(ep), "long") == 0) { long tmp; retval = (PD_read(pdb, (char *)name, (void *)&tmp) == TRUE); if(retval) *val = (int)tmp; } } } return retval; }
/*------------------------------------------------------------------------- * Function: lite_PD_read_as * * Purpose: Read an entry from the PDB file pointed to by the * symbol table into the location pointed to by VR. Convert * to type TYPE regardless of symbol entry type. * * Note: VR must be a pointer to an object with the type given * by TYPE (PDBLib will allocate space if necessary)! * * Return: Success: Number of items successfully read. * * Failure: 0 * * Programmer: Adapted from PACT PDB * Mar 4, 1996 11:55 AM EST * * Modifications: * *------------------------------------------------------------------------- */ int lite_PD_read_as (PDBfile *file, char *name, char *type, lite_SC_byte *vr) { int err; syment *ep; char msg[MAXLINE], fullpath[MAXLINE]; switch (setjmp(_lite_PD_read_err)) { case ABORT: return(FALSE); case ERR_FREE: return(TRUE); default: memset(lite_PD_err, 0, MAXLINE); break; } /* * Find the effective symbol table entry for the named item. */ ep = _lite_PD_effective_ep(file, name, TRUE, fullpath); if (ep == NULL) { if (snprintf(msg, sizeof(msg), "UNREADABLE OR MISSING ENTRY \"%s\" - PD_READ_AS",fullpath) >= sizeof(msg)) msg[sizeof(msg)-1] = '\0'; lite_PD_error(msg, PD_READ); } if (type == NULL) type = PD_entry_type(ep); err = _lite_PD_hyper_read(file, fullpath, type, ep, vr); _lite_PD_rl_syment_d(ep); return(err); }
/*------------------------------------------------------------------------- * Function: _lite_PD_rl_syment * * Purpose: Reclaim the space of the given syment. * * Return: void * * Programmer: Adapted from PACT PDB * Mar 5, 1996 12:05 PM EST * * Modifications: * *------------------------------------------------------------------------- */ void _lite_PD_rl_syment (syment *ep) { SFREE(PD_entry_type(ep)); SFREE(PD_entry_blocks(ep)); SFREE(ep); }
/*------------------------------------------------------------------------- * Function: _lite_PD_mk_syment * * Purpose: Make and return a pointer to an entry for the symbol table. * * Return: Success: * * Failure: * * Programmer: Adapted from PACT PDB * Mar 5, 1996 2:16 PM EST * * Modifications: * Eric Brugger, Tue Dec 8 15:16:07 PST 1998 * Remove unnecessary calls to lite_SC_mark, since reference count now * set when allocated. * *------------------------------------------------------------------------- */ syment * _lite_PD_mk_syment (char *type, long numb, long addr, symindir *indr, dimdes *dims) { syment *ep; symblock *sp; char *t; ep = FMAKE(syment, "_PD_MK_SYMENT:ep"); sp = FMAKE(symblock, "_PD_MK_SYMENT:sp"); PD_entry_blocks(ep) = sp; sp->number = numb; sp->diskaddr = addr; if (type == NULL) { t = NULL; } else { t = lite_SC_strsavef(type, "char*:_PD_MK_SYMENT:type"); } PD_entry_type(ep) = t; PD_entry_number(ep) = numb; PD_entry_dimensions(ep) = dims; if (indr == NULL) { symindir iloc; iloc.addr = 0L; iloc.n_ind_type = 0L; iloc.arr_offs = 0L; PD_entry_indirects(ep) = iloc; } else { PD_entry_indirects(ep) = *indr; } return(ep); }
static syment * _PD_write (PDBfile *file, char *name, char *intype, char *outtype, lite_SC_byte *vr, dimdes *dims, int appnd) { int reset; syment *ep; long number, addr; char bf[MAXLINE], fullpath[MAXLINE], *lname; _append_flag = FALSE; ep = NULL; switch (setjmp(_lite_PD_write_err)) { case ABORT : return(NULL); case ERR_FREE : return(ep); default : memset(lite_PD_err, 0, MAXLINE); break; } if (file->mode == PD_OPEN) { lite_PD_error("FILE OPENED IN READ-ONLY MODE - _PD_WRITE", PD_WRITE); } strcpy(fullpath, _lite_PD_fixname(file, name)); /* * Append a new block to an existing entry if TRUE. */ if (appnd) { strcpy(bf, fullpath); /* * Do this so that things such as a[20:20].b work properly * NOTE: this also implies that a[20:20].b.c works while * a.b[20:20].c doesn't * for now this defines the semantics of append (10/6/93) */ lname = lite_SC_firsttok(bf, ".()[]"); ep = lite_PD_inquire_entry(file, lname, FALSE, NULL); if (ep == NULL) { lite_PD_error("CAN'T APPEND TO NON-EXISTING ENTRY - _PD_WRITE", PD_WRITE); } _lite_PD_adj_dimensions(file, fullpath, ep); /* * Extend the syment. */ _lite_PD_add_block(file, ep, dims); } addr = file->chrtaddr; ep = _lite_PD_effective_ep(file, fullpath, FALSE, NULL); if (ep != NULL) { /* * If the variable already exists use the existing file info. */ addr = PD_entry_address(ep); _lite_PD_rl_dimensions(dims); lname = fullpath; reset = FALSE; } else { /* * If the variable doesn't exist define it to the file. */ number = _lite_PD_comp_num(dims); ep = _lite_PD_mk_syment(outtype, number, addr, NULL, dims); strcpy(bf, fullpath); lname = lite_SC_firsttok(bf, ".([ "); _lite_PD_e_install(lname, ep, file->symtab); reset = TRUE; } if (file->virtual_internal) { SC_address ad; ad.memaddr = vr; ep->blocks->diskaddr = ad.diskaddr; lite_SC_mark(vr, 1); ep = lite_PD_copy_syment(ep); } else { if (outtype == NULL) outtype = PD_entry_type(ep); if (intype == NULL) intype = outtype; /* * Go to the correct address. */ if (io_seek(file->stream, addr, SEEK_SET)) { lite_PD_error("FSEEK FAILED TO FIND CURRENT ADDRESS - _PD_WRITE", PD_WRITE); } /* * Do the low level write. */ if (!_lite_PD_hyper_write(file, lname, ep, vr, intype)) { lite_PD_error("CAN'T WRITE VARIABLE - _PD_WRITE", PD_WRITE); } /* * If the variable didn't previously exist we're at the end * of the file. */ if (reset) { file->chrtaddr = io_tell(file->stream); if (file->chrtaddr == -1L) { lite_PD_error("CAN'T FIND ADDRESS OF NEXT VARIABLE - _PD_WRITE", PD_WRITE); } /* * Make a releasable copy of the entry * SX depends on this critically!! */ ep = lite_PD_copy_syment(ep); } } return(ep); }
bool PDBFileObject::SymbolExists(const char *name, TypeEnum *t, std::string &typeString, int *nTotalElements, int **dimensions, int *nDims) { bool retval = false; syment *ep = 0; // Indicate that there is no type initially. if (t) *t = NO_TYPE; if (nTotalElements) *nTotalElements = 0; if (dimensions) *dimensions = 0; if (nDims) *nDims = 0; if(AutoOpen()) { if((ep = PD_inquire_entry(pdb, (char *)name, 0, NULL)) != NULL) { dimdes *dimptr = NULL; int i = 0, nd = 0, length = 1; int *dims = 0; // Return the actual name of type typeString = PD_entry_type(ep); // Figure out the number of dimensions and the number of elements // that are in the entire array. dimptr = PD_entry_dimensions(ep); if(dimptr != NULL) { // Figure out the number of dimensions. while(dimptr != NULL) { length *= dimptr->number; dimptr = dimptr->next; ++nd; } // Store the dimensions of the array. dims = new int[nd]; dimptr = PD_entry_dimensions(ep); while(dimptr != NULL) { dims[i++] = dimptr->number; dimptr = dimptr->next; } } else { dims = new int[1]; dims[0] = 1; } // Print the dimensions to the debug log. debug4 << "PDBFileObject::SymbolExists: name=" << name << ", dimensions={"; for(i = 0; i < nd; ++i) debug4 << dims[i] << ", "; debug4 << "}" << endl; // Set some of the return values. if (dimensions) *dimensions = dims; if (nDims) *nDims = nd; if (nTotalElements) *nTotalElements = length; // // Take the storage type along with the length to determine the real // type that we want to report. // if (t) { if(strcmp(PD_entry_type(ep), "char") == 0 || strcmp(PD_entry_type(ep), "string") == 0) *t = (length > 1) ? CHARARRAY_TYPE : CHAR_TYPE; else if(strcmp(PD_entry_type(ep), "short") == 0) *t = (length > 1) ? SHORTARRAY_TYPE : SHORT_TYPE; else if(strcmp(PD_entry_type(ep), "int") == 0 || strcmp(PD_entry_type(ep), "integer") == 0) *t = (length > 1) ? INTEGERARRAY_TYPE : INTEGER_TYPE; else if(strcmp(PD_entry_type(ep), "float") == 0) *t = (length > 1) ? FLOATARRAY_TYPE : FLOAT_TYPE; else if(strcmp(PD_entry_type(ep), "double") == 0) *t = (length > 1) ? DOUBLEARRAY_TYPE : DOUBLE_TYPE; else if(strcmp(PD_entry_type(ep), "long") == 0) *t = (length > 1) ? LONGARRAY_TYPE : LONG_TYPE; else { *t = OBJECT_TYPE; } } retval = true; } } return retval; }
int main(int argc, char** argv) { if(argc < 4) { fprintf(stderr, "Useage: %s <input file> <output file> <t stride>\n", argv[0]); return 1; } int tstride; if(sscanf(argv[3], "%d", &tstride) != 1) { fprintf(stderr, "\tERROR: t stride must be an integer\n"); return 1; } // Open input file PDBfile *in; if((in = PD_open(argv[1], "r")) == NULL) { fprintf(stderr, "\tERROR: Could not open input file '%s'\n", argv[1]); return 1; } // Open output file PDBfile *out; if((out = PD_open(argv[2], "w")) == NULL) { fprintf(stderr, "\tERROR: Could not open output file '%s'\n", argv[2]); return 1; } // Get list of variables int nvars; char **var_names = PD_ls(in, NULL, NULL, &nvars); if((var_names == (char**) NULL) || (nvars < 1)) { fprintf(stderr, "\tERROR: No variables\n"); return 1; } // Go through the variables char *varname; for(int var=0;var<nvars;var++) { varname = var_names[var]; syment *ep; // PDB query types dimdes* dims; // Query size of the variable if((ep = PD_query_entry(in, varname, NULL)) == (syment*) NULL) { fprintf(stderr, "\tError querying variable %s\n", varname); return 1; } dims = PD_entry_dimensions(ep); int nd = 0; // Count number of dimensions int varsize = 1; // Number of elements long inds[12]; while(dims != (dimdes*) NULL) { long min, max; min = dims->index_min; max = dims->index_max; if(nd > 3) { fprintf(stderr, "\tERROR: Can't handle variable '%s': more than 4D\n", varname); return 2; } inds[3*nd] = min; inds[3*nd + 1] = max; inds[3*nd + 2] = 1L; varsize *= max - min + 1; nd++; dims = dims->next; } // Get variable type char *typ; typ = PD_entry_type(ep); if((strcmp(varname, "t_array") == 0) && (nd == 1)) { float *fdata = new float[varsize]; // Read the data from the PDB file inds[2] = tstride; int nread; if( (nread = PD_read_as_alt(in, varname, "float", fdata, inds)) == 0) { fprintf(stderr, "\tWARNING: Could not read t_array. Ignoring\n"); delete[] fdata; continue; } inds[0] = 0L; inds[1] = nread-1; inds[2] = 1L; if(PD_write_alt(out, varname, "float", fdata, 1, inds) == FALSE) { fprintf(stderr, "\tWARNING: Could not write '%s'. Ignoring\n", varname); } delete[] fdata; }else if(nd == 4) { // Reducing time resolution if(strcasecmp(typ, "integer") == 0) { int *idata = new int[varsize]; // Read the data from the PDB file inds[2] = tstride; int nread; if( (nread = PD_read_as_alt(in, varname, "integer", idata, inds)) == 0) { fprintf(stderr, "\tWARNING: Could not read '%s'. Ignoring\n", varname); delete[] idata; continue; } if( nread % (varsize / (inds[1] - inds[0] + 1)) != 0 ) { fprintf(stderr, "ERROR: Accounting error: (%ld, %ld), %d, %d\n", inds[0], inds[1], varsize, nread); delete[] idata; continue; } nread = nread / (varsize / (inds[1] - inds[0] + 1)); inds[0] = 0L; inds[1] = nread - 1; inds[2] = 1L; if(PD_write_alt(out, varname, "integer", idata, 4, inds) == FALSE) { fprintf(stderr, "\tWARNING: Could not write '%s'. Ignoring\n", varname); } delete[] idata; }else if( (strcasecmp(typ, "float") == 0) || (strcasecmp(typ, "double") == 0) ) { // Convert doubles to floats float *fdata = new float[varsize]; // Read the data from the PDB file inds[2] = tstride; int nread; if( (nread = PD_read_as_alt(in, varname, "float", fdata, inds)) == 0) { fprintf(stderr, "\tWARNING: Could not read '%s'. Ignoring\n", varname); delete[] fdata; continue; } if( nread % (varsize / (inds[1] - inds[0] + 1)) != 0 ) { fprintf(stderr, "ERROR: Accounting error: (%ld, %ld), %d, %d\n", inds[0], inds[1], varsize, nread); delete[] fdata; continue; } nread = nread / (varsize / (inds[1] - inds[0] + 1)); inds[0] = 0L; inds[1] = nread - 1; inds[2] = 1L; if(PD_write_alt(out, varname, "float", fdata, 4, inds) == FALSE) { fprintf(stderr, "\tWARNING: Could not write '%s'. Ignoring\n", varname); } delete[] fdata; }else { fprintf(stderr, "\tWARNING: '%s' has unrecognised type '%s'. Ignoring\n", varname, typ); } }else { // Just copy the data across if(strcasecmp(typ, "integer") == 0) { int *idata = new int[varsize]; // Read the data from the PDB file if (PD_read_as(in, varname, "integer", idata) == 0) { fprintf(stderr, "\t\tWARNING: Could not read variable. Ignoring\n"); delete[] idata; continue; } if(PD_write_alt(out, varname, "integer", idata, nd, inds) == FALSE) { fprintf(stderr, "\tWARNING: Could not write variable '%s'\n", varname); } delete[] idata; }else if( (strcasecmp(typ, "float") == 0) || (strcasecmp(typ, "double") == 0) ) { // Convert doubles to floats float *fdata = new float[varsize]; // Read the data from the PDB file if (PD_read_as(in, varname, "float", fdata) == 0) { fprintf(stderr, "\tWARNING: Could not read variable '%s'. Ignoring\n", varname); delete[] fdata; continue; } if(PD_write_alt(out, varname, "float", fdata, nd, inds) == FALSE) { fprintf(stderr, "\tWARNING: Could not write variable '%s'\n", varname); } delete[] fdata; }else { fprintf(stderr, "WARNING: '%s' has unrecognised type '%s'. Ignoring\n", varname, typ); } } } PD_close(in); PD_close(out); return 0; }