% -----------------------------------------------------------------------------
%  (C) Altran Praxis Limited
% -----------------------------------------------------------------------------
% 
%  The SPARK toolset is free software; you can redistribute it and/or modify it
%  under terms of the GNU General Public License as published by the Free
%  Software Foundation; either version 3, or (at your option) any later
%  version. The SPARK toolset is distributed in the hope that it will be
%  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
%  Public License for more details. You should have received a copy of the GNU
%  General Public License distributed with the SPARK toolset; see file
%  COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
%  the license.
% 
% =============================================================================


process_command_line_data :-
        set_toplevel,
        !,
        get_command_line(DATA),
        !,
        process_dcl_args(DATA),
        !.

set_toplevel :-
        command_logging(ORIGLOG),
        asserta(toplevel_execute(user, ORIGLOG)).

process_dcl_args([]) :-
        !.
process_dcl_args(LIST) :-
        split_qualifiers(LIST, QUALIFIERS),
        !,
        process_dcl_qualifiers(QUALIFIERS),
        !.


split_qualifiers([FIRST|REST], RESULT) :-
        split_atom(FIRST, NEW_FIRST),
        !,
        split_qualifiers(REST, NEW_REST),
        !,
        (
           NEW_FIRST = [SINGLE_ATOM],
           RESULT = [SINGLE_ATOM|NEW_REST]
        ;
           append(NEW_FIRST, NEW_REST, RESULT)
        ),
        !.
split_qualifiers([], []) :- !.


split_atom(ATOM, LIST) :-
        name(ATOM, ATOM_CHARS),
        !,
        (
           is_in(59, ATOM_CHARS),       /* i.e. ";" */
           eliminate_semi_colons(ATOM_CHARS, NEW_ATOM_CHARS)
        ;
           NEW_ATOM_CHARS = ATOM_CHARS
        ),
        !,
        split_atom_list(NEW_ATOM_CHARS, LIST),
        !.


eliminate_semi_colons([59|REST], [46|NEW_REST]) :-
        eliminate_semi_colons(REST, NEW_REST),
        !.
eliminate_semi_colons([X|REST], [X|NEW_REST]) :-
        eliminate_semi_colons(REST, NEW_REST),
        !.
eliminate_semi_colons([], []) :- !.


split_atom_list(CHARS, [ATOM|LIST]) :-
        qualifier_prefix(QP),                                   /* CFR048 */
        (
           triple_append(FIRST, [QP], REST, CHARS),             /* CFR048 */
                /* N.B. QP=47 -> "/" (VAX), 45 -> "-" (SUN) */  /* CFR048 */
           name(ATOM, FIRST),
           !,
           split_atom_list([QP|REST], LIST)                     /* CFR048 */
        ;
           name(ATOM, CHARS),
           LIST = []
        ),
        !.


process_dcl_qualifiers([QUALIFIER|REST]) :-
        process_dcl_qualifier(QUALIFIER),
        !,
        process_dcl_qualifiers(REST),
        !.
process_dcl_qualifiers([]) :- !.


process_dcl_qualifier(QUALIFIER) :-
        qualifier_prefix(QP),                                   /* CFR048 */
        name(QUALIFIER, [QP|CHARS]),                            /* CFR048 */
        length(CHARS, LENGTH),
        LENGTH >= 1,
        !,
        (
           triple_append(QUAL, [61], FILELIST, CHARS),  /* N.B. chr(61) = "=" */
           QUAL=[_|_],                                  /* so >= 1 character! */
           (
              (
                 gen_append(QUAL, _, "proof_log")
              ;
                 gen_append(QUAL, _, "prooflog")        /* allow variant */
              ),
              \+ done__proof_log,
              !,
              process_proof_log_file_name(FILELIST),
              assertz(done__proof_log)
           ;                                                    /* CFR014 */
              gen_append(QUAL, _, "execute"),                   /* CFR014 */
              \+ perform_script_file(_),                        /* CFR014 */
              !,                                                /* CFR014 */
              process_execute_file_name(FILELIST)               /* CFR014 */
           ;
              (                                                 /* CFR016 */
                 gen_append(QUAL, _, "command_log")             /* CFR016 */
              ;                                                 /* CFR016 */
                 gen_append(QUAL, _, "commandlog")              /* CFR016 */
              ),                                                /* CFR016 */
              \+ cmd_line_command_log(_),                       /* CFR016 */
              !,                                                /* CFR016 */
              process_command_log_file_name(FILELIST)           /* CFR016 */
           ;
              scream_blue_murder
           )
        ;
           gen_append(CHARS, _, "resume"),
           (
              \+ done__resume,
              asserta(done__resume)
           ;
              scream_blue_murder
           )
        ;
           gen_append(CHARS, _, "plain"),
           !,
           retractall(plain_output(_)),
           asserta(plain_output(on))
        ;
           gen_append(CHARS, _, "overwrite_warning"),
           !,
           retractall(overwrite_warning(_)),
           assertz(overwrite_warning(on))
        ;
           gen_append(CHARS, _, "version"),
           !,
           process_version
        ;
           gen_append(CHARS, _, "help"),
           !,
           process_help
        ;
           scream_blue_murder
        ),
        !.

