wild services support

This commit is contained in:
Matej Sekoranja
2014-09-12 09:27:10 +02:00
parent e2facc2eac
commit 282b8fe11c
7 changed files with 668 additions and 5 deletions

168
src/utils/wildcard.cpp Normal file
View File

@@ -0,0 +1,168 @@
/*******************************************************************
* This implementation was adpoted from:
*
* Copyright (C) 1996, 1997, 1998, 1999, 2000 Florian Schintke
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307 USA
*
* F.Schintke, the author of the original code, has authorized to
* distribute these files under LGPL License.
*
* ----------------------
* Implementation of the UN*X wildcards
* Supported wild-characters: '*', '?'; sets: [a-z], '!' negation
* Examples:
* '[a-g]l*i?n' matches 'florian'
* '[!abc]*e' matches 'smile'
* '[-z] matches 'a'
*
*/
#define epicsExportSharedSymbols
#include <pv/wildcard.h>
using namespace epics::pvAccess;
int
Wildcard::wildcardfit (const char *wildcard, const char *test)
{
int fit = 1;
for (; ('\000' != *wildcard) && (1 == fit) && ('\000' != *test); wildcard++)
{
switch (*wildcard)
{
case '[':
wildcard++; /* leave out the opening square bracket */
fit = set (&wildcard, &test);
/* we don't need to decrement the wildcard as in case */
/* of asterisk because the closing ] is still there */
break;
case '?':
test++;
break;
case '*':
fit = asterisk (&wildcard, &test);
/* the asterisk was skipped by asterisk() but the loop will */
/* increment by itself. So we have to decrement */
wildcard--;
break;
default:
fit = (int) (*wildcard == *test);
test++;
}
}
while ((*wildcard == '*') && (1 == fit))
/* here the teststring is empty otherwise you cannot */
/* leave the previous loop */
wildcard++;
return (int) ((1 == fit) && ('\0' == *test) && ('\0' == *wildcard));
}
int
Wildcard::set (const char **wildcard, const char **test)
{
int fit = 0;
int negation = 0;
int at_beginning = 1;
if ('!' == **wildcard)
{
negation = 1;
(*wildcard)++;
}
while ((']' != **wildcard) || (1 == at_beginning))
{
if (0 == fit)
{
if (('-' == **wildcard)
&& ((*(*wildcard - 1)) < (*(*wildcard + 1)))
&& (']' != *(*wildcard + 1))
&& (0 == at_beginning))
{
if (((**test) >= (*(*wildcard - 1)))
&& ((**test) <= (*(*wildcard + 1))))
{
fit = 1;
(*wildcard)++;
}
}
else if ((**wildcard) == (**test))
{
fit = 1;
}
}
(*wildcard)++;
at_beginning = 0;
}
if (1 == negation)
/* change from zero to one and vice versa */
fit = 1 - fit;
if (1 == fit)
(*test)++;
return (fit);
}
int
Wildcard::asterisk (const char **wildcard, const char **test)
{
/* Warning: uses multiple returns */
int fit = 1;
/* erase the leading asterisk */
(*wildcard)++;
while (('\000' != (**test))
&& (('?' == **wildcard)
|| ('*' == **wildcard)))
{
if ('?' == **wildcard)
(*test)++;
(*wildcard)++;
}
/* Now it could be that test is empty and wildcard contains */
/* aterisks. Then we delete them to get a proper state */
while ('*' == (**wildcard))
(*wildcard)++;
if (('\0' == (**test)) && ('\0' != (**wildcard)))
return (fit = 0);
if (('\0' == (**test)) && ('\0' == (**wildcard)))
return (fit = 1);
else
{
/* Neither test nor wildcard are empty! */
/* the first character of wildcard isn't in [*?] */
if (0 == wildcardfit(*wildcard, (*test)))
{
do
{
(*test)++;
/* skip as much characters as possible in the teststring */
/* stop if a character match occurs */
while (((**wildcard) != (**test))
&& ('[' != (**wildcard))
&& ('\0' != (**test)))
(*test)++;
}
while ((('\0' != **test))?
(0 == wildcardfit (*wildcard, (*test)))
: (0 != (fit = 0)));
}
if (('\0' == **test) && ('\0' == **wildcard))
fit = 1;
return (fit);
}
}