Add
* routines to read string records, and interpret as welldate. (unfinished) * Routine to read chunks of data from file, with '--' as comment mark, '3*3.1415' for repeated values and '/' for termination of read.
This commit is contained in:
parent
a401f72ca7
commit
a2aaf9c590
614
common/io/readtokens.cpp
Normal file
614
common/io/readtokens.cpp
Normal file
@ -0,0 +1,614 @@
|
||||
/* Copyright 2010 (c) Jostein R. Natvig <Wbfgrva.angivt@tznvy.pbz> */
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cassert>
|
||||
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Interface for parsing records of '/'-separated strings */
|
||||
/* ------------------------------------------------------------------ */
|
||||
#define BUFSIZE 1024
|
||||
|
||||
struct State {
|
||||
int error;
|
||||
int lineno;
|
||||
};
|
||||
|
||||
static int parse_next_token (FILE *fp, struct State *s, char **t, int *c);
|
||||
static char *get_token_string (FILE *fp, struct State *s, char *buf);
|
||||
static void split_token_string (char *str, char *rstr, char *vstr);
|
||||
static int get_default_count (char *rstr, struct State *s);
|
||||
static void skip_line (FILE *fp, struct State *s);
|
||||
static char *string_to_int (int *value, char *str);
|
||||
|
||||
|
||||
static int
|
||||
readtokens(FILE *fp, char **tokens, int numtokens, struct State *s)
|
||||
{
|
||||
char *token;
|
||||
int defaultcount;
|
||||
int i;
|
||||
int pos;
|
||||
int finish;
|
||||
|
||||
defaultcount = 0;
|
||||
s->error = 0;
|
||||
pos = 0;
|
||||
|
||||
while ((finish=parse_next_token(fp, s, &token, &defaultcount)) && pos < numtokens)
|
||||
{
|
||||
if (defaultcount == 0)
|
||||
{
|
||||
tokens[pos++] = token;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defaultcount > numtokens - pos)
|
||||
{
|
||||
fprintf(stderr, "Too many default values '%s' on line %d. ", token, s->lineno);
|
||||
break;
|
||||
}
|
||||
|
||||
for (i=0; i<defaultcount; ++i)
|
||||
{
|
||||
tokens[pos++] = NULL; /* strdup("DEFAULT"); */
|
||||
}
|
||||
|
||||
free(token);
|
||||
}
|
||||
}
|
||||
|
||||
for (; pos < numtokens; ++pos)
|
||||
{
|
||||
tokens[pos] = NULL; /* strdup("DEFAULT"); */
|
||||
}
|
||||
|
||||
if (finish != 0)
|
||||
{
|
||||
fprintf(stderr, "Too many tokens?\n");
|
||||
}
|
||||
return finish == 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int
|
||||
parse_next_token(FILE *fp, struct State *s, char **tok,
|
||||
int *count)
|
||||
{
|
||||
char str[BUFSIZE];
|
||||
char rstr[BUFSIZE];
|
||||
char vstr[BUFSIZE];
|
||||
int ok = 1;
|
||||
|
||||
str[0]='\0';
|
||||
while (strlen(str)==0)
|
||||
{
|
||||
get_token_string(fp, s, str);
|
||||
}
|
||||
|
||||
if (str[0] == '/')
|
||||
{
|
||||
ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tok = strdup(str);
|
||||
*count = 0;
|
||||
|
||||
split_token_string(str, rstr, vstr);
|
||||
|
||||
if ((strlen(rstr)>0) && (strlen(vstr)==0))
|
||||
{
|
||||
*count = get_default_count(rstr, s);
|
||||
|
||||
if (s->error)
|
||||
{
|
||||
fprintf(stderr, "Warning: string token ends with a '*'\n");
|
||||
|
||||
/* attempt to proceed */
|
||||
s->error = 0;
|
||||
*count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
split_token_string(char *str, char *rstr, char *vstr)
|
||||
{
|
||||
/* str:'rrrr*vvvv' -> rstr:'rrrr' vstr:'vvvv' */
|
||||
char *ptr;
|
||||
|
||||
ptr=strchr(str, '*');
|
||||
if ((ptr != NULL) && (ptr!=str)) {
|
||||
while(str!=ptr)
|
||||
{
|
||||
*rstr++=*str++;
|
||||
}
|
||||
*rstr='\0';
|
||||
|
||||
str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rstr[0]='\0';
|
||||
}
|
||||
|
||||
while((*vstr++=*str++))
|
||||
{
|
||||
;
|
||||
}
|
||||
*vstr='\0';
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int
|
||||
get_default_count(char *rstr, struct State *s)
|
||||
{
|
||||
int r;
|
||||
char *ptr;
|
||||
|
||||
if (strlen(rstr)>0)
|
||||
{
|
||||
ptr=string_to_int(&r, rstr);
|
||||
|
||||
/* no conversion, extra characters, ... */
|
||||
if ((ptr==rstr) || (strlen(ptr)>0) || (r<1))
|
||||
{
|
||||
s->error = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* hint: always read '/' as a separate token */
|
||||
|
||||
static char *
|
||||
get_token_string(FILE *fp, struct State *s, char *str)
|
||||
{
|
||||
char *ptr = str;
|
||||
int c;
|
||||
int quote=0;
|
||||
|
||||
/* skip leading blanks */
|
||||
while((c = fgetc(fp)) != EOF && isspace(c)) {if (c=='\n') s->lineno++;}
|
||||
|
||||
|
||||
/* catch end marker */
|
||||
if (c == '/') {
|
||||
skip_line(fp, s);
|
||||
*ptr++ = c;
|
||||
*ptr++ = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/* otherwise, read the wole token in the next block*/
|
||||
ungetc(c, fp);
|
||||
|
||||
while((c = fgetc(fp)) != EOF && (quote || !isspace(c)))
|
||||
{
|
||||
*ptr++ = c;
|
||||
if (c=='\''){
|
||||
quote = quote ? 0 : 1;
|
||||
}
|
||||
|
||||
/* Break and skip rest of line if '--' if encountered */
|
||||
if (*(ptr-1) == '-' && ptr-str>1 && *(ptr-2) == '-'){
|
||||
ptr = ptr - 2;
|
||||
skip_line(fp, s);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If end marker is encontered, push character back onto stream. */
|
||||
if (c=='/') {
|
||||
ungetc(c, fp);
|
||||
ptr--;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(ptr-str < BUFSIZE);
|
||||
}
|
||||
|
||||
if (c=='\n')
|
||||
{
|
||||
s->lineno++;
|
||||
}
|
||||
|
||||
*ptr='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
skip_line(FILE *fp, struct State *s)
|
||||
{
|
||||
int c;
|
||||
while((c = fgetc(fp))!=EOF && c != '\n') {
|
||||
;
|
||||
}
|
||||
++s->lineno;
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static char *
|
||||
string_to_int(int *value, char *str)
|
||||
{
|
||||
char *q;
|
||||
*value = strtol(str, &q, 10);
|
||||
return q;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int
|
||||
all_defaults(char **t, int n)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<n; ++i)
|
||||
{
|
||||
if (t[i] != NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
// Convert this to std::vector<std::string>
|
||||
struct Record {
|
||||
char **fields;
|
||||
size_t numfields;
|
||||
|
||||
Record(size_t n)
|
||||
{
|
||||
numfields = n;
|
||||
fields = new char*[numfields];
|
||||
for(size_t i=0; i<numfields; ++i)
|
||||
{
|
||||
fields[i] = NULL;
|
||||
}
|
||||
}
|
||||
~Record() {
|
||||
for (size_t i=0; i<numfields; ++i)
|
||||
{
|
||||
free(fields[i]);
|
||||
fields[i] = NULL;
|
||||
}
|
||||
delete fields;
|
||||
}
|
||||
Record(const Record& R)
|
||||
{
|
||||
numfields = R.numfields;
|
||||
fields = new char*[numfields];
|
||||
for(size_t i=0; i<numfields; ++i)
|
||||
{
|
||||
if (R.fields[i] != NULL)
|
||||
{
|
||||
fields[i] = strdup(R.fields[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fields[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display(FILE *stream)
|
||||
{
|
||||
fprintf(stream, "[");
|
||||
for(size_t i=0; i<numfields; ++i)
|
||||
{
|
||||
fprintf(stream, "%s, ", fields[i]);
|
||||
}
|
||||
fprintf(stream, "\b\b]\n");
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void read_records(const char *fn, size_t record_width, std::vector<Record> &v)
|
||||
{
|
||||
Record r(record_width);
|
||||
struct State s = {0, 1};
|
||||
|
||||
FILE *fp = fopen(fn, "r");
|
||||
int ok;
|
||||
|
||||
/* read until am empty record is found (which is read as 'only
|
||||
* default values') */
|
||||
while ( (1 == (ok=readtokens (fp, r.fields, r.numfields, &s))) &&
|
||||
(0 == all_defaults (r.fields, r.numfields)) )
|
||||
{
|
||||
v.push_back(r);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void
|
||||
display_records(std::vector<Record> v, FILE *stream)
|
||||
{
|
||||
for (size_t i=0; i<v.size(); ++i)
|
||||
{
|
||||
v[i].display(stream);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
void
|
||||
read_compdat(const char *fn, std::vector<Record> &v)
|
||||
{
|
||||
size_t sz = 14;
|
||||
read_records(fn, sz, v);
|
||||
}
|
||||
void
|
||||
read_welspecs(const char *fn, std::vector<Record> &v)
|
||||
{
|
||||
size_t sz = 16;
|
||||
read_records(fn, sz, v);
|
||||
}
|
||||
void
|
||||
read_wconinje(const char *fn, std::vector<Record> &v)
|
||||
{
|
||||
size_t sz = 14;
|
||||
read_records(fn, sz, v);
|
||||
}
|
||||
|
||||
static char *trimspace (char *str)
|
||||
{
|
||||
char *ibuf, *obuf;
|
||||
|
||||
if (str) {
|
||||
for (ibuf = obuf = str; *ibuf; ) {
|
||||
while (*ibuf && (isspace (*ibuf))) {
|
||||
ibuf++;
|
||||
}
|
||||
if (*ibuf && (obuf != str)) {
|
||||
*(obuf++) = ' ';
|
||||
}
|
||||
while (*ibuf && (!isspace (*ibuf))) {
|
||||
*(obuf++) = *(ibuf++);
|
||||
}
|
||||
}
|
||||
*obuf = '\0';
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
static char* remove_quotes(char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
if ((str[0]=='\'') && (str[strlen(str)-1]=='\''))
|
||||
{
|
||||
str[0] = ' ';
|
||||
str[len-1] = '\0';
|
||||
trimspace(str);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
static void get_wellnames(std::vector<Record> welspecs, Record &wnames)
|
||||
{
|
||||
int n = welspecs.size();
|
||||
|
||||
for (int i=0; i<n; ++i)
|
||||
{
|
||||
assert(welspecs[i].fields[0] != NULL);
|
||||
|
||||
wnames.fields[i] = strdup(remove_quotes(welspecs[i].fields[0]));
|
||||
}
|
||||
}
|
||||
static int get_well_number(Record wnames, char *name)
|
||||
{
|
||||
size_t i;
|
||||
for(i=0; i<wnames.numfields; ++i)
|
||||
{
|
||||
if (strcmp(wnames.fields[i], remove_quotes(name))!=0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static double effective_pressure_radius(const Record &completion,
|
||||
double dx, double dy, double dz,
|
||||
double kx, double ky, double kz)
|
||||
{
|
||||
double k1,k2,dx1,dx2;
|
||||
double r0;
|
||||
|
||||
// assert( completion != NULL);
|
||||
|
||||
if (completion.fields[13] != NULL)
|
||||
{
|
||||
sscanf(completion.fields[13], "%lf", &r0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if a field is NULL, use the default value */
|
||||
if ((completion.fields[12] == NULL) ||
|
||||
(strcmp(completion.fields[12], "Z")==0))
|
||||
{
|
||||
dx1=dx;dx2=dy;k1=kx;k2=ky;
|
||||
}
|
||||
else if (strcmp(completion.fields[12], "X")==0)
|
||||
{
|
||||
dx1=dy;dx2=dz;k1=ky;k2=kz;
|
||||
}
|
||||
else if(strcmp(completion.fields[12], "Y")==0)
|
||||
{
|
||||
dx1=dx;dx2=dz;k1=kx;k2=kz;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "ERROR: unsupported completion direction (item 13)\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Effective pressure radius used in Peaceman formula for
|
||||
* rectangular grid block and permeability aligned with axes
|
||||
* of grid cell */
|
||||
r0 = 0.28;
|
||||
r0 *= sqrt(sqrt(k2/k1)*dx1*dx1 + sqrt(k1/k2)*dx2*dx2);
|
||||
r0 /= sqrt(sqrt(k1/k2)) + sqrt(sqrt(k2/k1));
|
||||
}
|
||||
|
||||
return r0;
|
||||
}
|
||||
static double compute_transmissibility(const Record &completion)
|
||||
{
|
||||
double r;
|
||||
double r0;
|
||||
double kh;
|
||||
double skin = 0;
|
||||
double twopi = 6.283185307179586;
|
||||
|
||||
double trans = -1.0;
|
||||
|
||||
if (completion.fields[7] != NULL )
|
||||
{
|
||||
sscanf(completion.fields[7], "%lf", &trans);
|
||||
}
|
||||
|
||||
|
||||
if (completion.fields[7] == NULL || trans == 0)
|
||||
{
|
||||
|
||||
if(completion.fields[8] !=NULL)
|
||||
{
|
||||
sscanf(completion.fields[8], "%lf", &r);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.3048;
|
||||
}
|
||||
|
||||
if(completion.fields[9] !=NULL)
|
||||
{
|
||||
sscanf(completion.fields[9], "%lf", &kh);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
kh = 1;
|
||||
}
|
||||
|
||||
if(completion.fields[10]!=NULL)
|
||||
{
|
||||
sscanf(completion.fields[10], "%lf", &skin);
|
||||
}
|
||||
else
|
||||
{
|
||||
skin = 0;
|
||||
}
|
||||
|
||||
r0 = effective_pressure_radius(completion, 100,100,1,10,10,1);
|
||||
|
||||
trans = twopi*kh/(logf(r0/r)+skin);
|
||||
|
||||
}
|
||||
return trans;
|
||||
}
|
||||
static void get_well_completions(const Record &completion,
|
||||
std::vector<Record> welspecs,
|
||||
int dims[3],
|
||||
std::vector<std::vector<int> > &completions)
|
||||
{
|
||||
int k;
|
||||
int i,j,k1,k2;
|
||||
int pcell;
|
||||
Record wnames(welspecs.size());
|
||||
|
||||
get_wellnames(welspecs, wnames);
|
||||
int wnum = get_well_number(wnames, completion.fields[0]);
|
||||
|
||||
assert(completion.fields[1]!=NULL);
|
||||
assert(completion.fields[2]!=NULL);
|
||||
assert(completion.fields[3]!=NULL);
|
||||
assert(completion.fields[4]!=NULL);
|
||||
|
||||
sscanf(completion.fields[1], "%d", &i);
|
||||
sscanf(completion.fields[2], "%d", &j);
|
||||
sscanf(completion.fields[3], "%d", &k1);
|
||||
sscanf(completion.fields[4], "%d", &k2);
|
||||
|
||||
|
||||
|
||||
compute_transmissibility(completion);
|
||||
|
||||
fprintf(stderr, "%d %d %d %d: ", i,j,k1,k2);
|
||||
|
||||
i = i==0 ? 0 : i-1;
|
||||
j = j==0 ? 0 : j-1;
|
||||
k1 = k1==0 ? 0 : k1-1;
|
||||
k2 = k2==0 ? 0 : k2-1;
|
||||
|
||||
for (k = k1; k<=k2; ++k)
|
||||
{
|
||||
pcell = i + dims[0]*(j + dims[1]*k);
|
||||
completions[wnum].push_back(pcell);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<Record> compdat;
|
||||
read_compdat("compdat.txt", compdat);
|
||||
display_records(compdat, stderr);
|
||||
fprintf(stderr, "\n\n");
|
||||
|
||||
std::vector<Record> welspecs;
|
||||
read_welspecs("welspecs.txt", welspecs);
|
||||
display_records(welspecs, stderr);
|
||||
fprintf(stderr, "\n\n");
|
||||
|
||||
std::vector<Record> wconinje;
|
||||
read_wconinje("wconinje.txt", wconinje);
|
||||
display_records(wconinje, stderr);
|
||||
|
||||
Record wnames(welspecs.size());
|
||||
get_wellnames(welspecs, wnames);
|
||||
wnames.display(stderr);
|
||||
|
||||
int dims[3] = {10,10,5};
|
||||
std::vector<std::vector<int> > completions(2);
|
||||
for (size_t i=0; i<compdat.size(); ++i)
|
||||
{
|
||||
get_well_completions(compdat[i], welspecs, dims, completions);
|
||||
}
|
||||
|
||||
fprintf(stderr, "here:\n");
|
||||
for (size_t i=0; i<completions.size(); ++i)
|
||||
{
|
||||
fprintf(stderr, "%d: ", (int)i);
|
||||
for (size_t j=0; j<completions[i].size(); ++j)
|
||||
{
|
||||
fprintf(stderr, "%d ", completions[i][j]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
282
common/io/readvector.cpp
Normal file
282
common/io/readvector.cpp
Normal file
@ -0,0 +1,282 @@
|
||||
/* Copyright 2010 (c) Jostein R. Natvig <jostein.natvig@gmail.com> */
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct ParserState {
|
||||
int error;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static void parse_next_token (FILE *fp, struct ParserState *s,
|
||||
T *v, int *count);
|
||||
static char *get_token_string (FILE *fp, struct ParserState *s, char *buf);
|
||||
static void skip_line (FILE *fp, struct ParserState *s);
|
||||
static char *convert_string (int *value, char *str);
|
||||
static char *convert_string (double *value, char *str);
|
||||
static void split_token_string(char *str, char *rstr, char *vstr);
|
||||
static int get_repeat_count (char *rstr, struct ParserState *s);
|
||||
template <typename T>
|
||||
static void get_value (char *vstr, struct ParserState *s, T *v);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static const int bufsz = 1024;
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
template <typename T>
|
||||
static void readvector(FILE *fp, struct ParserState *s, std::vector<T>& v)
|
||||
{
|
||||
T value;
|
||||
int count, i;
|
||||
int ret;
|
||||
int ok;
|
||||
|
||||
count = 1;
|
||||
s->error = 0;
|
||||
while (count > 0){
|
||||
|
||||
parse_next_token(fp, s, &value, &count);
|
||||
for (i=0; i<count; ++i)
|
||||
{
|
||||
v.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->error) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
template <typename T>
|
||||
static void parse_next_token(FILE *fp, struct ParserState *s, T *v, int *r)
|
||||
{
|
||||
char str[bufsz], *ptr;
|
||||
char rstr[bufsz];
|
||||
char vstr[bufsz];
|
||||
|
||||
str[0]='\0';
|
||||
while (strlen(str)==0)
|
||||
{
|
||||
get_token_string(fp, s, str);
|
||||
}
|
||||
|
||||
if (str[0] == '/')
|
||||
{
|
||||
/* end-of-vector marker */
|
||||
*r = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
split_token_string(str, rstr, vstr);
|
||||
*r = get_repeat_count(rstr, s);
|
||||
get_value(vstr, s, v);
|
||||
|
||||
if (s->error)
|
||||
{
|
||||
/* signal abort to caller */
|
||||
*r = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
/* split string 'rrrr*vvvv' in strings 'rrrr' and 'vvvv' */
|
||||
static void split_token_string(char *str, char *rstr, char *vstr)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr=strchr(str, '*');
|
||||
if ((ptr != NULL) && (ptr!=str)) {
|
||||
while(str!=ptr)
|
||||
{
|
||||
*rstr++=*str++;
|
||||
}
|
||||
*rstr='\0';
|
||||
|
||||
str++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rstr[0]='\0';
|
||||
}
|
||||
|
||||
while(*vstr++=*str++)
|
||||
{
|
||||
;
|
||||
}
|
||||
*vstr='\0';
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int get_repeat_count(char *rstr, struct ParserState *s)
|
||||
{
|
||||
int r;
|
||||
char *ptr;
|
||||
|
||||
if (strlen(rstr)>0)
|
||||
{
|
||||
ptr=convert_string(&r, rstr);
|
||||
|
||||
if ((ptr==rstr) || (strlen(ptr)>0) || (r<1))
|
||||
{
|
||||
s->error = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
template <typename T>
|
||||
static void get_value(char *vstr, struct ParserState *s, T *v)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
if (strlen(vstr)>0)
|
||||
{
|
||||
/* Convert FORTRAN style floats 3.13D-6 to IEEE */
|
||||
for(ptr=vstr; *ptr; ++ptr)
|
||||
{
|
||||
if (*ptr=='D')
|
||||
{
|
||||
*ptr='E';
|
||||
}
|
||||
}
|
||||
|
||||
ptr = convert_string(v, vstr);
|
||||
|
||||
if ((ptr==vstr) || (strlen(ptr)>0))
|
||||
{
|
||||
s->error = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s->error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static char *get_token_string(FILE *fp, struct ParserState *s, char *str)
|
||||
{
|
||||
char *ptr = str;
|
||||
int c;
|
||||
|
||||
/* Skip leading blanks */
|
||||
while((c = fgetc(fp)) != EOF && isspace(c))
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
*ptr++ = c;
|
||||
|
||||
/* Catch end marker */
|
||||
if (c == '/') {
|
||||
skip_line(fp, s);
|
||||
*ptr++ = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
while((c = fgetc(fp)) != EOF && !isspace(c))
|
||||
{
|
||||
*ptr++ = c;
|
||||
|
||||
/* Break and skip rest of line if '--' if encountered */
|
||||
if (*(ptr-1) == '-' && ptr-str>1 && *(ptr-2) == '-'){
|
||||
ptr = ptr - 2;
|
||||
skip_line(fp, s);
|
||||
break;
|
||||
}
|
||||
|
||||
/* If end marker is encontered, push character back onto stream. */
|
||||
if (c=='/') {
|
||||
ungetc(c, fp);
|
||||
ptr--;
|
||||
break;
|
||||
}
|
||||
|
||||
assert(ptr-str < bufsz);
|
||||
}
|
||||
|
||||
*ptr='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void skip_line(FILE *fp, struct ParserState *s)
|
||||
{
|
||||
int c;
|
||||
while((c = fgetc(fp))!=EOF && c != '\n') {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
// int version
|
||||
static char *convert_string(int *value, char *str)
|
||||
{
|
||||
char *q;
|
||||
*value = strtol(str, &q, 10);
|
||||
return q;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
// double version
|
||||
static char *convert_string(double *value, char *str)
|
||||
{
|
||||
char *q;
|
||||
*value = strtod(str, &q);
|
||||
return q;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
template <typename T>
|
||||
void read_vector_from_file(const char *fn, std::vector<T>& v)
|
||||
{
|
||||
FILE *fp = fopen(fn, "r");
|
||||
struct ParserState s = {1, 0};
|
||||
readvector(fp, &s, v);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 1
|
||||
int main()
|
||||
{
|
||||
std::vector<double> v;
|
||||
read_vector_from_file("example/zcorn.txt", zcorn);
|
||||
std::vector<int> actnum;
|
||||
read_vector_from_file("example/actnum.txt", actnum);
|
||||
for (int i=0; i<v.size(); ++i)
|
||||
{
|
||||
fprintf(stderr, "%f\n", zcorn[i]);
|
||||
}
|
||||
for (int i=0; i<actnum.size(); ++i)
|
||||
{
|
||||
fprintf(stderr, "%d\n", actnum[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user