40 fputs(
"Usage: bfc [input file] [options]\n", stderr);
42 fputs(
"\t-s [NUMBER] sets the stack size to this number\n", stderr);
43 fputs(
"\t-a [ARRSIZE] sets the array size in the program to this number\n", stderr);
44 fputs(
"\t-c only compile and assemble\n", stderr);
45 fputs(
"\t-S only compile\n", stderr);
46 fputs(
"\t-o [FILE] specify an output file\n", stderr);
47 fputs(
"\t-v enable verbose output\n", stderr);
48 fputs(
"\t-h, --help print this help message\n", stderr);
49 fputs(
"\t-i get input from stdin\n", stderr);
50 fputs(
"\t-pipe pipe to assembler if -S is not set, otherwise print to stdout\n", stderr);
71 int my_getopt(
int argc,
char **argv,
int *stack_size,
int *array_size,
char **output_file,
char **input_file,
int *mode)
74 for (i = 1; i < argc; i++) {
75 if (!strcmp(argv[i],
"-s")) {
76 if (i + 1 < argc &&
is_uint(argv[i + 1])) {
77 *stack_size = atoi(argv[++i]);
79 fprintf(stderr,
"%s: option requires a numerical argument -- 's'\n", *argv);
82 }
else if (!strcmp(argv[i],
"-a")) {
83 if (i + 1 < argc &&
is_uint(argv[i + 1])) {
84 *array_size = atoi(argv[++i]);
86 fprintf(stderr,
"%s: option requires a numerical argument -- 'a'\n", *argv);
89 }
else if (!strcmp(argv[i],
"-c")) {
91 }
else if (!strcmp(argv[i],
"-S")) {
92 *mode &= ~(LINK | ASSEMBLE);
93 }
else if (!strcmp(argv[i],
"-o")) {
95 *output_file = argv[++i];
98 fprintf(stderr,
"%s: option requires an argument -- 'o'\n", *argv);
101 }
else if (!strcmp(argv[i],
"-v")) {
103 }
else if (!strcmp(argv[i],
"-h") || !strcmp(argv[i],
"--help")) {
106 }
else if (!strcmp(argv[i],
"-pipe")) {
108 }
else if (!strcmp(argv[i],
"-i")) {
111 *input_file = argv[i];
127 int strl = strlen(str);
128 const char *s = str + strl - 1;
133 char *newstr = malloc(1 + s - str);
134 memcpy(newstr, str, s - str);
135 newstr[s - str] =
'\0';
153 char *
get_as(
int mode,
const char *name,
const char *original,
char **ret)
155 if (name != NULL && ~(mode & ASSEMBLE))
157 else if (mode & PIPE_OUT)
159 else if (original != NULL) {
161 int strl = strlen(base);
162 char *new_base = realloc(base, strl + 3);
163 if (new_base == NULL) {
164 fprintf(stderr,
"error: couldn't realloc string: ");
166 return (*ret = NULL);
169 *ret = strncat(base,
".s", strl + 3);
171 *ret = strdup(
"a.out.s");
184 char *
get_obj(
int mode,
const char *name,
const char *original,
char **ret)
186 if (name != NULL && ~(mode & LINK)) {
188 }
else if (original != NULL) {
190 int strl = strlen(base);
191 char *new_base = realloc(base, strl + 3);
192 if (new_base == NULL) {
193 puts(
"error: couldn't realloc string");
197 *ret = strncat(base,
".o", strl + 3);
199 *ret = strdup(
"a.out.o");
217 int get_as_file(
int mode, FILE **out,
const char *name,
const char *input_name)
219 if (name != NULL && ~(mode & ASSEMBLE)) {
220 *out = fopen(name,
"w");
222 fprintf(stderr,
"error: couldn't open file %s: ", name);
226 }
else if ((mode & PIPE_OUT) && (mode & ASSEMBLE)) {
229 if (
get_obj(mode, name, input_name, &foo) == NULL)
231 snprintf(buf, 100,
"as -g -o %s", foo);
233 *out = popen(buf,
"w");
235 fprintf(stderr,
"error: couldn't open process %s: ", buf);
239 }
else if (mode & PIPE_OUT) {
243 if (
get_as(mode, name, input_name, &foo) == NULL)
245 *out = fopen(foo,
"w");
247 fprintf(stderr,
"error: couldn't open file %s: ", foo);
270 if ((mode & PIPE_OUT) && (mode & ASSEMBLE))
272 else if (f != stdout)
289 int assemble(
int mode,
const char *as_file,
const char *obj_file)
291 if (!(mode & ASSEMBLE) || mode & PIPE_OUT)
294 snprintf(buf, 256,
"as %s -g -o %s", as_file, obj_file);
295 int ret = system(buf);
296 if (ret == 0 && !(mode & LINK)) {
297 ret =
remove(as_file);
310 int get_in(
int mode,
const char *input_file, FILE **in)
312 if (input_file == NULL && !(mode & PIPE_IN)) {
313 fprintf(stderr,
"bfc: error: no input files\ncompilation terminated.\n");
319 *in = fopen(input_file,
"r");
321 printf(
"opening file %s\n", input_file);
324 fprintf(stderr,
"error: couldn't open file %s: ", input_file);
int assemble(int mode, const char *as_file, const char *obj_file)
Wrapper around assembling the assembly code.
char * get_as(int mode, const char *name, const char *original, char **ret)
Gets the name of the assembly code file.
char * remove_extenstion(const char *str)
Removes the file extension from a string, if there is one at all.
int my_getopt(int argc, char **argv, int *stack_size, int *array_size, char **output_file, char **input_file, int *mode)
Custom getopt function.
int is_uint(const char *str)
Checks if the given string can represent a positive integer.
char * get_obj(int mode, const char *name, const char *original, char **ret)
Gets the name of the assembled file.
int get_in(int mode, const char *input_file, FILE **in)
Gets the source code file pointer and deals with IO errors.
int get_as_file(int mode, FILE **out, const char *name, const char *input_name)
Gets the file pointer to the assembly code file.
void print_help(void)
Prints the help message when "-h" or "--help" are command line arguments.
Header for extern functions.
int close_as_file(int mode, FILE *f)
Closes the file pointer to the assembly source file.