Added a new module to be used as a dump of generic utility functions.
authorparasti <parasti@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Sun, 6 Jan 2008 02:16:08 +0000 (02:16 +0000)
committerparasti <parasti@78b8d119-cf0a-0410-b17c-f493084dd1d7>
Sun, 6 Jan 2008 02:16:08 +0000 (02:16 +0000)
Until a brighter idea comes along, anyway.

git-svn-id: https://s.snth.net/svn/neverball/trunk@1416 78b8d119-cf0a-0410-b17c-f493084dd1d7

Makefile
ball/demo.c
ball/set.c
ball/set.h
ball/st_demo.c
ball/st_set.c
share/common.c [new file with mode: 0644]
share/common.h [new file with mode: 0644]

index e045478..6bf95c9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -146,6 +146,7 @@ BALL_OBJS := \
        share/text.o        \
        share/sync.o        \
        share/tilt.o        \
+       share/common.o      \
        ball/hud.o          \
        ball/mode.o         \
        ball/game.o         \
index 2903b7f..c297f42 100644 (file)
@@ -24,6 +24,7 @@
 #include "config.h"
 #include "binary.h"
 #include "text.h"
+#include "common.h"
 
 /*---------------------------------------------------------------------------*/
 
@@ -66,26 +67,6 @@ void demo_dump_info(const struct demo *d)
            d->time, d->goal, d->score, d->balls, d->times);
 }
 
-static time_t make_time_from_utc(struct tm *tm)
-{
-    struct tm local, *utc;
-    time_t t;
-
-    t = mktime(tm);
-
-    local = *localtime(&t);
-    utc   =  gmtime(&t);
-
-    local.tm_year += local.tm_year - utc->tm_year;
-    local.tm_mon  += local.tm_mon  - utc->tm_mon ;
-    local.tm_mday += local.tm_mday - utc->tm_mday;
-    local.tm_hour += local.tm_hour - utc->tm_hour;
-    local.tm_min  += local.tm_min  - utc->tm_min ;
-    local.tm_sec  += local.tm_sec  - utc->tm_sec ;
-
-    return mktime(&local);
-}
-
 static int demo_header_read(FILE *fp, struct demo *d)
 {
     int magic;
@@ -141,37 +122,6 @@ static int demo_header_read(FILE *fp, struct demo *d)
     return 0;
 }
 
-static char *bname(const char *name, const char *suffix)
-{
-    static char buf[MAXSTR];
-
-    char *base;
-    size_t l;
-
-    /* Remove the directory delimiter */
-
-    base = strrchr(name, '/');
-#ifdef _WIN32
-    if (!base)
-        base = strrchr(name, '\\');
-    else
-    {
-        char *tmp;
-        if ((tmp = strrchr(base, '\\')))
-            base = tmp;
-    }
-#endif
-    strncpy(buf, base ? base + 1 : name, MAXSTR);
-
-    /* Remove the extension */
-
-    l = strlen(buf) - strlen(suffix);
-    if ((l > 1) && (strcmp(buf + l, suffix) == 0))
-        buf[l] = '\0';
-
-    return buf;
-}
-
 static void demo_header_write(FILE *fp, struct demo *d)
 {
     int magic = MAGIC;
@@ -216,7 +166,8 @@ static void demo_scan_file(const char *filename)
         if (demo_header_read(fp, d))
         {
             strncpy(d->filename, config_user(filename), MAXSTR);
-            strncpy(d->name, bname(text_from_locale(d->filename), REPLAY_EXT),
+            strncpy(d->name,
+                    base_name(text_from_locale(d->filename), REPLAY_EXT),
                     PATHMAX);
             d->name[PATHMAX - 1] = '\0';
 
@@ -283,37 +234,16 @@ const struct demo *demo_get(int i)
     return (0 <= i && i < count) ? &demos[i] : NULL;
 }
 
-const char *date_to_str(time_t i)
-{
-    static char str[MAXSTR];
-    const char *fmt;
-
-    /* TRANSLATORS:  here is the format of the date shown at the
-       replay selection screen (and possibly elsewhere).  The default
-       format is necessarily locale-independent.  See strftime(3) for
-       details on the format.
-     */
-
-    fmt = /* xgettext:no-c-format */ L_("%Y-%m-%d %H:%M:%S");
-    strftime(str, MAXSTR, fmt, localtime(&i));
-    return text_from_locale(str);
-}
-
 /*---------------------------------------------------------------------------*/
 
 int demo_exists(const char *name)
 {
-    FILE *fp;
     char buf[MAXSTR];
 
     strcpy(buf, config_user(name));
     strcat(buf, REPLAY_EXT);
-    if ((fp = fopen(buf, "r")))
-    {
-        fclose(fp);
-        return 1;
-    }
-    return 0;
+
+    return file_exists(buf);
 }
 
 void demo_unique(char *name)
@@ -421,11 +351,7 @@ void demo_rename(const char *name)
         strcpy(dst, config_user(name));
         strcat(dst, REPLAY_EXT);
 
-#ifdef _WIN32
-        if (demo_exists(name))
-            remove(dst);
-#endif
-        rename(src, dst);
+        file_rename(src, dst);
     }
 }
 
