Begin to implement directives
This commit is contained in:
parent
dbe25195c4
commit
cc56dd93cb
|
@ -69,6 +69,8 @@ AsmString * asmcode_set_string(AsmCode * code, int id, char const * name,
|
||||||
|
|
||||||
/* useful */
|
/* useful */
|
||||||
/* assembly */
|
/* assembly */
|
||||||
|
int asmcode_directive(AsmCode * code, char const * name,
|
||||||
|
char const ** args, size_t args_cnt);
|
||||||
int asmcode_function(AsmCode * code, char const * name);
|
int asmcode_function(AsmCode * code, char const * name);
|
||||||
int asmcode_instruction(AsmCode * code, AsmArchInstructionCall * call);
|
int asmcode_instruction(AsmCode * code, AsmArchInstructionCall * call);
|
||||||
int asmcode_section(AsmCode * code, char const * name);
|
int asmcode_section(AsmCode * code, char const * name);
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#ifndef DEVEL_ASM_FORMAT_H
|
#ifndef DEVEL_ASM_FORMAT_H
|
||||||
# define DEVEL_ASM_FORMAT_H
|
# define DEVEL_ASM_FORMAT_H
|
||||||
|
|
||||||
# include <stdarg.h>
|
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# include <System/license.h>
|
# include <System/license.h>
|
||||||
# include "asm.h"
|
# include "asm.h"
|
||||||
|
@ -80,7 +79,7 @@ typedef struct _AsmFormatPluginDefinition
|
||||||
/* assembly */
|
/* assembly */
|
||||||
char const * (*guess)(AsmFormatPlugin * format, char const * hint);
|
char const * (*guess)(AsmFormatPlugin * format, char const * hint);
|
||||||
int (*directive)(AsmFormatPlugin * format, char const * directive,
|
int (*directive)(AsmFormatPlugin * format, char const * directive,
|
||||||
va_list args);
|
char const ** args, size_t size);
|
||||||
int (*function)(AsmFormatPlugin * format, char const * function);
|
int (*function)(AsmFormatPlugin * format, char const * function);
|
||||||
int (*section)(AsmFormatPlugin * format, char const * section);
|
int (*section)(AsmFormatPlugin * format, char const * section);
|
||||||
|
|
||||||
|
|
11
src/code.c
11
src/code.c
|
@ -490,6 +490,17 @@ int asmcode_decode_section(AsmCode * code, AsmSection * section,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* asmcode_directive */
|
||||||
|
int asmcode_directive(AsmCode * code, char const * name, char const ** args,
|
||||||
|
size_t args_cnt)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
|
||||||
|
#endif
|
||||||
|
return format_directive(code->format, name, args, args_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* asmcode_function */
|
/* asmcode_function */
|
||||||
int asmcode_function(AsmCode * code, char const * name)
|
int asmcode_function(AsmCode * code, char const * name)
|
||||||
{
|
{
|
||||||
|
|
|
@ -272,7 +272,8 @@ char const * format_detect_arch(AsmFormat * format)
|
||||||
|
|
||||||
|
|
||||||
/* format_directive */
|
/* format_directive */
|
||||||
int format_directive(AsmFormat * format, char const * name, va_list args)
|
int format_directive(AsmFormat * format, char const * name,
|
||||||
|
char const ** args, size_t args_cnt)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
|
fprintf(stderr, "DEBUG: %s(\"%s\")\n", __func__, name);
|
||||||
|
@ -282,7 +283,8 @@ int format_directive(AsmFormat * format, char const * name, va_list args)
|
||||||
if(format->definition->directive == NULL)
|
if(format->definition->directive == NULL)
|
||||||
return -error_set_code(1, "%s: %s", format->definition->name,
|
return -error_set_code(1, "%s: %s", format->definition->name,
|
||||||
"No support for directives");
|
"No support for directives");
|
||||||
return format->definition->directive(format->plugin, name, args);
|
return format->definition->directive(format->plugin, name, args,
|
||||||
|
args_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#ifndef ASM_FORMAT_H
|
#ifndef ASM_FORMAT_H
|
||||||
# define ASM_FORMAT_H
|
# define ASM_FORMAT_H
|
||||||
|
|
||||||
# include <stdarg.h>
|
|
||||||
# include "Asm/common.h"
|
# include "Asm/common.h"
|
||||||
# include "Asm/format.h"
|
# include "Asm/format.h"
|
||||||
# include "code.h"
|
# include "code.h"
|
||||||
|
@ -55,7 +54,8 @@ int format_exit(AsmFormat * format);
|
||||||
|
|
||||||
char const * format_guess_arch(AsmFormat * format, char const * hint);
|
char const * format_guess_arch(AsmFormat * format, char const * hint);
|
||||||
|
|
||||||
int format_directive(AsmFormat * format, char const * name, va_list args);
|
int format_directive(AsmFormat * format, char const * name, char const ** args,
|
||||||
|
size_t args_cnt);
|
||||||
int format_function(AsmFormat * format, char const * name);
|
int format_function(AsmFormat * format, char const * name);
|
||||||
int format_section(AsmFormat * format, char const * name);
|
int format_section(AsmFormat * format, char const * name);
|
||||||
|
|
||||||
|
|
37
src/parser.c
37
src/parser.c
|
@ -42,7 +42,8 @@ typedef struct _State
|
||||||
|
|
||||||
/* directive */
|
/* directive */
|
||||||
char * directive;
|
char * directive;
|
||||||
char * name;
|
char ** args;
|
||||||
|
size_t args_cnt;
|
||||||
|
|
||||||
/* instruction */
|
/* instruction */
|
||||||
AsmArchInstructionCall call;
|
AsmArchInstructionCall call;
|
||||||
|
@ -350,6 +351,7 @@ static int _directive(State * state)
|
||||||
/* "." directive_name [ space [ directive_args ] ] newline */
|
/* "." directive_name [ space [ directive_args ] ] newline */
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
fprintf(stderr, "DEBUG: %s()\n", __func__);
|
||||||
|
@ -368,20 +370,25 @@ static int _directive(State * state)
|
||||||
if(_parser_in_set(state, TS_DIRECTIVE_ARGS))
|
if(_parser_in_set(state, TS_DIRECTIVE_ARGS))
|
||||||
ret |= _directive_args(state);
|
ret |= _directive_args(state);
|
||||||
}
|
}
|
||||||
if(string_compare(state->directive, "section") == 0
|
/* execute the directive */
|
||||||
&& state->name != NULL)
|
if(string_compare(state->directive, "section") == 0)
|
||||||
{
|
{
|
||||||
if(asmcode_section(state->code, state->name) != 0)
|
if(state->args_cnt != 1)
|
||||||
|
ret |= _parser_error(state, "%s",
|
||||||
|
"Sections expect a name");
|
||||||
|
else if(asmcode_section(state->code, state->args[0]) != 0)
|
||||||
ret |= _parser_error(state, "%s", error_get(NULL));
|
ret |= _parser_error(state, "%s", error_get(NULL));
|
||||||
}
|
}
|
||||||
else
|
else if(asmcode_directive(state->code, state->directive, state->args,
|
||||||
/* FIXME implement */
|
state->args_cnt) != 0)
|
||||||
return error_set_code(1, "%s: %s", state->directive,
|
ret |= _parser_error(state, "%s", error_get(NULL));
|
||||||
"Unknown directive");
|
|
||||||
free(state->directive);
|
free(state->directive);
|
||||||
state->directive = NULL;
|
state->directive = NULL;
|
||||||
free(state->name);
|
for(i = 0; i < state->args_cnt; i++)
|
||||||
state->name = NULL;
|
free(state->args[i]);
|
||||||
|
free(state->args);
|
||||||
|
state->args = NULL;
|
||||||
|
state->args_cnt = 0;
|
||||||
/* newline */
|
/* newline */
|
||||||
if(!_parser_in_set(state, TS_NEWLINE))
|
if(!_parser_in_set(state, TS_NEWLINE))
|
||||||
return _parser_recover(state, AS_CODE_NEWLINE, "New line");
|
return _parser_recover(state, AS_CODE_NEWLINE, "New line");
|
||||||
|
@ -395,15 +402,21 @@ static int _directive_arg(State * state)
|
||||||
/* WORD | NUMBER */
|
/* WORD | NUMBER */
|
||||||
{
|
{
|
||||||
char const * string;
|
char const * string;
|
||||||
|
char ** p;
|
||||||
|
|
||||||
if(state->token == NULL
|
if(state->token == NULL
|
||||||
|| (string = token_get_string(state->token)) == NULL
|
|| (string = token_get_string(state->token)) == NULL
|
||||||
|| strlen(token_get_string(state->token)) == 0)
|
|| strlen(token_get_string(state->token)) == 0)
|
||||||
return error_set_code(1, "%s",
|
return error_set_code(1, "%s",
|
||||||
"Empty directive arguments are not allowed");
|
"Empty directive arguments are not allowed");
|
||||||
/* XXX only remembers the first argument */
|
if((p = realloc(state->args, sizeof(*p) * (state->args_cnt + 1)))
|
||||||
if(state->name == NULL && (state->name = strdup(string)) == NULL)
|
== NULL)
|
||||||
return error_set_code(1, "%s", strerror(errno));
|
return error_set_code(1, "%s", strerror(errno));
|
||||||
|
state->args = p;
|
||||||
|
p = &state->args[state->args_cnt];
|
||||||
|
if((*p = strdup(string)) == NULL)
|
||||||
|
return error_set_code(1, "%s", strerror(errno));
|
||||||
|
state->args_cnt++;
|
||||||
return _parser_scan(state);
|
return _parser_scan(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user