File: conf_filter.c

package info (click to toggle)
swish++ 6.1.5-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 2,256 kB
  • ctags: 1,759
  • sloc: ansic: 11,931; lisp: 804; sh: 629; perl: 366; makefile: 80
file content (120 lines) | stat: -rw-r--r-- 3,048 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
**	SWISH++
**	conf_filter.c
**
**	Copyright (C) 1998  Paul J. Lucas
**
**	This program is free software; you can redistribute it and/or modify
**	it under the terms of the GNU General Public License as published by
**	the Free Software Foundation; either version 2 of the License, or
**	(at your option) any later version.
**
**	This program 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 General Public License for more details.
**
**	You should have received a copy of the GNU General Public License
**	along with this program; if not, write to the Free Software
**	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

// standard
#include <cstdlib>			/* for exit(2) */
#include <cstring>

// local
#include "exit_codes.h"
#include "conf_filter.h"
#include "platform.h"

using namespace std;

//*****************************************************************************
//
// SYNOPSIS
//
	/* virtual */ void conf_filter::parse_value( char *line )
//
// DESCRIPTION
//
//	Parse a conf_filter configuration file line.  The format of such a line
//	is:
//
//		pattern	command
//
//	where "pattern" is a pattern and "command" is the command-line for
//	executing the filter on a file.
//
//	Furthermore, ensure the filter contains % and @ filename substitutions.
//
// PARAMETERS
//
//	line	The line to be parsed.
//
//*****************************************************************************
{
	char const *const pattern = ::strtok( line, " \r\t" );
	if ( !pattern ) {
		error() << "no pattern\n";
		::exit( Exit_Config_File );
	}
	char const *const command = ::strtok( 0, "\n" );
	if ( !command ) {
		error() << "no filter command\n";
		::exit( Exit_Config_File );
	}

	//
	// Check a filter command's %@ substitutions to ensure they're valid,
	// that there are at least two of them, and that exactly one of them is
	// a @ meaning the target filename.  Also ignore %% or @@ respresenting
	// literal @ or %, respectively.
	//
	bool	found_target = false;
	int	num_substitutions = 0;

	for ( register char const*
		s = command; *s && ( s = ::strpbrk( s, "%@" ) ); ++s
	) {
		if ( s[0] == s[1] ) {		// %% or @@ ...
			++s;			// ... skip past it
			continue;
		}

		if ( *s == '@' )
			if ( found_target ) {
				error() << "more than one @\n";
				::exit( Exit_Config_File );
			} else {
				found_target = true;
				continue;
			}

		switch ( s[1] ) {
			case 'b':
			case 'B':
			case 'e':
			case 'E':
			case 'f':
			case 'F':
				++num_substitutions;
				continue;
		}
		error() << "non-[bBeEfF%] character after %\n";
		::exit( Exit_Config_File );
	}

	if ( num_substitutions < 1 ) {
		error() << "at least 1 substitution is required\n";
		::exit( Exit_Config_File );
	}
	if ( !found_target ) {
		error() << "filter does not contain required @\n";
		::exit( Exit_Config_File );
	}

	map_.insert( map_type::value_type(
		::strdup( pattern ), value_type( ::strdup( command ) )
	) );
}