Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /trunk/src/tools/tcc/options.c – Rev 2 and 7

Subversion Repositories tendra.SVN

Rev

Rev 2 | Rev 38 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
29
 
59
 
-
 
60
 
-
 
61
#include <sys/types.h>
-
 
62
#include <sys/stat.h>
-
 
63
#include <errno.h>
30
 
64
 
31
#include "config.h"
65
#include "config.h"
32
#include "filename.h"
66
#include "filename.h"
33
#include "list.h"
67
#include "list.h"
34
#include "archive.h"
68
#include "archive.h"
Line 38... Line 72...
38
#include "options.h"
72
#include "options.h"
39
#include "startup.h"
73
#include "startup.h"
40
#include "suffix.h"
74
#include "suffix.h"
41
#include "utility.h"
75
#include "utility.h"
42
 
76
 
515
		}
775
		}
516
		error ( OPTION, "Unknown compilation stage, '%c'", b ) ;
-
 
517
		return ( null ) ;
-
 
518
	    }
-
 
519
	    goto case_O ;
-
 
520
	}
-
 
521
	case 'O' :
-
 
522
	case_O :{
-
 
523
	    switch ( b ) {
-
 
524
		case PRODUCE_ID : return ( &opt_produce ) ;
-
 
525
		case PREPROC_ID : return ( &opt_preproc ) ;
-
 
526
		case CPP_PRODUCE_ID : return ( &opt_cpp_produce ) ;
-
 
527
		case CPP_PREPROC_ID : return ( &opt_cpp_preproc ) ;
-
 
528
		case TDF_LINK_ID : return ( &opt_tdf_link ) ;
-
 
529
		case TRANSLATE_ID : return ( &opt_translate ) ;
-
 
530
		case ASSEMBLE_ID : return ( &opt_assemble ) ;
-
 
531
		case DYNLINK_ID : return ( &opt_dynlink ) ;
-
 
532
		case LINK_ID : return ( &opt_link ) ;
-
 
533
		case PRETTY_ID : return ( &opt_pretty ) ;
-
 
534
		case NOTATION_ID : return ( &opt_notation ) ;
-
 
535
		case PL_TDF_ID : return ( &opt_pl_tdf ) ;
-
 
536
		case ASSEMBLE_MIPS_ID : return ( &opt_assemble_mips ) ;
-
 
537
		case SPEC_LINK_ID : return ( &opt_spec_link ) ;
-
 
538
		case CPP_SPEC_LINK_ID : return ( &opt_cpp_spec_link ) ;
-
 
539
		case INSTALL_ID : return ( &opt_archive ) ;
-
 
540
		case ARCHIVER_ID : return ( &opt_joiner ) ;
-
 
541
		case CC_ID : return ( &opt_cc ) ;
-
 
542
	        case DUMP_ANAL_ID : return ( &opt_dump_anal );
-
 
543
	        case DUMP_LINK_ID : return ( &opt_dump_link );
-
 
544
	    }
-
 
545
	    error ( OPTION, "Unknown compilation stage, '%c'", b ) ;
-
 
546
	    return ( null ) ;
-
 
547
	}
-
 
548
	case 'S' : {
-
 
549
	    switch ( b ) {
-
 
550
		case 'I' : return ( &std_prod_incldirs ) ;
-
 
551
		case 'P' : return ( &std_prod_portfile ) ;
-
 
552
		case 'd' : return ( &std_prod_startdirs ) ;
-
 
553
		case 's' : return ( &std_prod_startup ) ;
-
 
554
		case 'i' : return ( &std_cpp_prod_incldirs ) ;
-
 
555
		case 'D' : return ( &std_cpp_prod_startdirs ) ;
-
 
556
		case 'S' : return ( &std_cpp_prod_startup ) ;
-
 
557
		case 'J' : return ( &std_tdf_link_libdirs ) ;
-
 
558
		case 'j' : return ( &std_tdf_link_libs ) ;
-
 
559
		case '0' : return ( &std_link_crt0 ) ;
-
 
560
		case '1' : return ( &std_link_crt1 ) ;
-
 
561
		case '2' : return ( &std_link_crtn ) ;
-
 
562
		case '3' : return ( &std_link_crtp_n ) ;
-
 
563
		case 'L' : return ( &std_link_libdirs ) ;
-
 
564
		case 'l' : return ( &std_link_libs ) ;
-
 
565
		case 'c' : return ( &std_link_c_libs ) ;
-
 
566
		case 'e' : return ( &std_link_entry ) ;
-
 
567
	    }
-
 
568
	    break ;
-
 
569
	}
-
 
570
	case 'U' : {
-
 
571
	    switch ( b ) {
-
 
572
		case 'I' : return ( &usr_prod_incldirs ) ;
-
 
573
		case 's' : return ( &usr_prod_startup ) ;
-
 
574
		case 'e' : return ( &usr_prod_eoptions ) ;
-
 
575
		case 'f' : return ( &usr_prod_foptions ) ;
-
 
576
		case 'P' : return ( &usr_pl_tdf_incldirs ) ;
-
 
577
		case 'J' : return ( &usr_tdf_link_libdirs ) ;
-
 
578
		case 'j' : return ( &usr_tdf_link_libs ) ;
-
 
579
		case 'L' : return ( &usr_link_libdirs ) ;
-
 
580
		case 'l' : return ( &usr_link_libs ) ;
-
 
581
	    }
-
 
582
	    break ;
-
 
583
	}
-
 
584
	case 'X' : {
-
 
585
	    switch ( b ) {
-
 
586
		case 'O' : return ( &opt_unknown ) ;
-
 
587
		case 'X' : return ( &xx_list ) ;
-
 
588
	    }
-
 
589
	    break ;
-
 
590
	}
-
 
591
    }
-
 
592
    error ( OPTION, "Unknown list identifier, '%c%c'", a, b ) ;
-
 
593
    return ( null ) ;
-
 
594
}
-
 
595
 
-
 
596
 
-
 
597
/*
-
 
598
    CONVERT A TWO LETTER CODE INTO A STRING
-
 
599
 
-
 
600
    This routine takes a two letter code, s, and returns a pointer to
-
 
601
    the corresponding string variable.
-
 
602
*/
-
 
603
 
776
 
604
static char **lookup_string
-
 
605
    PROTO_N ( ( s ) )
777
		t = find_type(b, 0);
606
    PROTO_T ( char *s )
-
 
607
{
-
 
608
    char a = s [0] ;
-
 
609
    char b = 0 ;
-
 
610
    if ( a ) b = s [1] ;
778
		return (suffixes + t);
611
    if ( a == 'N' ) {
-
 
612
	switch ( b ) {
-
 
613
	    case INDEP_TDF_KEY : return ( &name_j_file ) ;
-
 
614
	    case C_SPEC_KEY : return ( &name_k_file ) ;
-
 
615
	    case CPP_SPEC_KEY : return ( &name_K_file ) ;
-
 
616
	    case STARTUP_FILE_KEY : return ( &name_h_file ) ;
-
 
617
	    case PRETTY_TDF_KEY : return ( &name_p_file ) ;
-
 
618
	}
779
	}
619
	error ( OPTION, "Unknown output file specifier, '%c'", b ) ;
-
 
620
	return ( null ) ;
-
 
621
    }
