search paths (given via -I) are now also displayed in error messages.

also prepared filespecs to be relative to current file in next version.


git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@357 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2024-03-08 23:42:58 +00:00
parent 117aab0d6d
commit 640373c54f
24 changed files with 260 additions and 224 deletions

View File

@ -65,7 +65,7 @@ of the lower eight bits is the same. But if you have written any code
where the numerical value of a PetSCII character is used for
computations _in_the_source_code_, please check those computations.
Use the "--dialect 0.94.12" CLI switch to get the old behavior
Use the "--dialect 0.95.2" CLI switch to get the old behavior
concerning a) double quotes and b) backslashes. There is no way to get
the old behavior concerning c) character values, because, as explained
above, the old behavior was architecture-dependent, which is a bad
@ -81,7 +81,7 @@ In 6510 mode, ACME now outputs 0x0b instead of 0x2b when assembling
the undocumented ("illegal") ANC #imm8 instruction. Both opcodes do
the same thing, this was only changed because all other mnemonics use
the lowest-numbered possible opcode as well.
Forcing the old behavior via the "--dialect" switch is not supported.
Use the "--dialect 0.94.12" CLI switch to get the old behavior.

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for AmigaOS)
@ -15,12 +15,13 @@
// convert UNIX-style pathname to Amiga-style pathname (no change)
//#define PLATFORM_CONVERTPATH(p)
// directory separator for include paths
#define DIRECTORY_SEPARATOR '\0' // actually '/', but paths ending on ':' are ok, so auto-adding '/' is bad)
// directory separators for search paths
#define DIRECTORY_SEPARATOR '/'
#define ALTERNATIVE_DIR_SEP ':'
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX "progdir:acme_lib/"
#define NO_NEED_FOR_ENV_VAR
#define PLATFORM_LIBPREFIX "progdir:acme_lib/"
#define PLATFORM_NEEDS_ENV_VAR 0 // no "ACME" environment variable needed
// setting file types of created files
#define PLATFORM_SETFILETYPE_APPLE(a)

View File

