Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /****************************************************************************
  2. *
  3. *                            Open Watcom Project
  4. *
  5. *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
  6. *
  7. *  ========================================================================
  8. *
  9. *    This file contains Original Code and/or Modifications of Original
  10. *    Code as defined in and that are subject to the Sybase Open Watcom
  11. *    Public License version 1.0 (the 'License'). You may not use this file
  12. *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
  13. *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
  14. *    provided with the Original Code and Modifications, and is also
  15. *    available at www.sybase.com/developer/opensource.
  16. *
  17. *    The Original Code and all software distributed under the License are
  18. *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  19. *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
  20. *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
  21. *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
  22. *    NON-INFRINGEMENT. Please see the License for the specific language
  23. *    governing rights and limitations under the License.
  24. *
  25. *  ========================================================================
  26. *
  27. * Description:  Functions to set up argc and argv parameters of main(), etc.
  28. *
  29. ****************************************************************************/
  30. #define __NETWARE__
  31.  
  32. #ifdef __NETWARE__
  33.     void __Init_Argv( void ) { }
  34.     void __Fini_Argv( void ) { }
  35. #else
  36. //#include "dll.h"        // needs to be first
  37. #include "variety.h"
  38. #include "widechar.h"
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <io.h>
  43. //#include "liballoc.h"
  44. #include "initarg.h"
  45.  
  46. extern  int         __historical_splitparms;
  47. extern  void        _Not_Enough_Memory( void );             /* 25-jul-89 */
  48. static  unsigned    _SplitParms(int, CHAR_TYPE *, CHAR_TYPE **, CHAR_TYPE ** );
  49. _WCRTLINKD static CHAR_TYPE  *__F_NAME(__CmdLine,__wCmdLine);       /* cmdline buffer */
  50.  
  51. _WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
  52.         int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
  53.         int *pargc, CHAR_TYPE ***pargv );
  54.  
  55. void __F_NAME(__Init_Argv,__wInit_Argv)( void )
  56. {
  57.     __F_NAME( __CmdLine, __wCmdLine ) = __F_NAME( _getargv, _wgetargv )(
  58.         __historical_splitparms,
  59.         __F_NAME( _LpPgmName, _LpwPgmName ), __F_NAME( _LpCmdLine, _LpwCmdLine ),
  60.         &__F_NAME( _argc, _wargc ), &__F_NAME( _argv, _wargv ) );
  61.  
  62.     __F_NAME( __argc, __wargc )   = __F_NAME( _argc, _wargc );
  63.     __F_NAME( ___Argc, ___wArgc ) = __F_NAME( _argc, _wargc );
  64.     __F_NAME( __argv, __wargv )   = __F_NAME( _argv, _wargv );
  65.     __F_NAME( ___Argv, ___wArgv ) = __F_NAME( _argv, _wargv );
  66. }
  67.  
  68. _WCRTLINK void *__F_NAME( _getargv, _wgetargv )(
  69.         int historical, CHAR_TYPE *exe, CHAR_TYPE *cmd,
  70.         int *pargc, CHAR_TYPE ***pargv )
  71. {
  72.     unsigned    argc;           /* argument count */
  73.     CHAR_TYPE   **argv;         /* Actual arguments */
  74.     CHAR_TYPE   *endptr;        /* ptr to end of command line */
  75.     unsigned    len;            /* length of command line */
  76.     CHAR_TYPE   *cmdline;       /* copy of command line */
  77.     unsigned    size;           /* amount to allocate */
  78.     unsigned    argv_offset;    /* offset of argv in storage */
  79.  
  80.     argc = _SplitParms( historical, cmd, NULL, &endptr ) + 1;
  81.     len = (unsigned) ( endptr - cmd ) + 1;
  82.     argv_offset = __ALIGN_SIZE(len * sizeof(CHAR_TYPE));
  83.     size = argv_offset + (argc+1) * sizeof(CHAR_TYPE *);
  84.     // round up size for alignment of argv pointer
  85.     size = __ALIGN_SIZE( size );
  86.  
  87.     #if defined(__REAL_MODE__) && defined(__BIG_DATA__)
  88.         #if defined(__OS2_286__)
  89.             if( _osmode == DOS_MODE ) {
  90.                 cmdline = lib_nmalloc( size );
  91.                 if( (void _WCI86NEAR *) cmdline == NULL ) {
  92.                     cmdline = lib_malloc( size );
  93.                 }
  94.             } else {
  95.                 cmdline = lib_malloc( size );
  96.             }
  97.         #else
  98.             cmdline = lib_nmalloc( size );
  99.             if( (void _WCI86NEAR *) cmdline == NULL ) {
  100.                 cmdline = lib_malloc( size );
  101.             }
  102.         #endif
  103.     #else
  104.         cmdline = lib_malloc( size );
  105.     #endif
  106.     argv = NULL;
  107.     argc = 0;
  108.     if( cmdline ) {
  109.         memcpy( cmdline, cmd, len * sizeof(CHAR_TYPE) );
  110.         argv = (void *) ( ( ( char*) cmdline ) + argv_offset );
  111.         argv[0] = exe;
  112.         argc = _SplitParms( historical, cmdline, argv + 1, &endptr ) + 1;
  113.         argv[argc] = NULL;
  114.     }
  115.     *pargc = argc;
  116.     *pargv = argv;
  117.     return( cmdline );
  118. }
  119.  
  120.  
  121. static unsigned _SplitParms( int historical, CHAR_TYPE *p, CHAR_TYPE **argv, CHAR_TYPE **endptr )
  122. {
  123.     register unsigned argc;
  124.     register CHAR_TYPE *start;
  125.     register CHAR_TYPE *new;
  126.     enum QUOTE_STATE {
  127.         QUOTE_NONE,             /* no " active in current parm */
  128.         QUOTE_DELIMITER,        /* " was first char and must be last */
  129.         QUOTE_STARTED   /* " was seen, look for a match */
  130.     };
  131.     register enum QUOTE_STATE state;
  132.  
  133.     argc = 0;
  134.     for(;;) {
  135.         while( *p == ' ' || *p == '\t' ) {
  136.             ++p; /* skip over blanks or tabs */
  137.         }
  138.         if( *p == '\0' ) break;
  139.         /* we are at the start of a parm */
  140.         state = QUOTE_NONE;
  141.         if( *p == '\"' ) {
  142.             p++;
  143.             state = QUOTE_DELIMITER;
  144.         }
  145.         new = start = p;
  146.         for(;;) {
  147.             if( *p == '\"' ) {
  148.                 if( !historical ) {
  149.                     p++;
  150.                     if( state == QUOTE_NONE ) {
  151.                         state = QUOTE_STARTED;
  152.                     } else {
  153.                         state = QUOTE_NONE;
  154.                     }
  155.                     continue;
  156.                 } else {
  157.                     if( state == QUOTE_DELIMITER ) {
  158.                         break;
  159.                     }
  160.                 }
  161.             }
  162.             if( *p == ' ' || *p == '\t' ) {
  163.                 if( state == QUOTE_NONE ) {
  164.                     break;
  165.                 }
  166.             }
  167.             if( *p == '\0' ) break;
  168.             if( *p == '\\' ) {
  169.                 if( !historical ) {
  170.                     if( p[1] == '\"' ) {
  171.                         ++p;
  172.                         if( p[-2] == '\\' ) {
  173.                             continue;
  174.                         }
  175.                     }
  176.                 } else {
  177.                     if( p[1] == '\"' || p[1] == '\\' && state == QUOTE_DELIMITER ) {
  178.                         ++p;
  179.                     }
  180.                 }
  181.             }
  182.             if( argv ) {
  183.                 *(new++) = *p;
  184.             }
  185.             ++p;
  186.         }
  187.         if( argv ) {
  188.             argv[ argc ] = start;
  189.             ++argc;
  190.  
  191.             /*
  192.               The *new = '\0' is req'd in case there was a \" to "
  193.               translation. It must be after the *p check against
  194.               '\0' because new and p could point to the same char
  195.               in which case the scan would be terminated too soon.
  196.             */
  197.  
  198.             if( *p == '\0' ) {
  199.                 *new = '\0';
  200.                 break;
  201.             }
  202.             *new = '\0';
  203.             ++p;
  204.         } else {
  205.             ++argc;
  206.             if( *p == '\0' ) {
  207.                 break;
  208.             }
  209.             ++p;
  210.         }
  211.     }
  212.     *endptr = p;
  213.     return( argc );
  214. }
  215.  
  216. void __F_NAME(__Fini_Argv,__wFini_Argv)( void )
  217. {
  218.     if( __F_NAME(__CmdLine,__wCmdLine) != NULL ) {
  219.         lib_free( __F_NAME(__CmdLine,__wCmdLine) );
  220.     }
  221. }
  222. #endif
  223.