-
 
622
    if ( a == 'S' ) {
-
 
623
	int t = find_type ( b, 0 ) ;
-
 
624
	return ( suffixes + t ) ;
-
 
625
    }
-
 
626
    if ( a == 'A' && b == 'I' ) return ( &api_info ) ;
780
	if (a == 'A' && b == 'I') return (&api_info);
627
    if ( a == 'A' && b == 'O' ) return ( &api_output ) ;
781
	if (a == 'A' && b == 'O') return (&api_output);
628
    if ( a == 'D' && b == 'O' ) return ( &dump_opts ) ;
782
	if (a == 'D' && b == 'O') return (&dump_opts);
629
    if ( a == 'E' && b == 'D' ) return ( &environ_dir ) ;
783
	if (a == 'E' && b == 'D') return (&environ_dir);
630
    if ( a == 'F' && b == 'N' ) return ( &final_name ) ;
784
	if (a == 'F' && b == 'N') return (&final_name);
631
    if ( a == 'M' && b == 'N' ) return ( &machine_name ) ;
785
	if (a == 'M' && b == 'N') return (&machine_name);
632
    if ( a == 'P' && b == 'N' ) return ( &progname ) ;
786
	if (a == 'P' && b == 'N') return (&progname);
633
    if ( a == 'T' && b == 'D' ) return ( &temporary_dir ) ;
787
	if (a == 'T' && b == 'D') return (&temporary_dir);
634
    if ( a == 'V' && b == 'F' ) return ( &version_flag ) ;
788
	if (a == 'V' && b == 'F') return (&version_flag);
635
    if ( a == 'W' && b == 'D' ) return ( &workdir ) ;
789
	if (a == 'W' && b == 'D') return (&workdir);
636
    if ( a == 'X' && b == 'X' ) return ( &xx_string ) ;
790
	if (a == 'X' && b == 'X') return (&xx_string);
637
    error ( OPTION, "Unknown string identifier, '%c%c'", a, b ) ;
791
	error(OPTION, "Unknown string identifier, '%c%c'", a, b);
638
    return ( null ) ;
792
	return (null);
639
}
-
 
640
 
-
 
641
 
-
 
642
/*
-
 
643
    DUMMY ARGUMENT FOR PROCEDURE
-
 
644
 
-
 
645
    This variable is used to hold any argument passed to one of the procedures
-
 
646
    in lookup_proc.
-
 
647
*/
-
 
648
 
-
 
649
static char *lookup_proc_arg = null ;
-
 
650
 
-
 
651
 
-
 
652
/*
-
 
653
    DUMMY WRAPPER PROCEDURES
-
 
654
 
-
 
655
    These routine(s) are used to call procedures with an argument using
-
 
656
    lookup_proc.
-
 
657
*/
-
 
658
 
-
 
659
static void add_pragma_aux
-
 
660
    PROTO_Z ()
-
 
661
{
-
 
662
    add_pragma ( lookup_proc_arg ) ;
-
 
663
    return ;
-
 
664
}
-
 
665
 
-
 
666
static void add_token_aux
-
 
667
    PROTO_Z ()
-
 
668
{
-
 
669
    add_token ( lookup_proc_arg ) ;
-
 
670
    return ;
-
 
671
}
-
 
672
 
-
 
673
 
-
 
674
/*
-
 
675
    CONVERT A TWO LETTER CODE INTO A PROCEDURE
-
 
676
 
-
 
677
    This routine takes a two letter code, s, and returns a pointer to
-
 
678
    the corresponding procedure.
-
 
679
*/
-
 
680
 
-
 
681
typedef void ( *proc ) PROTO_Z () ;
-
 
682
 
-
 
683
static proc lookup_proc
-
 
684
    PROTO_N ( ( s ) )
-
 
685
    PROTO_T ( char *s )
-
 
686
{
-
 
687
    char a = s [0] ;
-
 
688
    char b = 0 ;
-
 
689
    if ( a ) b = s [1] ;
-
 
690
    if ( a == 'A' && b == 'P' ) return ( add_pragma_aux ) ;
-
 
691
    if ( a == 'A' && b == 'T' ) return ( add_token_aux ) ;
-
 
692
    if ( a == 'F' && b == 'E' ) return ( find_envpath ) ;
-
 
693
    if ( a == 'P' && b == 'V' ) return ( print_version ) ;
-
 
694
    if ( a == 'S' && b == 'E' ) return ( show_envpath ) ;
-
 
695
    if ( a == 'S' && b == 'M' ) return ( set_machine ) ;
-
 
696
    if ( a == 'S' && b == 'P' ) return ( special_option ) ;
-
 
697
    error ( OPTION, "Unknown procedure identifier, '%c%c'", a, b ) ;
-
 
698
    return ( null ) ;
-
 
699
}
793
}
700
 
794
 
701
 
795
 
702
/*
796
/*
703
    RETURN VALUES FOR MATCH_OPTION
797
 * DUMMY ARGUMENT FOR PROCEDURE
-
 
798
 *
-
 
799
 * This variable is used to hold any argument passed to one of the procedures
-
 
800
 * in lookup_proc.
-
 
801
 */
-
 
802
 
-
 
803
static char *lookup_proc_arg = null;
-
 
804
 
-
 
805
 
-
 
806
/*
-
 
807
 * DUMMY WRAPPER PROCEDURES
-
 
808
 *
-
 
809
 * These routine(s) are used to call procedures with an argument using
-
 
810
 * lookup_proc.
-
 
811
 */
-
 
812
 
-
 
813
static void
-
 
814
add_pragma_aux(void)
-
 
815
{
-
 
816
	add_pragma(lookup_proc_arg);
-
 
817
	return;
-
 
818
}
-
 
819
 
-
 
820
static void
-
 
821
add_token_aux(void)
-
 
822
{
-
 
823
	add_token(lookup_proc_arg);
-
 
824
	return;
-
 
825
}
-
 
826
 
-
 
827
 
-
 
828
/*
-
 
829
 * CONVERT A TWO LETTER CODE INTO A PROCEDURE
-
 
830
 *
-
 
831
 * This routine takes a two letter code, s, and returns a pointer to the
-
 
832
 * corresponding procedure.
-
 
833
 */
-
 
834
 
-
 
835
typedef void	(*proc)(void);
-
 
836
 
-
 
837
static proc
-
 
838
lookup_proc(char *s)
-
 
839
{
-
 
840
	char a = s[0];
-
 
841
	char b = 0;
-
 
842
	if (a) {
-
 
843
		b = s[1];
-
 
844
	}
-
 
845
	if (a == 'A' && b == 'P') return (add_pragma_aux);
-
 
846
	if (a == 'A' && b == 'T') return (add_token_aux);
-
 
847
	if (a == 'F' && b == 'E') return (find_envpath);
-
 
848
	if (a == 'P' && b == 'V') return (print_version);
-
 
849
	if (a == 'S' && b == 'E') return (show_envpath);
-
 
850
	if (a == 'S' && b == 'M') return (set_machine);
-
 
851
	if (a == 'S' && b == 'P') return (special_option);
-
 
852
	error(OPTION, "Unknown procedure identifier, '%c%c'", a, b);
-
 
853
	return (null);
-
 
854
}
704
 
