home *** CD-ROM | disk | FTP | other *** search
/ Programming Win32 Under the API / ProgrammingWin32UnderTheApiPatVillani.iso / Chapter9 / cmd32 / Scan.c < prev    next >
C/C++ Source or Header  |  2000-05-11  |  6KB  |  318 lines

  1. /****************************************************************/
  2. /*                                */
  3. /*                 scan.c                */
  4. /*                                */
  5. /*             command.com lexical support        */
  6. /*                                */
  7. /*            Copyright (c) 2000            */
  8. /*            Pasquale J. Villani            */
  9. /*            All Rights Reserved            */
  10. /*                                */
  11. /* This file is part of CMD32.                    */
  12. /*                                */
  13. /* CMD32 is free software; you can redistribute it and/or    */
  14. /* modify it under the terms of the GNU General Public License    */
  15. /* as published by the Free Software Foundation; either version    */
  16. /* 2, or (at your option) any later version.            */
  17. /*                                */
  18. /* CMD32 is distributed in the hope that it will be useful, but    */
  19. /* WITHOUT ANY WARRANTY; without even the implied warranty of    */
  20. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
  21. /* the GNU General Public License for more details.        */
  22. /*                                */
  23. /* You should have received a copy of the GNU General Public    */
  24. /* License along with CMD32; see the file COPYING.  If not,    */
  25. /* write to the Free Software Foundation, 675 Mass Ave,        */
  26. /* Cambridge, MA 02139, USA.                    */
  27. /****************************************************************/
  28.  
  29. /* $Logfile$ */
  30.  
  31. /* $Log$ 
  32.  * $EndLog$ */
  33.  
  34. #ifdef VERSION_STRINGS
  35. static char *RcsId = "$Header$";
  36. #endif
  37.  
  38. #include <windows.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <ctype.h>
  42.  
  43. #include "globals.h"
  44. /* #include "proto.h" */
  45.  
  46.  
  47.  
  48.  
  49. BYTE *skipwh(BYTE *s);
  50.  
  51.  
  52. INT tonum(INT c)
  53. {
  54.     INT i;
  55.  
  56.     for(i = 0; i < 9; i++)
  57.     {
  58.         if(c == "0123456789"[i])
  59.             return i;
  60.     }
  61.  
  62.     return 0;
  63. }
  64.  
  65.  
  66. void expand(BYTE *d, BYTE *s)
  67. {
  68.     INT idx, bufidx;
  69.     BYTE buffer[MAX_CMDLINE];
  70.  
  71.     *d = '\0';
  72.     while(*s)
  73.     {
  74.         if(*s == '%' && isdigit(s[1]))
  75.         {
  76.             idx = tonum(*++s);
  77.             idx = (idx == 0 ? 0 : idx + shift_offset);
  78.             strcpy(d, posparam[idx]);
  79.             d += strlen(posparam[idx]);
  80.             while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
  81.                 ++s;
  82.         }
  83.         else if(*s == '%' && *(s + 1) == '%')
  84.         {
  85.             /* swallow one % save the other            */
  86.             *d++ = *s++;
  87.             s++;
  88.         }
  89.         else if(*s == '%')
  90.         {
  91.             /* get passed the %                  */
  92.             ++s;
  93.             /* buffer until next %, see if string between the */
  94.             /* is an environment variable              */
  95.             /* if lp iswhite its not an env var, if its %     */
  96.             /* then look in env and substitute if found      */
  97.             bufidx = 0;
  98.             while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
  99.             {
  100.                 buffer[bufidx++] = *s++;
  101.                 buffer[bufidx] = '\0';
  102.             }
  103.             if(*s != '%')
  104.             {
  105.             /* can't be env variable so add to cmd line      */
  106.                 *d++ = '%';
  107.                 strcpy(d, buffer);
  108.                 d += strlen(buffer);
  109.             }
  110.             else
  111.             {
  112.             /* lookup and substitiue              */
  113.             /* get passed ending %                  */
  114.                 strcpy(d, getenv(buffer));
  115.                 d += strlen(getenv(buffer));
  116.                 s++;
  117.             }
  118.         }
  119.         else
  120.         {
  121.             *d++ = *s++;
  122.             *d = '\0';
  123.         }
  124.     }
  125. }
  126.  
  127. void expandspl(BYTE *s, BYTE *d, INT var, BYTE *sub)
  128. {
  129.     while(*s)
  130.     {
  131.         if(*s == '%' && s[1] == var)
  132.         {
  133.             strcpy(d, sub);
  134.             d += strlen(sub);
  135.             while(*s == '%')
  136.                 ++s;
  137.             while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%'))
  138.                 ++s;
  139.         }
  140.         if((*s == '%' && s[1] != var)
  141.         || (*s == '%' && s[1] == '%' && s[2] != var))
  142.         {
  143.             ++s;    /* Throw away leading %            */
  144.             *d++ = *s++;
  145.             *d = '\0';
  146.         }
  147.         else
  148.         {
  149.             *d++ = *s++;
  150.             *d = '\0';
  151.         }
  152.     }
  153. }
  154.  
  155. BYTE *scan(BYTE *s, BYTE *d)
  156. {
  157.     s = skipwh(s);
  158.  
  159.     if(batch_FLAG && *s == '%' && isdigit(s[1]))
  160.     {
  161.         strcpy(d, posparam[tonum(s[1])]);
  162.         s += 2;
  163.         return s;
  164.     }
  165.  
  166.  
  167.     while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t'))
  168.         *d++ = *s++;
  169.  
  170.     *d = '\0';
  171.  
  172.  
  173.     return s;
  174. }
  175.  
  176. BYTE *scanspl(BYTE *s, BYTE *d, INT c)
  177. {
  178.     s = skipwh(s);
  179.     while(*s && !(*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t' || *s == '%' || *s == c))
  180.         *d++ = *s++;
  181.  
  182.     *d = '\0';
  183.     return s;
  184. }
  185.  
  186. BYTE *skipwh(BYTE *s)
  187. {
  188.     while(*s && (*s == 0x0d || *s == 0x0a || *s == ' ' || *s == '\t'))
  189.         ++s;
  190.     return s;
  191. }
  192.  
  193.  
  194. BYTE *scan_seperator(BYTE *s, BYTE *d)
  195. {
  196.     s = skipwh(s);
  197.     if(*s)
  198.         *d++ = *s++;
  199.     *d = '\0';
  200.     return s;
  201. }
  202.  
  203.  
  204.  
  205. /*
  206.  * [d:][path]name
  207.  *
  208.  * d:   = [A-Za-z]':'
  209.  *
  210.  * path = ".\"         |
  211.  *        "..\"        |
  212.  *        ".\" string  |
  213.  *        "..\" string |
  214.  *        "\"          |
  215.  *        '\' string   |
  216.  *        string '\'   |
  217.  */
  218. BYTE *scan_name(BYTE *pszSrc, BYTE *pszDrive, BYTE *pszPath, BYTE *pszName)
  219. {
  220.     BYTE *pszEnd, *pszRoot = "\\";
  221.  
  222.     /* Initialize the destinations with "", just in case we don't do */
  223.     /* anything with them */
  224.     if(pszDrive)
  225.     {
  226.         *pszDrive = '\0';
  227.     }
  228.     if(pszPath)
  229.     {
  230.         *pszPath = '\0';
  231.     }
  232.     if(pszName)
  233.     {
  234.         *pszName = '\0';
  235.     }
  236.  
  237.     /* Check for a drive specifier  and strip it off if there */
  238.     if(isalpha(*pszSrc) && (*(pszSrc + 1) == ':'))
  239.     {
  240.         if(pszDrive)
  241.         {
  242.             *pszDrive++ = *pszSrc;
  243.         }
  244.         ++pszSrc;
  245.         ++pszSrc;
  246.     }
  247.  
  248.     /* There's a special case of only root.  Test for it and copy it to the path */
  249.     /* variable */
  250.     if((*pszSrc == '\\') && (!pszSrc[1] || isspace(pszSrc[1])))
  251.     {
  252.         if(pszPath)
  253.         {
  254.             strcpy(pszPath, pszRoot);
  255.         }
  256.         /* There can't be a name following, so initialize it to null string */
  257.         if(pszName)
  258.         {
  259.             *pszName = '\0';
  260.         }
  261.         return ++pszSrc;
  262.     }
  263.  
  264.     /* Look for the last path separator and use it to decide if we have */
  265.     /* path or not */
  266.     if(((pszEnd = strrchr(pszSrc, '\\')) != NULL) && (pszEnd >= pszSrc))
  267.     {
  268.         /* Is it root? */
  269.         if(pszSrc == pszEnd)
  270.         {
  271.             if(pszPath)
  272.             {
  273.                 strcpy(pszPath, pszRoot);
  274.                 ++pszSrc;
  275.             }
  276.         }
  277.         else
  278.         {
  279.             while(*pszSrc && (pszSrc < pszEnd))
  280.             {
  281.                 if(pszPath)
  282.                 {
  283.                     *pszPath++ = *pszSrc;
  284.                     *pszPath = '\0';
  285.                 }
  286.                 ++pszSrc;
  287.             }
  288.         }
  289.     }
  290.  
  291.     /*
  292.      * If we're here, we're either at a '\' character or we only have a pattern
  293.      * alone.  So we want to figure out if there's a name following or not
  294.      */
  295.     if(*pszSrc == '\\')
  296.     {
  297.         ++pszSrc;
  298.     }
  299.     if(pszName)
  300.     {
  301.         *pszName = '\0';
  302.     }
  303.     while(*pszSrc && !isspace(*pszSrc))
  304.     {
  305.         if(pszName)
  306.         {
  307.             *pszName++ = *pszSrc;
  308.             *pszName = '\0';
  309.         }
  310.         ++pszSrc;
  311.     }
  312.  
  313.     /* Done.  Return where we ended so that we scan further, if necessary. */
  314.     return pszSrc;
  315. }
  316.  
  317.  
  318.