@ -7,33 +7,6 @@
#define platform_C
#include <stdlib.h>
#include "dynabuf.h"
// variables
char *DOS_lib_prefix = NULL; // header string of library tree
// used as PLATFORM_INIT: reads "ACME" environment variable
void DOS_entry(void)
{
char *env_var;
// Find out the path of ACME's library
env_var = getenv("ACME");
// if environment variable was found, make a copy
if (env_var) {
dynabuf_clear(GlobalDynaBuf);
// copy environment variable to global dynamic buffer
dynabuf_add_string(GlobalDynaBuf, env_var);
dynabuf_append(GlobalDynaBuf, '\\'); // add dir separator
dynabuf_append(GlobalDynaBuf, '\0'); // add terminator
DOS_lib_prefix = dynabuf_get_copy(GlobalDynaBuf);
}
}
// convert UNIX-style pathname to DOS-style pathname
void DOS_convert_path(char *p)
{

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for DOS, OS/2 and Windows)
@ -13,16 +13,18 @@
// symbolic constants and macros
// called once on program startup (could register exit handler, if needed)
#define PLATFORM_INIT DOS_entry()
#define PLATFORM_INIT platform_read_env_var()
// convert UNIX-style pathname to DOS-style pathname
#define PLATFORM_CONVERTPATH(p) DOS_convert_path(p)
// directory separator for include paths
// directory separators for search paths
#define DIRECTORY_SEPARATOR '\\'
#define ALTERNATIVE_DIR_SEP '\\' // dummy
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX DOS_lib_prefix
#define PLATFORM_LIBPREFIX platform_lib_prefix
#define PLATFORM_NEEDS_ENV_VAR 1 // library access needs "ACME" environment variable
// setting file types of created files
#define PLATFORM_SETFILETYPE_APPLE(a)
@ -51,13 +53,6 @@ do { \
#define PLATFORM_LONGOPTION_CODE
// variables
extern char *DOS_lib_prefix; // header string of library tree
// used as PLATFORM_INIT: reads "ACME" environment variable
extern void DOS_entry(void);
// Convert UNIX-style pathname to DOS-style pathname
extern void DOS_convert_path(char *p);

View File

@ -18,12 +18,13 @@
// convert UNIX-style pathname to RISC OS-style pathname
#define PLATFORM_CONVERTPATH(path) RISCOS_convert_path(path)
// directory separator for include paths
#define DIRECTORY_SEPARATOR '\0' // actually '.', but paths ending on ':' are ok, so auto-adding '.' is bad)
// directory separators for search paths
#define DIRECTORY_SEPARATOR '.'
#define ALTERNATIVE_DIR_SEP ':'
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX "ACME_Lib:"
#define NO_NEED_FOR_ENV_VAR
#define PLATFORM_NEEDS_ENV_VAR 0 // no "ACME" environment variable needed
// setting file types of created files
#define PLATFORM_SETFILETYPE_APPLE(a) RISCOS_set_filetype(a, 0xffd) // FIXME - wrong value!

View File

@ -7,31 +7,4 @@
#define platform_C
#include <stdlib.h>
#include "dynabuf.h"
// variables
char *AnyOS_lib_prefix = NULL; // header string of library tree
// used as PLATFORM_INIT: reads "ACME" environment variable
void AnyOS_entry(void)
{
char *env_var;
// Find out the path of ACME's library
env_var = getenv("ACME");
// if environment variable was found, make a copy
if (env_var) {
dynabuf_clear(GlobalDynaBuf);
// copy environment variable to global dynamic buffer
dynabuf_add_string(GlobalDynaBuf, env_var);
dynabuf_append(GlobalDynaBuf, '/'); // add dir separator
dynabuf_append(GlobalDynaBuf, '\0'); // add terminator
AnyOS_lib_prefix = dynabuf_get_copy(GlobalDynaBuf);
}
}
#endif

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2020 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff (in this case, for unknown OSes)
@ -10,16 +10,18 @@
// symbolic constants and macros
// called once on program startup (could register exit handler, if needed)
#define PLATFORM_INIT AnyOS_entry()
#define PLATFORM_INIT platform_read_env_var()
// convert UNIX-style pathname to AnyOS-style pathname (no change)
// convert UNIX-style pathname to platform-style pathname (no change)
//#define PLATFORM_CONVERTPATH(p)
// directory separator for include paths
// directory separator for search paths
#define DIRECTORY_SEPARATOR '/'
#define ALTERNATIVE_DIR_SEP '/' // dummy
// string containing the prefix for accessing files from the library tree
#define PLATFORM_LIBPREFIX AnyOS_lib_prefix
#define PLATFORM_LIBPREFIX platform_lib_prefix
#define PLATFORM_NEEDS_ENV_VAR 1 // library access needs "ACME" environment variable
// setting the created files' types
#define PLATFORM_SETFILETYPE_APPLE(a)
@ -48,12 +50,4 @@ do { \
#define PLATFORM_LONGOPTION_CODE
// variables
extern char *AnyOS_lib_prefix; // header string of library tree
// used as PLATFORM_INIT: reads "ACME" environment variable
extern void AnyOS_entry(void);
#endif

View File

@ -324,7 +324,7 @@ static void perform_pass(void)
// Process toplevel files
for (ii = 0; ii < toplevel_src_count; ++ii) {
if ((fd = fopen(toplevel_sources_plat[ii], FILE_READBINARY))) {
flow_parse_and_close_platform_file(toplevel_sources_plat[ii], fd);
input_parse_and_close_platform_file(toplevel_sources_plat[ii], fd);
} else {
fprintf(stderr, "Error: Cannot open toplevel file \"%s\".\n", toplevel_sources_plat[ii]);
if (toplevel_sources_plat[ii][0] == '-')
@ -545,6 +545,7 @@ struct dialect_info dialects[] = {
{V0_94_12__NEW_FOR_SYNTAX, "0.94.12", "new \"!for\" syntax"},
{V0_95_2__NEW_ANC_OPCODE, "0.95.2", "changed ANC#8 from 0x2b to 0x0b"},
{V0_97__BACKSLASH_ESCAPING, "0.97", "backslash escaping and strings"},
// {V0_98__PATHS_AND_SYMBOLCHANGE, "0.98", "paths are relative to current file"},
// {V__CURRENT_VERSION, "default", "default"},
{V__FUTURE_VERSION, "future", "enable all experimental features"},
{0, NULL, NULL} // NULLs terminate

View File

@ -423,7 +423,7 @@ static void parse_quoted(char closing_quote)
// eat closing quote
GetByte();
// now convert to unescaped version
if (input_unescape_dynabuf(0))
if (input_unescape_dynabuf())
goto fail; // escaping error
// without backslash escaping, both ' and " are used for single

View File

@ -264,26 +264,3 @@ void flow_do_while(struct do_while *loop)
// then the main loop could choke on unexpected bytes. So we pretend
// that we got the outer input's GotByte value magically back.
}
// parse a whole source code file
// file name must be given in platform style, i.e.
// "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever!
void flow_parse_and_close_platform_file(const char *plat_filename, FILE *fd)
{
// be verbose
if (config.process_verbosity > 2)
printf("Parsing source file '%s'\n", plat_filename);
// set up new input
input_new_platform_file(plat_filename, fd);
// parse block and check end reason
parse_until_eob_or_eof();
if (GotByte != CHAR_EOF)
Throw_error("Found '}' instead of end-of-file.");
// close sublevel src
// (this looks like we could just use "fd" as arg, but maybe the file
// has been replaced with a different one in the meantime...)
fclose(input_now->src.fd);
}

View File

@ -73,12 +73,5 @@ extern void flow_store_while_condition(struct condition *condition);
// back end function for "!do" pseudo opcode
extern void flow_do_while(struct do_while *loop);
// parse a whole source code file
// file name must be given in platform style, i.e.
// "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever!
extern void flow_parse_and_close_platform_file(const char *plat_filename, FILE *fd);
#endif

View File

@ -54,8 +54,8 @@ enum dialect {
V0_95_2__NEW_ANC_OPCODE, // v0.95.2 changed ANC#8 from opcode 0x2b to 0x0b
V0_97__BACKSLASH_ESCAPING, // v0.97 introduced backslash escaping (and therefore strings)
V__CURRENT_VERSION, // "RELEASE"
V0_98__PATHS_AND_SYMBOLCHANGE, // v0.98 fixes paths and allows symbols to change
// possible changes in future versions:
// paths should be relative to file, not start dir
// ignore leading zeroes?
V__FUTURE_VERSION // future (for testing new features)
};

View File

@ -26,8 +26,9 @@ const char FILE_READBINARY[] = "rb";
// fake input structure (for error msgs before any real input is established)
static struct input outermost = {
"<none>", // file name for resolving paths
{
"<none>", // file name
"<none>", // file name where code initially came from (differs during macro execution)
0, // line number
},
INPUTSRC_FILE, // fake file access, so no RAM read
@ -44,19 +45,40 @@ struct input *input_now = &outermost; // current input structure
// functions
// let current input point to start of file
// parse a whole source code file
// file name must be given in platform style, i.e.
// "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS etc.
// "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever!
// FIXME - there is only one caller, "flow_parse_and_close_platform_file()", so maybe merge?
void input_new_platform_file(const char *plat_filename, FILE *fd)
void input_parse_and_close_platform_file(const char *eternal_plat_filename, FILE *fd)
{
input_now->location.plat_filename = plat_filename;
input_now->location.line_number = 1;
input_now->source = INPUTSRC_FILE;
input_now->state = INPUTSTATE_SOF;
input_now->src.fd = fd;
struct input new_input,
*outer_input;
// be verbose
if (config.process_verbosity > 2)
printf("Parsing source file '%s'\n", eternal_plat_filename);
// set up new input
new_input.plat_pathref_filename = eternal_plat_filename;
new_input.location.plat_filename = eternal_plat_filename;
new_input.location.line_number = 1;
new_input.source = INPUTSRC_FILE;
new_input.state = INPUTSTATE_SOF;
new_input.src.fd = fd;
// remember where outer input struct is
outer_input = input_now;
// activate new input struct
input_now = &new_input;
// parse block and check end reason
parse_until_eob_or_eof();
if (GotByte != CHAR_EOF)
Throw_error("Found '}' instead of end-of-file.");
// close sublevel src
// (this looks like we could just use "fd" as arg, but maybe the file
// has been replaced with a different one in the meantime...)
fclose(input_now->src.fd);
// restore outer input struct
input_now = outer_input;
}
@ -413,16 +435,16 @@ int input_quoted_to_dynabuf(char closing_quote)
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
// TODO - check: if this is only ever called directly after input_quoted_to_dynabuf, integrate that call here?
int input_unescape_dynabuf(int read_index)
int input_unescape_dynabuf(void)
{
int write_index;
int read_index = 0,
write_index = 0;
char byte;
boolean escaped;
if (config.dialect < V0_97__BACKSLASH_ESCAPING)
return 0; // ok
write_index = read_index;
escaped = FALSE;
// CAUTION - contents of dynabuf are not terminated:
while (read_index < GlobalDynaBuf->size) {
@ -621,31 +643,30 @@ int input_read_and_lower_keyword(void)
// Returns nonzero on error. Filename in GlobalDynaBuf, including terminator.
// Errors are handled and reported, but caller should call
// input_skip_remainder() then.
static int read_filename_shared_end(int prefix_size)
static int read_filename_shared_end(void)
{
// check length
if (GlobalDynaBuf->size == prefix_size) {
if (GlobalDynaBuf->size == 0) {
Throw_error("No file name given.");
return 1; // error
}
// resolve backslash escapes
if (input_unescape_dynabuf(prefix_size))
if (input_unescape_dynabuf())
return 1; // escaping error
// terminate string
dynabuf_append(GlobalDynaBuf, '\0');
#ifdef PLATFORM_CONVERTPATH
// platform-specific path name conversion
PLATFORM_CONVERTPATH(GLOBALDYNABUF_CURRENT + prefix_size);
PLATFORM_CONVERTPATH(GLOBALDYNABUF_CURRENT);
#endif
return 0; // ok
}
// try to read a file name for an input file.
// library access by using <...> quoting is allowed.
// if library access is used, the library prefix will be added to the file name
// and TRUE will be stored via the "uses_lib" ptr.
// if library access is used, TRUE will be stored via the "uses_lib" ptr.
// if library access is not used, FALSE will be stored via the "uses_lib" ptr.
// The file name given in the assembler source code is converted from
// UNIX style to platform style.
@ -654,27 +675,12 @@ static int read_filename_shared_end(int prefix_size)
// input_skip_remainder() then.
int input_read_input_filename(boolean *uses_lib)
{
char *lib_prefix; // depends on platform
int prefix_size; // this much does not get platform-converted because it is already correct
dynabuf_clear(GlobalDynaBuf);
SKIPSPACE();
if (GotByte == '<') {
// library access:
*uses_lib = TRUE;
// read platform's lib prefix
lib_prefix = PLATFORM_LIBPREFIX;
#ifndef NO_NEED_FOR_ENV_VAR
// if lib prefix not set, complain
if (lib_prefix == NULL) {
Throw_error("\"ACME\" environment variable not found.");
return 1; // error
}
#endif
// copy lib path
dynabuf_add_string(GlobalDynaBuf, lib_prefix);
// remember border between optional library prefix and string from assembler source file
prefix_size = GlobalDynaBuf->size;
// read file name string (must be a single string <literal>)
if (input_quoted_to_dynabuf('>'))
return 1; // unterminated or escaping error
@ -683,7 +689,6 @@ int input_read_input_filename(boolean *uses_lib)
} else {
// "normal", non-library access:
*uses_lib = FALSE;
prefix_size = 0; // no prefix in DynaBuf
// old algo (do not merge with similar parts from "if" block!):
if (GotByte != '"') {
Throw_error("File name quotes not found (\"\" or <>).");
@ -701,7 +706,7 @@ int input_read_input_filename(boolean *uses_lib)
// see lines 416 and 1317 in pseudoopcodes.c for two more possible callers!
}
// check length, unescape, terminate, do platform conversion
return read_filename_shared_end(prefix_size);
return read_filename_shared_end();
}
// try to read a file name for an output file.
@ -732,7 +737,7 @@ int input_read_output_filename(void)
GetByte(); // eat terminator
// check length, unescape, terminate, do platform conversion:
return read_filename_shared_end(0); // 0 -> there is no library prefix
return read_filename_shared_end();
}
@ -773,16 +778,63 @@ bits input_get_force_bit(void)
}
// include path stuff - should be moved to its own file:
// "include path" stuff:
// ring list struct
static STRUCT_DYNABUF_REF(pathbuf, 256); // to combine search path and file spec
// copy "default search path" from current file's file name into pathbuf:
static void default_path_to_pathbuf(void)
{
const char *start = input_now->plat_pathref_filename,
*readptr,
*found;
dynabuf_clear(pathbuf);
if (config.dialect >= V0_98__PATHS_AND_SYMBOLCHANGE) {
// scan filename for last directory separator
readptr = start;
found = NULL;
while (*readptr) {
if ((*readptr == DIRECTORY_SEPARATOR)
|| (*readptr == ALTERNATIVE_DIR_SEP)) {
found = readptr;
}
++readptr;
}
if (found) {
// +1 because we want the separator as well:
dynabuf_add_bytes(pathbuf, start, found - start + 1);
}
} else {
// do nothing -
// pathbuf is empty, which means "default search path" is "",
// which is exactly like it was in older versions.
}
}
// copy platform-specific library search path into pathbuf:
static void library_path_to_pathbuf(void)
{
char *lib_prefix; // depends on platform
dynabuf_clear(pathbuf);
lib_prefix = PLATFORM_LIBPREFIX;
if ((PLATFORM_NEEDS_ENV_VAR) && (lib_prefix == NULL)) {
Throw_error("\"ACME\" environment variable not found.");
} else {
dynabuf_add_string(pathbuf, lib_prefix);
}
}
// ring list struct for "include path items"
struct ipi {
struct ipi *next,
*prev;
const char *path;
};
static struct ipi ipi_head = {&ipi_head, &ipi_head, NULL}; // head element
static STRUCT_DYNABUF_REF(pathbuf, 256); // to combine search path and file spec
// head element
static struct ipi ipi_head = {&ipi_head, &ipi_head, NULL};
// add entry
void includepaths_add(const char *path)
@ -796,43 +848,64 @@ void includepaths_add(const char *path)
ipi->next->prev = ipi;
ipi->prev->next = ipi;
}
// open file for reading (trying list entries as prefixes)
// "uses_lib" tells whether to access library or to make use of include paths
// file name is expected in GlobalDynaBuf, in platform style, and if wanted, with library prefix!
// add filename (from GlobalDynaBuf) to pathbuf and try to open file:
static FILE *combine_and_open_ro(void)
{
// if path does not end with directory separator, add one:
if (pathbuf->size
&& (pathbuf->buffer[pathbuf->size - 1] != DIRECTORY_SEPARATOR)
&& (pathbuf->buffer[pathbuf->size - 1] != ALTERNATIVE_DIR_SEP)) {
dynabuf_append(pathbuf, DIRECTORY_SEPARATOR);
}
// add file name
dynabuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
// terminate
dynabuf_append(pathbuf, '\0');
// try to open for reading
return fopen(pathbuf->buffer, FILE_READBINARY);
}
// open file for reading
// "uses_lib" tells whether to use library prefix or to use search paths
// file name is expected in GlobalDynaBuf, in platform style and terminated
// returns NULL or open stream
// on success, GlobalDynaBuf contains full file name in platform style
FILE *includepaths_open_ro(boolean uses_lib)
{
FILE *stream;
struct ipi *ipi;
// first try directly, regardless of whether lib or not:
stream = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY);
// if failed and not lib, try include paths:
if ((stream == NULL) && !uses_lib) {
for (ipi = ipi_head.next; ipi != &ipi_head; ipi = ipi->next) {
dynabuf_clear(pathbuf);
// add first part
dynabuf_add_string(pathbuf, ipi->path);
// if wanted and possible, ensure last char is directory separator
if (DIRECTORY_SEPARATOR
&& pathbuf->size
&& (pathbuf->buffer[pathbuf->size - 1] != DIRECTORY_SEPARATOR))
dynabuf_append(pathbuf, DIRECTORY_SEPARATOR);
// add second part
dynabuf_add_string(pathbuf, GLOBALDYNABUF_CURRENT);
// terminate
dynabuf_append(pathbuf, '\0');
// try
stream = fopen(pathbuf->buffer, FILE_READBINARY);
//printf("trying <<%s>> - ", pathbuf->buffer);
if (stream) {
//printf("ok\n");
break;
} else {
//printf("failed\n");
if (uses_lib) {
// use library prefix
library_path_to_pathbuf();
stream = combine_and_open_ro();
} else {
// first try current default prefix
default_path_to_pathbuf();
stream = combine_and_open_ro();
if (stream == NULL) {
// default prefix failed, so try list entries:
for (ipi = ipi_head.next; ipi != &ipi_head; ipi = ipi->next) {
dynabuf_clear(pathbuf);
dynabuf_add_string(pathbuf, ipi->path);
stream = combine_and_open_ro();
//printf("trying <<%s>> - ", pathbuf->buffer);
if (stream) {
//printf("ok\n");
break;
} else {
//printf("failed\n");
}
}
}
}
if (stream == NULL) {
if (stream) {
// copy successful file name back to GlobalDynaBuf
dynabuf_clear(GlobalDynaBuf);
dynabuf_add_string(GlobalDynaBuf, pathbuf->buffer);
dynabuf_append(GlobalDynaBuf, '\0');
} else {
// CAUTION, I'm re-using the path dynabuf to assemble the error message:
dynabuf_clear(pathbuf);
dynabuf_add_string(pathbuf, "Cannot open input file \"");

View File

@ -31,6 +31,11 @@ enum inputsrc {
INPUTSRC_RAM
};
struct input {
const char *plat_pathref_filename; // file
// the filename *above* refers to the source file currently being parsed, which
// is needed as a reference for relative paths.
// the filename *below* (in "location") refers to the source file where
// the current code initially came from, i.e. it may change during macro execution.
struct location location; // file + line (during RAM reads as well)
enum inputsrc source;
enum inputstate state; // state of input
@ -59,12 +64,12 @@ extern struct input *input_now; // current input structure
// Prototypes
// let current input point to start of file
// parse a whole source code file
// file name must be given in platform style, i.e.
// "directory/basename.extension" on linux,
// "directory.basename/extension" on RISC OS, etc.
// and the pointer must remain valid forever!
extern void input_new_platform_file(const char *plat_filename, FILE *fd);
extern void input_parse_and_close_platform_file(const char *eternal_plat_filename, FILE *fd);
// get next byte from currently active byte source in shortened high-level
// format. When inside quotes, use input_quoted_to_dynabuf() instead!
@ -83,7 +88,7 @@ extern int input_quoted_to_dynabuf(char closing_quote);
// process backslash escapes in GlobalDynaBuf (so size might shrink)
// returns 1 on errors (escaping errors)
extern int input_unescape_dynabuf(int start_index);
extern int input_unescape_dynabuf(void);
// Skip or store block (starting with next byte, so call directly after
// reading opening brace).
@ -121,8 +126,7 @@ extern int input_read_and_lower_keyword(void);
// try to read a file name for an input file.
// library access by using <...> quoting is allowed.
// if library access is used, the library prefix will be added to the file name
// and TRUE will be stored via the "uses_lib" ptr.
// if library access is used, TRUE will be stored via the "uses_lib" ptr.
// if library access is not used, FALSE will be stored via the "uses_lib" ptr.
// The file name given in the assembler source code is converted from
// UNIX style to platform style.
@ -151,14 +155,16 @@ extern int input_accept_comma(void);
extern bits input_get_force_bit(void);
// include path stuff - should be moved to its own file:
// "include path" stuff:
// add entry
extern void includepaths_add(const char *path);
// open file for reading (trying list entries as prefixes)
// "uses_lib" tells whether to access library or to make use of include paths
// file name is expected in GlobalDynaBuf, in platform style, and if wanted, with library prefix!
// open file for reading
// "uses_lib" tells whether to use library prefix or to use search paths
// file name is expected in GlobalDynaBuf, in platform style and terminated
// returns NULL or open stream
// on success, GlobalDynaBuf contains full file name in platform style
extern FILE *includepaths_open_ro(boolean uses_lib);

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2016 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff
@ -16,7 +16,7 @@
#endif
// DOS, OS/2 and Windows
#if defined(__DJGPP__) || defined(__OS2__) || defined(__Windows__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#if defined(__DJGPP__) || defined(__OS2__) || defined(__Windows__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__)
#include "_dos.c"
#endif
@ -27,5 +27,36 @@
// add further platform files here
// Unix/Linux/others (surprisingly also works on at least some versions of Windows)
// Unix/Linux/others (also works on newer versions of Windows)
#ifndef platform_C
#include "_std.c"
#endif
// stuff shared by some, but not all platforms:
#if PLATFORM_NEEDS_ENV_VAR
#include <stdlib.h> // for getenv()
#include "dynabuf.h"
// path of library tree, taken from env var
char *platform_lib_prefix = NULL;
// function to setup pointer above
void platform_read_env_var(void)
{
char *env_var;
// Find out the path of ACME's library
env_var = getenv("ACME");
// if environment variable was found, make a copy
if (env_var) {
dynabuf_clear(GlobalDynaBuf);
// copy environment variable to global dynamic buffer
dynabuf_add_string(GlobalDynaBuf, env_var);
dynabuf_append(GlobalDynaBuf, '\0'); // add terminator
platform_lib_prefix = dynabuf_get_copy(GlobalDynaBuf);
}
}
#endif

View File

@ -1,5 +1,5 @@
// ACME - a crossassembler for producing 6502/65c02/65816/65ce02 code.
// Copyright (C) 1998-2016 Marco Baye
// Copyright (C) 1998-2024 Marco Baye
// Have a look at "acme.c" for further info
//
// Platform specific stuff
@ -12,8 +12,8 @@
#endif
// DOS, OS/2 and Windows
#if defined(__DJGPP__) || defined(__OS2__) || defined(__Windows__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#define PLATFORM_VERSION "DOS/OS2/Win32 version. Compiled by Dirk Hoepfner"
#if defined(__DJGPP__) || defined(__OS2__) || defined(__Windows__) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__)
#define PLATFORM_VERSION "DOS/OS2/Win32/Win64 version. Compiled by Dirk Hoepfner"
#include "_dos.h"
#endif
@ -25,8 +25,20 @@
// add further platform files here
// Unix/Linux/others (surprisingly also works on Windows)
// Unix/Linux/others (also works on newer versions of Windows)
#ifndef PLATFORM_VERSION
#define PLATFORM_VERSION "Platform independent version."
#endif
#include "_std.h"
#endif
// stuff shared by some, but not all platforms:
#if PLATFORM_NEEDS_ENV_VAR
// path to library tree, taken from env var:
extern char *platform_lib_prefix;
// function to setup pointer above
extern void platform_read_env_var(void);
#endif

View File

@ -484,7 +484,7 @@ static enum eos encode_string(const struct encoder *inner_encoder, unsigned char
// now convert to unescaped version
// FIXME - next call does nothing because wanted<escaping!
// FIXME - there is another block like this, scan for ROOSTA!
if (input_unescape_dynabuf(0))
if (input_unescape_dynabuf())
return SKIP_REMAINDER; // escaping error
// send characters
@ -928,8 +928,6 @@ static enum eos po_source(void) // now GotByte = illegal char
FILE *stream;
const char *eternal_plat_filename;
char local_gotbyte;
struct input new_input,
*outer_input;
// enter new nesting level
// quit program if recursion too deep
@ -943,18 +941,9 @@ static enum eos po_source(void) // now GotByte = illegal char
// if file could be opened, parse it. otherwise, complain
stream = includepaths_open_ro(uses_lib);
if (stream) {
// GlobalDynaBuf contains either
// library_prefix + platformstyle(source_argument) + '\0'
// or
// platformstyle(source_argument) + '\0'
// it does _not_ contain any search path added using "-I", even if used!
// if this is a problem, fix includepaths_open_ro()!
eternal_plat_filename = dynabuf_get_copy(GlobalDynaBuf);
outer_input = input_now; // remember old input
local_gotbyte = GotByte; // CAUTION - ugly kluge
input_now = &new_input; // activate new input
flow_parse_and_close_platform_file(eternal_plat_filename, stream);
input_now = outer_input; // restore previous input
input_parse_and_close_platform_file(eternal_plat_filename, stream);
GotByte = local_gotbyte; // CAUTION - ugly kluge
}
// leave nesting level
@ -1388,7 +1377,7 @@ static enum eos throw_src_string(enum debuglevel level, const char prefix[])
// now convert to unescaped version
// FIXME - next call does nothing because wanted<escaping!
// FIXME - there is another block like this, scan for ROOSTA!
if (input_unescape_dynabuf(0))
if (input_unescape_dynabuf())
return SKIP_REMAINDER; // escaping error
dynabuf_append(GlobalDynaBuf, '\0'); // terminate string

View File

@ -9,7 +9,7 @@
#define RELEASE "0.97" // update before release FIXME
#define CODENAME "Zem" // update before release
#define CHANGE_DATE "29 Feb" // update before release FIXME
#define CHANGE_DATE "1 Mar" // update before release FIXME
#define CHANGE_YEAR "2024" // update before release
//#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/"
#define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME

View File

@ -9,12 +9,13 @@ all: dialects outformats
echo "Testing cliargs: PASSED"
echo
dialects: dialect085.a dialect086.a dialect09406.a dialect09408.a dialect09412.a
dialects: dialect085.a dialect086.a dialect09406.a dialect09408.a dialect09412.a dialect097.a
acme --strict --dialect 0.85 dialect085.a
acme --strict --dialect 0.86 dialect086.a
acme --strict --dialect 0.94.6 dialect09406.a
acme --strict --dialect 0.94.8 dialect09408.a
acme --strict --dialect 0.94.12 dialect09412.a
acme --strict --dialect 0.97 dialect097.a
$(RM) test.o
outformats: outformats.a outformats.sh outformat-*.exp

View File

@ -3,3 +3,5 @@
; backslash becomes escape char in 0.97:
b = "\"
c = '\'
!src "dialect097.a"

View File

@ -0,0 +1,5 @@
; 0.97 interprets all file names as relative to the initial directory:
!src "subdir/sub1.inc"
!if depth_given_in_included_file != 0 {
!error "included wrong file."
}

View File

@ -0,0 +1,3 @@
; 0.97 interprets all file names as relative to the initial directory,
; so should include this file.
depth_given_in_included_file = 0

View File

@ -0,0 +1,3 @@
; 0.97 interprets all file names as relative to the initial directory,
; so shouldn't include this file.
depth_given_in_included_file = 1

View File

@ -0,0 +1,3 @@
; 0.97 interprets all file names as relative to the initial directory,
; so it looks for "file2" not in this directory, but one level up.
!src "file2.inc"