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

dcbr.c

/*
 *  Fenix - Videogame compiler/interpreter
 *  Current release       : FENIX - PROJECT 1.0 - R 0.84
 *  Last stable release   :
 *  Project documentation : http://fenix.divsite.net
 *
 *
 *  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
 *
 *  Copyright © 1999 José Luis Cebrián Pagüe
 *  Copyright © 2002 Fenix Team
 *
 */

/*
 * FILE        : dcbr.c
 * DESCRIPTION : DCB loading functions
 *
 * HISTORY:  0.83 - Patch to unify path processing
 *
 */

#include <stdio.h>
#ifdef TARGET_BEOS
#include <posix/assert.h>
#else
#include <assert.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifndef TARGET_Win32
#include <unistd.h>
#else
#include <direct.h>
#endif
#include "fxi.h"
#include "dcb.h"
#include "dirs.h"
#include "files.h"

void * globaldata = 0 ;
void * localdata  = 0 ;
int    local_size ;
int  * localstr   = 0 ;
int    local_strings ;

PROCDEF * procs = NULL ;
PROCDEF * mainproc = NULL ;
int procdef_count = 0 ;

PROCDEF * procdef_get (int n)
{
      if (n >= 0 && n < procdef_count)
            return &procs[n] ;

      return NULL ;
}

PROCDEF * procdef_get_by_name (char * name)
{
    int n;
    for (n = 0 ; n < procdef_count; n++)
        if (strcmp(procs[n].name, name) == 0)
            return &procs[n];

      return NULL ;
}

DCB_HEADER dcb ;

static char * trim(char * ptr)
{
    char * ostr = ptr;
    char * bptr = ptr;

    while (*ptr == ' ' || *ptr == '\n' || *ptr == '\r' || *ptr == '\t') ptr++;

    while (*ptr) *bptr++ = *ptr++;

    while (bptr > ostr && (bptr[-1] == ' ' || bptr[-1] == '\n' || bptr[-1] == '\r' || bptr[-1] == '\t')) bptr--;

    *bptr = 0;

    return (ostr);
}

static int load_file (const char * filename, int n)
{
    char line[2048] ;
    int allocated = 16 ;
    int count = 0 ;
    char ** lines ;
    file * fp ;

    fp = file_open (filename, "r0") ;
    if (!fp)
    {
        dcb.sourcelines[n] = 0 ;
        dcb.sourcecount[n] = 0 ;
        return 0 ;
    }

    lines = (char **) malloc(sizeof(char**) * 16) ;

    while (!file_eof(fp))
    {
        file_gets (fp, line, 2048) ;
        trim(line);
        if (allocated == count)
        {
            allocated += 16 ;
            lines = realloc (lines, sizeof(char**) * allocated) ;
        }
        lines[count++] = strdup(line) ;
    }
    file_close (fp) ;
    dcb.sourcelines[n] = lines ;
    dcb.sourcecount[n] = count ;
    return 1 ;
}

int dcb_load (const char * filename)
{
      file * fp ;

      /* check for existence of the DCB FILE */
      if (!file_exists(filename)) return 0 ;

      fp = file_open (filename, "rb0") ;
      if (!fp)
            gr_error ("Error al abrir %s\n", filename) ;

      return dcb_load_from (fp, 0);
}

