Annotation of GNUtools/cctools/as/driver.c, revision 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.