Blame config/makedepend/ifparser.c

Packit b099d7
/*
Packit b099d7
 * $XConsortium: ifparser.c /main/10 1996/09/28 16:15:18 rws $
Packit b099d7
 * $XFree86: xc/config/makedepend/ifparser.c,v 3.6 1996/12/30 13:57:55 dawes Exp $
Packit b099d7
 *
Packit b099d7
 * Copyright 1992 Network Computing Devices, Inc.
Packit b099d7
 * 
Packit b099d7
 * Permission to use, copy, modify, and distribute this software and its
Packit b099d7
 * documentation for any purpose and without fee is hereby granted, provided
Packit b099d7
 * that the above copyright notice appear in all copies and that both that
Packit b099d7
 * copyright notice and this permission notice appear in supporting
Packit b099d7
 * documentation, and that the name of Network Computing Devices may not be
Packit b099d7
 * used in advertising or publicity pertaining to distribution of the software
Packit b099d7
 * without specific, written prior permission.  Network Computing Devices makes
Packit b099d7
 * no representations about the suitability of this software for any purpose.
Packit b099d7
 * It is provided ``as is'' without express or implied warranty.
Packit b099d7
 * 
Packit b099d7
 * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
Packit b099d7
 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
Packit b099d7
 * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
Packit b099d7
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
Packit b099d7
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
Packit b099d7
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
Packit b099d7
 * PERFORMANCE OF THIS SOFTWARE.
Packit b099d7
 * 
Packit b099d7
 * Author:  Jim Fulton
Packit b099d7
 *          Network Computing Devices, Inc.
Packit b099d7
 * 
Packit b099d7
 * Simple if statement processor
Packit b099d7
 *
Packit b099d7
 * This module can be used to evaluate string representations of C language
Packit b099d7
 * if constructs.  It accepts the following grammar:
Packit b099d7
 * 
Packit b099d7
 *     EXPRESSION	:=	VALUE
Packit b099d7
 * 			 |	VALUE  BINOP	EXPRESSION
Packit b099d7
 *			 |	VALUE	'?'	EXPRESSION ':'	EXPRESSION
Packit b099d7
 * 
Packit b099d7
 *     VALUE		:=	'('  EXPRESSION  ')'
Packit b099d7
 * 			 |	'!'  VALUE
Packit b099d7
 * 			 |	'-'  VALUE
Packit b099d7
 *			 |	'~'  VALUE
Packit b099d7
 * 			 |	'defined'  '('  variable  ')'
Packit b099d7
 * 			 |	'defined'  variable
Packit b099d7
 *			 |	# variable '(' variable-list ')'
Packit b099d7
 * 			 |	variable
Packit b099d7
 * 			 |	number
Packit b099d7
 * 
Packit b099d7
 *     BINOP		:=	'*'	|  '/'	|  '%'
Packit b099d7
 * 			 |	'+'	|  '-'
Packit b099d7
 * 			 |	'<<'	|  '>>'
Packit b099d7
 * 			 |	'<'	|  '>'	|  '<='  |  '>='
Packit b099d7
 * 			 |	'=='	|  '!='
Packit b099d7
 * 			 |	'&'	|  '^'  |  '|'
Packit b099d7
 * 			 |	'&&'	|  '||'
Packit b099d7
 * 
Packit b099d7
 * The normal C order of precedence is supported.
Packit b099d7
 * 
Packit b099d7
 * 
Packit b099d7
 * External Entry Points:
Packit b099d7
 * 
Packit b099d7
 *     ParseIfExpression		parse a string for #if
Packit b099d7
 */
Packit b099d7
Packit b099d7
#include "ifparser.h"
Packit b099d7
#include <ctype.h>
Packit b099d7
#include <stdlib.h>
Packit b099d7
#include <string.h>
Packit b099d7
Packit b099d7
/****************************************************************************
Packit b099d7
		   Internal Macros and Utilities for Parser
Packit b099d7
 ****************************************************************************/
