Skip to content

Commit

Permalink
initial import of the new compiler frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
marianoguerra committed Aug 1, 2010
1 parent 9141547 commit 2fd6e38
Show file tree
Hide file tree
Showing 3 changed files with 279 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tools/Makefile
@@ -0,0 +1,15 @@
CC=gcc
CFLAGS=-Wall
main: fnc.o fnc
mv fnc ../bin/fncng

clean:
rm -f fnc.o ../bin/fncng

lint:
splint fnc.c

check:
valgrind fnc


251 changes: 251 additions & 0 deletions tools/fnc.c
@@ -0,0 +1,251 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "fnc.h"

#define STR_BUFFER_SIZE 512

// copy the path to efene from the environment variable FNPATH if available
// if not found return NULL
// you have to free the variable
char* get_efene_path_from_env() {
char *fnpath, *result;

result = NULL;
fnpath = getenv("FNPATH");

if (fnpath != NULL) {
result = (char*) malloc(sizeof(char) * (strlen(fnpath) + 1));
assert(result != NULL);
strcpy(result, fnpath);
}

return result;
}

void show_usage() {
printf("usage:\n");
}

int is_dir(const char *path) {
struct stat st;
return (stat(path, &st) == 0 && S_ISDIR(st.st_mode));
}

void run_shell() {
int count, status;
char *fnpath, command[STR_BUFFER_SIZE];
fnpath = get_efene_path_from_env();

if (fnpath == NULL) {
if (!is_dir("../ebin")) {
fprintf(stderr, "$FNPATH is not defined and ../ebin doesn't exist\n");
fprintf(stderr, "set $FNPATH to the path where efene is installed or run fnc -s from the bin directory\n");
exit(EXIT_FAILURE);
}

status = system("erl -run fn run shell -run init stop -noshell -pa ../ebin\n");
}
else {
count = snprintf(command, STR_BUFFER_SIZE,
"erl -run fn run shell -run init stop -noshell -pa %s/ebin\n",
fnpath);

if(count > STR_BUFFER_SIZE) {
fprintf(stderr, "$FNPATH seems huge, can't run command\n");
exit(EXIT_FAILURE);
}

status = system(command);
free(fnpath);
}

exit(status);
}

struct FnOptions* fn_options_new() {
struct FnOptions* options = (struct FnOptions*) malloc(sizeof(struct FnOptions));

if (options != NULL) {
options->output_path = NULL;
options->files = NULL;
options->output_type = NULL;
options->is_eval = 0;
options->is_erl_eval = 0;
}

return options;
}

void fn_options_free_files(struct FnOptions* options) {
int index;

if (options != NULL && options->files != NULL && options->files_num > 0) {
for (index = 0; index < options->files_num; index++) {
free(options->files[index]);
}

free(options->files);
}
}

void fn_options_delete(struct FnOptions* options) {
if (options != NULL) {

if (options->output_path != NULL) {
free(options->output_path);
}

fn_options_free_files(options);

if (options->output_type != NULL) {
free(options->output_type);
}

free(options);
}
}

void fn_options_print(struct FnOptions* options) {
int index;

if (options != NULL) {
printf("options:\n");

if (options->output_path != NULL) {
printf("\toutput: %s\n", options->output_path);
}

if (options->files != NULL && options->files_num > 0) {
for (index = 0; index < options->files_num; index++) {
printf("\tfile: %s\n", options->files[index]);
}
}

if (options->output_type != NULL) {
printf("\toutput type: %s\n", options->output_type);
}

printf("\tis eval: %d\n", options->is_eval);
printf("\tis erlang eval: %d\n", options->is_erl_eval);
}
else {
printf("options: NULL\n");
}
}

int fn_options_copy_output_type(struct FnOptions* options, const char* arg) {
if (arg == NULL || options == NULL) {
return 0;
}

if (options->output_type != NULL) {
free(options->output_type);
}

options->output_type = (char*) malloc(sizeof(char) * (strlen(arg) + 1));
strcpy(options->output_type, optarg);

return 1;
}

int fn_options_copy_output_path(struct FnOptions* options, const char* arg) {
if (arg == NULL || options == NULL) {
return 0;
}

if (options->output_path != NULL) {
free(options->output_path);
}

options->output_path = (char*) malloc(sizeof(char) * (strlen(arg) + 1));
strcpy(options->output_path, optarg);

return 1;
}

void fn_options_copy_extra_args(struct FnOptions* options, int optind, int argc, char **argv) {
int index;

if (options == NULL) {
return;
}

if (optind == argc) {
return;
}

fn_options_free_files(options);

options->files_num = argc - optind;
options->files = (char**) malloc(sizeof(char*) * options->files_num);

for (index = optind; index < argc; index++) {
options->files[index - optind] = (char*) malloc(sizeof(char) * (strlen(argv[index]) + 1));
strcpy(options->files[index - optind], argv[index]);
}
}

struct FnOptions* parse_options (int argc, char **argv) {
int c;
struct FnOptions* options = fn_options_new();

while ((c = getopt (argc, argv, "o:ht:s")) != -1) {
switch (c) {
case 'o':
if (fn_options_copy_output_path(options, optarg) == 0) {
fprintf(stderr, "error copying output path\n");
}

break;
case 'h':
show_usage();
exit(EXIT_SUCCESS);
case 't':
if (fn_options_copy_output_type(options, optarg) == 0) {
fprintf(stderr, "error copying output type\n");
}

break;
case 's':
run_shell();
exit(EXIT_SUCCESS);
case '?':
if (optopt == 'o') {
fprintf(stderr, "output path option requires an argument\n");

}
else if (optopt == 't') {
fprintf(stderr, "output type option requires an argument\n");

}
else if (isprint(optopt)) {
fprintf(stderr, "Unknown option `-%c'.\n", optopt);
}
else {
fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
}

exit(EXIT_FAILURE);
}
}

fn_options_copy_extra_args(options, optind, argc, argv);

return options;
}

int main (int argc, char **argv) {
struct FnOptions* options = parse_options(argc, argv);

fn_options_print(options);
fn_options_delete(options);
return 0;
}
13 changes: 13 additions & 0 deletions tools/fnc.h
@@ -0,0 +1,13 @@
#ifndef __FNC_H__
#define __FNC_H__

struct FnOptions {
char *output_path;
int files_num;
char **files;
char *output_type;
int is_eval;
int is_erl_eval;
};

#endif

0 comments on commit 2fd6e38

Please sign in to comment.