root/drivers/scsi/aic7xxx_asm.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. error
  2. Malloc
  3. Realloc
  4. Strdup
  5. define
  6. lookup
  7. patch
  8. backpatch
  9. output
  10. getl
  11. eval_operand
  12. eval_sdi
  13. eval_addr
  14. crack
  15. assemble
  16. main

   1 /*+M*************************************************************************
   2  * Adaptec AIC7770/AIC7870 sequencer code assembler.
   3  *
   4  * Copyright (c) 1994 John Aycock
   5  *   The University of Calgary Department of Computer Science.
   6  *
   7  * This program is free software; you can redistribute it and/or modify
   8  * it under the terms of the GNU General Public License as published by
   9  * the Free Software Foundation; either version 2, or (at your option)
  10  * any later version.
  11  *
  12  * This program is distributed in the hope that it will be useful,
  13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  * GNU General Public License for more details.
  16  *
  17  * You should have received a copy of the GNU General Public License
  18  * along with this program; see the file COPYING.  If not, write to
  19  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20  *
  21  * Comments are started by `#' and continue to the end of the line; lines
  22  * may be of the form:
  23  *      <label>*
  24  *      <label>*  <undef-sym> = <value>
  25  *      <label>*  <opcode> <operand>*
  26  *
  27  * A <label> is an <undef-sym> ending in a colon.  Spaces, tabs, and commas
  28  * are token separators.
  29  *-M*************************************************************************/
  30 static const char id[] = "$Id: aic7xxx_asm.c,v 2.4 1996/01/30 07:17:29 deang Exp $";
  31 #include <ctype.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <stdlib.h>
  35 #include <unistd.h>
  36 #include <fcntl.h>
  37 
  38 #define MEMORY          448
  39 #define MAXLINE         1024
  40 #define MAXTOKEN        32
  41 #define ADOTOUT         "a.out"
  42 #define NOVALUE         -1
  43 
  44 #ifndef TRUE
  45 #  define TRUE 1
  46 #endif
  47 #ifndef FALSE
  48 #  define FALSE 0
  49 #endif
  50 #define MAX_ARGS        16
  51 static const char *cpp[] = {
  52   "/lib/cpp -P - -",
  53   "/usr/lib/cpp -P - -",
  54   "/usr/bin/cpp -P - -",
  55   "/usr/bin/gcc -E -P -",
  56   "/usr/bin/cc -E -P -"
  57 };
  58 
  59 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
  60 
  61 /*
  62  * AIC-7770/AIC-7870 register definitions
  63  */
  64 #define R_SINDEX        0x65
  65 #define R_ALLONES       0x69
  66 #define R_ALLZEROS      0x6a
  67 #define R_NONE          0x6a
  68 
  69 int debug;
  70 int lineno, LC;
  71 char *filename;
  72 unsigned char M[MEMORY][4];
  73 
  74 void 
  75 error(const char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
  76 {
  77         fprintf(stderr, "%s: %s at line %d\n", filename, s, lineno);
  78         exit(EXIT_FAILURE);
  79 }
  80 
  81 void *
  82 Malloc(size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84         void *p = malloc(size);
  85         if (!p)
  86                 error("out of memory");
  87         return(p);
  88 }
  89 
  90 void *
  91 Realloc(void *ptr, size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         void *p = realloc(ptr, size);
  94         if (!p)
  95                 error("out of memory");
  96         return(p);
  97 }
  98 
  99 char *
 100 Strdup(char *s)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         char *p = (char *)Malloc(strlen(s) + 1);
 103         strcpy(p, s);
 104         return(p);
 105 }
 106 
 107 typedef struct sym_t {
 108         struct sym_t    *next;          /* MUST BE FIRST */
 109         char            *name;
 110         int             value;
 111         int             npatch; 
 112         int             *patch;
 113 } sym_t;
 114 
 115 sym_t *head;
 116 
 117 void
 118 define(char *name, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120         sym_t *p, *q;
 121 
 122         for (p = head, q = (sym_t *)&head; p; p = p->next) {
 123                 if (!strcmp(p->name, name))
 124                         error("redefined symbol");
 125                 q = p;
 126         }
 127 
 128         p = q->next = (sym_t *)Malloc(sizeof(sym_t));
 129         p->next = NULL;
 130         p->name = Strdup(name);
 131         p->value = value;
 132         p->npatch = 0;
 133         p->patch = NULL;
 134 
 135         if (debug) {
 136                 fprintf(stderr, "\"%s\" ", p->name);
 137                 if (p->value != NOVALUE)
 138                         fprintf(stderr, "defined as 0x%x\n", p->value);
 139                 else
 140                         fprintf(stderr, "undefined\n");
 141         }
 142 }
 143 
 144 sym_t *
 145 lookup(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147         sym_t *p;
 148 
 149         for (p = head; p; p = p->next)
 150                 if (!strcmp(p->name, name))
 151                         return(p);
 152         return(NULL);
 153 }
 154 
 155 void 
 156 patch(sym_t *p, int location)
     /* [previous][next][first][last][top][bottom][index][help] */
 157 {
 158         p->npatch += 1;
 159         p->patch = (int *)Realloc(p->patch, p->npatch * sizeof(int *));
 160 
 161         p->patch[p->npatch - 1] = location;
 162 }
 163 
 164 void backpatch(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166         int i;
 167         sym_t *p;
 168 
 169         for (p = head; p; p = p->next) {
 170 
 171                 if (p->value == NOVALUE) {
 172                         fprintf(stderr,
 173                                 "%s: undefined symbol \"%s\"\n",
 174                                 filename, p->name);
 175                         exit(EXIT_FAILURE);
 176                 }
 177 
 178                 if (p->npatch) {
 179                         if (debug)
 180                                 fprintf(stderr,
 181                                         "\"%s\" (0x%x) patched at",
 182                                         p->name, p->value);
 183 
 184                         for (i = 0; i < p->npatch; i++) {
 185                                 M[p->patch[i]][0] &= ~1;
 186                                 M[p->patch[i]][0] |= ((p->value >> 8) & 1);
 187                                 M[p->patch[i]][1] = p->value & 0xff;
 188 
 189                                 if (debug)
 190                                         fprintf(stderr, " 0x%x", p->patch[i]);
 191                         }
 192 
 193                         if (debug)
 194                                 fputc('\n', stderr);
 195                 }
 196         }
 197 }
 198 
 199 /*
 200  *  Output words in byte-reversed order (least significant first)
 201  *  since the sequencer RAM is loaded that way.
 202  */
 203 void
 204 output(FILE *fp)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206         int i;
 207 
 208         for (i = 0; i < LC; i++)
 209                 fprintf(fp, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
 210                         M[i][3],
 211                         M[i][2],
 212                         M[i][1],
 213                         M[i][0]);
 214         printf("%d out of %d instructions used.\n", LC, MEMORY);
 215 }
 216 
 217 char **
 218 getl(int *n)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         int i;
 221         char *p, *quote;
 222         static char buf[MAXLINE];
 223         static char *a[MAXTOKEN];
 224 
 225         i = 0;
 226 
 227         while (fgets(buf, sizeof(buf), stdin)) {
 228 
 229                 lineno += 1;
 230 
 231                 if (buf[strlen(buf)-1] != '\n')
 232                         error("line too long");
 233 
 234                 p = strchr(buf, '#');
 235                 if (p)
 236                         *p = '\0';
 237                 p = buf;
 238 rescan:
 239                 quote = strchr(p, '\"');
 240                 if (quote)
 241                         *quote = '\0';
 242                 for (p = strtok(p, ", \t\n"); p; p = strtok(NULL, ", \t\n"))
 243                         if (i < MAXTOKEN-1)
 244                                 a[i++] = p;
 245                         else
 246                                 error("too many tokens");
 247                 if (quote) {
 248                         quote++; 
 249                         p = strchr(quote, '\"');
 250                         if (!p)
 251                                 error("unterminated string constant");
 252                         else if (i < MAXTOKEN-1) {
 253                                 a[i++] = quote;
 254                                 *p = '\0';
 255                                 p++;
 256                         }
 257                         else
 258                                 error("too many tokens");
 259                         goto rescan;
 260                 }               
 261                 if (i) {
 262                         *n = i;
 263                         return(a);
 264                 }
 265         }
 266         return(NULL);
 267 }
 268 
 269 #define A       0x8000          /* `A'ccumulator ok */
 270 #define I       0x4000          /* use as immediate value */
 271 #define SL      0x2000          /* shift left */
 272 #define SR      0x1000          /* shift right */
 273 #define RL      0x0800          /* rotate left */
 274 #define RR      0x0400          /* rotate right */
 275 #define LO      0x8000          /* lookup: ori-{jmp,jc,jnc,call} */
 276 #define LA      0x4000          /* lookup: and-{jz,jnz} */
 277 #define LX      0x2000          /* lookup: xor-{je,jne} */
 278 #define NA      -1              /* not applicable */
 279 
 280 struct {
 281         const char *name;
 282         int n;                  /* number of operands, including opcode */
 283         unsigned int op;        /* immediate or L?|pos_from_0 */
 284         unsigned int dest;      /* NA, pos_from_0, or I|immediate */
 285         unsigned int src;       /* NA, pos_from_0, or I|immediate */
 286         unsigned int imm;       /* pos_from_0, A|pos_from_0, or I|immediate */
 287         unsigned int addr;      /* NA or pos_from_0 */
 288         int fmt;                /* instruction format - 1, 2, or 3 */
 289 } instr[] = {
 290 /*
 291  *                N  OP    DEST         SRC             IMM     ADDR    FMT
 292  */
 293         { "mov",  3, 1,    1,           2,              I|0xff, NA,     1 },
 294         { "mov",  4, LO|2, NA,          1,              I|0,    3,      3 },
 295         { "mvi",  3, 0,    1,           I|R_ALLZEROS,   A|2,    NA,     1 },
 296         { "mvi",  4, LO|2, NA,          I|R_ALLZEROS,   1,      3,      3 },
 297         { "not",  2, 2,    1,           1,              I|0xff, NA,     1 },
 298         { "and",  3, 1,    1,           1,              A|2,    NA,     1 },
 299         { "and",  4, 1,    1,           3,              A|2,    NA,     1 },
 300         { "or",   3, 0,    1,           1,              A|2,    NA,     1 },
 301         { "or",   4, 0,    1,           3,              A|2,    NA,     1 },
 302         { "or",   5, LO|3, NA,          1,              2,      4,      3 },
 303         { "xor",  3, 2,    1,           1,              A|2,    NA,     1 },
 304         { "xor",  4, 2,    1,           3,              A|2,    NA,     1 },
 305         { "nop",  1, 1,    I|R_NONE,    I|R_ALLZEROS,   I|0xff, NA,     1 },
 306         { "inc",  2, 3,    1,           1,              I|1,    NA,     1 },
 307         { "inc",  3, 3,    1,           2,              I|1,    NA,     1 },
 308         { "dec",  2, 3,    1,           1,              I|0xff, NA,     1 },
 309         { "dec",  3, 3,    1,           2,              I|0xff, NA,     1 },
 310         { "jmp",  2, LO|0,   NA,        I|R_SINDEX,     I|0,    1,      3 },
 311         { "jc",   2, LO|0,   NA,        I|R_SINDEX,     I|0,    1,      3 },
 312         { "jnc",  2, LO|0,   NA,        I|R_SINDEX,     I|0,    1,      3 },
 313         { "call", 2, LO|0,   NA,        I|R_SINDEX,     I|0,    1,      3 },
 314         { "test", 5, LA|3,   NA,        1,              A|2,    4,      3 },
 315         { "cmp",  5, LX|3,   NA,        1,              A|2,    4,      3 },
 316         { "ret",  1, 1,  I|R_NONE,      I|R_ALLZEROS,   I|0xff, NA,     1 },
 317         { "ret",  1, 1,  I|R_NONE,      I|R_ALLZEROS,   I|0xff, NA,     1 },
 318         { "clc",  1, 3,  I|R_NONE,      I|R_ALLZEROS,   I|1,    NA,     1 },
 319         { "clc",  4, 3,  2,             I|R_ALLZEROS,   A|3,    NA,     1 },
 320         { "stc",  2, 3,  1,             I|R_ALLONES,    I|1,    NA,     1 },
 321         { "add",  3, 3,  1,             1,              A|2,    NA,     1 },
 322         { "add",  4, 3,  1,             3,              A|2,    NA,     1 },
 323         { "adc",  3, 4,  1,             1,              A|2,    NA,     1 },
 324         { "adc",  4, 4,  1,             3,              A|2,    NA,     1 },
 325         { "shl",  3, 5,  1,             1,              SL|2,   NA,     2 },
 326         { "shl",  4, 5,  1,             2,              SL|3,   NA,     2 },
 327         { "shr",  3, 5,  1,             1,              SR|2,   NA,     2 },
 328         { "shr",  4, 5,  1,             2,              SR|3,   NA,     2 },
 329         { "rol",  3, 5,  1,             1,              RL|2,   NA,     2 },
 330         { "rol",  4, 5,  1,             2,              RL|3,   NA,     2 },
 331         { "ror",  3, 5,  1,             1,              RR|2,   NA,     2 },
 332         { "ror",  4, 5,  1,             2,              RR|3,   NA,     2 },
 333         /*
 334          *  Extensions (note also that mvi allows A)
 335          */
 336         { "clr",  2, 1,  1,     I|R_ALLZEROS,           I|0xff, NA,     1 },
 337         { 0,      0, 0,  0,     0,                      0,      0,      0 }
 338 };
 339 
 340 int 
 341 eval_operand(char **a, int spec)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343         int i;
 344         unsigned int want = spec & (LO|LA|LX);
 345 
 346         static struct {
 347                 unsigned int what;
 348                 const char *name;
 349                 int value;
 350         } jmptab[] = {
 351                 { LO,   "jmp",          8  },
 352                 { LO,   "jc",           9  },
 353                 { LO,   "jnc",          10 },
 354                 { LO,   "call",         11 },
 355                 { LA,   "jz",           15 },
 356                 { LA,   "jnz",          13 },
 357                 { LX,   "je",           14 },
 358                 { LX,   "jne",          12 },
 359         };
 360 
 361         spec &= ~(LO|LA|LX);
 362 
 363         for (i = 0; i < sizeof(jmptab)/sizeof(jmptab[0]); i++)
 364                 if (jmptab[i].what == want &&
 365                     !strcmp(jmptab[i].name, a[spec]))
 366                 {
 367                         return(jmptab[i].value);
 368                 }
 369 
 370         if (want)
 371                 error("invalid jump");
 372 
 373         return(spec);           /* "case 0" - no flags set */
 374 }
 375 
 376 int
 377 eval_sdi(char **a, int spec)
     /* [previous][next][first][last][top][bottom][index][help] */
 378 {
 379         sym_t *p;
 380         unsigned val;
 381 
 382         if (spec == NA)
 383                 return(NA);
 384 
 385         switch (spec & (A|I|SL|SR|RL|RR)) {
 386             case SL:
 387             case SR:
 388             case RL:
 389             case RR:
 390                 if (isdigit(*a[spec &~ (SL|SR|RL|RR)]))
 391                         val = strtol(a[spec &~ (SL|SR|RL|RR)], NULL, 0);
 392                 else {
 393                         p = lookup(a[spec &~ (SL|SR|RL|RR)]);
 394                         if (!p)
 395                                 error("undefined symbol used");
 396                         val = p->value;
 397                 }
 398 
 399                 switch (spec & (SL|SR|RL|RR)) {         /* blech */
 400                     case SL:
 401                         if (val > 7)
 402                                 return(0xf0);
 403                         return(((val % 8) << 4) |
 404                                (val % 8));
 405                     case SR:
 406                         if (val > 7)
 407                                 return(0xf0);
 408                         return(((val % 8) << 4) |
 409                                (1 << 3) |
 410                                ((8 - (val % 8)) % 8));
 411                     case RL:
 412                         return(val % 8);
 413                     case RR:
 414                         return((8 - (val % 8)) % 8);
 415                 }
 416             case I:
 417                 return(spec &~ I);
 418             case A:
 419                 /*
 420                  *  An immediate field of zero selects
 421                  *  the accumulator.  Vigorously object
 422                  *  if zero is given otherwise - it's
 423                  *  most likely an error.
 424                  */
 425                 spec &= ~A;
 426                 if (!strcmp("A", a[spec]))
 427                         return(0);
 428                 if (isdigit(*a[spec]) &&
 429                     strtol(a[spec], NULL, 0) == 0)
 430                 {
 431                         error("immediate value of zero selects accumulator");
 432                 }
 433                 /* falls through */
 434             case 0:
 435                 if (isdigit(*a[spec]))
 436                         return(strtol(a[spec], NULL, 0));
 437                 p = lookup(a[spec]);
 438                 if (p)
 439                         return(p->value);
 440                 error("undefined symbol used");
 441         }
 442 
 443         return(NA);             /* shut the compiler up */
 444 }
 445 
 446 int
 447 eval_addr(char **a, int spec)
     /* [previous][next][first][last][top][bottom][index][help] */
 448 {
 449         sym_t *p;
 450 
 451         if (spec == NA)
 452                 return(NA);
 453         if (isdigit(*a[spec]))
 454                 return(strtol(a[spec], NULL, 0));
 455 
 456         p = lookup(a[spec]);
 457 
 458         if (p) {
 459                 if (p->value != NOVALUE)
 460                         return(p->value);
 461                 patch(p, LC);
 462         } else {
 463                 define(a[spec], NOVALUE);
 464                 p = lookup(a[spec]);
 465                 patch(p, LC);
 466         }
 467 
 468         return(NA);             /* will be patched in later */
 469 }
 470 
 471 int
 472 crack(char **a, int n)
     /* [previous][next][first][last][top][bottom][index][help] */
 473 {
 474         int i;
 475         int I_imm, I_addr;
 476         int I_op, I_dest, I_src, I_ret;
 477 
 478         /*
 479          *  Check for "ret" at the end of the line; remove
 480          *  it unless it's "ret" alone - we still want to
 481          *  look it up in the table.
 482          */
 483         I_ret = (strcmp(a[n-1], "ret") ? 0 : !0);
 484         if (I_ret && n > 1)
 485                 n -= 1;
 486 
 487         for (i = 0; instr[i].name; i++) {
 488                 /*
 489                  *  Look for match in table given constraints,
 490                  *  currently just the name and the number of
 491                  *  operands.
 492                  */
 493                 if (!strcmp(instr[i].name, *a) && instr[i].n == n)
 494                         break;
 495         }
 496         if (!instr[i].name)
 497                 error("unknown opcode or wrong number of operands");
 498 
 499         I_op    = eval_operand(a, instr[i].op);
 500         I_src   = eval_sdi(a, instr[i].src);
 501         I_imm   = eval_sdi(a, instr[i].imm);
 502         I_dest  = eval_sdi(a, instr[i].dest);
 503         I_addr  = eval_addr(a, instr[i].addr);
 504 
 505         if( LC >= MEMORY )
 506                 error("Memory exhausted!\n");
 507 
 508         switch (instr[i].fmt) {
 509             case 1:
 510             case 2:
 511                 M[LC][0] = (I_op << 1) | I_ret;
 512                 M[LC][1] = I_dest;
 513                 M[LC][2] = I_src;
 514                 M[LC][3] = I_imm;
 515                 break;
 516             case 3:
 517                 if (I_ret)
 518                         error("illegal use of \"ret\"");
 519                 M[LC][0] = (I_op << 1) | ((I_addr >> 8) & 1);
 520                 M[LC][1] = I_addr & 0xff;
 521                 M[LC][2] = I_src;
 522                 M[LC][3] = I_imm;
 523                 break;
 524         }
 525 
 526         return (1);             /* no two-byte instructions yet */
 527 }
 528 
 529 #undef SL
 530 #undef SR
 531 #undef RL
 532 #undef RR
 533 #undef LX
 534 #undef LA
 535 #undef LO
 536 #undef I
 537 #undef A
 538 
 539 void
 540 assemble(FILE *ofile)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542         int n;
 543         char **a;
 544         sym_t *p;
 545 
 546         while ((a = getl(&n))) {
 547 
 548                 while (a[0][strlen(*a)-1] == ':') {
 549                         a[0][strlen(*a)-1] = '\0';
 550                         p = lookup(*a);
 551                         if (p)
 552                                 p->value = LC;
 553                         else
 554                                 define(*a, LC);
 555                         a += 1;
 556                         n -= 1;
 557                 }
 558 
 559                 if (!n)                 /* line was all labels */
 560                         continue;
 561 
 562                 if (n == 3 && !strcmp("VERSION", *a))
 563                         fprintf(ofile, "#define %s \"%s\"\n", a[1], a[2]);
 564                 else {
 565                         if (n == 3 && !strcmp("=", a[1]))
 566                                 define(*a, strtol(a[2], NULL, 0));
 567                         else
 568                                 LC += crack(a, n);
 569                 }
 570         }
 571 
 572         backpatch();
 573         output(ofile);
 574 
 575         if (debug)
 576                 output(stderr);
 577 }
 578 
 579 int
 580 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 581 {
 582         int c;
 583         int pid;
 584         int ifile;
 585         int status;
 586         FILE *ofile;
 587         char *ofilename;
 588         int fd[2];
 589 
 590         ofile = NULL;
 591         ofilename = NULL;
 592         while ((c = getopt(argc, argv, "dho:vD")) != EOF) {
 593                 switch (c) {
 594                     case 'd':
 595                         debug = !0;
 596                         break;
 597                     case 'D':
 598                     {
 599                         char *p;
 600                         if ((p = strchr(optarg, '=')) != NULL) {
 601                                 *p = '\0';
 602                                 define(optarg, strtol(p + 1, NULL, 0));
 603                         }
 604                         else
 605                                 define(optarg, 1);
 606                         break;
 607                     }
 608                     case 'o':
 609                         ofilename = optarg;
 610                         if ((ofile = fopen(ofilename, "w")) < 0) {
 611                                 perror(optarg);
 612                                 exit(EXIT_FAILURE);
 613                         }
 614                         break;
 615                     case 'h':
 616                         printf("usage: %s [-d] [-Dname] [-ooutput] input\n", 
 617                                 *argv);
 618                         exit(EXIT_SUCCESS);
 619                         break;
 620                     case 'v':
 621                         printf("%s\n", id);
 622                         exit(EXIT_SUCCESS);
 623                         break;
 624                     default:
 625                         exit(EXIT_FAILURE);
 626                         break;
 627                 }
 628         }
 629 
 630         if (argc - optind != 1) {
 631                 fprintf(stderr, "%s: must have one input file\n", *argv);
 632                 exit(EXIT_FAILURE);
 633         }
 634         filename = argv[optind];
 635 
 636         
 637         if ((ifile = open(filename, O_RDONLY)) < 0) {
 638                 perror(filename);
 639                 exit(EXIT_FAILURE);
 640         }
 641 
 642         if (!ofilename) {
 643                 ofilename = ADOTOUT;
 644                 if ((ofile = fopen(ofilename, "w")) < 0) {
 645                         perror(ofilename);
 646                         exit(EXIT_FAILURE);
 647                 }
 648         }
 649 
 650         if (pipe(fd) < 0) {
 651                 perror("pipe failed");
 652                 exit(1);
 653         }
 654 
 655         if ((pid = fork()) < 0 ) {
 656                 perror("fork failed");
 657                 exit(1);
 658         }
 659         else if (pid > 0) {             /* Parent */
 660                 close(fd[1]);           /* Close write end */
 661                 if (fd[0] != STDIN_FILENO) {
 662                         if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) {
 663                                 perror("dup2 error on stdin");
 664                                 exit(EXIT_FAILURE);
 665                         }
 666                         close(fd[0]);
 667                 }
 668                 assemble(ofile);
 669                 if (wait(&status) < 0) {
 670                         perror("wait error");
 671                 }
 672 
 673                 if (status != 0) {
 674                         unlink(ofilename);
 675                 }
 676                 exit(status);
 677         } else {                                /* Child */
 678                 int i, arg_cnt, found;
 679                 char *args[MAX_ARGS];
 680                 char *buf;
 681 
 682                 arg_cnt = 0;
 683                 found = FALSE;
 684                 for (i = 0; (!found && (i < NUMBER(cpp))); i++) {
 685                         char *bp;
 686 
 687                         buf = strdup(cpp[i]);
 688 
 689                         for (bp = strtok(buf, " \t\n"), arg_cnt = 0;
 690                              bp != NULL;
 691                              bp = strtok(NULL, " \t\n"), arg_cnt++) {
 692                                 if (arg_cnt == 0) {
 693                                         if (access(bp, X_OK) == 0) {
 694                                                 found = TRUE;
 695                                         }
 696                                 }
 697 
 698                                 args[arg_cnt] = bp;
 699                         }
 700 
 701                         if (!found) {
 702                                 free(buf);
 703                         }
 704                 }
 705                 args[arg_cnt] = NULL;
 706 
 707                 if (found) {
 708                         close(fd[0]);           /* Close Read end */
 709                         if (fd[1] != STDOUT_FILENO) {
 710                                 if (dup2(fd[1], STDOUT_FILENO) != STDOUT_FILENO) {
 711                                         perror("dup2 error on stdout");
 712                                         exit(EXIT_FAILURE);
 713                                 }
 714                                 close(fd[1]);
 715                         }
 716                         if (ifile != STDIN_FILENO) {
 717                                 if (dup2(ifile, STDIN_FILENO) != STDIN_FILENO) {
 718                                         perror("dup2 error on stdin");
 719                                         exit(EXIT_FAILURE);
 720                                 }
 721                                 close(ifile);
 722                         }
 723 
 724                         if (execvp(args[0], args) < 0) {
 725                                 perror("execvp() error");
 726                                 exit(EXIT_FAILURE);
 727                         }
 728                 } else {
 729                         fprintf(stderr, "%s: Cannot find CPP command.\n", argv[0]);
 730                         exit(EXIT_FAILURE);
 731                 }
 732         }
 733         return(EXIT_SUCCESS);
 734 }

/* [previous][next][first][last][top][bottom][index][help] */