00001
00002
00003
00004 static char version[] = "1.11";
00005
00006 #define nil 0
00007 #include <stdio.h>
00008 #include <stdarg.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <errno.h>
00012 #include <assert.h>
00013 #include "asmconv.h"
00014 #include "asm86.h"
00015 #include "languages.h"
00016
00017 void fatal(char *label)
00018 {
00019 fprintf(stderr, "asmconv: %s: %s\n", label, strerror(errno));
00020 exit(EXIT_FAILURE);
00021 }
00022
00023 void *allocate(void *mem, size_t size)
00024
00025 {
00026 mem= mem == nil ? malloc(size) : realloc(mem, size);
00027 if (mem == nil) fatal("malloc()");
00028 return mem;
00029 }
00030
00031 void deallocate(void *mem)
00032
00033 {
00034 if (mem != nil) free(mem);
00035 }
00036
00037 char *copystr(const char *s)
00038 {
00039 char *c;
00040
00041 c= allocate(nil, (strlen(s) + 1) * sizeof(s[0]));
00042 strcpy(c, s);
00043 return c;
00044 }
00045
00046 int isanumber(const char *s)
00047
00048 {
00049 char *end;
00050
00051 (void) strtol(s, &end, 0);
00052 return end != s && *end == 0;
00053 }
00054
00055
00056 int asm_mode32= (sizeof(int) == 4);
00057 int err_code= EXIT_SUCCESS;
00058
00059 int main(int argc, char **argv)
00060 {
00061 void (*parse_init)(char *file);
00062 asm86_t *(*get_instruction)(void);
00063 void (*emit_init)(char *file, const char *banner);
00064 void (*emit_instruction)(asm86_t *instr);
00065 char *lang_parse, *lang_emit, *input_file, *output_file;
00066 asm86_t *instr;
00067 char banner[80];
00068
00069 if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'm') {
00070 if (strcmp(argv[1], "-mi86") == 0) {
00071 set_use16();
00072 } else
00073 if (strcmp(argv[1], "-mi386") == 0) {
00074 set_use32();
00075 } else {
00076 fprintf(stderr, "asmconv: '%s': unknown machine\n",
00077 argv[1]+2);
00078 }
00079 argc--;
00080 argv++;
00081 }
00082
00083 if (argc < 3 || argc > 5) {
00084 fprintf(stderr,
00085 "Usage: asmconv <input-type> <output-type> [input-file [output-file]]\n");
00086 exit(EXIT_FAILURE);
00087 }
00088
00089 lang_parse= argv[1];
00090 lang_emit= argv[2];
00091 input_file= argc < 4 ? nil : argv[3];
00092 output_file= argc < 5 ? nil : argv[4];
00093
00094
00095 if (strcmp(lang_parse, "ack") == 0) {
00096
00097 parse_init= ack_parse_init;
00098 get_instruction= ack_get_instruction;
00099 } else
00100 if (strcmp(lang_parse, "ncc") == 0) {
00101
00102 parse_init= ncc_parse_init;
00103 get_instruction= ncc_get_instruction;
00104 } else
00105 if (strcmp(lang_parse, "gnu") == 0) {
00106
00107 parse_init= gnu_parse_init;
00108 get_instruction= gnu_get_instruction;
00109 } else
00110 if (strcmp(lang_parse, "bas") == 0) {
00111
00112 parse_init= bas_parse_init;
00113 get_instruction= bas_get_instruction;
00114 } else {
00115 fprintf(stderr, "asmconv: '%s': unknown input language\n",
00116 lang_parse);
00117 exit(EXIT_FAILURE);
00118 }
00119
00120
00121 if (strcmp(lang_emit, "ack") == 0) {
00122
00123 emit_init= ack_emit_init;
00124 emit_instruction= ack_emit_instruction;
00125 } else
00126 if (strcmp(lang_emit, "ncc") == 0) {
00127
00128
00129
00130 emit_init= ncc_emit_init;
00131 emit_instruction= ncc_emit_instruction;
00132 } else
00133 if (strcmp(lang_emit, "gnu") == 0) {
00134
00135
00136
00137 emit_init= gnu_emit_init;
00138 emit_instruction= gnu_emit_instruction;
00139 } else {
00140 fprintf(stderr, "asmconv: '%s': unknown output language\n",
00141 lang_emit);
00142 exit(EXIT_FAILURE);
00143 }
00144
00145 sprintf(banner, "Translated from %s to %s by asmconv %s",
00146 lang_parse, lang_emit, version);
00147
00148 (*parse_init)(input_file);
00149 (*emit_init)(output_file, banner);
00150 for (;;) {
00151 instr= (*get_instruction)();
00152 (*emit_instruction)(instr);
00153 if (instr == nil) break;
00154 del_asm86(instr);
00155 }
00156 exit(err_code);
00157 }