855
 
-
 
856
 
-
 
857
/*
-
 
858
 * RETURN VALUES FOR MATCH_OPTION
-
 
859
 *
705
    These values are returned by match_option.  MATCH_OK means that the
860
 * These values are returned by match_option. MATCH_OK means that the option
706
    option matches, MATCH_MORE means that it may match with an additional
861
 * matches, MATCH_MORE means that it may match with an additional option,
707
    option, MATCH_FAILED means it does not match, and the other values
862
 * MATCH_FAILED means it does not match, and the other values indicate errors
708
    indicate errors of some kind.
863
 * of some kind.
709
*/
864
 */
710
 
865
 
711
#define MATCH_OK		0
866
#define MATCH_OK		0
712
#define MATCH_MORE		1
867
#define MATCH_MORE		1
713
#define MATCH_FAILED		2
868
#define MATCH_FAILED		2
714
#define MATCH_IN_ERR		3
869
#define MATCH_IN_ERR		3
715
#define MATCH_OUT_ERR		4
870
#define MATCH_OUT_ERR		4
716
#define MATCH_OPT_ERR		5
871
#define MATCH_OPT_ERR		5
717
 
872
 
718
 
873
 
719
/*
874
/*
720
    MATCH AN OPTION
875
 * MATCH AN OPTION
721
*/
876
 */
722
 
877
 
723
static int match_option
878
static int
724
    PROTO_N ( ( in, out, opt, res ) )
-
 
725
    PROTO_T ( char *in X char *out X char *opt X args_out *res )