@@ -460,8 +386,9 @@ int demo_replay_init(const char *name, struct level_game *lg)
     if (demo_fp && demo_header_read(demo_fp, &demo_replay))
     {
         strncpy(demo_replay.filename, name, MAXSTR);
-        strncpy(demo_replay.name, bname(text_from_locale(demo_replay.filename),
-                REPLAY_EXT), PATHMAX);
+        strncpy(demo_replay.name,
+                base_name(text_from_locale(demo_replay.filename), REPLAY_EXT),
+                PATHMAX);
 
         if (!demo_load_level(&demo_replay, &demo_level_replay))
             return 0;
index de07f36..0f2c084 100644 (file)
 #include "text.h"
 #include "set.h"
 #include "game.h"
+#include "common.h"
 
 /*---------------------------------------------------------------------------*/
 
+static int set_state = 0;
+
 static int set;
 static int count;
 
@@ -158,21 +161,12 @@ static void set_load_hs(void)
     }
 }
 
-static char *strip_eol(char *str)
-{
-    char *c = str + strlen(str) - 1;
-
-    while (c >= str && (*c == '\n' || *c =='\r'))
-        *c-- = '\0';
-
-    return str;
-}
-
 static int set_load(struct set *s, const char *filename)
 {
     FILE *fin;
     char buf[MAXSTR];
-    int res;
+
+    char *scores;
 
     fin = fopen(config_data(filename), "r");
 
@@ -194,36 +188,45 @@ static int set_load(struct set *s, const char *filename)
 
     strcpy(s->file, filename);
 
-    if ((res = fgets(buf, MAXSTR, fin) != NULL))
-        strcpy(s->name, strip_eol(buf));
-    if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
-        strcpy(s->desc, strip_eol(buf));
-    if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
-        strcpy(s->id, strip_eol(buf));
-    if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
-        strcpy(s->shot, strip_eol(buf));
-    if (res && (res = fgets(buf, MAXSTR, fin) != NULL))
-        sscanf(buf, "%d %d %d %d %d %d",
-                &s->time_score.timer[0],
-                &s->time_score.timer[1],
-                &s->time_score.timer[2],
-                &s->coin_score.coins[0],
-                &s->coin_score.coins[1],
-                &s->coin_score.coins[2]);
-
-    strcpy(s->user_scores, "neverballhs-");
-    strcat(s->user_scores, s->id);
-
-    /* Count levels. */
-
-    s->count = 0;
-
-    while (s->count < MAXLVL && (fscanf(fin, "%s", buf) == 1))
-        s->count++;
+    if (read_line(&s->name, fin) &&
+        read_line(&s->desc, fin) &&
+        read_line(&s->id,   fin) &&
+        read_line(&s->shot, fin) &&
+        read_line(&scores,  fin))
+    {
+        sscanf(scores, "%d %d %d %d %d %d",
+               &s->time_score.timer[0],
+               &s->time_score.timer[1],
+               &s->time_score.timer[2],
+               &s->coin_score.coins[0],
+               &s->coin_score.coins[1],
+               &s->coin_score.coins[2]);
+
+        free(scores);
+
+        strcpy(s->user_scores, "neverballhs-");
+        strcat(s->user_scores, s->id);
+
+        /* Count levels. */
+
+        s->count = 0;
+
+        while (s->count < MAXLVL && fscanf(fin, "%s", buf) == 1)
+            s->count++;
+
+        fclose(fin);
+
+        return 1;
+    }
+
+    free(s->name);
+    free(s->desc);
+    free(s->id);
+    free(s->shot);
 
     fclose(fin);
 
-    return 1;
+    return 0;
 }
 
 /*---------------------------------------------------------------------------*/
