00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <ctype.h>
00019 #include <errno.h>
00020
00021 #include "converse.h"
00022 #include "pup.h"
00023 #include "ckhashtable.h"
00024
00025 PUP::er::~er() {}
00026
00027 void PUP::er::operator()(able& a)
00028 {a.pup(*this);}
00029
00030 void PUP::er::comment(const char *message)
00031 { }
00032
00033 const char * PUP::er::typeString() const
00034 {
00035 if (isSizing()) return "sizing";
00036 else if (isPacking()) return "packing";
00037 else if (isUnpacking()) return "unpacking";
00038 return "unknown";
00039 }
00040
00041 void PUP::er::synchronize(unsigned int m)
00042 { }
00043
00044
00045
00046
00047
00048 #ifdef CK_CHECK_PUP
00049 static int bannerDisplayed=0;
00050 static void showBanner(void) {
00051 bannerDisplayed=1;
00052 fprintf(stderr,"CK_CHECK_PUP pup routine checking enabled\n");
00053 CmiPrintf("CK_CHECK_PUP pup routine checking enabled\n");
00054 }
00055
00056 class pupCheckRec {
00057 unsigned char magic[4];
00058 unsigned char type;
00059 unsigned char length[3];
00060 enum {pupMagic=0xf36c5a21,typeMask=0x75};
00061 int getMagic(void) const {return (magic[3]<<24)+(magic[2]<<16)+(magic[1]<<8)+magic[0];}
00062 void setMagic(int v) {for (int i=0;i<4;i++) magic[i]=(v>>(8*i));}
00063 PUP::dataType getType(void) const {return (PUP::dataType)(type^typeMask);}
00064 void setType(PUP::dataType v) {type=v^typeMask;}
00065 int getLength(void) const {return (length[2]<<16)+(length[1]<<8)+length[0];}
00066 void setLength(int v) {for (int i=0;i<3;i++) length[i]=(v>>(8*i));}
00067
00068
00069
00070
00071 void compare(const char *kind,const char *why,int packed,int unpacked) const
00072 {
00073 if (packed==unpacked) return;
00074
00075 fprintf(stderr,"CK_CHECK_PUP error!\nPacked %s (%d, or %08x) does "
00076 "not equal unpacked value (%d, or %08x)!\nThis means %s\n",
00077 kind,packed,packed,unpacked,unpacked,why);
00078 CmiPrintf("CK_CHECK_PUP error! Run with debugger for more info.\n");
00079
00080 abort();
00081 }
00082 public:
00083 void write(PUP::dataType t,int n) {
00084 if (!bannerDisplayed) showBanner();
00085 setMagic(pupMagic);
00086 type=t^typeMask;
00087 setLength(n);
00088 }
00089 void check(PUP::dataType t,int n) const {
00090 compare("magic number",
00091 "you unpacked more than you packed, or the values were corrupted during transport",
00092 getMagic(),pupMagic);
00093 compare("data type",
00094 "the pack and unpack paths do not match up",
00095 getType(),t);
00096 compare("length",
00097 "you may have forgotten to pup the array length",
00098 getLength(),n);
00099 }
00100 };
00101 #endif
00102
00103
00104 void PUP::sizer::bytes(void * ,int n,size_t itemSize,dataType )
00105 {
00106 #ifdef CK_CHECK_PUP
00107 nBytes+=sizeof(pupCheckRec);
00108 #endif
00109 #ifndef CMK_OPTIMIZE
00110 if (n<0) CmiAbort("PUP::sizer> Tried to pup a negative number of items!");
00111 const unsigned int maxPupBytes=1024*1024*1024;
00112 if (((unsigned int)(n*itemSize))>maxPupBytes)
00113 CmiAbort("PUP::sizer> Tried to pup absurdly large number of bytes!");
00114 #endif
00115 nBytes+=n*itemSize;
00116 }
00117
00118
00119 void PUP::toMem::bytes(void *p,int n,size_t itemSize,dataType t)
00120 {
00121 #ifdef CK_CHECK_PUP
00122 ((pupCheckRec *)buf)->write(t,n);
00123 buf+=sizeof(pupCheckRec);
00124 #endif
00125 n*=itemSize;
00126 memcpy((void *)buf,p,n);
00127 buf+=n;
00128 }
00129 void PUP::fromMem::bytes(void *p,int n,size_t itemSize,dataType t)
00130 {
00131 #ifdef CK_CHECK_PUP
00132 ((pupCheckRec *)buf)->check(t,n);
00133 buf+=sizeof(pupCheckRec);
00134 #endif
00135 n*=itemSize;
00136 memcpy(p,(const void *)buf,n);
00137 buf+=n;
00138 }
00139
00140
00141 size_t CmiFwrite(const void *ptr, size_t size, size_t nmemb, FILE *f)
00142 {
00143 size_t nwritten = 0;
00144 const char *buf = (const char *)ptr;
00145 while (nwritten < nmemb) {
00146 size_t ncur = fwrite(buf+nwritten*size,size,nmemb-nwritten,f);
00147 if (ncur <= 0) {
00148 if (errno == EINTR)
00149 printf("Warning: CmiFwrite retrying ...\n");
00150 else
00151 break;
00152 }
00153 else
00154 nwritten += ncur;
00155 }
00156 return nwritten;
00157 }
00158
00159 FILE *CmiFopen(const char *path, const char *mode)
00160 {
00161 FILE *fp = NULL;
00162 while (1) {
00163 fp = fopen(path, mode);
00164 if (fp == 0 && errno==EINTR) {
00165 printf("Warning: CmiFopen retrying ...\n");
00166 continue;
00167 }
00168 else
00169 break;
00170 }
00171 return fp;
00172 }
00173
00174
00175 int CmiFclose(FILE *fp)
00176 {
00177 int status = 0;
00178 while (1) {
00179 status = fflush(fp);
00180 if (status != 0 && errno==EINTR) {
00181 printf("Warning: CmiFclose flush retrying ...\n");
00182 continue;
00183 }
00184 else
00185 break;
00186 }
00187 if (status != 0) return status;
00188 while (1) {
00189 status = fclose(fp);
00190 if (status != 0 && errno==EINTR) {
00191 printf("Warning: CmiFclose retrying ...\n");
00192 continue;
00193 }
00194 else
00195 break;
00196 }
00197 return status;
00198 }
00199
00200
00201 void PUP::toDisk::bytes(void *p,int n,size_t itemSize,dataType )
00202 { CmiFwrite(p,itemSize,n,F);}
00203 void PUP::fromDisk::bytes(void *p,int n,size_t itemSize,dataType )
00204 { fread(p,itemSize,n,F);}
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 PUP::seekBlock::seekBlock(PUP::er &Np,int nSections)
00223 :nSec(nSections),p(Np)
00224 {
00225 if (nSections<0 || nSections>maxSections)
00226 CmiAbort("Invalid # of sections passed to PUP::seekBlock!");
00227 p.impl_startSeek(*this);
00228 if (p.isPacking())
00229 {
00230 secTabOff=p.impl_tell(*this);
00231 for (int i=0;i<=nSec;i++) secTab[i]=-1;
00232 }
00233 p(secTab,nSec+1);
00234 hasEnded=CmiFalse;
00235 }
00236 PUP::seekBlock::~seekBlock()
00237 {
00238 if (!hasEnded)
00239 endBlock();
00240 }
00241
00242 void PUP::seekBlock::seek(int toSection)
00243 {
00244 if (toSection<0 || toSection>=nSec)
00245 CmiAbort("Invalid section # passed to PUP::seekBlock::seek!");
00246 if (p.isPacking())
00247 secTab[toSection]=p.impl_tell(*this);
00248 else if (p.isUnpacking())
00249 p.impl_seek(*this,secTab[toSection]);
00250
00251 }
00252
00253 void PUP::seekBlock::endBlock(void)
00254 {
00255 if (p.isPacking()) {
00256
00257 secTab[nSec]=p.impl_tell(*this);
00258 p.impl_seek(*this,secTabOff);
00259 p(secTab,nSec+1);
00260 }
00261
00262 p.impl_seek(*this,secTab[nSec]);
00263 p.impl_endSeek(*this);
00264 hasEnded=CmiTrue;
00265 }
00266
00268
00269
00270
00271 void PUP::er::impl_startSeek(PUP::seekBlock &s)
00272 {}
00273 int PUP::er::impl_tell(seekBlock &s)
00274 {return 0;}
00275 void PUP::er::impl_seek(seekBlock &s,int off)
00276 {}
00277 void PUP::er::impl_endSeek(seekBlock &s)
00278 {}
00279
00280
00281
00282 void PUP::mem::impl_startSeek(seekBlock &s)
00283 {s.data.ptr=buf;}
00284 int PUP::mem::impl_tell(seekBlock &s)
00285 {return buf-s.data.ptr;}
00286 void PUP::mem::impl_seek(seekBlock &s,int off)
00287 {buf=s.data.ptr+off;}
00288
00289
00290 void PUP::disk::impl_startSeek(seekBlock &s)
00291 {s.data.loff=ftell(F);}
00292 int PUP::disk::impl_tell(seekBlock &s)
00293 {return (int)(ftell(F)-s.data.loff);}
00294 void PUP::disk::impl_seek(seekBlock &s,int off)
00295 {fseek(F,s.data.loff+off,0);}
00296
00297
00298 void PUP::wrap_er::impl_startSeek(seekBlock &s)
00299 {p.impl_startSeek(s);}
00300 int PUP::wrap_er::impl_tell(seekBlock &s)
00301 {return p.impl_tell(s);}
00302 void PUP::wrap_er::impl_seek(seekBlock &s,int off)
00303 {p.impl_seek(s,off);}
00304 void PUP::wrap_er::impl_endSeek(seekBlock &s)
00305 {p.impl_endSeek(s);}
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 static PUP::able::PUP_ID null_PUP_ID(0);
00324
00325 PUP::able *PUP::able::clone(void) const {
00326
00327 PUP::able *ret=get_constructor(get_PUP_ID()) ();
00328
00329
00330 PUP::able *mthis=(PUP::able *)this;
00331 int size;
00332 { PUP::sizer ps; mthis->pup(ps); size=ps.size(); }
00333 void *buf=malloc(size);
00334 { PUP::toMem pt(buf); mthis->pup(pt); }
00335
00336
00337 { PUP::fromMem pf(buf); ret->pup(pf); }
00338 free(buf);
00339
00340 return ret;
00341 }
00342
00343
00344 PUP::able::~able() {}
00345 void PUP::able::pup(PUP::er &p) {}
00346
00347
00348
00349 void PUP::able::PUP_ID::setName(const char *name)
00350 {
00351 int i,o,n=strlen(name);
00352 int t[len]={0};
00353 for (o=0;o<n;o++)
00354 for (i=0;i<len;i++) {
00355 unsigned char c=name[o];
00356 int shift1=(((o+2)*(i+1)*5+4)%13);
00357 int shift2=(((o+2)*(i+1)*3+2)%11)+13;
00358 t[i]+=(c<<shift1)+(c<<shift2);
00359 }
00360 for (i=0;i<len;i++)
00361 hash[i]=(unsigned char)(t[i]%20117 + t[i]%1217 + t[i]%157);
00362 }
00363
00364
00365 class PUP_regEntry {
00366 public:
00367 PUP::able::PUP_ID id;
00368 const char *name;
00369 PUP::able::constructor_function ctor;
00370 PUP_regEntry(const char *Nname,
00371 const PUP::able::PUP_ID &Nid,PUP::able::constructor_function Nctor)
00372 :id(Nid),name(Nname),ctor(Nctor) {}
00373 PUP_regEntry(int zero) {
00374 name=NULL;
00375 }
00376 };
00377
00378 typedef CkHashtableTslow<PUP::able::PUP_ID,PUP_regEntry> PUP_registry;
00379
00380
00381 static PUP_registry *PUP_getRegistry(void) {
00382 static PUP_registry *reg = NULL;
00383 if (reg==NULL)
00384 reg=new PUP_registry();
00385 return reg;
00386 }
00387
00388 const PUP_regEntry *PUP_getRegEntry(const PUP::able::PUP_ID &id)
00389 {
00390 const PUP_regEntry *cur=(const PUP_regEntry *)(
00391 PUP_getRegistry()->CkHashtable::get((const void *)&id) );
00392 if (cur==NULL)
00393 CmiAbort("Unrecognized PUP::able::PUP_ID. is there an unregistered module?");
00394 return cur;
00395 }
00396
00397 PUP::able::PUP_ID PUP::able::register_constructor
00398 (const char *className,constructor_function fn)
00399 {
00400 PUP::able::PUP_ID id(className);
00401 PUP_getRegistry()->put(id)=PUP_regEntry(className,id,fn);
00402 return id;
00403 }
00404
00405 PUP::able::constructor_function PUP::able::get_constructor
00406 (const PUP::able::PUP_ID &id)
00407 {
00408 return PUP_getRegEntry(id)->ctor;
00409 }
00410
00411
00412 void PUP::er::object(able** a)
00413 {
00414 const PUP_regEntry *r=NULL;
00415 if (isUnpacking())
00416 {
00417 PUP::able::PUP_ID id;
00418 id.pup(*this);
00419 if (id==null_PUP_ID) {*a=NULL; return;}
00420 r=PUP_getRegEntry(id);
00421
00422 *a=(r->ctor)();
00423
00424 } else {
00425 if (*a==NULL) {
00426 null_PUP_ID.pup(*this);
00427 return;
00428 } else {
00429 const PUP::able::PUP_ID &id=(*a)->get_PUP_ID();
00430 id.pup(*this);
00431 r=PUP_getRegEntry(id);
00432 }
00433 }
00434 syncComment(PUP::sync_begin_object,r->name);
00435 (*a)->pup(*this);
00436 syncComment(PUP::sync_end_object);
00437 }
00438
00439
00440
00441 char *PUP::toTextUtil::beginLine(void) {
00442
00443 for (int i=0;i<level;i++) cur[i]='\t';
00444 cur[level]=0;
00445 return cur+level;
00446 }
00447 void PUP::toTextUtil::endLine(void) {
00448 cur=advance(cur);
00449 }
00450 void PUP::toTextUtil::beginEnv(const char *type,int n)
00451 {
00452 char *o=beginLine();
00453 sprintf(o,"begin "); o+=strlen(o);
00454 sprintf(o,type,n); o+=strlen(o);
00455 sprintf(o," {\n");
00456 endLine();
00457 level++;
00458 }
00459 void PUP::toTextUtil::endEnv(const char *type)
00460 {
00461 level--;
00462 sprintf(beginLine(),"} end %s;\n",type);
00463 endLine();
00464 }
00465 PUP::toTextUtil::toTextUtil(unsigned int inType,char *buf)
00466 :er(inType)
00467 {
00468 cur=buf;
00469 level=0;
00470 }
00471
00472 void PUP::toTextUtil::comment(const char *message)
00473 {
00474 sprintf(beginLine(),"//%s\n",message); endLine();
00475 }
00476
00477 void PUP::toTextUtil::synchronize(unsigned int m)
00478 {
00479 sprintf(beginLine(),"sync=0x%08x\n",m); endLine();
00480 #if 0
00481 char *o=beginLine();
00482 sprintf(o,"sync=");o+=strlen(o);
00483 const char *consonants="bcdfgjklmprstvxz";
00484 const char *vowels="aeou";
00485 for (int firstBit=0;firstBit<32;firstBit+=6) {
00486 sprintf(o,"%c%c%c", consonants[0xf&(m>>firstBit)],
00487 vowels[0x3&(m>>(firstBit+4))],
00488 (firstBit==30)?';':'-');
00489 o+=strlen(o);
00490 }
00491 sprintf(o,"\n"); endLine();
00492 #endif
00493 }
00494
00495 void PUP::toTextUtil::bytes(void *p,int n,size_t itemSize,dataType t) {
00496 if (t==Tchar)
00497 {
00498 char *o=beginLine();
00499 sprintf(o,"string=");o+=strlen(o);
00500 *o++='\"';
00501
00502 const char *c=(const char *)p;
00503 for (int i=0;i<n;i++) {
00504 if (c[i]=='\n') {
00505 sprintf(o,"\\n");o+=strlen(o);
00506 } else if (iscntrl(c[i])) {
00507 sprintf(o,"\\x%02X",(unsigned char)c[i]);o+=strlen(o);
00508 } else if (c[i]=='\\' || c[i]=='\"') {
00509 sprintf(o,"\\%c",c[i]);o+=strlen(o);
00510 } else
00511 *o++=c[i];
00512 }
00513
00514 sprintf(o,"\";\n");o+=strlen(o);
00515 endLine();
00516 } else if (t==Tbyte || t==Tuchar)
00517 {
00518 beginEnv("byte %d",n);
00519 const unsigned char *c=(const unsigned char *)p;
00520 char *o=beginLine();
00521 for (int i=0;i<n;i++) {
00522 sprintf(o,"%02X ",c[i]);o+=strlen(o);
00523 if (i%25==24 && (i+1!=n))
00524 {
00525 sprintf(o,"\n"); o+=strlen(o);
00526 endLine(); o=beginLine();
00527 }
00528 }
00529 sprintf(o,"\n");
00530 endLine();
00531 endEnv("byte");
00532 }
00533 else
00534 {
00535 if (n!=1) beginEnv("array %d",n);
00536 for (int i=0;i<n;i++) {
00537 char *o=beginLine();
00538 switch(t) {
00539 case Tshort: sprintf(o,"short=%d;\n",((short *)p)[i]); break;
00540 case Tushort: sprintf(o,"ushort=%u;\n",((unsigned short *)p)[i]); break;
00541 case Tint: sprintf(o,"int=%d;\n",((int *)p)[i]); break;
00542 case Tuint: sprintf(o,"uint=%u;\n",((unsigned int *)p)[i]); break;
00543 case Tlong: sprintf(o,"long=%ld;\n",((long *)p)[i]); break;
00544 case Tulong: sprintf(o,"ulong=%lu;\n",((unsigned long *)p)[i]); break;
00545 case Tfloat: sprintf(o,"float=%.7g;\n",((float *)p)[i]); break;
00546 case Tdouble: sprintf(o,"double=%.15g;\n",((double *)p)[i]); break;
00547 case Tbool: sprintf(o,"bool=%s;\n",((CmiBool *)p)[i]?"true":"false"); break;
00548 #if CMK_LONG_DOUBLE_DEFINED
00549 case Tlongdouble: sprintf(o,"longdouble=%Lg;\n",((long double *)p)[i]);break;
00550 #endif
00551 #ifdef CMK_PUP_LONG_LONG
00552 case Tlonglong: sprintf(o,"longlong=%lld;\n",((CMK_PUP_LONG_LONG *)p)[i]);break;
00553 case Tulonglong: sprintf(o,"ulonglong=%llu;\n",((unsigned CMK_PUP_LONG_LONG *)p)[i]);break;
00554 #endif
00555 case Tpointer: sprintf(o,"pointer=%p;\n",((void **)p)[i]); break;
00556 default: CmiAbort("Unrecognized pup type code!");
00557 }
00558 endLine();
00559 }
00560 if (n!=1) endEnv("array");
00561 }
00562 }
00563 void PUP::toTextUtil::object(able** a) {
00564 beginEnv("object");
00565 er::object(a);
00566 endEnv("object");
00567 }
00568
00569
00570
00571 char *PUP::sizerText::advance(char *cur) {
00572 charCount+=strlen(cur);
00573 return line;
00574 }
00575
00576 PUP::sizerText::sizerText(void)
00577 :toTextUtil(IS_SIZING+IS_COMMENTS,line),charCount(0) { }
00578
00579
00580 char *PUP::toText::advance(char *cur) {
00581 charCount+=strlen(cur);
00582 return buf+charCount;
00583 }
00584
00585 PUP::toText::toText(char *outBuf)
00586 :toTextUtil(IS_PACKING+IS_COMMENTS,outBuf),buf(outBuf),charCount(0) { }
00587
00588
00589 void PUP::toTextFile::bytes(void *p,int n,size_t itemSize,dataType t)
00590 {
00591 for (int i=0;i<n;i++)
00592 switch(t) {
00593 case Tchar: fprintf(f," '%c'",((char *)p)[i]); break;
00594 case Tuchar:
00595 case Tbyte: fprintf(f," %02X",((unsigned char *)p)[i]); break;
00596 case Tshort: fprintf(f," %d",((short *)p)[i]); break;
00597 case Tushort: fprintf(f," %u",((unsigned short *)p)[i]); break;
00598 case Tint: fprintf(f," %d",((int *)p)[i]); break;
00599 case Tuint: fprintf(f," %u",((unsigned int *)p)[i]); break;
00600 case Tlong: fprintf(f," %ld",((long *)p)[i]); break;
00601 case Tulong: fprintf(f," %lu",((unsigned long *)p)[i]); break;
00602 case Tfloat: fprintf(f," %.7g",((float *)p)[i]); break;
00603 case Tdouble: fprintf(f," %.15g",((double *)p)[i]); break;
00604 case Tbool: fprintf(f," %s",((CmiBool *)p)[i]?"true":"false"); break;
00605 #if CMK_LONG_DOUBLE_DEFINED
00606 case Tlongdouble: fprintf(f," %Lg",((long double *)p)[i]);break;
00607 #endif
00608 #ifdef CMK_PUP_LONG_LONG
00609 case Tlonglong: fprintf(f," %lld",((CMK_PUP_LONG_LONG *)p)[i]);break;
00610 case Tulonglong: fprintf(f," %llu",((unsigned CMK_PUP_LONG_LONG *)p)[i]);break;
00611 #endif
00612 case Tpointer: fprintf(f," %p",((void **)p)[i]); break;
00613 default: CmiAbort("Unrecognized pup type code!");
00614 };
00615 fprintf(f,"\n");
00616 }
00617 void PUP::toTextFile::comment(const char *message)
00618 {
00619 fprintf(f,"! %s\n",message);
00620 }
00621
00622 void PUP::fromTextFile::parseError(const char *what) {
00623
00624 long cur = ftell(f);
00625 int lineno=0;
00626 rewind(f);
00627 while (!feof(f)) {
00628 char c;
00629 fscanf(f,"%c",&c);
00630 if (c=='\n') lineno++;
00631 if (ftell(f) > cur) break;
00632 }
00633 fprintf(stderr,"Parse error during pup from text file: %s at line: %d\n",what, lineno);
00634 CmiAbort("Parse error during pup from text file!\n");
00635 }
00636 int PUP::fromTextFile::readInt(const char *fmt) {
00637 int ret=0;
00638 if (1!=fscanf(f,fmt,&ret)) {
00639 if (feof(f)) return 0;
00640 else parseError("could not match integer");
00641 }
00642 return ret;
00643 }
00644 unsigned int PUP::fromTextFile::readUint(const char *fmt) {
00645 unsigned int ret=0;
00646 if (1!=fscanf(f,fmt,&ret)) {
00647 if (feof(f)) return 0u;
00648 else parseError("could not match unsigned integer");
00649 }
00650 return ret;
00651 }
00652 CMK_TYPEDEF_INT8 PUP::fromTextFile::readLongInt(const char *fmt) {
00653 CMK_TYPEDEF_INT8 ret=0;
00654 if (1!=fscanf(f,fmt,&ret)) {
00655 if (feof(f)) return 0u;
00656 else parseError("could not match large integer");
00657 }
00658 return ret;
00659 }
00660 double PUP::fromTextFile::readDouble(void) {
00661 double ret=0;
00662 if (1!=fscanf(f,"%lg",&ret)) {
00663 if (feof(f)) return 0.0;
00664 else parseError("could not match double");
00665 }
00666 return ret;
00667 }
00668 void PUP::fromTextFile::bytes(void *p,int n,size_t itemSize,dataType t)
00669 {
00670 for (int i=0;i<n;i++)
00671 switch(t) {
00672 case Tchar:
00673 if (1!=fscanf(f," '%c'",&((char *)p)[i]))
00674 parseError("Could not match character");
00675 break;
00676 case Tuchar:
00677 case Tbyte: ((unsigned char *)p)[i]=(unsigned char)readInt("%02X"); break;
00678 case Tshort:((short *)p)[i]=(short)readInt(); break;
00679 case Tushort: ((unsigned short *)p)[i]=(unsigned short)readUint(); break;
00680 case Tint: ((int *)p)[i]=readInt(); break;
00681 case Tuint: ((unsigned int *)p)[i]=readUint(); break;
00682 case Tlong: ((long *)p)[i]=readInt(); break;
00683 case Tulong:((unsigned long *)p)[i]=readUint(); break;
00684 case Tfloat: ((float *)p)[i]=(float)readDouble(); break;
00685 case Tdouble:((double *)p)[i]=readDouble(); break;
00686 #if CMK_LONG_DOUBLE_DEFINED
00687 case Tlongdouble: {
00688 long double ret=0;
00689 if (1!=fscanf(f,"%Lg",&ret)) parseError("could not match long double");
00690 ((long double *)p)[i]=ret;
00691 } break;
00692 #endif
00693 #ifdef CMK_PUP_LONG_LONG
00694 case Tlonglong: {
00695 CMK_PUP_LONG_LONG ret=0;
00696 if (1!=fscanf(f,"%lld",&ret)) parseError("could not match long long");
00697 ((CMK_PUP_LONG_LONG *)p)[i]=ret;
00698 } break;
00699 case Tulonglong: {
00700 unsigned CMK_PUP_LONG_LONG ret=0;
00701 if (1!=fscanf(f,"%llu",&ret)) parseError("could not match unsigned long long");
00702 ((unsigned CMK_PUP_LONG_LONG *)p)[i]=ret;
00703 } break;
00704 #endif
00705 case Tbool: {
00706 char tmp[20];
00707 if (1!=fscanf(f," %20s",tmp)) parseError("could not read boolean string");
00708 CmiBool val=CmiFalse;
00709 if (0==strcmp(tmp,"true")) val=CmiTrue;
00710 else if (0==strcmp(tmp,"false")) val=CmiFalse;
00711 else parseError("could not recognize boolean string");
00712 ((CmiBool *)p)[i]=val;
00713 }
00714 break;
00715 case Tpointer: {
00716 void *ret=0;
00717 if (1!=fscanf(f,"%p",&ret)) parseError("could not match pointer");
00718 ((void **)p)[i]=ret;
00719 } break;
00720 default: CmiAbort("Unrecognized pup type code!");
00721 };
00722 }
00723 void PUP::fromTextFile::comment(const char *message)
00724 {
00725 char c;
00726
00727 while (isspace(c=fgetc(f))) {}
00728
00729 if (c!='!') return;
00730
00731 char *commentBuf=(char *)CmiTmpAlloc(1024);
00732 fgets(commentBuf,1024,f);
00733 CmiTmpFree(commentBuf);
00734 }
00735
00736
00737
00738
00739
00740
00741