home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / flex-2.5 / flex-2 / flex-2.5.3 / MISC / VMS / vms-code.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-05  |  4.3 KB  |  153 lines

  1. /* vms-code.c -- additional VMS-specific support code for flex
  2.  */
  3.  
  4. #include "flexdef.h"
  5.  
  6. static const char *original_arg0;
  7. static const char default_arg0[] = "flex.exe";
  8.  
  9. #define IN_FD    0
  10. #define OUT_FD    1
  11. #define ERR_FD    2
  12.  
  13. static char *fix_arg0 PROTO((const char *));
  14.  
  15. /* Command line arguments fixup -- simplify argv[0], and handle `>'
  16.    output redirection request; called first thing from main().  */
  17.  
  18. void argv_fixup( iargc, iargv )
  19. int *iargc;
  20. char ***iargv;
  21. {
  22.     const char *mode[3], *rfm[3], *name[3];
  23.     char *p;
  24.     int i, oargc, punct, which, append, alt_rfm;
  25.  
  26.     /*
  27.      * Get original argv[0] supplied by run-time library startup code,
  28.      * then replace it with a stripped down one.
  29.      */
  30.     original_arg0 = (*iargv)[0];
  31.     (*iargv)[0] = fix_arg0(original_arg0);
  32.  
  33.     /*
  34.      *    Check command line arguments for redirection request(s).
  35.      *    For simplicity, if multiple attempts are made, the last one wins.
  36.      */
  37.     name[0] = name[1] = name[2] = 0;
  38.     oargc = 1;    /* number of args caller will see; count includes argv[0] */
  39.     for (i = 1; i < *iargc; i++) {
  40.     p = (*iargv)[i];
  41.     switch (*p) {
  42.         case '<':
  43.         /* might be "<dir>file"; then again, perhaps "<<dir>file" */
  44.         punct = (strchr(p, '>') != 0);
  45.         if (p[1] == '<') {
  46.             if (!punct || p[2] == '<')
  47.             flexerror("<<'sentinel' input not supported.");
  48.             punct = 0;
  49.         }
  50.         if (punct)    /* the '<' seems to be directory punctuation */
  51.             goto arg;    /*GOTO*/
  52.         mode[IN_FD] = "r";
  53.         rfm[IN_FD]  = 0;
  54.         name[IN_FD] = ++p;
  55.         if (!*p && (i + 1) < *iargc)
  56.             name[IN_FD] = (*iargv)[++i];
  57.         break;
  58.         case '>':
  59.         append = (p[1] == '>');
  60.         if (append) ++p;
  61.         alt_rfm = (p[1] == '$');
  62.         if (alt_rfm) ++p;
  63.         which = (p[1] == '&' ? ERR_FD : OUT_FD);
  64.         if (which == ERR_FD) ++p;
  65.         mode[which] = append ? "a" : "w";
  66.         rfm[which]  = alt_rfm ? "rfm=var" : "rfm=stmlf";
  67.         name[which] = ++p;
  68.         if (!*p && (i + 1) < *iargc)
  69.             name[which] = (*iargv)[++i];
  70.         break;
  71.         case '|':
  72.         flexerror("pipe output not supported.");
  73.         /*NOTREACHED*/
  74.         break;
  75.         default:
  76.  arg:        /* ordinary option or argument */
  77.         (*iargv)[oargc++] = p;
  78.         break;
  79.     }
  80.     }
  81.     /* perform any requested redirection; don't bother with SYS$xxx logicals */
  82.     if (name[IN_FD])
  83.     if (!freopen(name[IN_FD], mode[IN_FD], stdin))
  84.         lerrsf("failed to redirect `stdin' from \"%s\"", name[IN_FD]);
  85.     if (name[OUT_FD])
  86.     if (!freopen(name[OUT_FD], mode[OUT_FD], stdout,
  87.              rfm[OUT_FD], "rat=cr", "mbc=32", "shr=nil"))
  88.         lerrsf("failed to redirect `stdout' to \"%s\"", name[OUT_FD]);
  89.     if (name[ERR_FD])  /* likely won't see message if this fails; oh well... */
  90.     if (!freopen(name[ERR_FD], mode[ERR_FD], stderr,
  91.              rfm[ERR_FD], "rat=cr"))
  92.         lerrsf("failed to redirect `stderr' to \"%s\"", name[ERR_FD]);
  93.     /* remove any excess arguments (used up from redirection) */
  94.     while (*iargc > oargc)
  95.     (*iargv)[--*iargc] = 0;
  96.     /* all done */
  97.     return;
  98. }
  99.  
  100. /* Pick out the basename of a full filename, and return a pointer
  101.    to a modifiable copy of it.  */
  102.  
  103. static char *fix_arg0( arg0 )
  104. const char *arg0;
  105. {
  106.     char *p, *new_arg0;
  107.  
  108.     if (arg0) {
  109.     /* strip off the path */
  110.     if ((p = strrchr(arg0, ':')) != 0)    /* device punctuation */
  111.         arg0 = p + 1;
  112.     if ((p = strrchr(arg0, ']')) != 0)    /* directory punctuation */
  113.         arg0 = p + 1;
  114.     if ((p = strrchr(arg0, '>')) != 0)    /* alternate dir punct */
  115.         arg0 = p + 1;
  116.     }
  117.     if (!arg0 || !*arg0)
  118.     arg0 = default_arg0;
  119.     /* should now have "something.exe;#"; make a modifiable copy */
  120.     new_arg0 = copy_string(arg0);
  121.  
  122.     /* strip off ".exe" and/or ";#" (version number),
  123.        unless it ended up as the whole name */
  124.     if ((p = strchr(new_arg0, '.')) != 0 && (p > new_arg0)
  125.     && (p[1] == 'e' || p[1] == 'E')
  126.     && (p[2] == 'x' || p[2] == 'X')
  127.     && (p[3] == 'e' || p[3] == 'E')
  128.     && (p[4] == ';' || p[4] == '.' || p[4] == '\0'))
  129.     *p = '\0';
  130.     else if ((p = strchr(new_arg0, ';')) != 0 && (p > new_arg0))
  131.     *p = '\0';
  132.  
  133.     return new_arg0;
  134. }
  135.  
  136.  
  137. #include <ssdef.h>
  138. #include <stsdef.h>
  139.  
  140. #ifdef exit
  141. #undef exit
  142. extern void exit PROTO((int));    /* <stdlib.h> ended up prototyping vms_exit */
  143. #endif
  144.  
  145. /* Convert zero to VMS success and non-zero to VMS failure.  The latter
  146.    does not bother trying to distinguish between various failure reasons.  */
  147.  
  148. void vms_exit( status )
  149. int status;
  150. {
  151.     exit( status == 0 ? SS$_NORMAL : (SS$_ABORT | STS$M_INHIB_MSG) );
  152. }
  153.