⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbc_output.c

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  output.c  The object file creator  (c) 2000-2004 Beno� Minisini <gambas@users.sourceforge.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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __GBC_OUTPUT_C#include "gb_common.h"#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <ctype.h>#include "gb_error.h"#include "gb_alloc.h"#include "gb_str.h"#include "gb_file.h"#include "gbc_compile.h"#include "gb_magic.h"#include "gbc_output.h"/*#define DEBUG*//*#define DEBUG_MORE*/PRIVATE FILE *File;PRIVATE CLASS *Class;PRIVATE long StringAddr;PRIVATE TABLE *StringTable;PRIVATE int NSection;PRIVATE long PosStartSection;PRIVATE int SizeSection;PRIVATE bool _swap;/*#define START_SECTION()  long pos = write_long(0);#define END_SECTION()    write_pad(); write_long_at(pos, get_pos() - pos - sizeof(long));*/PRIVATE void output_init(void){  TABLE_create(&StringTable, sizeof(OUTPUT_SYMBOL), TF_NORMAL);  StringAddr = 0;  NSection = 0;}PRIVATE void output_exit(void){  TABLE_delete(&StringTable);}PRIVATE long get_string(const char *string, int len){  OUTPUT_SYMBOL *sym;  if (len < 0)    len = strlen(string);  if (!TABLE_add_symbol(StringTable, string, len, (SYMBOL **)&sym, NULL))  {    sym->value = StringAddr;    StringAddr += len + 1;  }  #ifdef DEBUG  printf("'%.*s' -> %ld\n", len, string, sym->value);  #endif  return sym->value;}PRIVATE long get_pos(void){  return ftell(File);}PRIVATE void write_byte(unsigned char val){  #ifdef DEBUG_MORE  printf("%ld : b %u 0x%X\n", get_pos(), val, val);  #endif  /* MSB & LSB */  if (fwrite(&val, sizeof(char), 1, File) != 1)    THROW("Write error");}PRIVATE void write_short(unsigned short val){  #ifdef DEBUG_MORE  printf("%ld : i %u 0x%X\n", get_pos(), val, val);  #endif  if (_swap)    val = (val >> 8) | (val << 8);  /* MSB & LSB */  if (fwrite(&val, sizeof(val), 1, File) != 1)    THROW("Write error");}static void write_type(TYPE type){	write_byte(type.t.flag);	write_byte(type.t.id);	write_short(type.t.value);}PRIVATE long write_long(unsigned long val){  long pos = get_pos();  #ifdef DEBUG_MORE  printf("%ld : l %lu 0x%lX\n", get_pos(), val, val);  #endif  if (_swap)    val = (val >> 24) | ((val >> 8) & 0xFF00) | ((val << 8) & 0xFF0000) | (val << 24);  /* MSB & LSB */  if (fwrite(&val, sizeof(val), 1, File) != 1)    THROW("Write error");  return pos;}PRIVATE void write_long_at(long pos, unsigned long val){  long prev = get_pos();  fseek(File, pos, SEEK_SET);  #ifdef DEBUG_MORE  printf("@ ");  #endif  write_long(val);  fseek(File, prev, SEEK_SET);}PRIVATE void write_string(const char *str, int len){  #ifdef DEBUG_MORE  printf("%ld : s \"%.*s\"\n", get_pos(), len, str);  #endif  if (fwrite(str, sizeof(char), len, File) != len)    THROW("Write error");  write_byte(0);}PRIVATE void write_buffer(void *str, long len){  #ifdef DEBUG_MORE  printf("%ld : buffer %ld octets\n", get_pos(), len);  #endif  if (len == 0)    return;  if (fwrite(str, sizeof(char), len, File) != len)    THROW("Write error");}PRIVATE void write_pad(void){  while (get_pos() & 0x3)    write_byte(0);}PRIVATE void begin_section(const char *name, int size){  NSection++;  #ifdef DEBUG  printf("Section #%d : %s\n", NSection, name);  #endif  if (size)    PosStartSection = write_long(0);  else    PosStartSection = 0;  SizeSection = size;}PRIVATE void end_section(void){  long len;  if (PosStartSection)  {    write_pad();    len = get_pos() - PosStartSection - sizeof(long);    write_long_at(PosStartSection, len);    #ifdef DEBUG    printf("==> %ld %s\n", len / SizeSection, (SizeSection == 1) ? "bytes" : "elements");    if (len % SizeSection)      printf("*** remain %ld bytes\n", len % SizeSection);    #endif  }}PRIVATE void output_header(void){  begin_section("Header", 0);  /* magic */  write_long(OUTPUT_MAGIC);  /* version */  write_long(OUTPUT_VERSION);  /* endianess */  write_long(OUTPUT_ENDIAN);  /* flag */  if (JOB->debug)    write_long(1);  else    write_long(0);  end_section();}PRIVATE void output_class(void){  begin_section("Class", 1);  /* classe parente */  write_short(Class->parent);  /* reserved */  write_short(0);  /* size_static */  write_long(Class->size_stat);  /* size_dynamic */  write_long(Class->size_dyn);  end_section();}PRIVATE void output_desc(void){  int i, n, nn = 0;  CLASS_SYMBOL *csym;  TYPE type;  short out_type;  n = TABLE_count(Class->table);  begin_section("Description", 6 * sizeof(long));  for (i = 0; i < n; i++)  {    csym = (CLASS_SYMBOL *)TABLE_get_symbol(Class->table, i);    csym = (CLASS_SYMBOL *)TABLE_get_symbol(Class->table, csym->symbol.sort);    type = csym->global.type;    if (TYPE_is_public(type))    {      nn++;      /* name */      write_long(get_string(csym->symbol.name, csym->symbol.len));      switch (TYPE_get_kind(type))      {        case TK_VARIABLE:          /* type de donn�s */          write_type((csym->global.type));          /* offset */          write_long(csym->global.value);          /* read */          write_long(0);          /* write */          write_long(0);          if (TYPE_is_static(type))            out_type = CD_STATIC_VARIABLE_ID;          else            out_type = CD_VARIABLE_ID;          break;        case TK_PROPERTY:          /* type de donn�s */          write_type((csym->global.type));          /* read */          write_long(Class->prop[csym->global.value].read);          /* write */          write_long(Class->prop[csym->global.value].write);          /* flag */          write_long(0);          if (TYPE_is_static(type))            out_type = CD_STATIC_PROPERTY_ID;          else            out_type = CD_PROPERTY_ID;          break;        case TK_CONST:          /* type de donn�s */          write_type((csym->global.type));          /* param */          write_long(csym->global.value);          /* read */          write_long(0);          /* write */          write_long(0);          out_type = CD_CONSTANT_ID;          break;        case TK_FUNCTION:          /* type de la valeur de retour */          write_type((csym->global.type));          /* exec */          write_long(csym->global.value);          /* signature */          write_long(0);          /* nparam */          write_long(0);          if (TYPE_is_static(type))            out_type = CD_STATIC_METHOD_ID;          else            out_type = CD_METHOD_ID;          break;        case TK_EVENT:          /* type de la valeur de retour */          write_type((csym->global.type));          /* exec */          write_long(csym->global.value);          /* signature */          write_long(0);          /* nparam */          write_long(0);          out_type = CD_EVENT_ID;          break;        default:          ERROR_panic("output_desc: unknown symbol type");          continue;       }      /* type de symbole */      write_long(out_type);    }  }  end_section();}PRIVATE void output_constant(void){  int i, n;  CONSTANT *constant;  SYMBOL *sym;  TABLE *table;  n = ARRAY_count(Class->constant);  begin_section("Constants", 3 * sizeof(long));  for (i = 0; i < n; i++)  {    constant = &Class->constant[i];    /* type */    write_type((constant->type));    /* value */    if (TYPE_can_be_long(constant->type))    {      write_long(constant->value);      write_long(0);    }    else    {      if (TYPE_get_id(constant->type) == T_STRING || TYPE_get_id(constant->type) == T_CSTRING)        table = Class->string;      else        table = Class->table;      sym = TABLE_get_symbol(table, constant->value);      write_long(get_string(sym->name, sym->len));      write_long(sym->len);    }  }  end_section();}PRIVATE void output_class_ref(void){  int i, n;  SYMBOL *sym;  n = ARRAY_count(Class->class);  begin_section("External classes", sizeof(long));  for (i = 0; i < n; i++)  {    sym = TABLE_get_symbol(Class->table, Class->class[i]);    write_long(get_string(sym->name, sym->len));  }  end_section();}PRIVATE void output_unknown_ref(void){  int i, n;  SYMBOL *sym;  n = ARRAY_count(Class->unknown);  begin_section("External symbols", sizeof(long));  for (i = 0; i < n; i++)  {    sym = TABLE_get_symbol(Class->table, Class->unknown[i]);    write_long(get_string(sym->name, sym->len));  }  end_section();}PRIVATE void output_static(void){  int i, n;  VARIABLE *var;  n = ARRAY_count(Class->stat);  begin_section("Static variables", 2 * sizeof(long));  for (i = 0; i < n; i++)  {    var = &Class->stat[i];    /* type */    write_type((var->type));    /* addr */    write_long(var->pos);  }  end_section();}PRIVATE void output_dynamic(void){  int i, n;  VARIABLE *var;  n = ARRAY_count(Class->dyn);  begin_section("Dynamic variables", 2 * sizeof(long));  for (i = 0; i < n; i++)  {    var = &Class->dyn[i];    /* type */    write_type((var->type));    /* addr */    write_long(var->pos);  }  end_section();}PRIVATE void output_event(void){  int i, n;  EVENT *event;  SYMBOL *sym;  n = ARRAY_count(Class->event);  begin_section("Events", 4 * sizeof(long));  for (i = 0; i < n; i++)  {    event = &Class->event[i];    /* type */    write_type((event->type));    /* n_param */    write_short(event->nparam);    /* reserved */    write_short(0);    /* desc_param */    write_long(0);    /* name */    sym = TABLE_get_symbol(Class->table, event->name);    write_long(get_string(sym->name, sym->len));  }  end_section();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -