#include #include #include #include #include #include #include /* struct to hold the lines/columns to/not to print in a for(;;) like * structure */ typedef struct fields_ { int *from,*to,*inc; int num; /* number of fields allocated */ } fields; typedef struct cellstr_ { int type; /* BP_Mask means absolute columns */ long long from, to, inc; /* object number */ fields *f; /* fields of object */ } cellstr; #define BT_EOL 0 #define BT_Wall 1 #define BT_Ball 2 #define BT_Cylinder 3 #define BT_Disk 4 #define BT_BallCC 5 #define BT_Force 6 #define BT_STBall 7 #define BT_DTEdge 8 #define BT_DGBall 9 #define BT_Ellipsoid 10 #define BT_Arrow 12 #define BT_Cone 13 #define BT_Triangle 14 #define BT_Triangle2 15 #define BT_Tetragon 16 #define BT_Quadratic 17 #define BT_NULL 18 /* body parameter (type 4) */ #define BP_Mask 31 #define BP_Size 0 #define BP_Pos 32 #define BP_Orient 64 #define BP_Coord 128 #define BP_Velo 256 #define BP_Force 512 #define BP_AngVelo 1024 #define BP_Torque 2048 #define BP_TrVelo 4096 #define BP_TrForce 8192 #define BP_TrAngVelo 16384 #define BP_Handle 32768 #define BP_LifeTime 65536 #define BP_MatPar 131072 #define BP_TrCoord 262144 #define BP_TrTorque 524288 #define BP_UpMask 0x1fffe0 /* one more bit is needed!!! */ #define BP_N 16 /* maximum parameter an object can have update! XXX */ int par_typ[BP_N] = { BP_Size, BP_Pos, BP_Orient, BP_Coord, BP_Velo, BP_Force, BP_AngVelo, BP_Torque, BP_TrVelo, BP_TrForce, BP_TrAngVelo, BP_Handle, BP_LifeTime, BP_MatPar, BP_TrCoord, BP_TrTorque }; #define dble double #define Buff_Size 65535 #ifndef min #define min(a,b) (a>b?b:a) #endif #ifndef max #define max(a,b) (a0)+((typ&BP_Handle)>0)))*dd+ ii*(((typ&BP_Coord)>0)+((typ&BP_Handle)>0)); if ((t==BT_Wall) || (t==BT_Cylinder) || (t==BT_Arrow)) { *col+=1;*size+=dd; } if ((t==BT_Force) || (t==BT_DTEdge)) { *col+=3;*size+=ii*2+dd; } if (t==BT_BallCC) { *col+=1;*size+=ii; } if ((t==BT_Ellipsoid) || (t==BT_Cone) || (t==BT_Triangle) || (t==BT_Triangle2) || (t==BT_Tetragon) || (t==BT_Quadratic)) { *col+=2;*size+=2*dd; } /* put information in colt */ (*colt)=(int *)malloc(ii*(*col)); /* size */ a=0; if (t!=BT_NULL) (*colt)[a++]=D_D; if ((t==BT_Ellipsoid) || (t==BT_Cone) || (t==BT_Triangle) || (t==BT_Triangle2) || (t==BT_Tetragon) || (t==BT_Quadratic)) { (*colt)[a++]=D_D; (*colt)[a++]=D_D; } if (t==BT_BallCC) (*colt)[a++]=D_I; if ((t==BT_Wall) || (t==BT_Cylinder) || (t==BT_Arrow)) { (*colt)[a++]=D_D; } if ((t==BT_Force) || (t==BT_DTEdge)) { (*colt)[a++]=D_D; (*colt)[a++]=D_I; (*colt)[a++]=D_I; } for (t=0;t0) { obj_timeall=1; } else { obj_timeall=100000; } col_num=(int *) malloc(ii*obj_timeall); start_pos=(long long *) malloc(sizeof(long long)*obj_timeall); col_num[0]=1; objp=0; /* skip time */ if (startpos) start_pos[0]=startpos; else start_pos[0]=ftell(in); fseek(in,start_pos[0],SEEK_SET); fread(&time,dd,1,in); do { fread(&typ,ii,1,in); if (debug) printf("type %d (pos: %d)\n",typ,ftell(in)); /* typ=0 at the end of the line */ if ((typ>0) && (objp=OBJMAX) perr("too many objects (>%d)",OBJMAX); } while (typ>0); if (mode) return; data_size[0]=1; data_size[1]=ii; data_size[2]=dd; if (line_length<=0) { /* line_length is not fixed */ t=1; /* time */ goon=1; do { if ((line_max>0) && (t>line_max)) break; col_num[t]=1; start_pos[t]=ftell(in); fread(&timen,dd,1,in); if ((increment_time) && (timen0) && (op0) perr("Cannot have new objects in time! %d",start_pos[t]); } while (typ>0); if (t>=obj_timeall) { obj_timeall*=2; obj_num[objp]=realloc(obj_num[objp],ii*obj_timeall); obj_pos[objp]=realloc(obj_pos[objp],ii*obj_timeall); col_num=realloc(col_num,ii*obj_timeall); start_pos=realloc(start_pos,sizeof(long long)*obj_timeall); } } while ((!feof(in)) && (goon)); line_num=t-1; } else { fseek(in,0L,SEEK_END); line_num=(ftell(in)-start_pos[0])/line_length-1; } } void Print_File_Info(void) { const char *obj_name[]= { "EOL(0)", "Wall(1)", "Ball(2)", "Cylinder(3)", "Disk(4)", "BallCC(5)", "Force(6)", "STBall(7)", "DTEdge(8)", "DGBall(9)", "Ellipsoid(10)", "", "Arrow(12)", "Cone(13)", "Triangle(14)", "Triangle2(15)", "Tetragon(16)", "Quadratic(17)", "NULL(18)" }; const char *par_name[]= { "Pos(x,y,z)", "Orient(rx,ry,rz,phi)", "Coord(Z)", "Velo(vx,vy,vz)", "Force(fx,fy,fz)", "AngVelo(omx,omy,omz)", "Torque(tx,ty,tz)", "TrVelo(tvx,tvy,tvz)", "TrForce(tfx,tfy,tfz)", "TrAngVelo(tox,toy,toz)", "Handle(hand)", "Lifetime(life)", "MatPar(mu,im,iI)", "TrCoord(tZ)", "TrTorque(ttx,tty,ttz)" }; int a,b; for (a=0;aCELLSIZE) { perr("Insufficient CELLSIZE (%d)\n",CELLSIZE); return; } if (para[a][0]=='%') { /* object */ c=0; parp=0; ures[0]='\0'; spnum=sppar=ures; sp=¶[a][1]; /* object determination %a%b%c * `a': object type (number) * `b': object num (range) * `c': object param (range) */ if ((*sp)=='g') { sp++; type=-atoi(sp); } else { type=atoi(sp); } if (*sp!='%') sp=strchr(sp,'%'); if (sp!=NULL) { sp++;spnum=sp; if (*sp!='%') sp=strchr(sp,'%'); if (sp!=NULL) { *sp='\0'; sp++;sppar=sp; /* count the number of fields */ b=1; while (*sp) { if (*sp==',') b++; sp++; } } else sppar=NULL; } else spnum=sppar=NULL; /* allocate memory for the field struct */ f=(fields *)malloc(sizeof(fields)); f->from=(int *)malloc(b*ii); f->to=(int *)malloc(b*ii); f->inc=(int *)malloc(b*ii); f->num=0; /* fill the fields */ sppar=strtok(sppar,","); if (sppar==NULL) sppar=ures; while (sppar) { Range(sppar,C_PARAM,&from,&to,&inc); f->from[f->num]=from; f->to[f->num]=to; f->inc[f->num]=inc; f->num++; sppar=strtok(NULL,","); } /* get object number */ spnum=strtok(spnum,","); if (spnum==NULL) spnum=ures; while (spnum) { Range(spnum,C_COL,&from,&to,&inc); cells[c][cellp[c]].from=from; cells[c][cellp[c]].to=to; cells[c][cellp[c]].inc=inc; cells[c][cellp[c]].f=f; cells[c][cellp[c]].type=type; cellp[c]++; spnum=strtok(NULL,","); } } else { /* not an object */ sp=para[a]; sp=strtok(sp,","); while (sp) { Range(sp,c,&from,&to,&inc); cells[c][cellp[c]].type=BP_Mask; cells[c][cellp[c]].from=from; cells[c][cellp[c]].to=to; cells[c][cellp[c]].inc=inc; cellp[c]++; sp=strtok(NULL,","); } } } } } /* and line ranges are checked with a for cycle nl arguments checked * for every available field, not too slow, but any better idea? * XXX */ int Not_In(long long l,int c) { int a,rv; rv=1; for (a=0;a=cells[c][a].from) && (l<=cells[c][a].to) && ((l-cells[c][a].from)%cells[c][a].inc==0)) { return(0); } } return(1); } /* find file position of column c at time t */ long long Find_Col(int t,int c,long long *dt) { long long pos,a,b,p; pos=start_pos[t]; /* well it's time, easy job */ *dt=D_D; if (c==0) return(pos); /* Skip time from loop */ c--;pos+=dd; *dt=D_I; p=0; /* local object pointer */ while ((c>0) && (p0) { c--; b++; pos+=data_size[*dt]; *dt=obj_colt[p][b]&BP_Mask; } return(pos); } c-=obj_num[p][t]*obj_col[p]; pos+=obj_num[p][t]*obj_size[p]; p++; } if (p0)) { return(-1); }*/ /* the rest has two except for BT_Force and BT_DTEdge */ /* if ((col>1) && (t!=BT_Force) && (t!=BT_DTEdge)) return(-1);*/ /* BT_Force has four parameters */ /* if (col>3) return(-1);*/ return(col); } else { /* optional parameter */ c=col&BP_UpMask; if (ft) { for (a=0;a=0;a--) { if (c>=(obj_colt[op][a]&BP_UpMask)) { do { a--; } while ((a>=0) && (c==(obj_colt[op][a]&BP_UpMask))); a++; break; } } if ((a==-1) || (c>(obj_colt[op][a]&BP_UpMask))) a++; } /* parameter groups contain more columns */ if (a=obj_col[op]) return(-1); /* not that many column */ return(a); } } void Print_ptr(void *ptr,int dt,FILE *out) { if (output_type) { switch (dt) { case D_D: fwrite(ptr,dd,1,out); break; case D_I: fwrite(ptr,ii,1,out); break; case D_B: fwrite(ptr,sizeof(char),1,out); break; } } else { if (formkrep) { switch (dt) { case D_D: fprintf(out,"%.*le ",long_prec,*((double *)ptr)); break; case D_I: fprintf(out,"i %u ",*((int *)ptr)); break; case D_B: fprintf(out,"%d ",*((char *)ptr)); break; } } else { switch (dt) { case D_D: fprintf(out,"%.*le ",long_prec,*((double *)ptr)); break; case D_I: fprintf(out,"%u ",*((int *)ptr)); break; case D_B: fprintf(out,"%d ",*((char *)ptr)); break; } } } } /* print data according to determined options */ void Print_Data(FILE *in) { long long a,b,l,c,t,dt,d,e,f,g,po; long long from,to,inc,cto,mm; long long lp,fp,ir; void *ptr; if (cellp[C_LINE]==0) { /* no column is specified, then print all */ cells[C_LINE][0].from=0; cells[C_LINE][0].to=line_num; cells[C_LINE][0].inc=1; cellp[C_LINE]=1; } if (cellp[C_COL]==0) { /* no column is specified, then print only time */ cells[C_COL][0].from=0; cells[C_COL][0].to=0; cells[C_COL][0].inc=1; cellp[C_COL]=1; } ptr=(void *)malloc(Buff_Size); /* XXX carefull with this */ for (a=0;a=line_num) { fseek(in,0,SEEK_END); fp=ftell(in); } else { fp=start_pos[l+1]; } } else { fp=start_pos[0]+(l+1)*line_length; } if (nohead) lp+=sizeof(double); fseek(in,lp,SEEK_SET); fp-=lp; /* length */ if (noeol) fp-=sizeof(int); while (fp>0) { ir=fread(ptr,1,min(Buff_Size,fp),in); fwrite(ptr,1,ir,out); fp-=ir; } } else { /* columns */ for (b=0;b0) { fseek(in,fp,SEEK_SET); fread(ptr,data_size[dt],1,in); Print_ptr(ptr,dt,out); if (split) fprintf(out,"\n"); } } else { /* object */ for (d=0;dnum;e++) { from=Get_Pos(cells[C_COL][b].f->from[e],d,0); to=Get_Pos(cells[C_COL][b].f->to[e],d,1); inc=cells[C_COL][b].f->inc[e]; if ((from>=0) && (to>=from) && (c