Logo Search packages:      
Sourcecode: gaby version File versions  Download package

gaby1.c

/*  Gaby
 *  Copyright (C) 1998-1999 Frederic Peters
 *
 *  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.
 */

/*
 * This is copied from gaby 1.8 (ie ../gaby/gaby.c), not from 1.0 files.
 *   `822-date` -> Wed, 10 Mar 1999 15:17:25 +0100
 * It is probable that _real_ gaby format (>=1.8) will not be in sync
 * with this one since I will work on it and not on this.
 */

#include <format_plugin.h>

/* This should be enough (it will be increased if huge records appears) */
#define           RECORD_MAX_SIZE         2048

static gboolean record_add_str(table *t, char *str, struct location *loc);
static void record_get_str(table *t, record r, char *str);
static void fill_date_field(char *str, struct tm *date);

gboolean gaby1_load_file (struct location *loc)
{
      table *t = loc->table;
      FILE *f;
      char s[RECORD_MAX_SIZE];
#ifdef SUPERFLUOUS
      char *twirling = "-/|\\-/|\\-";
      static int twirlingpos=0;
#endif
      
#ifdef DEBUG_GABY
      debug_print("Loading %s\n", loc->filename);
#endif

      f = fopen(loc->filename, "r" );
      if ( f == NULL ) {
            gaby_errno = FILE_READ_ERROR;
            gaby_message = g_strdup(loc->filename);
            gaby_perror_in_a_box();
            return FALSE;
      }

      fgets(s, 512, f);
      while ( ! feof(f) ) {
#ifdef SUPERFLUOUS
            putchar(twirling[(twirlingpos++)%9]); putchar('\b');
            fflush(stdout);
#endif
            record_add_str(t, s, loc);
            fgets(s, 512, f);
      }

      fclose(f);
      
      return TRUE;
}

gboolean gaby1_save_file (struct location *loc)
{
      table *t = loc->table;
      FILE *f;
      int i;
      char str[RECORD_MAX_SIZE];
      
#ifdef DEBUG_GABY
      debug_print("Saving %s\n", loc->filename);
#endif

      f = fopen(loc->filename, "w" );
      if ( f == NULL ) {
            gaby_errno = FILE_WRITE_ERROR;
            gaby_message = g_strdup(loc->filename);
            gaby_perror_in_a_box();
            return FALSE;
      }
      
      for ( i=0; i<t->max_records;i++ ) {
            if ( t->records[i] == NULL || t->records[i]->id == 0 )
                  continue;
            if ( loc->type != NULL && t->records[i]->file_loc != loc )
                  continue;
            record_get_str(t, *(t->records[i]), str );
            fputs(str, f);
      }
      fputs("\n", f);
      fclose(f);
      
      return TRUE;
}

static gboolean record_add_str(table *t, char *str, struct location *loc)
{
      record *r;
      char *s2, *s1, *s3;
      int i=0, j;
      int ta;
      char *src="n;\\";
      char *dst="\n;\\";
      static int lid=0;
      struct tm fake_date;
      
      if ( str[0] == '#' || str[0] == '\n' )
            return FALSE;
      
      r = g_malloc(sizeof(record));
      r->id = loc->offset + lid++;
      r->file_loc = loc;
      s1 = str;

#ifdef DEBUG_GABY
      debug_print("Adding : (%d) %s\n", r->id, str);
#endif

      
      r->cont = g_new0(union data, t->nb_fields);
      do {
            s2 = s1;
            do {
                  s2 = strchr(s2, ';');
                  if ( s2 == NULL ) { s2 = s1+strlen(s1); break;}
                  s2++;
            } while ( s2[-2] == '\\' );
            ta = s2-s1-1;
            s3 = g_malloc(ta+1);
            strncpy(s3, s1, ta);
            s3[ta] = 0;
            for ( j=0; j<strlen(src); j++ ) {
                  s2 = s3;
                  while ( strchr(s2, src[j]) != NULL ) {
                        s2 = strchr(s2, src[j]);
                        if ( s2[-1] != '\\' ) {
                              s2++;
                              continue;
                        }
                        s2[-1] = dst[j];
                        strcpy(s2, s2+1);
                  }
            }
            switch ( t->fields[i].type ) {
                  case T_STRING:
                  case T_STRINGS:
                  case T_MULTIMEDIA:
                  case T_FILE:
                  {
                        r->cont[i].str = g_string_new(s3);
                  } break;
                  case T_DATE:
                  {
#if 0
                        fill_date_field(s3, &fake_date);
                        r->cont[i].date = g_date_new_dmy(   
                                    fake_date.tm_mday,  
                                    fake_date.tm_mon+1, 
                                    fake_date.tm_year );
#else
                        r->cont[i].date = g_date_new();
                        g_date_set_parse(r->cont[i].date, s3);
                        if (r->cont[i].date->month == G_DATE_BAD_MONTH){
                              g_date_free(r->cont[i].date);
                              r->cont[i].date = NULL;
                        }
#endif
                  } break;
                  case T_INTEGER:
                  case T_DECIMAL:
                  {
                        r->cont[i].i = atoi(s3);
                  } break;
                  case T_REAL:
                  {
                        r->cont[i].d = atof(s3);
                  } break;
                  default:
                  {
                        ;
                  } break;
            }
            
            g_free(s3);
            s1 += ta+1;
            i++;
      } while ( s1[-1] != '\n');

      record_add(t, r, FALSE, TRUE);

      return TRUE;
}