@@ -233,21 +236,41 @@ int set_init()
     FILE *fin;
     char  name[MAXSTR];
 
+    if (set_state)
+        set_free();
+
     set   = 0;
     count = 0;
 
     if ((fin = fopen(config_data(SET_FILE), "r")))
     {
         while (count < MAXSET && fgets(name, MAXSTR, fin))
-            if (set_load(&set_v[count], strip_eol(name)))
+            if (set_load(&set_v[count], strip_newline(name)))
                 count++;
 
         fclose(fin);
+
+        set_state = 1;
     }
 
     return count;
 }
 
+void set_free(void)
+{
+    int i;
+
+    for (i = 0; i < count; i++)
+    {
+        free(set_v[i].name);
+        free(set_v[i].desc);
+        free(set_v[i].id);
+        free(set_v[i].shot);
+    }
+
+    set_state = 0;
+}
+
 /*---------------------------------------------------------------------------*/
 
 int  set_exists(int i)
@@ -564,5 +587,4 @@ void set_cheat(void)
         level_v[i].is_locked = 0;
 }
 
-
 /*---------------------------------------------------------------------------*/
index 81b49aa..48d240c 100644 (file)
@@ -15,10 +15,10 @@ struct set
 {
     char file[PATHMAX];
 
-    char id[MAXSTR];           /* Internal set identifier    */
-    char name[MAXSTR];         /* Set name                   */
-    char desc[MAXSTR];         /* Set description            */
-    char shot[MAXSTR];         /* Set screen-shot            */
+    char *id;                  /* Internal set identifier    */
+    char *name;                /* Set name                   */
+    char *desc;                /* Set description            */
+    char *shot;                /* Set screen-shot            */
 
     char user_scores[PATHMAX]; /* User high-score file       */
 
@@ -32,8 +32,10 @@ struct set
 
 /*---------------------------------------------------------------------------*/
 
-int set_init();
-int set_exists(int);
+int  set_init(void);
+void set_free(void);
+
+int  set_exists(int);
 
 const struct set *get_set(int);
 
index 79a4167..3b136d4 100644 (file)
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "st_shared.h"
 #include "util.h"
+#include "common.h"
 
 #include "st_demo.h"
 #include "st_title.h"
index 2402a1b..7f2db14 100644 (file)
@@ -44,6 +44,7 @@ static int set_action(int i)
     switch (i)
     {
     case GUI_BACK:
+        set_free();
         return goto_state(&st_title);
         break;
 
diff --git a/share/common.c b/share/common.c
new file mode 100644 (file)
index 0000000..de5d267
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ *  Copyright (C) 2007  Neverball contributors
+ *
+ *  This  program is  free software;  you can  redistribute  it and/or
+ *  modify it  under the  terms of the  GNU General Public  License as
+ *  published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  This program  is distributed in the  hope that it  will be useful,
+ *  but  WITHOUT ANY WARRANTY;  without even  the implied  warranty of
+ *  MERCHANTABILITY or FITNESS FOR  A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a  copy of the GNU General Public License
+ *  along  with this  program;  if  not, write  to  the Free  Software
+ *  Foundation,  Inc.,   59  Temple  Place,  Suite   330,  Boston,  MA
+ *  02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#include "common.h"
+
+#define MAXSTR 256
+
+/*---------------------------------------------------------------------------*/
+
+int read_line(char **dst, FILE *fin)
+{
+    char buffer[MAXSTR] = "";
+    int  buffer_size    = 0;
+
+    char *store      = NULL;
+    char *store_new  = NULL;
+    int   store_size = 0;
+
+    int seen_newline = 0;
+
+    while (!seen_newline)
+    {
+        if (fgets(buffer, sizeof (buffer), fin) == NULL)
+        {
+            if (store_size > 0)
+                break;
+            else
+            {
+                *dst = NULL;
+                return 0;
+            }
+        }
+
+        buffer_size = strlen(buffer) + 1;
+
+        /* Erase trailing newline. */
+
+        if (buffer[buffer_size - 2] == '\n')
+        {
+            seen_newline = 1;
+            buffer[buffer_size - 2] = '\0';
+            buffer_size--;
+        }
+
+        /* Allocate or reallocate space for the buffer. */
+
+        if ((store_new = realloc(store, store_size + buffer_size)))
+        {
+            /* Avoid passing garbage to string functions. */
+
+            if (store == NULL)
+                store_new[0] = '\0';
+
+            store       = store_new;
+            store_size += buffer_size;
+
+            store_new = NULL;
+        }
+        else
+        {
+            fprintf(stderr, "Failed to allocate memory.\n");
+
+            free(store);
+            *dst = NULL;
+            return 0;
+        }
+
+        strncat(store, buffer, buffer_size);
+    }
+
+    *dst = store;
+
+    return 1;
+}
+
+char *strip_newline(char *str)
+{
+    char *c = str + strlen(str) - 1;
+
+    while (c >= str && (*c == '\n' || *c =='\r'))
+        *c-- = '\0';
+
+    return str;
+}
+
+time_t make_time_from_utc(struct tm *tm)
+{
+    struct tm local, *utc;
+    time_t t;
+
+    t = mktime(tm);
+
+    local = *localtime(&t);
+    utc   =  gmtime(&t);
+
+    local.tm_year += local.tm_year - utc->tm_year;
+    local.tm_mon  += local.tm_mon  - utc->tm_mon ;
+    local.tm_mday += local.tm_mday - utc->tm_mday;
+    local.tm_hour += local.tm_hour - utc->tm_hour;
+    local.tm_min  += local.tm_min  - utc->tm_min ;
+    local.tm_sec  += local.tm_sec  - utc->tm_sec ;
+
+    return mktime(&local);
+}
+
+const char *date_to_str(time_t i)
+{
+    static char str[sizeof ("YYYY-mm-dd HH:MM:SS")];
+    strftime(str, sizeof (str), "%Y-%m-%d %H:%M:%S", localtime(&i));
+    return str;
+}
+
+int file_exists(const char *name)
+{
+    FILE *fp;
+
+    if ((fp = fopen(name, "r")))
+    {
+        fclose(fp);
+        return 1;
+    }
+    return 0;
+}
+
+int file_rename(const char *src, const char *dst)
+{
+#ifdef _WIN32
+    if (file_exists(dst))
+        remove(dst);
+#endif
+    return rename(src, dst);
+}
+
+char *base_name(const char *name, const char *suffix)
+{
+    static char buf[MAXSTR];
+
+    char *base;
+    size_t l;
+
+    /* Remove the directory delimiter. */
+
+    base = strrchr(name, '/');
+#ifdef _WIN32
+    if (!base)
+        base = strrchr(name, '\\');
+    else
+    {
+        char *tmp;
+        if ((tmp = strrchr(base, '\\')))
+            base = tmp;
+    }
+#endif
+    strncpy(buf, base ? base + 1 : name, MAXSTR);
+
+    /* Remove the extension. */
+
+    l = strlen(buf) - strlen(suffix);
+    if ((l > 1) && (strcmp(buf + l, suffix) == 0))
+        buf[l] = '\0';
+
+    return buf;
+}
+
+/*---------------------------------------------------------------------------*/
diff --git a/share/common.h b/share/common.h
new file mode 100644 (file)
index 0000000..d232ee8
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (C) 2007  Neverball contributors
+ *
+ *  This  program is  free software;  you can  redistribute  it and/or
+ *  modify it  under the  terms of the  GNU General Public  License as
+ *  published by the Free Software Foundation; either version 2 of the
+ *  License, or (at your option) any later version.
+ *
+ *  This program  is distributed in the  hope that it  will be useful,
+ *  but  WITHOUT ANY WARRANTY;  without even  the implied  warranty of
+ *  MERCHANTABILITY or FITNESS FOR  A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a  copy of the GNU General Public License
+ *  along  with this  program;  if  not, write  to  the Free  Software
+ *  Foundation,  Inc.,   59  Temple  Place,  Suite   330,  Boston,  MA
+ *  02111-1307 USA
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <time.h>
+
+int   read_line(char **, FILE *);
+char *strip_newline(char *);
+
+time_t make_time_from_utc(struct tm *);
+const char *date_to_str(time_t);
+
+int file_exists(const char *);
+int file_rename(const char *, const char *);
+
+char *base_name(const char *name, const char *suffix);
+
+#endif