Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Sidewinder on March 23, 2004, 04:39:32 AM
-
I've created a little program to generate simple assembly source files and wish to call the assembler (PhxAss) directly from the C program. I've found that the Execute() function works nicely for this, but I'm having trouble getting it all the work properly. Here's the code of my function:
#include <exec/types.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "assembler.h"
int assemble(char *file_name)
{
struct Library *DOSBase = NULL;
if (!(DOSBase = OpenLibrary(DOSNAME, 0)))
{
printf("Unable to open dos.library\n");
return FALSE;
}
else
{
char *command = NULL;
char *assembler_name = "PhxAss";
char *output_file_name = "file.err";
BPTR output_file = NULL;
if (!(command = (char *)malloc(sizeof(assembler_name) + sizeof(file_name) + 2)))
{
printf("Out of memory\n");
return FALSE;
}
strcat(command, assembler_name);
strcat(command, " ");
strcat(command, file_name);
output_file = Open(output_file_name, MODE_NEWFILE);
printf("%s\n", command);
Execute(command, NULL, output_file); /* Call the assembler. */
if (output_file)
{
Close(output_file);
}
CloseLibrary(DOSBase);
}
return TRUE;
}
This seems to work up to a point. It finds PhxAss which is in the default directory but fails to find the source file in the same directory. I get the following error in the output:
12 File doesn't exist (Init).
PhxAss failed returncode 20
This is a PhxAss error that means it can't find the file. I've tried adding the full path to the file name with the same results.
Does anyone have any idea what could be going on?
Thanks.
-
Shouldn`t Phxass be called with Phxass TO ?
BTW, have you tried using Snoopdos to see what Phxass is failing to look for?
-
@Doobrey
If the "TO " is left off of the command line then the executable will have the same name as the source file minus the extension. I have tired it both ways just in case but get the same results. However, the same command line works fine from a shell.
I haven't used SnoopDOS yet. I don't have it setup on this machine. I'll give it a try.
-
-
Hello Sidewinder,
Your using sizeof() in the malloc statement, which I think is incorrect. Both sizeof(assembler_name) and sizeof(file_name) should both return a value of four(4) since this is the size of a pointer in bytes.
I'd use strlen() instead of sizeof()...
Hope this helps.
Regards,
Stephen.
-
Fixed the bugs pointed out by CodeSmith and nueron. Also fixed a bug that would occur with filename with spaces.
#include <exec/types.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "assembler.h"
int assemble(char *file_name)
{
struct Library *DOSBase = NULL;
if (!(DOSBase = OpenLibrary(DOSNAME, 33)))
{
printf("Unable to open dos.library\n");
return FALSE;
}
else
{
char *command = NULL;
char *assembler_name = "PhxAss";
char *output_file_name = "file.err";
BPTR output_file = NULL;
if (!(command = (char *)malloc(strlen(assembler_name) + strlen(file_name) + 4)))
{
printf("Out of memory\n");
return FALSE;
}
strcpy(command, assembler_name);
strcat(command, " \"");
strcat(command, file_name);
strcat(command, "\"");
output_file = Open(output_file_name, MODE_NEWFILE);
printf("command <%s>\n", command);
Execute(command, NULL, output_file); /* Call the assembler. */
if (output_file)
{
Close(output_file);
}
CloseLibrary(DOSBase);
}
return TRUE;
}
-
Everyone, thanks for the corrections. I've made them and installed SnoopDOS. Apparently PhxAss is looking for a file called PHXOPTIONS which I do not havea and I'd really rather not use it.
Here's the SnoopDOS log:
SnoopDos logging started on Tuesday, 23-Mar-04 at 16:50:33
Count Process Name Action Target Name Options Res.
----- ------------ ------ ----------- ------- ----
38 [4] PhxAss Open prog.s Read OK
39 [4] PhxAss Open prog Write OK
40 [4] compiler Open prog.in Read OK
41 [4] compiler Open prog.s Write OK
42 [4] compiler Open file.err Write OK
43 [4] compiler Execute PhxAss "prog.s" Single
44 [3] PhxAss Open PHXOPTIONS Read Fail
45 [3] PhxAss Open ENV:PhxAss/PHXOPTIONS Read Fail
Closed SnoopDos log at 16:51:24
38 and 39 are from directly calling PhxAss from the command line as:
PhxAss "prog.s"
40 through 45 are the result of running my little compiler. It doesn't seem to even attempt to open the source but rather looks for the PHXOPTIONS file even though the command line is the same.
Does anyone have any more clues?
-
Don`t worry about the phxoptions file, it`s just an env var for setting default compiler options such as CPU/FPU and optimization level.
AFAIK, even if it does exist, any options passed directly to phxass, or those in the source will override those in the phxoptions file.
-
@ Doobrey
True, this is how I thought it was supposed to work, but if I follow the SnoopDOS output correctly, it never attempts to open the prog.s file, it can't open the PHXOPTIONS file in the current directory or in ENV: and then chokes...it doesn't ever assemble anything. As far as I can tell the command passed to Execute() is the same one that I run from the DOS prompt, but the results are totally different. This is crazy.
-
What is the contents of file.err ? I guess PhxAss tries to tell you what is wrong.
Bye,
Thomas
-
Hi
@Sidewinder
There might be a little difference in the command as passed via the CLI and the one passed to Execute() in your app:
The line of the CLI command is terminated by a linefeed! You might enlarge your command-buffer "command" by one and add a "strcat(command, "\n")" to your code.
Maybe this works.
Noster
-
@Noster
You might enlarge your command-buffer "command" by one and add a "strcat(command, "\n")" to your code.
No, the command need not be newline terminated for Execute().
@Sidewinder
If you enable "AmigaDOS Functions/Lock" in SnoopDos you will see PhxAss Lock()s the source file before it Open() it. So if the Lock()ing fails, no Open() will ever happen.
Execute() doesn't interherit the current directory of the parent calling it, so you need to pass absolute path to sourcefile.
There are several ways to do this: one is to Lock() the sourcefile, NameFromLock() the full path the file. Another is to add a temporary assign to the sourcedir, and use this assign + filename with phxass.
-
@Piru
Thanks for the tip on using SnoopDOS. I found out the the lock was indeed failing. After a little thought on why a lock might fail I realized that I was calling the assemble function before closing the file in the calling function. :crazy: It works now. Thanks everyone for your help!!!
-
Hi
Ok, I've seen the failure has been found so this thread is dead ;-)
@Piru
> No, the command need not be newline terminated for Execute().
Of cause, I know that Execute() doesn't requires a newline terminated command string, but I've thought: "Who knows how PhxAss parses its arguments ?"
Bad written programs may not use the C-style argument parsing or the AmigaDOS ReadArgs() command for parsing their arguments, instead looking for a terminating linefeed to find the end of the command line.
Noster
-
@Noster
Of cause, I know that Execute() doesn't requires a newline terminated command string, but I've thought: "Who knows how PhxAss parses its arguments ?"
Bad written programs may not use the C-style argument parsing or the AmigaDOS ReadArgs() command for parsing their arguments, instead looking for a terminating linefeed to find the end of the command line.
Ok.
Execute() adds the linefeed however. :-)