URI: 
       Permit to write input file or create output file from scratch - addrom - Simple tool for adding a rom entry to a Pandora's Box 3 list.dat
       
   DIR Log
   DIR Files
   DIR Refs
   DIR LICENSE
       ---
   DIR commit be215e106234f8a2061cfedb8d4561c7281629fa
   DIR parent ed830780cc8dd15c040cb5a6dd8e3f9d08ec16b6
  HTML Author: Quentin Rameau <quinq@fifth.space>
       Date:   Tue, 10 Nov 2015 02:23:03 +0100
       
       Permit to write input file or create output file from scratch
       
       Diffstat:
         addrom.c                            |      95 +++++++++++++++++++++----------
         config.mk                           |       2 +-
       
       2 files changed, 66 insertions(+), 31 deletions(-)
       ---
   DIR diff --git a/addrom.c b/addrom.c
       @@ -64,18 +64,35 @@ addrom(char *datfile, const Rom *rom)
        }
        
        static uint32_t
       -setgamecount(uint64_t n)
       +getbingamecount(uint64_t n)
        {
                return (n << 32 << 6) / 0x88888888;
        }
        
        static void
       +setgamecount(char *buf, const uint32_t hexcount)
       +{
       +        *(uint32_t *)(buf) = hexcount;
       +}
       +
       +static void
        ereadinfile(char *datbuf, const ssize_t size, FILE *infile)
        {
                if (fread(datbuf, 1, size, infile) != size)
                        die("Couldn't read %zu bytes of input file %s\n", size, in);
        }
        
       +static void *
       +ecalloc(const ssize_t size)
       +{
       +        char *buf;
       +
       +        if (!(buf = calloc(size, 1)))
       +                die("Can't allocate enough memory for buffer\n");
       +
       +        return buf;
       +}
       +
        static void
        usage(void)
        {
       @@ -130,56 +147,74 @@ main(int argc, char *argv[])
                        break;
                } ARGEND
        
       -        if (!in || !out || !rom.romname)
       +        if (!(in || out) || !rom.romname)
                        usage();
        
       -        if (access(out, F_OK) != -1)
       +        if (out && access(out, F_OK) != -1)
                        die("Output file %s exists and will not be overwritten\n",
                            out);
        
       -        if ((infd = open(in, O_RDONLY)) == -1)
       -                die("Can't open input file %s\n", in);
       +        /* create and populate buffer */
       +        if (in) { /* from existing file */
       +                if ((infd = open(in, out ? O_RDONLY : O_RDWR)) == -1)
       +                        die("Can't open input file %s\n", in);
        
       -        if (fstat(infd, &st) == -1 || !S_ISREG(st.st_mode))
       -                die("File %s is not a regular file\n", in);
       +                if (fstat(infd, &st) == -1 || !S_ISREG(st.st_mode))
       +                        die("Input file %s is not a regular file\n", in);
        
       -        if ((infilesize = st.st_size) < HEADERSZ)
       -                die("Corrupted input file %s\n", in);
       +                if ((infilesize = st.st_size) < HEADERSZ)
       +                        die("Corrupted input file %s\n", in);
        
       -        if (!(infile = fdopen(infd, "r")))
       -                die("Can't open input file %s\n", in);
       +                if (!(infile = fdopen(infd, out ? "r" : "r+")))
       +                        die("Can't open input file %s\n", in);
        
       -        outbufsize = infilesize + ENTRYSZ;
       +                outbufsize = infilesize + ENTRYSZ;
        
       -        if (!(outbuf = calloc(outbufsize, 1)))
       -                die("Can't allocate enough memory for reading input file\n");
       +                outbuf = ecalloc(outbufsize);
        
       -        if (place == 0 || place * ENTRYSZ + HEADERSZ > infilesize)
       -                offset = infilesize;
       -        else
       -                offset = HEADERSZ + (place - 1) * ENTRYSZ;
       +                if (place == 0 || place * ENTRYSZ + HEADERSZ > infilesize)
       +                        offset = infilesize;
       +                else
       +                        offset = HEADERSZ + (place - 1) * ENTRYSZ;
        
       -        ereadinfile(outbuf, offset, infile);
       +                ereadinfile(outbuf, offset, infile);
        
       -        *(uint32_t *)(outbuf + HEADERSZSZ) = setgamecount(
       -            (infilesize - HEADERSZ) / ENTRYSZ + 1);
       +                setgamecount(outbuf + HEADERSZSZ,
       +                    getbingamecount((infilesize - HEADERSZ) / ENTRYSZ + 1));
        
       -        addrom(outbuf + offset, &rom);
       +                addrom(outbuf + offset, &rom);
        
       -        ereadinfile(outbuf + offset + ENTRYSZ, infilesize - offset, infile);
       +                ereadinfile(outbuf + offset + ENTRYSZ, infilesize - offset,
       +                    infile);
       +        } else { /* from scratch, position is ignored */
       +                outbufsize = HEADERSZ + ENTRYSZ;
        
       -        if (fclose(infile) == EOF)
       -                fprintf(stderr, "There was an error while closing input file "
       -                    "%s\n", in);
       +                outbuf = ecalloc(outbufsize);
       +
       +                *(uint32_t *)(outbuf) = HEADERSZ;
       +
       +                setgamecount(outbuf + HEADERSZSZ, getbingamecount(1));
       +
       +                offset = HEADERSZ;
        
       -        if (!(outfile = fopen(out, "w")))
       +                addrom(outbuf + offset, &rom);
       +        }
       +
       +        /* write out buffer */
       +        if (out && !(outfile = fopen(out, "w")))
                        die("Can't open output file %s\n", out);
       +        else if (!out && fseeko(infile, 0, SEEK_SET) == -1)
       +                die("Couldn't seek input file %s\n", in);
        
       -        if (fwrite(outbuf, 1, outbufsize, outfile) !=
       +        if (fwrite(outbuf, 1, outbufsize, out ? outfile : infile) !=
                    outbufsize)
       -                die("Couldn't write all data to output file %s\n", out);
       +                die("Couldn't write all data to file %s\n", out ? out : in);
       +
       +        if (in && fclose(infile) == EOF)
       +                fprintf(stderr, "There was an error while closing input file "
       +                    "%s\n", in);
        
       -        if (fclose(outfile) == EOF)
       +        if (out && fclose(outfile) == EOF)
                        fprintf(stderr, "There was an error while closing output file "
                            "%s\n", out);
        
   DIR diff --git a/config.mk b/config.mk
       @@ -7,7 +7,7 @@ INCS = -I. -I/usr/include
        LIBS = -L/usr/lib
        
        # flags
       -CPPFLAGS += -D_POSIX_SOURCE
       +CPPFLAGS += -D_POSIX_SOURCE -D_XOPEN_SOURCE=600
        CFLAGS += -std=c99 -pedantic -Wall -Os -s ${INCS} ${CPPFLAGS}
        LDFLAGS += -s ${LIBS}