⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 genio.c

📁 地球模拟器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* genio.c   9-9-92 genebank input/output routines *//* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */#ifndef lintstatic char sccsid[] = "@(#)genio.c	1.5 7/21/92";#endif#include "license.h"#include "tierra.h"#include "extern.h"#include <sys/types.h>#include <sys/stat.h>#include <errno.h>#ifdef MEM_CHK#include <memcheck.h>#endif#define WritEcoS(bits)                WritEcoB(bits, mes[9])/* * open_ar - open a genebank archive * *     file - the filename; *     size - the creature size *     format - a byte, usually the instruction set number *     mode - 0 if the file exists its contents should be preserved, *            < 0, if doesn't exit create it *              else if the file should be created (or truncated). mode > 1 *              is taken as the number of index entries to allocate *            (will be rounded to the next highest # such that *            index + header is a multiple of 1K) * * returns a pointer to a file opened for update, or NULL if unsuccessful. * open_ar fails if size or format are incompatible with the archive. */FILE *open_ar(file, size, format, mode)    I8s *file;    I32s size, mode, format;{    FILE *fp = NULL;    head_t head;    struct stat buf;     if (( mode > 0) || (mode < 0 && (stat(file, &buf) == -1)))    {   if (mode < 0) /* if file doesn't exist, no entries */            mode = 0;        if (fp = fopen(file, "w+b"))        {   strcpy(head.magic, "tie");            head.magic[3] = '0' + format;            head.size = size;            head.n = 0;            head.n_alloc = (((int) ((sizeof(head_t) + mode * sizeof(indx_t)) /                      1024.0) + 1) * 1024 - sizeof head) / sizeof(indx_t);            head.g_off = sizeof(head_t) + head.n_alloc * sizeof(indx_t);            write_head(fp, &head);        }    }    else if (mode < 1 && (fp = fopen(file, "r+b")))    {   head = read_head(fp);        if (head.size != size || (format > -1) && head.magic[3] !=            format + '0' || strncmp(head.magic, "tie", 3))        {   fclose(fp);            fp = NULL;            errno = EINVAL;        }    }    return fp;}/* * read_head - read header from a genebank archive */head_t read_head(fp)    FILE *fp;{    head_t t;    if ((fp != NULL) && !fseek(fp, 0, 0))        fread(&t, sizeof(head_t), 1, fp);    else    {#ifdef ARG        fprintf(stderr, "Tierra read_head() file access failed");        exit(errno);#else        FEError(-400,EXIT,NOWRITE, "Tierra read_head() file access failed");#endif    }    if (GFormat < 0)         GFormat = t.magic[3] -'0';        /* autoselect */    return t;}/* * write_head - write header to a genebank archive */void write_head(fp, head)    FILE *fp;    head_t *head;{    if (!fseek(fp, 0, 0))        fwrite(head, sizeof(head_t), 1, fp);    else    {#ifdef ARG        fprintf(stderr, "Tierra write_head() file access failed");        exit(errno);#else        FEError(-401,EXIT,NOWRITE, "Tierra write_head() file access failed");#endif    }}/* * read_indx - read the index from a genebank archive */indx_t *read_indx(fp, head)    FILE *fp;    head_t *head;{#ifdef ERROR    I32s  i;#endif /* ERROR */    indx_t *t = 0;#ifdef __TURBOC__     t = &GIndx;#else /* __TURBOC__ */    if (!fseek(fp, sizeof(head_t), 0))    {   t = (indx_t *) thcalloc(head->n_alloc, sizeof(indx_t));        if (t != NULL)            fread(t, sizeof(indx_t), head->n, fp);    }    else    {#ifdef ARG        fprintf(stderr, "Tierra read_index() file access failed");        exit(errno);#else /* ARG */        FEError(-402,EXIT,NOWRITE, "Tierra read_index() file access failed");#endif /* ARG */    }#ifdef ERROR    if (t != NULL)        for (i = 0; i < head->n; i++)            if (!(t + i)->psize)#ifdef ARG            {   fprintf(stderr, "Tierra read_index() indx array corrupted");                exit(errno);            }#else  /* ARG */                FEError(-403,EXIT,NOWRITE,                    "Tierra read_index() indx array corrupted");#endif /* ARG */#endif /* ERROR */#endif /* __TURBOC__ */    return t;}/* * write_indx - write the index to a genebank archive */void write_indx(fp, head, indx)    FILE *fp;    head_t *head;    indx_t *indx;{#ifdef ERROR    I32s  i;#endif /* ERROR */#ifdef __TURBOC__     return ;#endif /* __TURBOC__ */#ifdef ERROR    for (i = 0; i < head->n; i++)        if (!(indx + i)->psize)#ifdef ARG        {   fprintf(stderr, "Tierra write_index() indx array corrupted");            exit(errno);        }#else  /* ARG */            FEError(-404,EXIT,NOWRITE,                "Tierra write_index() indx array corrupted");#endif /* ARG */#endif /* ERROR */    if (!fseek(fp, sizeof(head_t), 0))        fwrite(indx, sizeof(indx_t), head->n_alloc, fp);    else    {#ifdef ARG        fprintf(stderr, "Tierra write_index() file access failed");        exit(errno);#else        FEError(-405,EXIT,NOWRITE, "Tierra write_index() file access failed");#endif    }}/* * find_gen - find the index of a genome in an archive by its 3 letter name * * will return n (number of genomes) if not found, otherwise the position * (0 - n-1) in archive */I32s find_gen(fp, indx, gen, n)    FILE    *fp;    indx_t  *indx;    I8s     *gen;    I32s    n;{    I32s i;#ifdef __TURBOC__    if (!strncmp("---", gen, 3))    {   fseek(fp, sizeof(head_t) + (n * sizeof(indx_t)), 0);        fread(indx, sizeof(indx_t), 1, fp);        i = n;    }    else    {   fseek(fp, sizeof(head_t), 0);      /* seek past head */        for(i = 0; i < n; i++)       /* scan index for gen */        {   fread(indx, sizeof(indx_t), 1, fp);            if (!strncmp(indx->gen, gen, 3))                break;        }    }#else /* __TURBOC__ */    for (i = 0; i < n; i++)        if (!strncmp((indx + i)->gen, gen, 3))            break;#endif /* __TURBOC__ */    return i;}/* * get_gen - read a genome from genebank archive and return a pointer *     to a struct g_list containing all saved info. * *     fp - pointer to open archive file *     head - archive header *     indxn - index entry of desired genome *     n - position of desired genome in archive * * reads the genome and reformats its other args into the form used * internally by tierra. the genotype must be in archive. n can be * determined by find_gen(). currently no error checking */Pgl get_gen(fp, head, indxn, n)    FILE *fp;    indx_t *indxn;    head_t *head;    I32s n;{       Pgl t = (Pgl) tcalloc(1, sizeof(GList));    fseek(fp, head->g_off +          (n * head->size * (sizeof(Instruction) + sizeof(GenBits))), 0);    t->genome = (FpInst) tcalloc(head->size, sizeof(Instruction));    t->gbits = (FpGenB) tcalloc(head->size, sizeof(GenBits));    fread(t->genome, head->size * sizeof(Instruction), 1, fp);    fread(t->gbits, head->size * sizeof(GenBits), 1, fp);    t->gen.size = head->size;    strncpy(t->gen.label, indxn->gen, 3);    t->parent.size = indxn->psize;    strncpy(t->parent.label, indxn->pgen, 3);    t->bits = indxn->bits;    t->hash = indxn->hash;    t->d1 = indxn->d1;    t->d2 = indxn->d2;    t->originI = indxn->originI;    t->originC = indxn->originC;    t->MaxPropPop = (float) indxn->mpp / 10000.;    t->MaxPropInst = (float) indxn->mpi / 10000.;    t->mpp_time = indxn->mppT;    t->ploidy = (indxn->pt & 0360) >> 4;    t->track = indxn->pt & 017;    return t;}/* * add_gen - replace or add a genotype to end of genebank archive * *     fp - pointer to open archive file *     head - header of archive *     indx - index of archive *     gen - genotype to be added * * reformats the genotype and replaces it in the archive, or adds it to * the end if not found. args head & indx are modified by this fn. * returns 0 on add, and 1 on replace. * * Scheme of add_gen(): * * 1) find the gen in the file, or find out if it is not in the file. *    This may be done with find_gen() if we have indx in RAM, or by *    by repeated freads if we don't have indx. * 2) If gen is not in file and file is full, we must enlarge the file by *    moving the genotypes out to make room for more indexes. *    Three strategies are used here.  In Unix, we read the entire index *    and bank of genomes into RAM, then write them back out into their *    new locations.  In DOS, when memory is available, we will copy *    the genomes one by one from their old to their new locations on disk, *    then we write the free index structures over with zeros.  In DOS *    when memory is not available, we copy the genomes byte by byte. * 3) We write the new genome and genbits to the file. * 4) We determine if this was an add or a replace. * 5) We write the new updated head. * 6) We update the index of the new gen in RAM. * 7) We write the new index to the file. * 8) We return add or replace. * */I32s add_gen(fp, head, indx, gen)    FILE *fp;    head_t *head;    indx_t **indx;    Pgl gen;{    I8s     t_buf = '\0';    I32s    n, s, ret, oldoff, gensiz, old_n_alloc, i;    I32s    wsiz = 0, rsiz = 0, segs, rem;    indx_t  t_indx, *tp_indx, *tindx;#ifdef __TURBOC__    I8s     buf[512];#else  /* __TURBOC__ */    I8s     *buf;#endif /* __TURBOC__ */    Swap = 0; /* to avoid recursion */    gensiz = (head->size * (sizeof(Instruction) + sizeof(GenBits)));/* 1) find the gen in the file, or find out if it is not in the file. *    This may be done with find_gen() if we have indx in RAM, or by *    by repeated freads if we don't have indx.  */    n = find_gen(fp, *indx, gen->gen.label, head->n); /* does not alloc *//* 2) If gen is not in file and file is full, we must enlarge the file by *    moving the genotypes out to make room for more indexes. *    Three strategies are used here.  In Unix, we read the entire index *    and bank of genomes into RAM, then write them back out into their *    new locations.  In DOS, when memory is available, we will copy the *    genomes one by one from their old to their new locations on disk, *    then we write over with zeros, the free index structures.  In DOS *    when memory is not available, we copy the genomes byte by byte. */    /* n == head->n means not in index */    /* head->n == head->n_alloc means file is full */    /* if not in file and file is full */    if (n == head->n && head->n == head->n_alloc)    {   old_n_alloc = head->n_alloc;        head->n_alloc += 1024 / sizeof(indx_t);        oldoff = head->g_off;        head->g_off = sizeof(head_t) + (head->n_alloc * sizeof(indx_t));#ifdef __TURBOC__        fseek(fp, 0, SEEK_END); /* make room at end for slide */        fwrite(&t_buf, sizeof(I8s), head->g_off - oldoff, fp);/* write zeros*/        segs = (gensiz * head->n) / 512;        rem  = (gensiz * head->n) % 512;        if (rem)        {   fseek(fp, (segs * 512) + oldoff, 0);            rsiz += fread(buf, sizeof(I8s), rem, fp);            fseek(fp, (segs * 512) + head->g_off, 0);            wsiz += fwrite(buf, sizeof(I8s), rem, fp);        }        if (segs) for(i = segs - 1; i >= 0; i--)        {   fseek(fp, (i * 512) + oldoff, 0);            rsiz += fread(buf, sizeof(I8s), 512, fp);            fseek(fp, (i * 512) + head->g_off, 0);            wsiz += fwrite(buf, sizeof(I8s), 512, fp);        }#ifdef ERROR        if ((rsiz != gensiz * head->n) || (wsiz != gensiz * head->n))#ifdef ARG        {   fprintf(stderr, "Tierra add_gen() rsiz or wsiz bad");            exit(errno);        }#else  /* ARG */            FEError(-406,EXIT,NOWRITE, "Tierra add_gen() rsiz or wsiz bad");#endif /* ARG */#endif /* ERROR */#else  /* __TURBOC__ */        fseek(fp, oldoff, 0);        buf = (I8s *) thcalloc(s = gensiz * head->n , 1);        fread(buf, s, 1, fp);        fseek(fp, head->g_off, 0);        fwrite(buf, s, 1, fp);        if (buf)        {   thfree(buf);            buf = NULL;        }        tindx = (indx_t *) threcalloc(*indx,            sizeof(indx_t) * head->n_alloc,            sizeof(indx_t) * old_n_alloc);        if (tindx)        {   *indx = tindx;            for (i = old_n_alloc * sizeof(indx_t);                i < head->n_alloc * sizeof(indx_t); i++)                ((I8s  *) *indx)[i] = (I8s) 0;        }        else if (*indx)        {   thfree(*indx);            *indx = NULL;        }#endif /* __TURBOC__ */    }/* 3) We write the new genome and genbits to the file. */    fseek(fp, head->g_off + (n * gensiz), 0);    fwrite(gen->genome, head->size * sizeof(Instruction), 1, fp);    fwrite(gen->gbits, head->size * sizeof(GenBits), 1, fp);/* 4) We determine if this was an add or a replace. */    head->n += ret = (n == head->n);/* 5) We write the new updated head. */    write_head(fp, head); /* no alloc *//* 6) We update the index of the new gen in RAM. */#ifdef __TURBOC__    tp_indx = *indx; /* fake pointers for meat of function */#else  /* __TURBOC__ */    tp_indx = &((*indx)[n]);#endif /* __TURBOC__ */    strncpy((tp_indx)->gen, gen->gen.label, 3);    (tp_indx)->psize = gen->parent.size;    strncpy((tp_indx)->pgen, gen->parent.label, 3);    (tp_indx)->bits = gen->bits;    (tp_indx)->hash = gen->hash;    (tp_indx)->d1 = gen->d1;    (tp_indx)->d2 = gen->d2;    (tp_indx)->originI = gen->originI;    (tp_indx)->originC = gen->originC;    (tp_indx)->mpp = (short) (gen->MaxPropPop * 10000);    (tp_indx)->mpi = (short) (gen->MaxPropInst * 10000);    (tp_indx)->mppT =  (gen->mpp_time);    (tp_indx)->pt = (gen->ploidy << 4) + gen->track;/* 7) We write the new index to the file. */#ifdef ERROR#ifdef __TURBOC__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -