gbc_compile.c
#define __GBC_COMPILE_C
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include "gb_common.h"
#include "gb_error.h"
#include "gb_str.h"
#include "gb_file.h"
#include "gb_component.h"
#include "gbc_compile.h"
#include "gb_reserved.h"
#include "gbc_read.h"
#include "gbc_trans.h"
#include "gbc_header.h"
#include "gb_code.h"
#include "gbc_output.h"
#include "gbc_form.h"
PUBLIC char *COMP_project;
PUBLIC char *COMP_info_path;
PUBLIC char *COMP_classes = NULL;
PUBLIC COMPILE COMP_current;
PRIVATE bool read_line(FILE *f, char *dir, int max)
{
char *p;
int c;
p = dir;
for(;;)
{
max--;
c = fgetc(f);
if (c == EOF)
return TRUE;
if (c == '\n' || max == 0)
{
*p = 0;
return FALSE;
}
*p++ = (char)c;
}
}
PRIVATE void add_list_file(char *library)
{
char *path;
FILE *fi;
char line[256];
path = (char *)FILE_cat(COMP_info_path, library, NULL);
strcat(path, ".list");
fi = fopen(path, "r");
if (!fi)
THROW(E_OPEN, path);
for(;;)
{
if (read_line(fi, line, sizeof(line)))
break;
BUFFER_add(&COMP_classes, line, strlen(line));
BUFFER_add(&COMP_classes, "\n", 1);
}
fclose(fi);
}
PUBLIC void COMPILE_init(const char *exec)
{
const char *path;
FILE *fp;
char line[256];
DIR *dir;
struct dirent *dirent;
const char *name;
RESERVED_init();
path = FILE_find_gambas(exec);
COMP_info_path = STR_copy(FILE_cat(FILE_get_dir(FILE_get_dir(path)), "share/gambas/info", NULL));
BUFFER_create(&COMP_classes);
add_list_file("gb");
fp = fopen(COMP_project, "r");
if (!fp)
THROW(E_OPEN, COMP_project);
for(;;)
{
if (read_line(fp, line, sizeof(line)))
break;
if (strncmp(line, "Library=", 8))
continue;
add_list_file(&line[8]);
}
fclose(fp);
dir = opendir(FILE_get_dir(COMP_project));
if (dir)
{
while ((dirent = readdir(dir)) != NULL)
{
name = dirent->d_name;
if (*name == '.')
continue;
if ((strcasecmp(FILE_get_ext(name), "module") == 0)
|| (strcasecmp(FILE_get_ext(name), "class") == 0))
{
name = FILE_get_basename(name);
BUFFER_add(&COMP_classes, name, strlen(name));
BUFFER_add(&COMP_classes, "\n", 1);
}
}
closedir(dir);
}
BUFFER_add(&COMP_classes, "\n", 1);
}
PUBLIC void COMPILE_begin(const char *file, bool trans)
{
CLEAR(JOB);
JOB->name = STR_copy(file);
JOB->form = FORM_get_file(JOB->name);
JOB->output = OUTPUT_get_file(JOB->name);
if (trans)
{
JOB->trans = TRUE;
JOB->tname = OUTPUT_get_trans_file(JOB->name);
}
BUFFER_create(&JOB->source);
ARRAY_create(&JOB->pattern);
CLASS_create(&JOB->class);
}
PUBLIC void COMPILE_load(void)
{
BUFFER_load_file(&JOB->source, JOB->name);
if (JOB->source[BUFFER_length(JOB->source) - 1] != '\n')
BUFFER_add(&JOB->source, "\n", 1);
}
PUBLIC void COMPILE_end(void)
{
CLASS_delete(&JOB->class);
BUFFER_delete(&JOB->source);
ARRAY_delete(&JOB->pattern);
STR_free(JOB->name);
STR_free(JOB->form);
STR_free(JOB->output);
if (JOB->trans)
STR_free(JOB->tname);
}
PUBLIC void COMPILE_exit(void)
{
RESERVED_exit();
BUFFER_delete(&COMP_classes);
STR_free(COMP_project);
STR_free(COMP_info_path);
}