Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
OS = linux
VERSION = 1.4.2
VERSION = 1.4.2b

DISTFILES = src \
includes \
Expand All @@ -16,6 +16,7 @@ TARGET_INCLUDE_PATH ?= $(PREFIX)/include/avr

CDEFS = -DDEFAULT_INCLUDE_PATH='"$(TARGET_INCLUDE_PATH)"' \
-DVERSION='"$(VERSION)"'
CDEFS += $(USER_DEFS)
export CDEFS

.PHONY: all
Expand Down
158 changes: 126 additions & 32 deletions src/avra.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>

#include "misc.h"
#include "args.h"
#include "avra.h"
#include "device.h"

#define debug 0

const char *title = "AVRA: advanced AVR macro assembler (version %s)\n";

const char *usage =
Expand Down Expand Up @@ -90,7 +89,7 @@ main(int argc, const char *argv[])
#if debug == 1
int i;
for (i = 0; i < argc; i++) {
printf(argv[i]);
printf("%s", argv[i]);
printf("\n");
}
#endif
Expand Down Expand Up @@ -259,42 +258,27 @@ assemble(struct prog_info *pi)
int
load_arg_defines(struct prog_info *pi)
{
int i;
char *expr;
char buff[256];
struct data_list *define;
char *value;
char buff[256];

for (define = GET_ARG_LIST(pi->args, ARG_DEFINE); define; define = define->next) {
#if debug == 1
printf("load_arg_defines opt \"%s\"\n", define->data);
#endif
strcpy(buff, define->data);
expr = get_next_token(buff, TERM_EQUAL);
if (expr) {
/* we reach this, when there is actually a value passed.. */
if (!get_expr(pi, expr, &i)) {
return (False);
}
} else {
/* if user didnt specify a value, we default to 1 */
i = 1;
}
/* Forward references allowed. But check, if everything is ok... */
if (pi->pass==PASS_1) { /* Pass 1 */
if (test_constant(pi,buff,NULL)!=NULL) {
fprintf(stderr,"Error: Can't define symbol %s twice\n", buff);
return (False);
}
if (def_const(pi, buff, i)==False)
return (False);
} else { /* Pass 2 */
int j;
if (get_constant(pi, buff, &j)==False) { /* Defined in Pass 1 and now missing ? */
fprintf(stderr,"Constant %s is missing in pass 2\n",buff);
value = get_next_token(buff, TERM_EQUAL);
if (!value)
value = "1";
if (pi->pass == PASS_1) {
if (test_preproc_macro(pi,buff,NULL)!=NULL) {
fprintf(stderr,"Error: Can't define preprocessor macro %s twice\n", buff);
return (False);
}
if (i != j) {
fprintf(stderr,"Constant %s changed value from %d in pass1 to %d in pass 2\n",buff,j,i);
if (def_preproc_macro(pi, buff, PREPROC_MACRO_OBJECT_LIKE, NULL, value)==False)
return (False);
}
/* OK. Definition is unchanged */
} else {
/* Pass 2 */
}
}
return (True);
Expand Down Expand Up @@ -396,6 +380,7 @@ free_pi(struct prog_info *pi)
free_ifdef_blacklist(pi);
free_ifndef_blacklist(pi);
free_orglist(pi);
free_preproc_macros(pi);
}

void
Expand Down Expand Up @@ -871,6 +856,115 @@ free_orglist(struct prog_info *pi)
pi->last_orglist = NULL;
}

int
get_preproc_macro(struct prog_info *pi,char *name,struct preproc_macro **pm)
{
struct preproc_macro *macro;
macro = search_preproc_macro(pi, pi->first_preproc_macro, name, NULL);
if (macro == NULL) return False;
if (pm != NULL) *pm = macro;
return True;
}

struct preproc_macro *
test_preproc_macro(struct prog_info *pi,char *name,char *message)
{
return search_preproc_macro(pi, pi->first_preproc_macro, name, message);
}

struct preproc_macro *
search_preproc_macro(struct prog_info *pi,struct preproc_macro *first,char *name,char *message)
{
struct preproc_macro *macro;
for (macro = first; macro; macro = macro->next)
if (!nocase_strcmp(macro->name, name)) {
if (message) {
print_msg(pi, MSGTYPE_ERROR, message, name);
}
return (macro);
}
return (NULL);
}

int
def_preproc_macro(struct prog_info *pi, char *name, int type, struct item_list *params, char *value) {
struct preproc_macro *macro;
macro = malloc(sizeof(struct preproc_macro));
if (!macro) {
print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
return (False);
}
memset(macro, 0, sizeof(struct preproc_macro));
macro->name = malloc(strlen(name)+1);
if (!macro->name) {
free(macro);
print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
return (False);
}
strcpy(macro->name, name);
macro->type = type;
macro->params = params;
macro->value = malloc(strlen(value)+1);
if (!macro->value) {
free(macro->name);
free(macro);
print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
return (False);
}
strcpy(macro->value, value);

if (pi->last_preproc_macro)
pi->last_preproc_macro->next = macro;
else
pi->first_preproc_macro = macro;
pi->last_preproc_macro = macro;
return (True);
}

void
free_preproc_macros(struct prog_info *pi)
{
struct preproc_macro *macro, *temp_macro;

for (macro = pi->first_preproc_macro; macro;) {
temp_macro = macro;
macro = macro->next;

free(temp_macro->value);
if (temp_macro->type == PREPROC_MACRO_FUNCTION_LIKE)
free_item_list(temp_macro->params);
free(temp_macro->name);
free(temp_macro);
}

pi->first_preproc_macro = NULL;
pi->last_preproc_macro = NULL;
}

/* Determine the length of an item list. */
int
item_list_length(struct item_list *lst)
{
int len = 0;
while (lst) {
len++;
lst = lst->next;
}
return (len);
}

/* Free up an item list. */
void
free_item_list(struct item_list *lst)
{
struct item_list *temp_lst;
while (lst) {
temp_lst = lst;
lst = lst->next;
free(temp_lst->value);
free(temp_lst);
}
}

/* avra.c */

50 changes: 49 additions & 1 deletion src/avra.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,24 @@ enum {
TERM_EQUAL,
TERM_DASH,
TERM_DOUBLEQUOTE,
TERM_COLON
TERM_COLON,
TERM_CLOSING_PAREN
};

enum {
PREPROCESS_FATAL_ERROR = 0,
PREPROCESS_NEXT_LINE,
PREPROCESS_PARSE_LINE
};

enum {
PREPROC_MACRO_OBJECT_LIKE = 0,
PREPROC_MACRO_FUNCTION_LIKE
};

enum {
PREPROC_LINE_PART_WHITE = 0,
PREPROC_LINE_PART_GREY
};

/* Structures */
Expand Down Expand Up @@ -157,6 +174,8 @@ struct prog_info {
int error_count;
int max_errors;
int warning_count;
struct preproc_macro *first_preproc_macro;
struct preproc_macro *last_preproc_macro;
struct include_file *last_include_file;
struct include_file *first_include_file;
struct def *first_def;
Expand Down Expand Up @@ -273,6 +292,19 @@ struct location {
int file_num;
};

struct item_list {
struct item_list *next;
char *value;
};

struct preproc_macro {
struct preproc_macro *next;
char *name;
int type;
struct item_list* params;
char *value;
};

/* Prototypes */
/* avra.c */
int assemble(struct prog_info *pi);
Expand Down Expand Up @@ -313,12 +345,27 @@ void free_ifdef_blacklist(struct prog_info *pi);
void free_ifndef_blacklist(struct prog_info *pi);
void free_variables(struct prog_info *pi);
void free_orglist(struct prog_info *pi);
int get_preproc_macro(struct prog_info *pi,char *name,struct preproc_macro **pm);
struct preproc_macro *test_preproc_macro(struct prog_info *pi,char *name,char *message);
struct preproc_macro *search_preproc_macro(struct prog_info *pi,struct preproc_macro *first,char *name,char *message);
int def_preproc_macro(struct prog_info *pi, char *name, int type, struct item_list *params, char *value);
void free_preproc_macros(struct prog_info *pi);
int item_list_length(struct item_list *lst);
void free_item_list(struct item_list *lst);

/* parser.c */
int parse_file(struct prog_info *pi, const char *filename);
int preprocess_line(struct prog_info *pi, char *line);
int parse_line(struct prog_info *pi, char *line);
char *get_next_token(char *scratch, int term);
char *fgets_new(struct prog_info *pi, char *s, int size, FILE *stream);
char *funcall_token(char *token);
char *locate_macro_call(char *line, char *name, char **end);
char *locate_funcall_expr(char *line, char *name, char **end);
int is_label(char *word);
int collect_paramarg(struct prog_info *pi, char *paramarg, struct item_list **first_paramarg, struct item_list **last_paramarg);
int inplace_replace(char *line, char *begin, char *end, char *value, int buff_len);
void apply_preproc_macro_opers(char *line);

/* expr.c */
int get_expr(struct prog_info *pi, char *data, int *value);
Expand Down Expand Up @@ -378,6 +425,7 @@ int atoi_n(char *s, int n);
int atox_n(char *s, int n);
char *my_strlwr(char *in);
char *my_strupr(char *in);
char *strdup_section(char *begin, char *end);
char *snprint_list(char *buf, size_t limit, const char *const list[]);

/* coff.c */
Expand Down
43 changes: 2 additions & 41 deletions src/directiv.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,45 +533,6 @@ parse_directive(struct prog_info *pi)
if (test_constant(pi,next,"%s have already been defined as a .EQU constant")!=NULL)
return (True);
return (def_var(pi, next, i));
case DIRECTIVE_DEFINE:
if (!next) {
print_msg(pi, MSGTYPE_ERROR, ".DEFINE needs an operand");
return (True);
}
data = get_next_token(next, TERM_SPACE);
if (data) {
get_next_token(data, TERM_END);
if (!get_expr(pi, data, &i))
return (False);
} else
i = 1;
if (test_label(pi,next,"%s have already been defined as a label")!=NULL)
return (True);
if (test_variable(pi,next,"%s have already been defined as a .SET variable")!=NULL)
return (True);
/* Forward references allowed. But check, if everything is ok ... */
if (pi->pass==PASS_1) { /* Pass 1 */
if (test_constant(pi,next,"Can't redefine constant %s, use .SET instead")!=NULL)
return (True);
if (def_const(pi, next, i)==False)
return (False);
} else { /* Pass 2 */
int j;
if (get_constant(pi, next, &j)==False) { /* Defined in Pass 1 and now missing ? */
print_msg(pi, MSGTYPE_ERROR, "Constant %s is missing in pass 2", next);
return (False);
}
if (i != j) {
print_msg(pi, MSGTYPE_ERROR, "Constant %s changed value from %d in pass1 to %d in pass 2", next,j,i);
return (False);
}
/* OK. Definition is unchanged */
}
if ((pi->pass == PASS_2) && pi->list_line && pi->list_on) {
fprintf(pi->list_file, " %s\n", pi->list_line);
pi->list_line = NULL;
}
break;
case DIRECTIVE_NOOVERLAP:
if (pi->pass == PASS_1) {
fix_orglist(pi->segment);
Expand Down Expand Up @@ -640,7 +601,7 @@ parse_directive(struct prog_info *pi)
get_next_token(next, TERM_END);
/* Store location of ifdef (line number and file number) if the condition
* fails on pass 1 so that we do not reinterpret it as succeeding on pass 2. */
if ((pi->pass==PASS_1 && get_symbol(pi, next, NULL)) || (pi->pass==PASS_2 && !ifdef_is_blacklisted(pi))) {
if ((pi->pass==PASS_1 && (get_preproc_macro(pi, next, NULL) || get_symbol(pi, next, NULL))) || (pi->pass==PASS_2 && !ifdef_is_blacklisted(pi))) {
pi->conditional_depth++;
} else {
if (pi->pass==PASS_1) {
Expand All @@ -662,7 +623,7 @@ parse_directive(struct prog_info *pi)
get_next_token(next, TERM_END);
/* Store location of ifndef (line number and file number) if the condition
* fails on pass 1 so that we do not reinterpret it as succeeding on pass 2. */
if ((pi->pass==PASS_1 && !get_symbol(pi, next, NULL)) || (pi->pass==PASS_2 && !ifndef_is_blacklisted(pi))) {
if ((pi->pass==PASS_1 && (!get_preproc_macro(pi, next, NULL) && !get_symbol(pi, next, NULL))) || (pi->pass==PASS_2 && !ifndef_is_blacklisted(pi))) {
pi->conditional_depth++;
} else {
if (pi->pass==PASS_1) {
Expand Down
2 changes: 1 addition & 1 deletion src/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ get_expr(struct prog_info *pi, char *data, int *value)
break;
}
data[i + length++] = '\0';
if (get_symbol(pi, &data[i], NULL))
if (get_preproc_macro(pi, &data[i], NULL) || get_symbol(pi, &data[i], NULL))
element->data = 1;
else
element->data = 0;
Expand Down
Loading