home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / misc / emu / AROSdev.lha / AROS / rom / dos / parsepattern.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-27  |  6.0 KB  |  218 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: parsepattern.c,v 1.4 1997/01/27 00:36:27 ldp Exp $
  4.     $Log: parsepattern.c,v $
  5.     Revision 1.4  1997/01/27 00:36:27  ldp
  6.     Polish
  7.  
  8.     Revision 1.3  1996/12/09 13:53:37  aros
  9.     Added empty templates for all missing functions
  10.  
  11.     Moved #include's into first column
  12.  
  13.     Revision 1.2  1996/10/24 15:50:34  aros
  14.     Use the official AROS macros over the __AROS versions.
  15.  
  16.     Revision 1.1  1996/09/11 12:54:46  digulla
  17.     A couple of new DOS functions from M. Fleischer
  18.  
  19.     Desc:
  20.     Lang: english
  21. */
  22. #include <proto/exec.h>
  23. #include <dos/dos.h>
  24. #include <dos/dosasl.h>
  25. #include "dos_intern.h"
  26.  
  27. /*****************************************************************************
  28.  
  29.     NAME */
  30. #include <proto/dos.h>
  31.  
  32.     AROS_LH3(LONG, ParsePattern,
  33.  
  34. /*  SYNOPSIS */
  35.     AROS_LHA(STRPTR, Source,      D1),
  36.     AROS_LHA(STRPTR, Dest,        D2),
  37.     AROS_LHA(LONG,   DestLength,  D3),
  38.  
  39. /*  LOCATION */
  40.     struct DosLibrary *, DOSBase, 140, Dos)
  41.  
  42. /*  FUNCTION
  43.     Takes a pattern containing wildcards and transforms it into some
  44.     intermediate representation for use with the MathPattern() function.
  45.     The intermediate representation is longer but generally a buffer
  46.     size of 2*(strlen(Source)+1) is enough. Nevertheless you should check
  47.     the returncode to be sure that everything went fine.
  48.  
  49.     INPUTS
  50.     Source     - Pattern describing the kind of strings that match.
  51.              Possible tokens are:
  52.              #x     - The following character or item is repeaded 0 or
  53.                       more times.
  54.              ?      - Item matching a single non-NUL character.
  55.              a|b|c  - Matches one of multiple strings.
  56.              ~x     - This item matches if the item x doesn't match.
  57.              (a)    - Parens
  58.              [a-z]  - Matches a single character out of the set.
  59.              [~a-z] - Matches a single non-NUL character not in the set.
  60.              'c     - Escapes the following character.
  61.              *      - Same as #?, but optional.
  62.     Dest       - Buffer for the destination.
  63.     DestLength - Size of the buffer.
  64.  
  65.     RESULT
  66.      1 - There are wildcards in the pattern (it might match more than
  67.          one string).
  68.      0 - No wildcards in it, all went fine.
  69.     -1 - An error happened. IoErr() gives additional information in
  70.          that case.
  71.  
  72.     NOTES
  73.  
  74.     EXAMPLE
  75.  
  76.     BUGS
  77.  
  78.     SEE ALSO
  79.  
  80.     INTERNALS
  81.  
  82.     HISTORY
  83.     29-10-95    digulla automatically created from
  84.                 dos_lib.fd and clib/dos_protos.h
  85.  
  86. *****************************************************************************/
  87. {
  88.     AROS_LIBFUNC_INIT
  89.     AROS_LIBBASE_EXT_DECL(struct DosLibrary *,DOSBase)
  90.     STRPTR stack, end;
  91.     UBYTE a, b, t;
  92.     LONG iswild=0;
  93.  
  94.     LONG *result=&((struct Process *)FindTask(NULL))->pr_Result2;
  95. #define ERROR(a) { *result=a; return -1; }
  96.     stack=end=Dest+DestLength;
  97. #define PUT(a) { if(Dest>=stack) ERROR(ERROR_BUFFER_OVERFLOW); *Dest++=(a); }
  98.     
  99.     if(!*Source)
  100.     {
  101.         PUT(0);
  102.         return 0;
  103.     }else
  104.         PUT(MP_OR);
  105.  
  106.     while(*Source)
  107.     {
  108.         switch(*Source++)
  109.         {
  110.             case '#':
  111.                 iswild=1;
  112.                 if(*Source=='?')
  113.                 {
  114.                     Source++;
  115.                     PUT(MP_ALL);
  116.                 }else
  117.                 {
  118.                     PUT(MP_MULT);
  119.                     *--stack=MP_MULT_END;
  120.                     continue;
  121.                 }
  122.                 break;
  123.             case '~':
  124.                 iswild=1;
  125.                 PUT(MP_NOT);
  126.                 *--stack=MP_NOT_END;
  127.                 continue;
  128.             case '?':
  129.                 iswild=1;
  130.                 PUT(MP_SINGLE);
  131.                 break;
  132.             case '(':
  133.                 PUT(MP_OR);
  134.                 *--stack=MP_OR_END;
  135.                 continue;
  136.             case '|':
  137.                 iswild=1;
  138.                 if(stack!=end&&*stack!=MP_OR_END)
  139.                     ERROR(ERROR_BAD_TEMPLATE);
  140.                 PUT(MP_OR_NEXT);
  141.                 break;
  142.             case ')':
  143.                 if(stack==end||*stack!=MP_OR_END)
  144.                     ERROR(ERROR_BAD_TEMPLATE);
  145.                 PUT(*stack++);
  146.                 break;
  147.             case '[':
  148.                 if(*Source=='~')
  149.                 {
  150.                     Source++;
  151.                     PUT(MP_NOT_SET);
  152.                 }else
  153.                     PUT(MP_SET);
  154.                 a=*Source++;
  155.                 if(!a)
  156.                     ERROR(ERROR_BAD_TEMPLATE);
  157.                 do
  158.                 {
  159.                     if(Source[0]=='-'&&Source[1]!=']')
  160.                     {
  161.                         Source++;
  162.                         b=*Source++;
  163.                         if(!b)
  164.                             ERROR(ERROR_BAD_TEMPLATE);
  165.                         if(b>a)
  166.                             t=a, a=b, b=t;
  167.                         PUT(MP_DASH);
  168.                         if(b>=0x81&&b<=0x8e)
  169.                         {
  170.                             PUT(MP_ESCAPE);
  171.                             b-=0x80;
  172.                         }
  173.                         PUT(b);
  174.                     }
  175.                     if(a>=0x81&&a<=0x8e)
  176.                     {
  177.                         PUT(MP_ESCAPE);
  178.                         a-=0x80;
  179.                     }
  180.                     PUT(a);
  181.                     a=*Source++;
  182.                     if(!a)
  183.                         ERROR(ERROR_BAD_TEMPLATE);
  184.                 }while(a!=']');
  185.                 PUT(MP_SET_END);
  186.                 break;
  187.             case '*':
  188.                 if(DOSBase->dl_Flags&RNF_WILDSTAR)
  189.                 {
  190.                     PUT(MP_ALL);
  191.                 }else
  192.                     PUT('*');
  193.                 break;
  194.             case '\'':
  195.                 if(!*Source++)
  196.                     ERROR(ERROR_BAD_TEMPLATE);
  197.                 /* Fall through */
  198.             default:
  199.                 a=Source[-1];
  200.                 if(a>=0x81&&a<=0x8e)
  201.                 {
  202.                     PUT(MP_ESCAPE);
  203.                     a-=0x80;
  204.                 }
  205.                 PUT(a);
  206.                 break;
  207.         }
  208.         while(stack!=end&&*stack!=MP_OR_END)
  209.             PUT(*stack++);
  210.     }
  211.     if(stack!=end)
  212.         ERROR(ERROR_BAD_TEMPLATE);
  213.     PUT(MP_OR_END);
  214.     PUT(0);
  215.     return iswild;
  216.     AROS_LIBFUNC_EXIT
  217. } /* ParsePattern */
  218.