Packit b099d7
Packit b099d7
#define DO(val) if (!(val)) return NULL
Packit b099d7
#define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff))
Packit b099d7
#define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++
Packit b099d7
#define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_')
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_variable (g, cp, varp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    const char **varp;
Packit b099d7
{
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    if (!isvarfirstletter (*cp))
Packit b099d7
	return CALLFUNC(g, handle_error) (g, cp, "variable name");
Packit b099d7
Packit b099d7
    *varp = cp;
Packit b099d7
    /* EMPTY */
Packit b099d7
    for (cp++; isalnum(*cp) || *cp == '_'; cp++) ;
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_number (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    if (!isdigit(*cp))
Packit b099d7
	return CALLFUNC(g, handle_error) (g, cp, "number");
Packit b099d7
Packit b099d7
    *valp = strtol(cp, &cp, 0);
Packit b099d7
    /* skip trailing qualifiers */
Packit b099d7
    while (*cp == 'U' || *cp == 'u' || *cp == 'L' || *cp == 'l') cp++;
Packit b099d7
#if 0
Packit b099d7
    *valp = atoi (cp);
Packit b099d7
    /* EMPTY */
Packit b099d7
    for (cp++; isdigit(*cp); cp++) ;
Packit b099d7
#endif
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_character (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    char val;
Packit b099d7
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
    if (*cp == '\\')
Packit b099d7
	switch (cp[1]) {
Packit b099d7
	case 'n': val = '\n'; break;
Packit b099d7
	case 't': val = '\t'; break;
Packit b099d7
	case 'v': val = '\v'; break;
Packit b099d7
	case 'b': val = '\b'; break;
Packit b099d7
	case 'r': val = '\r'; break;
Packit b099d7
	case 'f': val = '\f'; break;
Packit b099d7
	case 'a': val = '\a'; break;
Packit b099d7
	case '\\': val = '\\'; break;
Packit b099d7
	case '?': val = '\?'; break;
Packit b099d7
	case '\'': val = '\''; break;
Packit b099d7
	case '\"': val = '\"'; break;
Packit b099d7
	case 'x': val = (char) strtol (cp + 2, NULL, 16); break;
Packit b099d7
	default: val = (char) strtol (cp + 1, NULL, 8); break;
Packit b099d7
	}
Packit b099d7
    else
Packit b099d7
	val = *cp;
Packit b099d7
    while (*cp != '\'') cp++;
Packit b099d7
    *valp = (long) val;
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_value (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    const char *var;
Packit b099d7
Packit b099d7
    *valp = 0;
Packit b099d7
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
    if (!*cp)
Packit b099d7
	return cp;
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '(':
Packit b099d7
	DO (cp = ParseIfExpression (g, cp + 1, valp));
Packit b099d7
	SKIPSPACE (cp);
Packit b099d7
	if (*cp != ')') 
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, ")");
Packit b099d7
Packit b099d7
	return cp + 1;			/* skip the right paren */
Packit b099d7
Packit b099d7
      case '!':
Packit b099d7
	DO (cp = parse_value (g, cp + 1, valp));
Packit b099d7
	*valp = !(*valp);
Packit b099d7
	return cp;
Packit b099d7
Packit b099d7
      case '-':
Packit b099d7
	DO (cp = parse_value (g, cp + 1, valp));
Packit b099d7
	*valp = -(*valp);
Packit b099d7
	return cp;
Packit b099d7
Packit b099d7
      case '~':
Packit b099d7
	DO (cp = parse_value (g, cp + 1, valp));
Packit b099d7
	*valp = ~(*valp);
Packit b099d7
	return cp;
Packit b099d7
Packit b099d7
      case '#':
Packit b099d7
	DO (cp = parse_variable (g, cp + 1, &var);;
Packit b099d7
	SKIPSPACE (cp);
Packit b099d7
	if (*cp != '(')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, "(");
Packit b099d7
	do {
Packit b099d7
	    DO (cp = parse_variable (g, cp + 1, &var);;
Packit b099d7
	    SKIPSPACE (cp);
Packit b099d7
	} while (*cp && *cp != ')');
Packit b099d7
	if (*cp != ')')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, ")");
Packit b099d7
	*valp = 1; /* XXX */
Packit b099d7
	return cp + 1;
Packit b099d7
Packit b099d7
      case '\'':
Packit b099d7
	DO (cp = parse_character (g, cp + 1, valp));
Packit b099d7
	if (*cp != '\'')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, "'");
Packit b099d7
	return cp + 1;
Packit b099d7
Packit b099d7
      case 'd':
Packit b099d7
	if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) {
Packit b099d7
	    int paren = 0;
Packit b099d7
	    int len;
Packit b099d7
Packit b099d7
	    cp += 7;
Packit b099d7
	    SKIPSPACE (cp);
Packit b099d7
	    if (*cp == '(') {
Packit b099d7
		paren = 1;
Packit b099d7
		cp++;
Packit b099d7
	    }
Packit b099d7
	    DO (cp = parse_variable (g, cp, &var);;
Packit b099d7
	    len = cp - var;
Packit b099d7
	    SKIPSPACE (cp);
Packit b099d7
	    if (paren && *cp != ')')
Packit b099d7
		return CALLFUNC(g, handle_error) (g, cp, ")");
Packit b099d7
	    *valp = (*(g->funcs.eval_defined)) (g, var, len);
Packit b099d7
	    return cp + paren;		/* skip the right paren */
Packit b099d7
	}
Packit b099d7
	/* fall out */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (isdigit(*cp)) {
Packit b099d7
	DO (cp = parse_number (g, cp, valp));
Packit b099d7
    } else if (!isvarfirstletter(*cp))
Packit b099d7
	return CALLFUNC(g, handle_error) (g, cp, "variable or number");
Packit b099d7
    else {
Packit b099d7
	DO (cp = parse_variable (g, cp, &var);;
Packit b099d7
	*valp = (*(g->funcs.eval_variable)) (g, var, cp - var);
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_product (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_value (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '*':
Packit b099d7
	DO (cp = parse_product (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp * rightval);
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '/':
Packit b099d7
	DO (cp = parse_product (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp / rightval);
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '%':
Packit b099d7
	DO (cp = parse_product (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp % rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_sum (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_product (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '+':
Packit b099d7
	DO (cp = parse_sum (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp + rightval);
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '-':
Packit b099d7
	DO (cp = parse_sum (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp - rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_shift (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_sum (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '<':
Packit b099d7
	if (cp[1] == '<') {
Packit b099d7
	    DO (cp = parse_shift (g, cp + 2, &rightval));
Packit b099d7
	    *valp = (*valp << rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '>':
Packit b099d7
	if (cp[1] == '>') {
Packit b099d7
	    DO (cp = parse_shift (g, cp + 2, &rightval));
Packit b099d7
	    *valp = (*valp >> rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_inequality (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_shift (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '<':
Packit b099d7
	if (cp[1] == '=') {
Packit b099d7
	    DO (cp = parse_inequality (g, cp + 2, &rightval));
Packit b099d7
	    *valp = (*valp <= rightval);
Packit b099d7
	} else {
Packit b099d7
	    DO (cp = parse_inequality (g, cp + 1, &rightval));
Packit b099d7
	    *valp = (*valp < rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '>':
Packit b099d7
	if (cp[1] == '=') {
Packit b099d7
	    DO (cp = parse_inequality (g, cp + 2, &rightval));
Packit b099d7
	    *valp = (*valp >= rightval);
Packit b099d7
	} else {
Packit b099d7
	    DO (cp = parse_inequality (g, cp + 1, &rightval));
Packit b099d7
	    *valp = (*valp > rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_equality (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_inequality (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '=':
Packit b099d7
	if (cp[1] == '=')
Packit b099d7
	    cp++;
Packit b099d7
	DO (cp = parse_equality (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp == rightval);
Packit b099d7
	break;
Packit b099d7
Packit b099d7
      case '!':
Packit b099d7
	if (cp[1] != '=')
Packit b099d7
	    break;
Packit b099d7
	DO (cp = parse_equality (g, cp + 2, &rightval));
Packit b099d7
	*valp = (*valp != rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_band (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_equality (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '&':
Packit b099d7
	if (cp[1] != '&') {
Packit b099d7
	    DO (cp = parse_band (g, cp + 1, &rightval));
Packit b099d7
	    *valp = (*valp & rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_bxor (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_band (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '^':
Packit b099d7
	DO (cp = parse_bxor (g, cp + 1, &rightval));
Packit b099d7
	*valp = (*valp ^ rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_bor (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_bxor (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '|':
Packit b099d7
	if (cp[1] != '|') {
Packit b099d7
	    DO (cp = parse_bor (g, cp + 1, &rightval));
Packit b099d7
	    *valp = (*valp | rightval);
Packit b099d7
	}
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_land (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_bor (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '&':
Packit b099d7
	if (cp[1] != '&')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, "&&";;
Packit b099d7
	DO (cp = parse_land (g, cp + 2, &rightval));
Packit b099d7
	*valp = (*valp && rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_lor (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long rightval;
Packit b099d7
Packit b099d7
    DO (cp = parse_land (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '|':
Packit b099d7
	if (cp[1] != '|')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, "||");
Packit b099d7
	DO (cp = parse_lor (g, cp + 2, &rightval));
Packit b099d7
	*valp = (*valp || rightval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static const char *
Packit b099d7
parse_cond(g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    long trueval, falseval;
Packit b099d7
Packit b099d7
    DO (cp = parse_lor (g, cp, valp));
Packit b099d7
    SKIPSPACE (cp);
Packit b099d7
Packit b099d7
    switch (*cp) {
Packit b099d7
      case '?':
Packit b099d7
	DO (cp = parse_cond (g, cp + 1, &trueval));
Packit b099d7
	SKIPSPACE (cp);
Packit b099d7
	if (*cp != ':')
Packit b099d7
	    return CALLFUNC(g, handle_error) (g, cp, ":");
Packit b099d7
	DO (cp = parse_cond (g, cp + 1, &falseval));
Packit b099d7
	*valp = (*valp ? trueval : falseval);
Packit b099d7
	break;
Packit b099d7
    }
Packit b099d7
    return cp;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/****************************************************************************
Packit b099d7
			     External Entry Points
Packit b099d7
 ****************************************************************************/
Packit b099d7
Packit b099d7
const char *
Packit b099d7
ParseIfExpression (g, cp, valp)
Packit b099d7
    IfParser *g;
Packit b099d7
    const char *cp;
Packit b099d7
    long *valp;
Packit b099d7
{
Packit b099d7
    return parse_cond (g, cp, valp);
Packit b099d7
}