process_dcl_qualifier(QUALIFIER) :-
    %Does not lead with a qualifier.
    name(QUALIFIER, [QP|_CHARS]),
    \+ qualifier_prefix(QP),

    %Have not yet encountered a filename.
    \+ cmd_line_filename(_FILENAME),

    %Take this as the filename.
    assert(cmd_line_filename(QUALIFIER)),
    !.

process_dcl_qualifier(QUALIFIER) :-
    %Does not lead with a qualifier.
    name(QUALIFIER, [QP|_CHARS]),
    \+ qualifier_prefix(QP),

    %Have already encountered a filename.
    cmd_line_filename(FILENAME),

    %Raise error.
    format('Error: Multiple files provided on command line: ~a and ~a.~n', [FILENAME, QUALIFIER]),
    scream_blue_murder,
    !.

process_dcl_qualifier(_QUALIFIER) :-
        scream_blue_murder,
        !.


scream_blue_murder :-
        nl,
        write('FAILED: ERROR IN COMMAND LINE SYNTAX'),
        nl,
        !,
        close_all_streams,
        halt.

process_version:-
    display_header(user_output),
    close_all_streams,
    halt(0),
    !.

process_help:-
    display_help(user_output),
    close_all_streams,
    halt(0),
    !.

process_proof_log_file_name(LIST) :-
        triple_append(_FRONT, ".", EXTENSION, LIST),
        \+ is_in(46, EXTENSION),                        /* so no "." */
        name(FILE, LIST),
        !,
        assertz(cmd_line_proof_log(FILE)),
        !.
process_proof_log_file_name(LIST) :-
        append(LIST, ".plg", FILELIST),                         /* CFR048 */
        name(FILE, FILELIST),
        !,
        assertz(cmd_line_proof_log(FILE)),
        !.


process_execute_file_name(LIST) :-                              /* CFR014 */
        triple_append(_FRONT, ".", EXTENSION, LIST),            /* CFR014 */
        \+ is_in(46, EXTENSION),        /* so no "." */         /* CFR014 */
        name(FILE, LIST),                                       /* CFR014 */
        (                                                       /* CFR014 */
           file_exists_and_is_readable(FILE)                    /* CFR014 */
        ;                                                       /* CFR014 */
           write('Aborted: '),                                  /* CFR014 */
           print(FILE),
           write(' does not exist or cannot be read.'),
           nl,                                                  /* CFR014 */
           !,                                                   /* CFR014 */
           close_all_streams,
           halt                                                 /* CFR014 */
        ),                                                      /* CFR014 */
        !,                                                      /* CFR014 */
        asserta(perform_script_file(FILE)),                     /* CFR014 */
        command_logging(ORIGLOG),
        asserta(toplevel_execute(script, ORIGLOG)),
        !.                                                      /* CFR014 */
process_execute_file_name(LIST) :-                              /* CFR014 */
        append(LIST, ".cmd", FILELIST),                         /* CFR014 */
        name(FILE, FILELIST),                                   /* CFR014 */
        (                                                       /* CFR014 */
           file_exists_and_is_readable(FILE)                    /* CFR014 */
        ;                                                       /* CFR014 */
           write('Aborted: '),                                  /* CFR014 */
           print(FILE),
           write(' does not exist or cannot be read.'),
           nl,                                                  /* CFR014 */
           !,                                                   /* CFR014 */
           close_all_streams,
           halt                                                 /* CFR014 */
        ),                                                      /* CFR014 */
        !,                                                      /* CFR014 */
        asserta(perform_script_file(FILE)),                     /* CFR014 */
        !.                                                      /* CFR014 */


process_command_log_file_name(LIST) :-                          /* CFR016 */
        triple_append(_FRONT, ".", EXTENSION, LIST),            /* CFR016 */
        \+ is_in(46, EXTENSION),        /* so no "." */         /* CFR016 */
        name(FILE, LIST),                                       /* CFR016 */
        !,                                                      /* CFR016 */
        assertz(cmd_line_command_log(FILE)),                    /* CFR016 */
        !.                                                      /* CFR016 */
process_command_log_file_name(LIST) :-                          /* CFR016 */
        append(LIST, ".cmd", FILELIST),                     /* CFR016,048 */
        name(FILE, FILELIST),                                   /* CFR016 */
        !,                                                      /* CFR016 */
        assertz(cmd_line_command_log(FILE)),                    /* CFR016 */
        !.                                                      /* CFR016 */




/*** triple_append(L1, L2, L3, RESULT) - RESULT = L1@L2@L3 and L1,L2 <> [] ***/
triple_append(X, Y, Z, L) :-
        gen_append(X, T, L),
        X \= [],
        gen_append(Y, Z, T),
        Y \= [].
%###############################################################################
%END-OF-FILE