int dcb_load_from (file * fp, int offset)
{
      unsigned int n ;
      char *path, *ptr ;

      /* Cambia al directorio del DCB con chdir */
      path = dir_path_convert(fp->name) ;
      for (ptr = path+strlen(path) ; ptr >= path ; ptr--)
            if (*ptr == '/' || *ptr == '\\') break ;
      ptr[1] = 0 ;
      chdir (path) ;
      base_dir = path ;

      /* En WIN32, cambia a la unidad del DCB */

#ifdef WIN32
      if (path[0] && path[1] == ':')
      {
            if (path[0] >= 'A' && path[0] <= 'Z')
                  base_drive = path[0]-'A'+1 ;

            if (path[0] >= 'a' && path[0] <= 'z')
                  base_drive = path[0]-'a'+1 ;

            _chdrive (base_drive);
      }
#endif

      /* Lee el contenido del fichero */

      file_seek (fp, offset, SEEK_SET);
      file_read (fp, &dcb, sizeof(DCB_HEADER_DATA)) ;

      if (memcmp (dcb.data.Header, "dcb\xD\x0A\x1F\x00\x00", 8) != 0 ||
          (dcb.data.Version & 0xFF00) != (DCB_VERSION & 0xFF00))
      {
      /*    gr_error ("%s: no es un DCB version %d o compatible", filename, DCB_VERSION >> 8) ;*/
            return 0 ;
      }

      globaldata = malloc (dcb.data.SGlobal + 4) ;
      localdata  = malloc (dcb.data.SLocal + 4) ;
      localstr   = (int *) malloc (4 * dcb.data.NLocStrings + 4) ;
      dcb.proc   = (DCB_PROC *) malloc (sizeof(DCB_PROC) * (1+dcb.data.NProcs)) ;
      procs      = (PROCDEF *) malloc (sizeof(PROCDEF) * (1+dcb.data.NProcs)) ;
      mainproc   = procs ;

      procdef_count = dcb.data.NProcs ;
      local_size    = dcb.data.SLocal ;
      local_strings = dcb.data.NLocStrings ;

      /* Recupera las zonas de datos globales */

      file_seek (fp, offset + dcb.data.OGlobal, SEEK_SET) ;
      file_read (fp, globaldata, dcb.data.SGlobal) ;

      file_seek (fp, offset + dcb.data.OLocal, SEEK_SET) ;
      file_read (fp, localdata, dcb.data.SLocal) ;

      if (dcb.data.NLocStrings)
      {
            file_seek (fp, offset + dcb.data.OLocStrings, SEEK_SET) ;
            file_read (fp, localstr, dcb.data.NLocStrings * 4) ;
      }

      file_seek (fp, offset + dcb.data.OProcsTab, SEEK_SET) ;
      for (n = 0 ; n < dcb.data.NProcs ; n++)
      {
            file_read (fp, &dcb.proc[n], sizeof(DCB_PROC_DATA)) ;
      }

      /* Recupera las cadenas */

      dcb.data.OStrings += offset;
      dcb.data.OText += offset;
      string_load (fp) ;

      /* Recupera los ficheros incluídos */

      if (dcb.data.NFiles)
      {
            dcb.file = (DCB_FILE *) malloc(sizeof(DCB_FILE) * dcb.data.NFiles) ;
            file_seek (fp, offset + dcb.data.OFilesTab, SEEK_SET) ;
            file_read (fp, dcb.file, sizeof(DCB_FILE) * dcb.data.NFiles) ;

            for (n = 0 ; n < dcb.data.NFiles ; n++)
            {
                  file_add_xfile (fp, dcb.file[n].OFile, dcb.file[n].Name, dcb.file[n].SFile) ;
            }
      }

      /* Recupera los imports */

      if (dcb.data.NImports)
      {
            dcb.imports = (Uint32 *)malloc(4 * dcb.data.NImports) ;
            file_seek (fp, offset + dcb.data.OImports, SEEK_SET) ;
            file_read (fp, dcb.imports, 4 * dcb.data.NImports) ;
      }

      /* Recupera los datos de depurado */

      if (dcb.data.NID)
      {
            dcb.id = (DCB_ID *) malloc(sizeof(DCB_ID) * dcb.data.NID) ;
            file_seek (fp, offset + dcb.data.OID, SEEK_SET) ;
            file_read (fp, dcb.id, sizeof(DCB_ID) * dcb.data.NID) ;
      }

      if (dcb.data.NGloVars)
      {
            dcb.glovar = (DCB_VAR *) malloc(sizeof(DCB_VAR) * dcb.data.NGloVars) ;
            file_seek (fp, offset + dcb.data.OGloVars, SEEK_SET) ;
            file_read (fp, dcb.glovar, sizeof(DCB_VAR) * dcb.data.NGloVars) ;
      }

      if (dcb.data.NLocVars)
      {
            dcb.locvar = (DCB_VAR *) malloc(sizeof(DCB_VAR) * dcb.data.NLocVars) ;
            file_seek (fp, offset + dcb.data.OLocVars, SEEK_SET) ;
            file_read (fp, dcb.locvar, sizeof(DCB_VAR) * dcb.data.NLocVars) ;
      }

      if (dcb.data.NVarSpaces)
      {
            dcb.varspace = (DCB_VARSPACE *) malloc(sizeof(DCB_VARSPACE) * dcb.data.NVarSpaces) ;
            dcb.varspace_vars = (DCB_VAR **) malloc(sizeof(DCB_VAR *) * dcb.data.NVarSpaces) ;
            file_seek (fp, offset + dcb.data.OVarSpaces, SEEK_SET) ;
            file_read (fp, dcb.varspace, sizeof(DCB_VARSPACE) * dcb.data.NVarSpaces) ;

            for (n = 0 ; n < dcb.data.NVarSpaces ; n++)
            {
                  dcb.varspace_vars[n] = 0 ;
                  if (!dcb.varspace[n].NVars) continue ;
                  dcb.varspace_vars[n] = (DCB_VAR *)
                        malloc (sizeof(DCB_VAR) * dcb.varspace[n].NVars) ;
                  file_seek (fp, offset + dcb.varspace[n].OVars, SEEK_SET) ;
                  file_read (fp, dcb.varspace_vars[n],
                        sizeof(DCB_VAR) * dcb.varspace[n].NVars) ;
            }
      }

      if (dcb.data.NSourceFiles)
      {
            char filename[256] ;

            dcb.sourcecount = (int*)malloc (sizeof(int) * dcb.data.NSourceFiles) ;
            dcb.sourcelines = (char ***)malloc (sizeof(char **) * dcb.data.NSourceFiles) ;
            file_seek (fp, offset + dcb.data.OSourceFiles, SEEK_SET) ;
            for (n = 0 ; n < dcb.data.NSourceFiles ; n++)
            {
                  file_read (fp, filename, 256) ; /* FIX PARA LOS INCLUDES */
                  if (!load_file (filename, n))
                        gr_con_printf ("[FXI] File %s not found", filename) ;
            }
      }

      /* Recupera los procesos */

      for (n = 0 ; n < dcb.data.NProcs ; n++)
      {
            procs[n].params             = dcb.proc[n].data.NParams ;
            procs[n].string_count       = dcb.proc[n].data.NPriStrings ;
            procs[n].pubstring_count    = dcb.proc[n].data.NPubStrings ;
            procs[n].private_size       = dcb.proc[n].data.SPrivate ;
            procs[n].public_size        = dcb.proc[n].data.SPublic ;
            procs[n].code_size          = dcb.proc[n].data.SCode ;
            procs[n].id                 = dcb.proc[n].data.ID ;
            procs[n].flags              = dcb.proc[n].data.Flags ;
            procs[n].type               = n ;
            procs[n].name               = getid(procs[n].id) ;
        procs[n].breakpoint         = 0;

            if (dcb.proc[n].data.SPrivate)
            {
                  procs[n].pridata = (int *)malloc(dcb.proc[n].data.SPrivate) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPrivate, SEEK_SET) ;
                  file_read (fp, procs[n].pridata, dcb.proc[n].data.SPrivate) ;
            }

            if (dcb.proc[n].data.SPublic)
            {
                  procs[n].pubdata = (int *)malloc(dcb.proc[n].data.SPublic) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPublic, SEEK_SET) ;
                  file_read (fp, procs[n].pubdata, dcb.proc[n].data.SPublic) ;
            }

            if (dcb.proc[n].data.SCode)
            {
                  procs[n].code = (int *) malloc(dcb.proc[n].data.SCode) ;
                  file_seek (fp, offset + dcb.proc[n].data.OCode, SEEK_SET) ;
                  file_read (fp, procs[n].code, dcb.proc[n].data.SCode) ;

              if (dcb.proc[n].data.OExitCode)
                  procs[n].exitcode = procs[n].code + dcb.proc[n].data.OExitCode ;
              else
                  procs[n].exitcode = NULL ;
            }

            if (dcb.proc[n].data.NPriStrings)
            {
                  procs[n].strings = (int *)malloc(dcb.proc[n].data.NPriStrings * 4) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPriStrings, SEEK_SET) ;
                  file_read (fp, procs[n].strings, dcb.proc[n].data.NPriStrings * 4) ;
            }

            if (dcb.proc[n].data.NPubStrings)
            {
                  procs[n].pubstrings = (int *)malloc(dcb.proc[n].data.NPubStrings * 4) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPubStrings, SEEK_SET) ;
                  file_read (fp, procs[n].pubstrings, dcb.proc[n].data.NPubStrings * 4) ;
            }

            if (dcb.proc[n].data.NPriVars)
            {
                  dcb.proc[n].privar = (DCB_VAR *)malloc(dcb.proc[n].data.NPriVars * sizeof(DCB_VAR)) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPriVars, SEEK_SET) ;
                  file_read (fp, dcb.proc[n].privar, dcb.proc[n].data.NPriVars * sizeof(DCB_VAR)) ;
            }

            if (dcb.proc[n].data.NPubVars)
            {
                  dcb.proc[n].pubvar = (DCB_VAR *)malloc(dcb.proc[n].data.NPubVars * sizeof(DCB_VAR)) ;
                  file_seek (fp, offset + dcb.proc[n].data.OPubVars, SEEK_SET) ;
                  file_read (fp, dcb.proc[n].pubvar, dcb.proc[n].data.NPubVars * sizeof(DCB_VAR)) ;
            }
      }

      return 1 ;
}

char * getid(unsigned int code)
{
      unsigned int n ;
      for (n = 0 ; n < dcb.data.NID ; n++) {
            if (dcb.id[n].Code == code)
                  return dcb.id[n].Name ;
      }
      return "(?)" ;
}

Generated by  Doxygen 1.6.0   Back to index