Annotation of GNUtools/cctools/as/driver.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The assembler driver that lives in /bin/as and runs the assembler for the
                      3:  * "-arch <arch_flag>" (if given) in /lib/<arch_flag>/as or in
                      4:  * /usr/local/lib/<arch_flag>/as.  Or runs the assembler for the host
                      5:  * architecture as returned by get_arch_from_host().  The driver only checks
                      6:  * to make sure their are not multiple arch_flags and then passes all flags to
                      7:  * the assembler it will run.
                      8:  */
                      9: #include "stdio.h"
                     10: #include "stdlib.h"
                     11: #include "string.h"
                     12: #include "libc.h"
                     13: #include <sys/file.h>
                     14: #include <mach/mach.h>
                     15: #include "stuff/arch.h"
                     16: #include "stuff/errors.h"
                     17: #include "stuff/execute.h"
                     18: #include "stuff/allocate.h"
                     19: 
                     20: /* used by error calls (exported) */
                     21: char *progname = NULL;
                     22: 
                     23: void
                     24: main(
                     25: int argc,
                     26: char **argv,
                     27: char **envp)
                     28: {
                     29:     const char *LIB = "/lib/";
                     30:     const char *LOCALLIB = "/usr/local/lib/";
                     31:     const char *AS = "/as";
                     32: 
                     33:     unsigned long i, count, verbose;
                     34:     char *p, c, *arch_name, *as, *as_local;
                     35:     struct arch_flag arch_flag;
                     36:     const struct arch_flag *arch_flags, *family_arch_flag;
                     37: 
                     38:        progname = argv[0];
                     39:        arch_name = NULL;
                     40:        verbose = 0;
                     41:        /*
                     42:         * Process the assembler flags exactly like the assembler would (except
                     43:         * let the assembler complain about multiple flags, bad combinations of
                     44:         * flags, unknown single letter flags and the like).  The main thing
                     45:         * here is to parse out the "-arch <arch_flag>" and to do so the
                     46:         * multiple argument and multiple character flags need to be known how
                     47:         * to be stepped over correctly.
                     48:         */
                     49:        for(i = 1; i < argc; i++){
                     50:            /*
                     51:             * The assembler flags start with '-' except that "--" is recognized
                     52:             * as assemble from stdin and that flag "--" is not allowed to be
                     53:             * grouped with other flags (so "-a-" is not the same as "-a --").
                     54:             */
                     55:            if(argv[i][0] == '-' &&
                     56:               !(argv[i][1] == '-' && argv[i][2] == '0')){
                     57:                /*
                     58:                 * the assembler allows single letter flags to be grouped
                     59:                 * together so "-abc" is the same as "-a -b -c".  So that
                     60:                 * logic must be followed here.
                     61:                 */
                     62:                for(p = &(argv[i][1]); (c = *p); p++){
                     63:                    /*
                     64:                     * The assembler simply ignores the high bit of flag
                     65:                     * characters and not treat them as different characters
                     66:                     * as they are (but the argument following the flag
                     67:                     * character is not treated this way).  So it's done
                     68:                     * here as well to match it.
                     69:                     */
                     70:                    c &= 0x7F;
                     71:                    switch(c){
                     72:                    /*
                     73:                     * Flags that take a single argument.  The argument is the
                     74:                     * rest of the current argument if there is any or the it is
                     75:                     * the next argument.  Again errors like missing arguments
                     76:                     * are not handled here but left to the assembler.
                     77:                     */
                     78:                    case 'o':   /* -o name */
                     79:                    case 'I':   /* -I directory */
                     80:                    case 'm':   /* -mc68000, -mc68010 and mc68020 */
                     81:                    case 'N':   /* -NEXTSTEP-deployment-target */
                     82:                        if(p[1] == '\0')
                     83:                            i++;
                     84:                        break;
                     85: 
                     86:                    case 'a':
                     87:                        if(strcmp(p, "arch") == 0){
                     88:                            if(i + 1 >= argc)
                     89:                                fatal("missing argument to %s option", argv[i]);
                     90:                            if(arch_name != NULL)
                     91:                                fatal("more than one %s option (not allowed, "
                     92:                                      "use cc(1) instead)", argv[i]);
                     93:                            arch_name = argv[i+1];
                     94:                            break;
                     95:                        }
                     96:                        /* fall through for non "-arch" */
                     97:                    case 'f':
                     98:                    case 'k':
                     99:                    case 'g':
                    100:                    case 'v':
                    101:                    case 'W':
                    102:                    case 'L':
                    103:                    case 'l':
                    104:                    default:
                    105:                        /* just recognize it, do nothing */
                    106:                        break;
                    107:                    case 'V':
                    108:                        verbose = 1;
                    109:                        break;
                    110:                    }
                    111:                }
                    112:            }
                    113:        }
                    114: 
                    115:        /*
                    116:         * Construct the name of the assembler to run from the given -arch
                    117:         * <arch_flag> or if none then from the value returned from
                    118:         * get_arch_from_host().
                    119:         */
                    120:        if(arch_name == NULL){
                    121:            if(get_arch_from_host(&arch_flag, NULL))
                    122:                arch_name = arch_flag.name;
                    123:            else
                    124:                fatal("known host architecture (can't determine which assembler"
                    125:                      " to run)");
                    126:        }
                    127:        else{
                    128:            /*
                    129:             * Convert a possible machine specific architecture name to a
                    130:             * family name to base the name of the assembler to run.
                    131:             */
                    132:            if(get_arch_from_flag(arch_name, &arch_flag) != 0){
                    133:                family_arch_flag =
                    134:                        get_arch_family_from_cputype(arch_flag.cputype);
                    135:                if(family_arch_flag != NULL)
                    136:                    arch_name = (char *)(family_arch_flag->name);
                    137:            }
                    138: 
                    139:        }
                    140:        as = makestr(LIB, arch_name, AS, NULL);
                    141: 
                    142:        /*
                    143:         * If this assembler exist try to run it else print an error message.
                    144:         */
                    145:        if(access(as, F_OK) == 0){
                    146:            argv[0] = as;
                    147:            if(execute(argv, verbose))
                    148:                exit(0);
                    149:            else
                    150:                exit(1);
                    151:        }
                    152:        as_local = makestr(LOCALLIB, arch_name, AS, NULL);
                    153:        if(access(as_local, F_OK) == 0){
                    154:            argv[0] = as_local;
                    155:            if(execute(argv, verbose))
                    156:                exit(0);
                    157:            else
                    158:                exit(1);
                    159:        }
                    160:        else{
                    161:            printf("%s: assembler (%s or %s) for architecture %s not "
                    162:                   "installed\n", progname, as, as_local, arch_name);
                    163:            arch_flags = get_arch_flags();
                    164:            count = 0;
                    165:            for(i = 0; arch_flags[i].name != NULL; i++){
                    166:                as = makestr(LIB, arch_flags[i].name, AS, NULL);
                    167:                if(access(as, F_OK) == 0){
                    168:                    if(count == 0)
                    169:                        printf("Installed assemblers are:\n");
                    170:                    printf("%s for architecture %s\n", as, arch_flags[i].name);
                    171:                    count++;
                    172:                }
                    173:                else{
                    174:                    as_local = makestr(LOCALLIB, arch_flags[i].name, AS, NULL);
                    175:                    if(access(as_local, F_OK) == 0){
                    176:                        if(count == 0)
                    177:                            printf("Installed assemblers are:\n");
                    178:                        printf("%s for architecture %s\n", as_local,
                    179:                               arch_flags[i].name);
                    180:                        count++;
                    181:                    }
                    182:                }
                    183:            }
                    184:            if(count == 0)
                    185:                printf("%s: no assemblers installed\n", progname);
                    186:            exit(1);
                    187:        }
                    188: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.