879
match_option(char *in, char *out, char *opt, args_out *res)
726
{
880
{
727
    char *p = in ;
881
    char *p = in;
728
    char *q = opt ;
882
    char *q = opt;
729
 
883
 
730
    int i, a, v = 1 ;
884
    int i, a, v = 1;
731
    int go = 1, loop = 1, loopv = -1 ;
885
    int go = 1, loop = 1, loopv = -1;
732
    struct { char *txt ; int len ; } var [ max_var ] ;
886
    struct { char *txt; int len; } var[max_var];
733
 
887
 
734
    /* Process input */
888
    /* Process input */
735
    while ( *p && go ) {
889
    while (*p && go) {
736
	if ( *p == '$' ) {
890
	if (*p == '$') {
737
	    char c = p [1] ;
891
	    char c = p[1];
738
	    if ( c ) {
892
	    if (c) {
739
		int wraps = 0 ;
893
		int wraps = 0;
740
		if ( p [2] == '+' && p [3] == '*' ) {
894
		if (p[2] == '+' && p[3] == '*') {
741
		    /* List of strings with breaks : $c+* */
895
		    /* List of strings with breaks : $c+* */
742
		    wraps = 1 ;
896
		    wraps = 1;
743
		    p++ ;
897
		    p++;
744
		}
898
		}
745
		if ( p [2] == '*' ) {
899
		if (p[2] == '*') {
746
		    /* List of strings : $c* */
900
		    /* List of strings : $c* */
747
		    loop = 0 ;
901
		    loop = 0;
748
		    loopv = v ;
902
		    loopv = v;
749
		    if ( p [3] ) return ( MATCH_IN_ERR ) ;
903
		    if (p[3]) return (MATCH_IN_ERR);
750
		    while ( *q ) {
904
		    while (*q) {
751
			int l = 0 ;
905
			int l = 0;
752
			var [v].txt = q ;
906
			var[v].txt = q;
753
			while ( *q && *q != c ) {
907
			while (*q && *q != c) {
754
			    l++ ;
908
			    l++;
755
			    q++ ;
909
			    q++;
756
			}
910
			}
757
			var [v].len = l ;
911
			var[v].len = l;
758
			if ( *q ) {
912
			if (*q) {
759
			    /* Found c */
913
			    /* Found c */
760
			    q++ ;
914
			    q++;
761
			    if ( *q == 0 && wraps ) return ( MATCH_MORE ) ;
915
			    if (*q == 0 && wraps) return (MATCH_MORE);
762
			}
916
			}
763
			if ( ++v >= max_var ) return ( MATCH_OPT_ERR ) ;
917
			if (++v >= max_var) return (MATCH_OPT_ERR);
764
			loop++ ;
918
			loop++;
765
		    }
919
		    }
766
		    go = 0 ;
920
		    go = 0;
767
		} else {
921
		} else {
768
		    /* Terminated string : $c */
922
		    /* Terminated string : $c */
769
		    int l = 0 ;
923
		    int l = 0;
770
		    var [v].txt = q ;
924
		    var[v].txt = q;
771
		    while ( *q != c ) {
925
		    while (*q != c) {
772
			if ( *q == 0 ) return ( MATCH_FAILED ) ;
926
			if (*q == 0) return (MATCH_FAILED);
773
			l++ ;
927
			l++;
774
			q++ ;
928
			q++;
775
		    }
929
		    }
776
		    var [v].len = l ;
930
		    var[v].len = l;
777
		    if ( ++v >= max_var ) return ( MATCH_OPT_ERR ) ;
931
		    if (++v >= max_var) return (MATCH_OPT_ERR);
778
		}
932
		}
779
	    } else {
933
	    } else {
780
		/* Simple string : $ */
934
		/* Simple string : $ */
781
		int l = ( int ) strlen ( q ) ;
935
		int l = (int)strlen(q);
782
		var [v].txt = q ;
936
		var[v].txt = q;
783
		var [v].len = l ;
937
		var[v].len = l;
784
		if ( ++v >= max_var ) return ( MATCH_OPT_ERR ) ;
938
		if (++v >= max_var) return (MATCH_OPT_ERR);
785
		go = 0 ;
939
		go = 0;
786
	    }
940
	    }
787
	} else if ( *p == '?' ) {
941
	} else if (*p == '?') {
788
	    if ( p [1] == '*' ) {
942
	    if (p[1] == '*') {
789
		/* List of characters : ?* */
943
		/* List of characters : ?* */
790
		if ( p [2] ) return ( MATCH_IN_ERR ) ;
944
		if (p[2]) return (MATCH_IN_ERR);
791
		loop = 0 ;
945
		loop = 0;
792
		loopv = v ;
946
		loopv = v;
793
		while ( *q ) {
947
		while (*q) {
794
		    var [v].txt = q ;
948
		    var[v].txt = q;
795
		    var [v].len = 1 ;
949
		    var[v].len = 1;
796
		    if ( ++v >= max_var ) return ( MATCH_OPT_ERR ) ;
950
		    if (++v >= max_var) return (MATCH_OPT_ERR);
797
		    q++ ;
951
		    q++;
798
		    loop++ ;
952
		    loop++;
799
		}
953
		}
800
		go = 0 ;
954
		go = 0;
801
	    } else {
955
	    } else {
802
		/* Simple character : ? */
956
		/* Simple character : ? */
803
		if ( *q == 0 ) return ( MATCH_FAILED ) ;
957
		if (*q == 0) return (MATCH_FAILED);
804
		var [v].txt = q ;
958
		var[v].txt = q;
805
		var [v].len = 1 ;
959
		var[v].len = 1;
806
		if ( ++v >= max_var ) return ( MATCH_OPT_ERR ) ;
960
		if (++v >= max_var) return (MATCH_OPT_ERR);
807
		q++ ;
961
		q++;
808
	    }
962
	    }
809
	} else if ( *p == '+' ) {
963
	} else if (*p == '+') {
810
	    /* Potential break : + */
964
	    /* Potential break : + */
811
	    if ( *q == 0 ) return ( MATCH_MORE ) ;
965
	    if (*q == 0) return (MATCH_MORE);
812
	} else if ( *p == '^' ) {
966
	} else if (*p == '^') {
813
	    /* Negated letter */
967
	    /* Negated letter */
814
	    p++ ;
968
	    p++;
815
	    if ( *p == 0 ) return ( MATCH_IN_ERR ) ;
969
	    if (*p == 0) return (MATCH_IN_ERR);
816
	    if ( *p == *q ) return ( MATCH_FAILED ) ;
970
	    if (*p == *q) return (MATCH_FAILED);
817
	    q++ ;
971
	    q++;
818
	} else if ( *p == '\\' ) {
972
	} else if (*p == '\\') {
819
	    /* Escaped letter : \c */
973
	    /* Escaped letter : \c */
820
	    p++ ;
974
	    p++;
821
	    if ( *p == 0 ) return ( MATCH_IN_ERR ) ;
975
	    if (*p == 0) return (MATCH_IN_ERR);
822
	    if ( *p != *q ) return ( MATCH_FAILED ) ;
976
	    if (*p != *q) return (MATCH_FAILED);
823
	    q++ ;
977
	    q++;
824
	} else {
978
	} else {
825
	    /* Letter : c */
979
	    /* Letter : c */
826
	    if ( *p != *q ) return ( MATCH_FAILED ) ;
980
	    if (*p != *q) return (MATCH_FAILED);
827
	    q++ ;
981
	    q++;
828
	}
982
	}
829
	p++ ;
983
	p++;
830
    }
984
    }
831
 
985
 
832
    /* Check end of option */
986
    /* Check end of option */
833
    if ( go && *q ) return ( MATCH_FAILED ) ;
987
    if (go && *q) return (MATCH_FAILED);
834
 
988
 
835
    /* The first variable is the whole option */
989
    /* The first variable is the whole option */
836
    var [0].txt = opt ;
990
    var[0].txt = opt;
837
    var [0].len = ( int ) strlen ( opt ) ;
991
    var[0].len = (int)strlen(opt);
838
 
992
 
839
    /* Print output */
993
    /* Print output */
840
    a = 0 ;
994
    a = 0;
841
    for ( i = 0 ; i < loop ; i++ ) {
995
    for (i = 0; i < loop; i++) {
-
 
996
	int count = 0;
842
	char buff [1000] ;
997
	char buff[MAX_LINE];
843
	q = buff ;
998
	q = buff;
844
	for ( p = out ; *p ; p++ ) {
999
	for (p = out; *p && count < MAX_LINE; p++, count++) {
845
	    if ( *p == '$' ) {
1000
	    if (*p == '$') {
846
		/* Variable */
1001
		/* Variable */
847
		int n ;
1002
		int n;
848
		char c = *( ++p ) ;
1003
		char c = *(++p);
849
		if ( c == 's' ) {
1004
		if (c == 's') {
850
		    /* $s expands to a space */
1005
		    /* $s expands to a space */
851
		    *( q++ ) = ' ' ;
1006
		    *(q++) = ' ';
852
		} else if ( c == 'n' ) {
1007
		} else if (c == 'n') {
853
		    /* $n expands to a newline */
1008
		    /* $n expands to a newline */
854
		    *( q++ ) = '\n' ;
1009
		    *(q++) = '\n';
855
		} else if ( c >= '0' && c <= '9' ) {
1010
		} else if (c >= '0' && c <= '9') {
856
		    n = ( c - '0' ) ;
1011
		    n = (c - '0');
857
		    if ( n == loopv ) n += i ;
1012
		    if (n == loopv)n += i;
858
		    if ( n < v ) {
1013
		    if (n < v) {
859
			int l = var [n].len ;
1014
			int l = var[n].len;
860
			IGNORE strncpy ( q, var [n].txt, ( size_t ) l ) ;
1015
			IGNORE strncpy(q, var[n].txt,(size_t)l);
861
			q += l ;
1016
			q += l;
862
		    }
1017
		    }
863
		} else if ( c == 'B' ) {
1018
		} else if (c == 'B') {
864
		    boolean *b = lookup_bool ( p + 1 ) ;
1019
		    boolean *b = lookup_bool(p + 1);
865
		    if ( b == null ) return ( MATCH_OUT_ERR ) ;
1020
		    if (b == null) return (MATCH_OUT_ERR);
866
		    IGNORE sprintf ( q, "%d", ( int ) *b ) ;
1021
		    IGNORE sprintf(q, "%d",(int)*b);
867
		    while ( *q ) q++ ;
1022
		    while (*q)q++;
868
		    p += 2 ;
1023
		    p += 2;
869
		} else if ( c == 'L' ) {
1024
		} else if (c == 'L') {
870
		    list *pt ;
1025
		    list *pt;
871
		    list **sp = lookup_list ( p + 1 ) ;
1026
		    list **sp = lookup_list(p + 1);
872
		    if ( sp == null ) return ( MATCH_OUT_ERR ) ;
1027
		    if (sp == null) return (MATCH_OUT_ERR);
873
		    for ( pt = *sp ; pt ; pt = pt->next ) {
1028
		    for (pt = *sp; pt; pt = pt->next) {
874
			int l = ( int ) strlen ( pt->item ) ;
1029
			int l = (int)strlen(pt->item);
875
			IGNORE strncpy ( q, pt->item, ( size_t ) l ) ;
1030
			IGNORE strncpy(q, pt->item,(size_t)l);
876
			q += l ;
1031
			q += l;
877
			*( q++ ) = ' ' ;
1032
			*(q++) = ' ';
878
		    }
1033
		    }
879
		    p += 2 ;
1034
		    p += 2;
880
		} else if ( c == 'S' ) {
1035
		} else if (c == 'S') {
881
		    int l ;
1036
		    int l;
882
		    char **sp = lookup_string ( p + 1 ) ;
1037
		    char **sp = lookup_string(p + 1);
883
		    if ( sp == null ) return ( MATCH_OUT_ERR ) ;
1038
		    if (sp == null) return (MATCH_OUT_ERR);
884
		    if ( *sp ) {
1039
		    if (*sp) {
885
			l = ( int ) strlen ( *sp ) ;
1040
			l = (int)strlen(*sp);
886
			IGNORE strncpy ( q, *sp, ( size_t ) l ) ;
1041
			IGNORE strncpy(q, *sp,(size_t)l);
887
			q += l ;
1042
			q += l;
888
		    }
1043
		    }
889
		    p += 2 ;
1044
		    p += 2;
890
		} else {
1045
		} else {
891
		    return ( MATCH_OUT_ERR ) ;
1046
		    return (MATCH_OUT_ERR);
892
		}
1047
		}
893
	    } else if ( *p == '|' ) {
1048
	    } else if (*p == '|') {
894
		/* Multiple output */
1049
		/* Multiple output */
895
		*q = 0 ;
1050
		*q = 0;
896
		res->argv [a] = string_copy ( buff ) ;
1051
		res->argv[a] = string_copy(buff);
897
		if ( ++a >= max_var ) return ( MATCH_OPT_ERR ) ;
1052
		if (++a >= max_var) return (MATCH_OPT_ERR);
898
		q = buff ;
1053
		q = buff;
899
	    } else if ( *p == '\\' ) {
1054
	    } else if (*p == '\\') {
900
		/* Escaped output character */
1055
		/* Escaped output character */
901
		if ( *( ++p ) == 0 ) return ( MATCH_OUT_ERR ) ;
1056
		if (*(++p) == 0) return (MATCH_OUT_ERR);
902
		*( q++ ) = *p ;
1057
		*(q++) = *p;
903
	    } else {
1058
	    } else {
904
		/* Simple output character */
1059
		/* Simple output character */
905
		*( q++ ) = *p ;
1060
		*(q++) = *p;
906
	    }
1061
	    }
907
	}
1062
	}
908
	*q = 0 ;
1063
	*q = 0;
909
	res->argv [a] = string_copy ( buff ) ;
1064
	res->argv[a] = string_copy(buff);
910
	if ( ++a >= max_var ) return ( MATCH_OPT_ERR ) ;
1065
	if (++a >= max_var) return (MATCH_OPT_ERR);
911
    }
1066
    }
912
    res->argc = a ;
1067
    res->argc = a;
913
    return ( MATCH_OK ) ;
1068
    return (MATCH_OK);
914
}
1069
}
915
 
