URI: 
       Initial commit - 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 682cab4976ad367d532c5d47e73bab73ade40024
  HTML Author: Quentin Rameau <quinq@fifth.space>
       Date:   Mon,  9 Nov 2015 09:46:55 +0100
       
       Initial commit
       
       Diffstat:
         Makefile                            |      38 +++++++++++++++++++++++++++++++
         addrom.c                            |     205 ++++++++++++++++++++++++++++++
         arg.h                               |      63 +++++++++++++++++++++++++++++++
         config.mk                           |      14 ++++++++++++++
       
       4 files changed, 320 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       @@ -0,0 +1,38 @@
       +include config.mk
       +
       +SRC = addrom.c
       +OBJ = ${SRC:.c=.o}
       +
       +all: options addrom
       +
       +options:
       +        @echo addrom build options:
       +        @echo "CFLAGS   = ${CFLAGS}"
       +        @echo "LDFLAGS  = ${LDFLAGS}"
       +        @echo "CC       = ${CC}"
       +
       +.c.o:
       +        @echo CC $<
       +        @${CC} -c ${CFLAGS} $<
       +
       +${OBJ}: config.mk
       +
       +addrom: ${OBJ}
       +        @echo CC -o $@
       +        @${CC} -o $@ ${OBJ} ${LDFLAGS}
       +
       +clean:
       +        @echo cleaning
       +        @rm -f addrom ${OBJ}
       +
       +install: all
       +        @echo installing executable file to ${DESTDIR}${PREFIX}/bin
       +        @mkdir -p ${DESTDIR}${PREFIX}/bin
       +        @cp -f addrom ${DESTDIR}${PREFIX}/bin
       +        @chmod 755 ${DESTDIR}${PREFIX}/bin/addrom
       +
       +uninstall:
       +        @echo removing executable file from ${DESTDIR}${PREFIX}/bin
       +        @rm -f ${DESTDIR}${PREFIX}/bin/addrom
       +
       +.PHONY: all options clean install uninstall
   DIR diff --git a/addrom.c b/addrom.c
       @@ -0,0 +1,205 @@
       +#include <sys/types.h>
       +#include <sys/stat.h>
       +
       +#include <fcntl.h>
       +#include <inttypes.h>
       +#include <libgen.h>
       +#include <stdarg.h>
       +#include <stdint.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include <unistd.h>
       +
       +#include "arg.h"
       +
       +#define HEADERSZSZ 4
       +#define GAMECNTSZ  4
       +#define HEADERSZ  16
       +#define CHTITLESZ 64
       +#define ENTITLESZ 32
       +#define ROMNAMESZ 16
       +#define MAGICSZ    8
       +#define ENTRYSZ   (CHTITLESZ + ENTITLESZ + ROMNAMESZ + MAGICSZ)
       +
       +#define MAGIC     0x0000000000000000
       +
       +ttypedef struct {
       +        char *chtitle;
       +        char *entitle;
       +        char *romname;
       +} Rom;
       +
       +char *argv0;
       +static char *in, *out;
       +static intmax_t place;
       +
       +static void
       +die(const char *errstr, ...)
       +{
       +        va_list ap;
       +
       +        va_start(ap, errstr);
       +        vfprintf(stderr, errstr, ap);
       +        va_end(ap);
       +
       +        exit(1);
       +}
       +
       +static void
       +addrom(char *datfile, const Rom *rom)
       +{
       +        ssize_t pos = 0;
       +
       +        if (rom->chtitle)
       +                strncpy(datfile + pos, rom->chtitle, CHTITLESZ);
       +        pos += CHTITLESZ;
       +        if (rom->entitle)
       +                strncpy(datfile + pos, rom->entitle, ENTITLESZ);
       +        pos += ENTITLESZ;
       +        if (rom->romname)
       +                strncpy(datfile + pos, rom->romname, ROMNAMESZ);
       +        pos += ROMNAMESZ;
       +        *(uint64_t *)(datfile + pos) = MAGIC;
       +}
       +
       +/* not used
       +static uint64_t
       +getgamecount(int n)
       +{
       +        return (n * 0x88888889) >> 32 >> 6;
       +}
       +*/
       +
       +static uint32_t
       +setgamecount(uint64_t n)
       +{
       +        return (n << 32 << 6) / 0x88888888;
       +}
       +
       +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
       +usage(void)
       +{
       +        die("usage: %s [-c chinesetitle] [-e englishtitle] -i inputlist "
       +            "[-n placeinlist] -o outputlist -r romname\n", basename(argv0));
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        struct stat st;
       +        Rom rom = { 0 };
       +        off_t infilesize;
       +        size_t outbufsize;
       +        ssize_t offset;
       +        FILE *infile, *outfile;
       +        char *outbuf;
       +        int infd;
       +
       +        ARGBEGIN {
       +        case 'c':
       +                rom.chtitle = EARGF(usage());
       +                if (strlen(rom.chtitle) > CHTITLESZ)
       +                        die("Chinese title must be less then than %zu bytes\n",
       +                            CHTITLESZ);
       +                break;
       +        case 'e':
       +                rom.entitle = EARGF(usage());
       +                if (strlen(rom.entitle) > ENTITLESZ)
       +                        die("English title must be less then than %zu bytes\n",
       +                            ENTITLESZ);
       +                break;
       +        case 'i':
       +                in = EARGF(usage());
       +                break;
       +        case 'n':
       +                place = strtoimax(EARGF(usage()), NULL, 10);
       +                if (place < 1)
       +                        die("Place must be superior to 0\n");
       +                break;
       +        case 'o':
       +                out = EARGF(usage());
       +                break;
       +        case 'r':
       +                rom.romname = EARGF(usage());
       +                if (strlen(rom.romname) > ROMNAMESZ)
       +                        die("Rom name must be less then than %zu bytes\n",
       +                            ROMNAMESZ);
       +                break;
       +        default:
       +                usage();
       +                break;
       +        } ARGEND
       +
       +        if (!in || !out || !rom.romname)
       +                usage();
       +
       +        if (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);
       +
       +        if (fstat(infd, &st) == -1 || !S_ISREG(st.st_mode))
       +                die("File %s is not a regular file\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);
       +
       +        outbufsize = infilesize + ENTRYSZ;
       +
       +        if (!(outbuf = calloc(outbufsize, 1)))
       +                die("Can't allocate enough memory for reading input file\n");
       +/*
       +        if (place * ENTRYSZ + HEADERSZ > infilesize)
       +                place = 0;
       +
       +        offset = place ? HEADERSZ + (place - 1) * ENTRYSZ : infilesize;
       +*/
       +        if (place == 0 || place * ENTRYSZ + HEADERSZ > infilesize)
       +                offset = infilesize;
       +        else
       +                offset = HEADERSZ + (place - 1) * ENTRYSZ;
       +
       +        ereadinfile(outbuf, offset, infile);
       +
       +        *(uint32_t *)(outbuf + HEADERSZSZ) = setgamecount(
       +            (infilesize - HEADERSZ) / ENTRYSZ + 1);
       +
       +        addrom(outbuf + offset, &rom);
       +
       +        ereadinfile(outbuf + offset + ENTRYSZ, infilesize - offset, infile);
       +
       +        if (!(outfile = fopen(out, "w")))
       +                die("Can't open output file %s\n", out);
       +
       +        if (fwrite(outbuf, 1, outbufsize, outfile) !=
       +            outbufsize)
       +                die("Couldn't write all data to output file %s\n", out);
       +
       +        free(outbuf);
       +
       +        if (fclose(infile) == EOF)
       +                die("There was an error while closing input file %s\n", in);
       +
       +        /* already closed by fclose()
       +        if (close(infd) == -1)
       +                die("There was an error while closing input file %s\n", in);
       +        */
       +
       +        if (fclose(outfile) == EOF)
       +                die("There was an error while closing output file %s\n", out);
       +
       +        return(0);
       +}
   DIR diff --git a/arg.h b/arg.h
       @@ -0,0 +1,63 @@
       +/*
       + * Copy me if you can.
       + * by 20h
       + */
       +
       +#ifndef ARG_H__
       +#define ARG_H__
       +
       +extern char *argv0;
       +
       +/* use main(int argc, char *argv[]) */
       +#define ARGBEGIN        for (argv0 = *argv, argv++, argc--;\
       +                                        argv[0] && argv[0][1]\
       +                                        && argv[0][0] == '-';\
       +                                        argc--, argv++) {\
       +                                char argc_;\
       +                                char **argv_;\
       +                                int brk_;\
       +                                if (argv[0][1] == '-' && argv[0][2] == '\0') {\
       +                                        argv++;\
       +                                        argc--;\
       +                                        break;\
       +                                }\
       +                                for (brk_ = 0, argv[0]++, argv_ = argv;\
       +                                                argv[0][0] && !brk_;\
       +                                                argv[0]++) {\
       +                                        if (argv_ != argv)\
       +                                                break;\
       +                                        argc_ = argv[0][0];\
       +                                        switch (argc_)
       +
       +/* Handles obsolete -NUM syntax */
       +#define ARGNUM                                case '0':\
       +                                        case '1':\
       +                                        case '2':\
       +                                        case '3':\
       +                                        case '4':\
       +                                        case '5':\
       +                                        case '6':\
       +                                        case '7':\
       +                                        case '8':\
       +                                        case '9'
       +
       +#define ARGEND                        }\
       +                        }
       +
       +#define ARGC()                argc_
       +
       +#define ARGNUMF(base)        (brk_ = 1, strtol(argv[0], NULL, (base)))
       +
       +#define EARGF(x)        ((argv[0][1] == '\0' && argv[1] == NULL)?\
       +                                ((x), abort(), (char *)0) :\
       +                                (brk_ = 1, (argv[0][1] != '\0')?\
       +                                        (&argv[0][1]) :\
       +                                        (argc--, argv++, argv[0])))
       +
       +#define ARGF()                ((argv[0][1] == '\0' && argv[1] == NULL)?\
       +                                (char *)0 :\
       +                                (brk_ = 1, (argv[0][1] != '\0')?\
       +                                        (&argv[0][1]) :\
       +                                        (argc--, argv++, argv[0])))
       +
       +#endif
   DIR diff --git a/config.mk b/config.mk
       @@ -0,0 +1,14 @@
       +# paths
       +PREFIX = /usr/local
       +
       +# includes and libs
       +INCS = -I. -I/usr/include
       +LIBS = -L/usr/lib
       +
       +# flags
       +CPPFLAGS += -D_POSIX_SOURCE
       +CFLAGS += -std=c99 -pedantic -Wall -Os -s ${INCS} ${CPPFLAGS}
       +LDFLAGS += -s ${LIBS}
       +
       +# compiler and linker
       +# CC = cc