static void record_get_str(table *t, record r, char *str)
{
      int i;
      char *fix_str = str;
      char *semi_fix_str = str;
      char *src="\\\n;"; /* those will be replaced */
      char *dst="\\n;";  /* by \ + these ones */
      int j;
      
      for ( i=0; i<t->nb_fields; i++ ) {
            switch ( t->fields[i].type ) {
                  case T_STRING:
                  case T_STRINGS:
                  case T_MULTIMEDIA:
                  case T_FILE:
                  {
                        sprintf(str, "%s", r.cont[i].str->str);
                  } break;
                  case T_DATE:
                  {
                        sprintf(str, "%d/%d/%d", 
                                    g_date_day(r.cont[i].date),
                                    g_date_month(r.cont[i].date),
                                    g_date_year(r.cont[i].date) );
                  } break;
                  case T_INTEGER:
                  case T_DECIMAL:
                  {
                        sprintf(str, "%d", r.cont[i].i);
                  } break;
                  case T_REAL:
                  {
                        sprintf(str, "%f", r.cont[i].d);
                  } break;

                  default: {} break;
            }
            for ( j=0; j<strlen(src); j++ ) {
                  str = semi_fix_str;
                  while ( /* str = */ strchr(str, src[j]) != NULL ) {
                        str = strchr(str, src[j]); /* cleaner */
                        memmove(str+2, str+1, strlen(str+1)+1);
                        str[0] = '\\'; str[1] = dst[j]; str+=2;
                  }
            }
            str = fix_str;
            str += strlen(str);
            str[0] = ';'; str[1] = 0; str++;
            semi_fix_str = str;
      }
      str = fix_str;
      str[strlen(str)-1] = '\n'; /* we don't want a terminal ';' */
      
}

static void fill_date_field(char *str, struct tm *date)
{
      /*
       * we assume dd/mm/yy; it would be better to be less strict
       * (later)
       * we should use date functions in glib but I didn't read them yet.
       * I think there's a function to determine wether to use mm/dd/yy or
       * dd/mm/yy using locales but I just had a quick look on them.
       */

      /* default is 1/1/2000, let's test y2k bug :) */

      
      date->tm_mday = 1;
      date->tm_mon = 0;
      date->tm_year = 2000;

      if ( strlen(str) == 0 ) return;
      if ( ! strchr(str,'/') ) return;

      strchr(str,'/')[0] = 0;
      date->tm_mday = atoi(str);
      if ( date->tm_mday == 0 ) date->tm_mday++;
      str += strlen(str)+1;
      
      if ( ! strchr(str,'/') ) return;

      strchr(str,'/')[0] = 0;
      date->tm_mon = atoi(str)-1; /* tm_mon is 0..11, not 1..12 */
      str += strlen(str)+1;
      
      date->tm_year = atoi(str);
      
      if ( date->tm_year < 100 ) {
            /* we try to be smarter than you : 2 digit years are 19xx
             * there's no way to force a date < 1/1/100, but I believe
             * it's enough for your friends/family
             */
            date->tm_year += 1900;
      }

}


Generated by  Doxygen 1.6.0   Back to index