1070
 
916
 
1071
 
917
/*
1072
/*
918
    INTERPRET AN OPTION COMMAND
1073
 * INTERPRET AN OPTION COMMAND
919
*/
1074
 */
920
 
1075
 
921
static void interpret_cmd
1076
static void
922
    PROTO_N ( ( cmd ) )
-
 
923
    PROTO_T ( char *cmd )
1077
interpret_cmd(char *cmd)
924
{
1078
{
925
    char c = *cmd ;
1079
    char c = *cmd;
926
 
1080
 
927
    /* Debugging */
1081
    /* Debugging */
928
    if ( debug_options ) error ( OPTION, "Interpreting '%s'", cmd ) ;
1082
    if (debug_options) error(OPTION, "Interpreting '%s'", cmd);
929
 
1083
 
930
    /* Deal with at-hack */
1084
    /* Deal with at-hack */
931
    if ( c == '@' ) {
1085
    if (c == '@') {
932
	char *p = string_copy ( cmd + 1 ), *q ;
1086
	char *p = string_copy(cmd + 1), *q;
933
	for ( q = p ; *q ; q++ ) {
1087
	for (q = p; *q; q++) {
934
	    if ( *q == '@' ) *q = ' ' ;
1088
	    if (*q == '@') *q = ' ';
935
	}
1089
	}
936
	cmd = p ;
1090
	cmd = p;
937
	c = *p ;
1091
	c = *p;
938
    }
1092
    }
939
 
1093
 
940
    /* Deal with empty strings */
1094
    /* Deal with empty strings */
941
    if ( c == 0 ) return ;
1095
    if (c == 0) return;
942
 
1096
 
943
    /* Digits set values */
1097
    /* Digits set values */
944
    if ( c >= '0' && c <= '9' ) {
1098
    if (c >= '0' && c <= '9') {
945
	boolean *b = lookup_bool ( cmd + 1 ) ;
1099
	boolean *b = lookup_bool(cmd + 1);
946
	if ( b == null ) return ;
1100
	if (b == null) return;
947
	*b = ( boolean ) ( c - '0' ) ;
1101
	*b = (boolean)(c - '0');
948
	return ;
1102
	return;
949
    }
1103
    }
950
 
1104
 
951
    /* Translations */
1105
    /* Translations */
952
    if ( c == '>' ) c = 'A' ;
1106
    if (c == '>') c = 'A';
953
    if ( c == '<' ) c = 'B' ;
1107
    if (c == '<') c = 'B';
954
    if ( c == '+' ) c = 'L' ;
1108
    if (c == '+') c = 'L';
955
 
1109
 
956
    /* Deal with list query */
1110
    /* Deal with list query */
957
    if ( c == '?' ) {
1111
    if (c == '?') {
958
	if ( cmd [1] == ':' ) {
1112
	if (cmd[1] == ':') {
959
	    char **sp = lookup_string ( cmd + 2 ) ;
1113
	    char **sp = lookup_string(cmd + 2);
960
	    if ( sp == null ) return ;
1114
	    if (sp == null) return;
961
	    comment ( 1, "%s=\"%s\"\n", cmd + 4, *sp ) ;
1115
	    comment(1, "%s=\"%s\"\n", cmd + 4, *sp);
962
	} else {
1116
	} else {
963
	    list *p ;
1117
	    list *p;
964
	    list **sp = lookup_list ( cmd + 1 ) ;
1118
	    list **sp = lookup_list(cmd + 1);
965
	    if ( sp == null ) return ;
1119
	    if (sp == null) return;
966
	    comment ( 1, "%s=\"", cmd + 3 ) ;
1120
	    comment(1, "%s=\"", cmd + 3);
967
	    for ( p = *sp ; p != null ; p = p->next ) {
1121
	    for (p = *sp; p != null; p = p->next) {
968
		comment ( 1, "%s", p->item ) ;
1122
		comment(1, "%s", p->item);
969
		if ( p->next ) comment ( 1, " " ) ;
1123
		if (p->next)comment(1, " ");
970
	    }
1124
	    }
971
	    comment ( 1, "\"\n" ) ;
1125
	    comment(1, "\"\n");
972
	}
1126
	}
973
	return ;
1127
	return;
974
    }
1128
    }
975
 
1129
 
976
    /* Deal with equivalences */
1130
    /* Deal with equivalences */
977
    if ( c == '=' ) {
1131
    if (c == '=') {
978
	list *p = make_list ( cmd + 1 ) ;
1132
	list *p = make_list(cmd + 1);
979
	process_options ( p, main_optmap ) ;
1133
	process_options(p, main_optmap, 1);
980
	free_list ( p ) ;
1134
	free_list(p);
981
	return ;
1135
	return;
982
    }
1136
    }
983
 
1137
 
984
    /* Deal with primitives */
1138
    /* Deal with primitives */
985
    switch ( c ) {
1139
    switch (c) {
986
 
-
 
987
	case 'A' : {
1140
	case 'A': {
988
	    /* Change list */
1141
	    /* Change list */
989
	    list **sp = lookup_list ( cmd + 1 ) ;
1142
	    list **sp = lookup_list(cmd + 1);
990
	    if ( sp == null ) return ;
1143
	    if (sp == null) {
-
 
1144
		    return;
-
 
1145
	    }
991
	    *sp = add_list ( *sp, make_list ( cmd + 3 ) ) ;
1146
	    *sp = add_list(*sp, make_list(cmd + 3));
992
	    return ;
1147
	    return;
993
	}
1148
	}
994
 
-
 
995
	case 'B' : {
1149
	case 'B': {
996
	    /* Change list */
1150
	    /* Change list */
997
	    list **sp = lookup_list ( cmd + 1 ) ;
1151
	    list **sp = lookup_list(cmd + 1);
998
	    if ( sp == null ) return ;
1152
	    if (sp == null) {
-
 
1153
		    return;
-
 
1154
	    }
999
	    *sp = add_list ( make_list ( cmd + 3 ), *sp ) ;
1155
	    *sp = add_list(make_list(cmd + 3), *sp);
1000
	    return ;
1156
	    return;
1001
	}
1157
	}
1002
 
-
 
1003
	case 'L' : {
1158
	case 'L': {
1004
	    /* Change list */
1159
	    /* Change list */
1005
	    list **sp = lookup_list ( cmd + 1 ) ;
1160
	    list **sp = lookup_list(cmd + 1);
1006
	    if ( sp == null ) return ;
1161
	    if (sp == null) {
-
 
1162
		    return;
-
 
1163
	    }
1007
	    free_list ( *sp ) ;
1164
	    free_list(*sp);
1008
	    *sp = make_list ( cmd + 3 ) ;
1165
	    *sp = make_list(cmd + 3);
1009
	    return ;
1166
	    return;
1010
	}
1167
	}
1011
 
-
 
1012
	case 'C' : {
1168
	case 'C': {
1013
	    /* Call */
1169
	    /* Call */
1014
	    proc p = lookup_proc ( cmd + 1 ) ;
1170
	    proc p = lookup_proc(cmd + 1);
1015
	    if ( p == null ) return ;
1171
	    if (p == null) {
-
 
1172
		    return;
-
 
1173
	    }
1016
	    if ( cmd [3] == ':' ) {
1174
	    if (cmd[3] == ':') {
1017
		lookup_proc_arg = cmd + 4 ;
1175
		lookup_proc_arg = cmd + 4;
1018
	    } else {
1176
	    } else {
1019
		lookup_proc_arg = null ;
1177
		lookup_proc_arg = null;
1020
	    }
1178
	    }
1021
	    ( *p ) () ;
1179
	    (*p)();
1022
	    return ;
1180
	    return;
1023
	}
1181
	}
1024
 
-
 
1025
	case 'D' : {
1182
	case 'D':
1026
	    /* Startup options */
1183
	    /* Startup options */
1027
	    add_to_startup ( cmd + 1 ) ;
1184
	    add_to_startup(cmd + 1);
1028
	    return ;
1185
	    return;
-
 
1186
	case 'E': {
-
 
1187
            /* Environment */
-
 
1188
            if (*(cmd + 1) == '?') {
-
 
1189
		char var[MAX_LINE];
-
 
1190
		char val[MAX_LINE];
-
 
1191
		int  count;
-
 
1192
		char *p, *q, *r;
-
 
1193
		char c1;
-
 
1194
		char **subs;
-
 
1195
		int i;
-
 
1196
#if FS_STAT
-
 
1197
		struct stat sb;
-
 
1198
#endif
-
 
1199
		q = var;
-
 
1200
		r = val;
-
 
1201
		p = cmd + 2;
-
 
1202
		count = 0;
-
 
1203
		while ((c1 = *p++) != '?') {
-
 
1204
		        *q++ = c1;
-
 
1205
		}
-
 
1206
		*q++='\0';
-
 
1207
 
-
 
1208
		while ((c1 = *p++) != NULL) {
-
 
1209
		    *r++ = c1;
-
 
1210
		    /*
-
 
1211
		     * Only the value is user supplied and needs bounds
-
 
1212
		     * checking.
-
 
1213
		     */
-
 
1214
		    if (++count >= MAX_LINE){
-
 
1215
			error(FATAL,
-
 
1216
			       "Exceeded maximum buffer length in -y argument\n");
-
 
1217
		    }
-
 
1218
		}
-
 
1219
 
-
 
1220
		*r++ ='\0';
-
 
1221
		/*
-
 
1222
		 * Additional error checking for those platforms supporting
-
 
1223
		 * stat().
-
 
1224
		 */
-
 
1225
#if FS_STAT
-
 
1226
		if (stat(val, &sb) == -1) {
-
 
1227
		    error(SERIOUS, "interpret_cmd: %s %s",
-
 
1228
			val, strerror(errno));
-
 
1229
		}
-
 
1230
#endif
-
 
1231
		i = 0;
-
 
1232
		subs = PATH_SUBS;
-
 
1233
		while (*subs) {
-
 
1234
		    if (!strcmp(*subs, var)) {
-
 
1235
			env_paths[i] = string_copy(val);
-
 
1236
			break;
-
 
1237
		    }
-
 
1238
		    i++;
-
 
1239
		    subs++;
-
 
1240
		}
-
 
1241
		if (!*subs)
-
 
1242
		    error(WARNING,
-
 
1243
			  "Ignoring non-standard env assignment: %s=%s", var,
-
 
1244
			  val);
-
 
1245
	    } else {
-
 
1246
		read_env(cmd + 1);
-
 
1247
            }
-
 
1248
            return;
1029
	}
1249
	}
1030
 
-
 
1031
	case 'E' : {
-
 
1032
	    /* Environment */
-
 
1033
	    read_env ( cmd + 1 ) ;
-
 
1034
	    return ;
-
 
1035
	}
-
 
1036
 
-
 
1037
	case 'F' : {
1250
	case 'F':
1038
	    /* Endup options */
1251
	    /* Endup options */
1039
	    add_to_endup ( cmd + 1 ) ;
1252
	    add_to_endup(cmd + 1);
1040
	    return ;
1253
	    return;
1041
	}
-
 
1042
 
-
 
1043
	case 'H' : {
1254
	case 'H': {
1044
	    /* Halt */
1255
	    /* Halt */
1045
	    char stage = cmd [1] ;
1256
	    char stage = cmd[1];
1046
	    set_stage ( find_type ( stage, 0 ), STOP_STAGE ) ;
1257
	    set_stage(find_type(stage, 0), STOP_STAGE);
1047
	    return ;
1258
	    return;
1048
	}
1259
	}
1049
 
-
 
1050
	case 'I' : {
1260
	case 'I': {
1051
	    /* Input file */
1261
	    /* Input file */
1052
	    int t ;
1262
	    int t;
1053
	    filename *f ;
1263
	    filename *f;
1054
	    char stage = cmd [1] ;
1264
	    char stage = cmd[1];
1055
	    char *name = cmd + 2 ;
1265
	    char *name = cmd + 2;
1056
	    if ( stage == '?' ) {
1266
	    if (stage == '?') {
1057
		t = UNKNOWN_TYPE ;
1267
		t = UNKNOWN_TYPE;
1058
	    } else {
1268
	    } else {
1059
		t = find_type ( stage, 0 ) ;
1269
		t = find_type(stage, 0);
1060
	    }
1270
	    }
1061
	    f = find_filename ( name, t ) ;
1271
	    f = find_filename(name, t);
1062
	    input_files = add_filename ( input_files, f ) ;
1272
	    input_files = add_filename(input_files, f);
1063
	    return ;
1273
	    return;
1064
	}
1274
	}
1065
 
-
 
1066
	case 'K' : {
1275
	case 'K': {
1067
	    /* Keep */
1276
	    /* Keep */
1068
	    static int k = KEEP_STAGE ;
1277
	    static int k = KEEP_STAGE;
1069
	    char stage = cmd [1] ;
1278
	    char stage = cmd[1];
1070
	    if ( stage == '-' ) {
1279
	    if (stage == '-') {
1071
		k = DONT_KEEP_STAGE ;
1280
		k = DONT_KEEP_STAGE;
1072
	    } else {
1281
	    } else {
1073
		set_stage ( find_type ( stage, 0 ), k ) ;
1282
		set_stage(find_type(stage, 0), k);
1074
		k = KEEP_STAGE ;
1283
		k = KEEP_STAGE;
1075
	    }
1284
	    }
1076
	    return ;
1285
	    return;
1077
	}
1286
	}
1078
 
-
 
1079
	case 'Q' : {
1287
	case 'Q': {
1080
	    /* Query */
1288
	    /* Query */
1081
	    char *s ;
1289
	    char *s;
1082
	    optmap *t = main_optmap ;
1290
	    optmap *t = main_optmap;
1083
	    error ( INFO, "List of recognised options" ) ;
1291
	    error(INFO, "List of recognised options");
1084
	    while ( s = t->in, s != null ) {
1292
	    while (s = t->in, s != null) {
1085
		if ( *s == '-' ) {
1293
		if (*s == '-') {
1086
		    char d ;
1294
		    char d;
1087
		    comment ( 0, " " ) ;
1295
		    comment(0, " ");
1088
		    while ( d = *( s++ ), d != 0 ) {
1296
		    while (d = *(s++), d != 0) {
1089
			switch ( d ) {
1297
			switch (d) {
1090
			    case '$' : {
1298
			    case '$':
1091
				IGNORE fputs ( "<string>", stderr ) ;
1299
				IGNORE fputs("<string>", stderr);
1092
				break ;
1300
				break;
1093
			    }
-
 
1094
			    case '?' : {
1301
			    case '?':
1095
				IGNORE fputs ( "<letter>", stderr ) ;
1302
				IGNORE fputs("<letter>", stderr);
1096
				break ;
1303
				break;
1097
			    }
-
 
1098
			    case '*' : {
1304
			    case '*':
1099
				IGNORE fputs ( "...", stderr ) ;
1305
				IGNORE fputs("...", stderr);
1100
				break ;
1306
				break;
1101
			    }
-
 
1102
			    case '+' : {
1307
			    case '+':
1103
				IGNORE fputc ( ' ', stderr ) ;
1308
				IGNORE fputc(' ', stderr);
1104
				break ;
1309
				break;
1105
			    }
-
 
1106
			    case '\\' : {
1310
			    case '\\':
1107
				IGNORE fputc ( *( s++ ), stderr ) ;
1311
				IGNORE fputc(*(s++), stderr);
1108
				break ;
1312
				break;
1109
			    }
-
 
1110
			    default : {
1313
			    default:
1111
				IGNORE fputc ( d, stderr ) ;
1314
				IGNORE fputc(d, stderr);
1112
				break ;
1315
				break;
1113
			    }
-
 
1114
			}
1316
			}
1115
		    }
1317
		    }
1116
		    s = t->explain ;
1318
		    s = t->explain;
-
 
1319
		    if (s == null) {
1117
		    if ( s == null ) s = "not documented" ;
1320
			    s = "not documented";
-
 
1321
		    }
1118
		    comment ( 0, " : " ) ;
1322
		    comment(0, " : ");
1119
		    comment ( 0, s, progname ) ;
1323
		    comment(0, s, progname);
1120
		    comment ( 0, ".\n" ) ;
1324
		    comment(0, ".\n");
-
 
1325
		}
-
 
1326
		t++;
-
 
1327
	    }
-
 
1328
	    return;
-
 
1329
	}
-
 
1330
	case 'S': {
-
 
1331
	    /* String */
-
 
1332
	    char **s = lookup_string(cmd + 1);
-
 
1333
	    if (s == null) {
-
 
1334
		    return;
-
 
1335
	    }
-
 
1336
	    *s = cmd + 3;
-
 
1337
	    return;
-
 
1338
	}
-
 
1339
	case 'V':
-
 
1340
	    if (cmd[1] == 'B') {
-
 
1341
		boolean *b = lookup_bool(cmd + 2);
-
 
1342
		if (b == null) {
-
 
1343
			return;
1121
		}
1344
		}
1122
		t++ ;
-
 
1123
	    }
-
 
1124
	    return ;
-
 
1125
	}
-
 
1126
 
-
 
1127
	case 'S' : {
-
 
1128
	    /* String */
-
 
1129
	    char **s = lookup_string ( cmd + 1 ) ;
-
 
1130
	    if ( s == null ) return ;
-
 
1131
	    *s = cmd + 3 ;
-
 
1132
	    return ;
-
 
1133
	}
-
 
1134
 
-
 
1135
	case 'V' : {
-
 
1136
	    if ( cmd [1] == 'B' ) {
-
 
1137
		boolean *b = lookup_bool ( cmd + 2 ) ;
-
 
1138
		if ( b == null ) return ;
-
 
1139
		comment ( 1, "%c%c = %d\n", cmd [2], cmd [3], *b ) ;
1345
		comment(1, "%c%c = %d\n", cmd[2], cmd[3], *b);
1140
		return ;
1346
		return;
1141
	    } else if ( cmd [1] == 'L' ) {
1347
	    } else if (cmd[1] == 'L') {
1142
		list **sp = lookup_list ( cmd + 2 ), *pt ;
1348
		list **sp = lookup_list(cmd + 2), *pt;
1143
		if ( sp == null ) return ;
1349
		if (sp == null) {
-
 
1350
			return;
-
 
1351
		}
1144
		comment ( 1, "%c%c =", cmd [2], cmd [3] ) ;
1352
		comment(1, "%c%c =", cmd[2], cmd[3]);
1145
		for ( pt = *sp ; pt != null ; pt = pt->next ) {
1353
		for (pt = *sp; pt != null; pt = pt->next) {
1146
		    if ( pt->item ) {
1354
		    if (pt->item) {
1147
			comment ( 1, " %s", pt->item ) ;
1355
			comment(1, " %s", pt->item);
1148
		    } else {
1356
		    } else {
1149
			comment ( 1, " (null)" ) ;
1357
			comment(1, " (null)");
1150
		    }
1358
		    }
1151
		}
1359
		}
1152
		comment ( 1, "\n" ) ;
1360
		comment(1, "\n");
1153
		return ;
1361
		return;
1154
	    } else if ( cmd [1] == 'S' ) {
1362
	    } else if (cmd[1] == 'S') {
1155
		char **s = lookup_string ( cmd + 2 ) ;
1363
		char **s = lookup_string(cmd + 2);
1156
		if ( s == null ) return ;
1364
		if (s == null) {
-
 
1365
			return;
-
 
1366
		}
1157
		if ( *s ) {
1367
		if (*s) {
1158
		    comment ( 1, "%c%c = %s\n", cmd [2], cmd [3], *s ) ;
1368
		    comment(1, "%c%c = %s\n", cmd[2], cmd[3], *s);
1159
		} else {
1369
		} else {
1160
		    comment ( 1, "%c%c = (null)\n", cmd [2], cmd [3] ) ;
1370
		    comment(1, "%c%c = (null)\n", cmd[2], cmd[3]);
1161
		}
1371
		}
1162
		return ;
1372
		return;
1163
	    }
1373
	    }
1164
	    break ;
1374
	    break;
1165
	}
-
 
1166
 
-
 
1167
	case 'X' : {
1375
	case 'X':
1168
	    /* Error */
1376
	    /* Error */
1169
	    error ( WARNING, "%s", cmd + 1 ) ;
1377
	    error(WARNING, "%s", cmd + 1);
1170
	    return ;
1378
	    return;
1171
	}
-
 
1172
    }
1379
    }
1173
    error ( OPTION, "Syntax error, '%s'", cmd ) ;
1380
    error(OPTION, "Syntax error, '%s'", cmd);
1174
    return ;
1381
    return;
1175
}
1382
}
1176
 
