Tom Moran wrote:
>> Does anyone know if it is possible to call dos commands (i.e. dir, copy, mkdir, etc) from within a Ada program?

> Yes. How to do it depends on your compiler and OS.

Answer Number 1. For dir, copy, mkdir, etc., using gnat

In gnat the arguments have to be first separated into an array of type
gnat.OS_lib.argument_list (1..nargs+2). The first argument contains an
access string with the value "/C". The second argument contains an
access string with the name sof the command. The third through nargs+2
contains access strings with the first through narg-th argument.

After lexical scan of the arguments into the arglist array, code similar
to the following excerpt will shove all this stuff into the proper place
and run it.

--------------

  success: boolean := false;
  nargs: natural := 0; -- scanner fills this in
  subtype arg_lists is gnat.OS_lib.argument_list (1..nargs);
  arglist: arg_lists; -- scanner fills this in

---------------


  declare
    subtype expanded_arg_lists is gnat.OS_lib.argument_list(1..nargs+2);
    expanded_arglist: expanded_arg_lists;
  begin
    for i in reverse 3..nargs+2 loop
      expanded_arglist(i) := arglist (i-2);
    end loop; -- There is room for the slash C.
    expanded_arglist(1) := new string(1..2);
    expanded_arglist(1).all := "/C"; -- The slash C is the first arg.
    expanded_arglist(2) := new string(cmd'range);
    expanded_arglist(2).all := cmd;
    gnat.OS_lib.spawn ("command", expanded_arglist, success);
  end;

----------------

Answer Number 2. For batch files or executables using gnat

Here you don't have to shift the arglist over by 2, you just use the
arglist directly.

  gnat.OS_lib.spawn (cmd, arglist, success);

----------------

Answer Number 3. In Janus

Here the command_line contains just what you would have typed in from
the DOS command line.


  dosdrive.disk_reset; -- always empty disk buffers
  chainlib.prog_call("c:\command.com",
                     "/e:1024/c " & command_line,
                     halt_on_return => false);
  return chainlib.return_code = 0;


Again, if it is a batch file or an executable, then just:

  dosdrive.disk_reset; -- always empty disk buffers
  chainlib.prog_call(command,
                     argument_string,
                     halt_on_return => false);
  return chainlib.return_code = 0;


-----------------


Answer Number 4. In Alsys

Here the Alsys runtime library takes care of everything, like a runtime
should. YOu just put in your command_line and don't have to test
separately for the DOS commands versus the batch files versus the
executables.

  begin
    dosdrive.disk_reset; -- always empty disk buffers
    dos.exec_command (command_line);
    return integer (dos.wait_process) = 0;
  exception
    when dos.DOS_error => return false;

------------------

Answer Number 5. In Python

It takes many lines of code to create the lexical scanning process to
crack off the arguments from the command line string, and that process
needs to be enhanced for each new type of command argument used.
Therefore, it might be advantageous to use a scripting language like
perl, or its better sisters PHP, awk, or the best scripting language,
python to execute the command for you. In python, it is done like this.

  os.system(command_line)

Alternatively, you may break out the arguments yourself. One example of
this is the following.

  os.execv (command_path, (arg0, arg1, ... argN), environ['PATH']);

The above separates the argument list from the command name, and gives a
choice of which level of environmental variables it uses. In addition,
the python interpretor is replaced in memory by the executable or the
command processor that is brought in by the execv command.

-----------------

Answer Number 6. In SunAda and in Verdix for DOS

(BTW, is you are using SunAda your license has permanently expired -- do
you know how to override and continue to use it?)

Verdix comes with an examples and a standard directory. In the standard
directory, you can use the execute function.

  declare
    command_string: a_string;
  begin
    return_code := execute (cmd);
  end;

------------------