1383
 
1177
 
1384
 
1178
/*
1385
/*
1179
    PROCESS A LIST OF OPTIONS
1386
 * PROCESS A LIST OF OPTIONS
-
 
1387
 *
-
 
1388
 * This routine processes a list of options, opt, using the options from table
-
 
1389
 * tab.
-
 
1390
 */
1180
 
1391
 
1181
    This routine processes a list of options, opt, using the options
-
 
1182
    from table tab.
-
 
1183
*/
1392
void
1184
 
-
 
1185
void process_options
-
 
1186
    PROTO_N ( ( opt, tab ) )
-
 
1187
    PROTO_T ( list *opt X optmap *tab )
1393
process_options(list *opt, optmap *tab, int fast)
1188
{
1394
{
1189
    optmap *t ;
1395
	optmap *t;
1190
    list *p = opt ;
1396
	list *p = opt;
-
 
1397
	list *accum = null;
1191
    char *arg = null ;
1398
	char *arg = null;
1192
    int status = MATCH_OK ;
1399
	int status = MATCH_OK;
-
 
1400
	int a;
1193
 
1401
 
1194
    /* Scan through the options */
1402
	/* Scan through the options */
1195
    while ( p != null ) {
1403
	while (p != null) {
1196
	if ( status == MATCH_MORE ) {
1404
		if (status == MATCH_MORE) {
1197
	    arg = string_concat ( arg, p->item ) ;
1405
			arg = string_concat(arg, p->item);
1198
	} else {
1406
		} else {
1199
	    arg = p->item ;
1407
			arg = p->item;
1200
	}
1408
		}
1201
	status = MATCH_FAILED ;
1409
		status = MATCH_FAILED;
1202
	for ( t = tab ; t->in != null ; t++ ) {
1410
		for (t = tab; t->in != null; t++) {
1203
	    args_out res ;
1411
			args_out res;
1204
	    status = match_option ( t->in, t->out, arg, &res ) ;
1412
			status = match_option(t->in, t->out, arg, &res);
1205
	    switch ( status ) {
1413
			switch (status) {
1206
		case MATCH_OK : {
1414
			case MATCH_OK:
1207
		    /* Complete option - interpret result */
1415
				/* Complete option - interpret result */
1208
		    int a ;
1416
				for (a = 0; a < res.argc; a++) {
1209
		    for ( a = 0 ; a < res.argc ; a++ ) {
1417
					if (no_shuffle != 0 || fast == 1) {
1210
			interpret_cmd ( res.argv [a] ) ;
1418
						interpret_cmd(res.argv[a]);
1211
		    }
1419
					} else {
-
 
1420
						ordered_node *dn =
1212
		    goto end_search ;
1421
						    (ordered_node *)
-
 
1422
						    xalloc(sizeof(ordered_node));
-
 
1423
						dn->rank = t->rank;
-
 
1424
						dn->cmd  = res.argv[a];
-
 
1425
						accum = insert_inorder(dn,
-
 
1426
								       accum);
-
 
1427
					}
1213
		}
1428
				}
-
 
1429
				goto end_search;
1214
		case MATCH_MORE : {
1430
			case MATCH_MORE:
1215
		    /* Incomplete option - move on to next option */
1431
				/* Incomplete option - move on to next option */
1216
		    goto end_search ;
1432
				goto end_search;
1217
		}
-
 
1218
		case MATCH_FAILED : {
1433
			case MATCH_FAILED:
1219
		    /* Try again */
1434
				/* Try again */
1220
		    break ;
1435
				break;
1221
		}
-
 
1222
		case MATCH_IN_ERR : {
1436
			case MATCH_IN_ERR:
1223
		    /* Error in optmap input */
1437
				/* Error in optmap input */
1224
		    error ( OPTION, "Illegal input '%s'", t->in ) ;
1438
				error(OPTION, "Illegal input '%s'", t->in);
1225
		    status = MATCH_FAILED ;
1439
				status = MATCH_FAILED;
1226
		    break ;
1440
				break;
1227
		}
-
 
1228
		case MATCH_OUT_ERR : {
1441
			case MATCH_OUT_ERR:
1229
		    /* Error in optmap output */
1442
				/* Error in optmap output */
1230
		    error ( OPTION, "Illegal option '%s'", t->out ) ;
1443
				error(OPTION, "Illegal option '%s'", t->out);
1231
		    status = MATCH_FAILED ;
1444
				status = MATCH_FAILED;
1232
		    break ;
1445
				break;
1233
		}
-
 
1234
		case MATCH_OPT_ERR : {
1446
			case MATCH_OPT_ERR:
1235
		    /* Ran out of space for result */
1447
				/* Ran out of space for result */
1236
		    error ( OPTION, "Too many components, '%s'", arg ) ;
1448
				error(OPTION, "Too many components, '%s'", arg);
1237
		    status = MATCH_FAILED ;
1449
				status = MATCH_FAILED;
1238
		    break ;
1450
				break;
-
 
1451
			}
-
 
1452
		}
-
 
1453
		error(OPTION, "Can't interpret '%s'", arg);
-
 
1454
end_search:
-
 
1455
		p = p->next;
-
 
1456
	}
-
 
1457
 
-
 
1458
	/* Check for incomplete options */
-
 
1459
	if (status == MATCH_MORE) {
-
 
1460
		error(WARNING, "Option '%s' is incomplete", arg);
-
 
1461
	}
-
 
1462
 
-
 
1463
	/* if the no_shuffle flag is unset, we have order cmds to run */
-
 
1464
	if (no_shuffle == 0 && fast == 0) {
-
 
1465
		while (accum) {
-
 
1466
			ordered_node* dn;
-
 
1467
			dn = accum->item;
-
 
1468
			interpret_cmd (dn->cmd);
-
 
1469
			accum = accum->next;
1239
		}
1470
		}
1240
	    }
-
 
1241
	}
1471
	}
1242
	error ( OPTION, "Can't interpret '%s'", arg ) ;
-
 
1243
	end_search : p = p->next ;
-
 
1244
    }
-
 
1245
 
-
 
1246
    /* Check for incomplete options */
-
 
1247
    if ( status == MATCH_MORE ) {
-
 
1248
	error ( WARNING, "Option '%s' is incomplete", arg ) ;
-
 
1249
    }
-
 
1250
 
1472
 
1251
    return ;
1473
	return;
1252
}
1474
}