69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * CDDL HEADER START
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The contents of this file are subject to the terms of the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Common Development and Distribution License (the "License").
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * You may not use this file except in compliance with the License.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * or http://www.opensolaris.org/os/licensing.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * See the License for the specific language governing permissions
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and limitations under the License.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * When distributing Covered Code, include this CDDL HEADER in each
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If applicable, add the following below this CDDL HEADER, with the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * fields enclosed by brackets "[]" replaced with your own identifying
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * information: Portions Copyright [yyyy] [name of copyright owner]
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * CDDL HEADER END
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Copyright (c) 1988 AT&T
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * All Rights Reserved
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Map file parsing (Shared Core Code).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <fcntl.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <stdio.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <unistd.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <sys/stat.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <errno.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <limits.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <dirent.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <ctype.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include <debug.h>
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include "msg.h"
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include "_libld.h"
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#include "_map.h"
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * There are two styles of mapfile supported by the link-editor:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 1) The original System V defined syntax, as augmented at Sun
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * from Solaris 2.0 through Solaris 10. This style is also known
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * as version 1.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 2) A newer syntax, currently at version 2.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The original syntax uses special characters (=, :, -, |, etc) as
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * operators to indicate the operation being specified. Over the years,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * this syntax has been problematic:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 1) Too cryptic: It's hard for people to remember which character
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * means what.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 2) Limited expansion potential: There only a few special characters
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * available on the keyboard for new features, and it is difficult to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * add options to existing ones.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Adding new features into this framework (2) have the effect of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * making the syntax even more cryptic (1). The newer syntax addresses
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * these issues by moving to an extendible identifier based syntax that
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * allows new features to be added without complicating old ones.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The new syntax uses the following terminology:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Control directives are the directives that start with a '$'.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * They control how the mapfile is interpreted. We use the 'cdir_'
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * prefix on functions and variables related to these directives.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Conditional Expressions are the expressions found in $if and $elif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * control directives. They evaluate to boolean true/false values.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We use the 'cexp_' prefix for functions and variables related to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * these expressions.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Regular Directives are names (SYMBOL, VERSION, etc) that convey
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * directions to the link-editor for building the output object.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This file contains core code used by both mapfile styles: File management,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * lexical analysis, and other shared core functionality. It also contains
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the code for control directives, as they are intrinsically part of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * lexical analysis --- this is disabled when processing Sysv mapfiles.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We use a stack of cdir_level_t structs to manage $if/$elif/$else/$endif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * processing. At each level, we keep track of the information needed to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * determine whether or not to process nested input lines or skip them,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * along with information needed to report errors.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitypedef struct {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Lineno cdl_if_lineno; /* Line number of opening $if */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Lineno cdl_else_lineno; /* 0, or line on which $else seen */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int cdl_done; /* True if no longer accepts input */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int cdl_pass; /* True if currently accepting input */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami} cdir_level_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/* Operators in the expressions accepted by $if/$elif */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitypedef enum {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_NONE, /* Not an operator */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_AND, /* && */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_OR, /* || */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_NEG, /* ! */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_OPAR, /* ( */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_OP_CPAR /* ) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami} cexp_op_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Type of conditional expression identifier AVL tree nodes
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitypedef struct cexp_name_node {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami avl_node_t ceid_avlnode; /* AVL book-keeping */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami const char *ceid_name; /* boolean identifier name */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami} cexp_id_node_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Declare a "stack" type, containing a pointer to data, a count of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * allocated, and currently used items in the stack. The data type
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * is specified as the _type argument.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK(_type) \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami struct { \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami _type *stk_s; /* Stack array */ \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t stk_n; /* Current stack depth */ \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t stk_n_alloc; /* # of elements pointed at by s */ \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The following type represents a "generic" stack, where the data
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * type is (void). This type is never instantiated. However, it has
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the same struct layout as any other STACK(), and is therefore a good
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * generic type that can be used for stack_resize().
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitypedef STACK(void) generic_stack_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Ensure that the stack has enough room to push one more item
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_RESERVE(_stack, _n_default) \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (((_stack).stk_n < (_stack).stk_n_alloc) || \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami stack_resize((generic_stack_t *)&(_stack).stk_s, _n_default, \
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sizeof (*(_stack).stk_s)))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Reset a stack to empty.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_RESET(_stack) (_stack).stk_n = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * True if stack is empty, False otherwise.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_IS_EMPTY(_stack) ((_stack).stk_n == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Push a value onto a stack. Caller must ensure that stack has room.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This macro is intended to be used as the LHS of an assignment, the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * RHS of which is the value:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * STACK_PUSH(stack) = value;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_PUSH(_stack) (_stack).stk_s[(_stack).stk_n++]
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Pop a value off a stack. Caller must ensure
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * that stack is not empty.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_POP(_stack) ((_stack).stk_s[--(_stack).stk_n])
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Access top element on stack without popping. Caller must ensure
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * that stack is not empty.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define STACK_TOP(_stack) (((_stack).stk_s)[(_stack).stk_n - 1])
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Initial sizes used for the stacks: The stacks are allocated on demand
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to these sizes, and then doubled as necessary until they are large enough.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The ideal size would be large enough that only a single allocation
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * occurs, and our defaults should generally have that effect. However,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * in doing so, we run the risk of a latent error in the resize code going
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * undetected until triggered by a large task in the field. For this reason,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * we set the sizes to the smallest size possible when compiled for debug.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#ifdef DEBUG
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CDIR_STACK_INIT 1
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CEXP_OP_STACK_INIT 1
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CEXP_VAL_STACK_INIT 1
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#else
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CDIR_STACK_INIT 16
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CEXP_OP_STACK_INIT 8
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define CEXP_VAL_STACK_INIT (CEXP_OP_STACK_INIT * 2) /* 2 vals per binop */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#endif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Persistent state maintained by map module in between calls.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This is kept as static file scope data, because it is only used
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * when libld is called by ld, and not by rtld. If that should change,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the code is designed so that it can become reentrant easily:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Add a pointer to the output descriptor to a structure of this type,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * allocated dynamically on the first call to ld_map_parse().
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Change all references to lms to instead reference the pointer in
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the output descriptor.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Until then, it is simpler not to expose these details.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitypedef struct {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int lms_cdir_valid; /* Allow control dir. on entry to gettoken() */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK(cdir_level_t) lms_cdir_stack; /* Conditional input level */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK(cexp_op_t) lms_cexp_op_stack; /* Cond. expr operators */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK(uchar_t) lms_cexp_val_stack; /* Cond. expr values */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami avl_tree_t *lms_cexp_id;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami} ld_map_state_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic ld_map_state_t lms;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Version 1 (SysV) syntax dispatch table for ld_map_gettoken(). For each
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * of the 7-bit ASCII characters, determine how the lexical analyzer
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * should behave.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This table must be kept in sync with tkid_attr[] below.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Identifier Note:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The Linker and Libraries Guide states that the original syntax uses
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * C identifier rules, allowing '.' to be treated as a letter. However,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the implementation is considerably looser than that: Any character
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * with an ASCII code (0-127) which is printable and not used to start
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * another token is allowed to start an identifier, and they are terminated
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * by any of: space, double quote, tab, newline, ':', ';', '=', or '#'.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The original code has been replaced, but this table encodes the same
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * rules, to ensure backward compatibility.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic const mf_tokdisp_t gettok_dispatch_v1 = {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_EOF, /* 0 - NUL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 1 - SOH */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 2 - STX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 3 - ETX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 4 - EOT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 5 - ENQ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 6 - ACK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 7 - BEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 8 - BS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 9 - HT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NL, /* 10 - NL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 11 - VT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 12 - FF */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 13 - CR */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 14 - SO */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 15 - SI */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 16 - DLE */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 17 - DC1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 18 - DC2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 19 - DC3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 20 - DC4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 21 - NAK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 22 - SYN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 23 - ETB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 24 - CAN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 25 - EM */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 26 - SUB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 27 - ESC */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 28 - FS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 29 - GS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 30 - RS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 31 - US */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 32 - SP */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 33 - ! */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_SIMQUOTE, /* 34 - " */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CMT, /* 35 - # */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 36 - $ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 37 - % */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 38 - & */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 39 - ' */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 40 - ( */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 41 - ) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 42 - * */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 43 - + */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 44 - , */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_DASH, /* 45 - - */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 46 - . */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 47 - / */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 48 - 0 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 49 - 1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 50 - 2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 51 - 3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 52 - 4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 53 - 5 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 54 - 6 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 55 - 7 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 56 - 8 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 57 - 9 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_COLON, /* 58 - : */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_SEMICOLON, /* 59 - ; */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 60 - < */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_EQUAL, /* 61 - = */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 62 - > */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 63 - ? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_ATSIGN, /* 64 - @ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 65 - A */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 66 - B */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 67 - C */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 68 - D */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 69 - E */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 70 - F */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 71 - G */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 72 - H */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 73 - I */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 74 - J */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 75 - K */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 76 - L */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 77 - M */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 78 - N */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 79 - O */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 80 - P */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 81 - Q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 82 - R */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 83 - S */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 84 - T */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 85 - U */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 86 - V */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 87 - W */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 88 - X */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 89 - Y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 90 - Z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 91 - [ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 92 - \ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 93 - ] */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 94 - ^ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 95 - _ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 96 - ` */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 97 - a */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 98 - b */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 99 - c */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 100 - d */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 101 - e */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 102 - f */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 103 - g */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 104 - h */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 105 - i */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 106 - j */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 107 - k */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 108 - l */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 109 - m */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 110 - n */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 111 - o */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 112 - p */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 113 - q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 114 - r */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 115 - s */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 116 - t */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 117 - u */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 118 - v */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 119 - w */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 120 - x */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 121 - y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 122 - z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_LEFTBKT, /* 123 - { */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_PIPE, /* 124 - | */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_RIGHTBKT, /* 125 - } */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 126 - ~ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 127 - DEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami};
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Version 2 syntax dispatch table for ld_map_gettoken(). For each of the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 7-bit ASCII characters, determine how the lexical analyzer should behave.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This table must be kept in sync with tkid_attr[] below.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Identifier Note:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We define a letter as being one of the character [A-Z], [a-z], or [_%/.]
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * A digit is the numbers [0-9], or [$-]. An unquoted identifier is defined
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * as a letter, followed by any number of letters or digits. This is a loosened
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * version of the C definition of an identifier. The extra characters not
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * allowed by C are common in section names and/or file paths.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic const mf_tokdisp_t gettok_dispatch_v2 = {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_EOF, /* 0 - NUL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 1 - SOH */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 2 - STX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 3 - ETX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 4 - EOT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 5 - ENQ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 6 - ACK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 7 - BEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 8 - BS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 9 - HT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NL, /* 10 - NL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 11 - VT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 12 - FF */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 13 - CR */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 14 - SO */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 15 - SI */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 16 - DLE */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 17 - DC1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 18 - DC2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 19 - DC3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 20 - DC4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 21 - NAK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 22 - SYN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 23 - ETB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 24 - CAN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 25 - EM */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 26 - SUB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 27 - ESC */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 28 - FS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 29 - GS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 30 - RS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 31 - US */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_WS, /* 32 - SP */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_BANG, /* 33 - ! */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CQUOTE, /* 34 - " */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CMT, /* 35 - # */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CDIR, /* 36 - $ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 37 - % */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 38 - & */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_SIMQUOTE, /* 39 - ' */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 40 - ( */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 41 - ) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_STAR, /* 42 - * */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CEQUAL, /* 43 - + */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 44 - , */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_CEQUAL, /* 45 - - */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 46 - . */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 47 - / */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 48 - 0 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 49 - 1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 50 - 2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 51 - 3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 52 - 4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 53 - 5 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 54 - 6 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 55 - 7 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 56 - 8 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_NUM, /* 57 - 9 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_COLON, /* 58 - : */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_SEMICOLON, /* 59 - ; */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 60 - < */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_EQUAL, /* 61 - = */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 62 - > */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 63 - ? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 64 - @ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 65 - A */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 66 - B */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 67 - C */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 68 - D */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 69 - E */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 70 - F */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 71 - G */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 72 - H */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 73 - I */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 74 - J */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 75 - K */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 76 - L */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 77 - M */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 78 - N */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 79 - O */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 80 - P */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 81 - Q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 82 - R */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 83 - S */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 84 - T */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 85 - U */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 86 - V */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 87 - W */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 88 - X */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 89 - Y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 90 - Z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 91 - [ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 92 - \ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 93 - ] */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 94 - ^ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 95 - _ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 96 - ` */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 97 - a */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 98 - b */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 99 - c */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 100 - d */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 101 - e */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 102 - f */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 103 - g */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 104 - h */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 105 - i */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 106 - j */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 107 - k */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 108 - l */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 109 - m */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 110 - n */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 111 - o */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 112 - p */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 113 - q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 114 - r */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 115 - s */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 116 - t */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 117 - u */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 118 - v */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 119 - w */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 120 - x */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 121 - y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ID, /* 122 - z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_LEFTBKT, /* 123 - { */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 124 - | */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_RIGHTBKT, /* 125 - } */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_BADCHR, /* 126 - ~ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR, /* 127 - DEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami};
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Table used to identify unquoted identifiers. Each element of this array
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * contains a bitmask indicating whether the character it represents starts,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * or continues an identifier, for each supported mapfile syntax version.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic const char tkid_attr[128] = {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 0 - NUL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 1 - SOH */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 2 - STX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 3 - ETX */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 4 - EOT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 5 - ENQ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 6 - ACK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 7 - BEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 8 - BS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 9 - HT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 10 - NL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 11 - VT */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 12 - FF */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 13 - CR */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 14 - SO */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 15 - SI */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 16 - DLE */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 17 - DC1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 18 - DC2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 19 - DC3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 20 - DC4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 21 - NAK */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 22 - SYN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 23 - ETB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 24 - CAN */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 25 - EM */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 26 - SUB */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 27 - ESC */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 28 - FS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 29 - GS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 30 - RS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 31 - US */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 32 - SP */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 33 - ! */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 34 - " */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 35 - # */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 36 - $ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 37 - % */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 38 - & */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 39 - ' */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 40 - ( */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 41 - ) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 42 - * */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 43 - + */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 44 - , */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1) | TKID_ATTR_CONT(2), /* 45 - - */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 46 - . */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 47 - / */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 48 - 0 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 49 - 1 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 50 - 2 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 51 - 3 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 52 - 4 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 53 - 5 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 54 - 6 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 55 - 7 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 56 - 8 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR_CONT(2), /* 57 - 9 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 58 - : */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 59 - ; */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 60 - < */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0, /* 61 - = */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 62 - > */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 63 - ? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 64 - @ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 65 - A */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 66 - B */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 67 - C */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 68 - D */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 69 - E */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 70 - F */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 71 - G */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 72 - H */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 73 - I */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 74 - J */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 75 - K */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 76 - L */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 77 - M */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 78 - N */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 79 - O */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 80 - P */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 81 - Q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 82 - R */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 83 - S */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 84 - T */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 85 - U */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 86 - V */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 87 - W */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 88 - X */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 89 - Y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 90 - Z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 91 - [ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 92 - \ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 93 - ] */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 94 - ^ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 95 - _ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 96 - ` */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 97 - a */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 98 - b */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 99 - c */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 100 - d */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 101 - e */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 102 - f */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 103 - g */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 104 - h */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 105 - i */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 106 - j */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 107 - k */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 108 - l */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 109 - m */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 110 - n */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 111 - o */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 112 - p */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 113 - q */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 114 - r */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 115 - s */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 116 - t */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 117 - u */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 118 - v */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 119 - w */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 120 - x */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 121 - y */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1) | TKID_ATTR(2), /* 122 - z */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 123 - { */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 124 - | */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 125 - } */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR(1), /* 126 - ~ */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TKID_ATTR_CONT(1), /* 127 - DEL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami};
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Advance the given string pointer to the next newline character,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * or the terminating NULL if there is none.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static void
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiadvance_to_eol(char **str)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *s = *str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while ((*s != '\n') && (*s != '\0'))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami s++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *str = s;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Insert a NULL patch at the given address
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static void
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahraminull_patch_set(char *str, ld_map_npatch_t *np)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami np->np_ptr = str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami np->np_ch = *str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *str = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Undo a NULL patch
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static void
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahraminull_patch_undo(ld_map_npatch_t *np)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *np->np_ptr = np->np_ch;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Insert a NULL patch at the end of the line containing str.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic void
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahraminull_patch_eol(char *str, ld_map_npatch_t *np)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami advance_to_eol(&str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_set(str, np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Locate the end of an unquoted identifier.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor, positioned to first character
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * of identifier.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the item pointed at by mf is not an identifier, returns NULL.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Otherwise, returns pointer to character after the last character
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * of the identifier.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static char *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiident_delimit(Mapfile *mf)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *str = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int c = *str++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* If not a valid start character, report the error */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((c & 0x80) || !(tkid_attr[c] & mf->mf_tkid_start)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_set(str, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (NULL);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Keep going until we hit a non-continuing character */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (c = *str; !(c & 0x80) && (tkid_attr[c] & mf->mf_tkid_cont);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami c = *++str)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Allocate memory for a stack.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * stack - Pointer to stack for which memory is required, cast
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to the generic stack type.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * n_default - Size to use for initial allocation.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * elt_size - sizeof(elt), where elt is the actual stack data type.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns (1) on success. On error (memory allocation), a message
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * is printed and False (0) is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * note:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The caller casts the pointer to their actual datatype-specific stack
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to be a (generic_stack_t *). The C language will give all stack
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * structs the same size and layout as long as the underlying platform
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * uses a single integral type for pointers. Hence, this cast is safe,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and lets a generic routine modify data-specific types without being
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * aware of those types.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistack_resize(generic_stack_t *stack, size_t n_default, size_t elt_size)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t new_n_alloc;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami void *newaddr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Use initial size first, and double the allocation on each call */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_n_alloc = (stack->stk_n_alloc == 0) ?
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami n_default : (stack->stk_n_alloc * 2);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami newaddr = libld_realloc(stack->stk_s, new_n_alloc * elt_size);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (newaddr == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami stack->stk_s = newaddr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami stack->stk_n_alloc = new_n_alloc;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * AVL comparison function for cexp_id_node_t items.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * n1, n2 - pointers to nodes to be compared
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns -1 if (n1 < n2), 0 if they are equal, and 1 if (n1 > n2)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic int
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_cmp(const void *n1, const void *n2)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int rc;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami rc = strcmp(((cexp_id_node_t *)n1)->ceid_name,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ((cexp_id_node_t *)n2)->ceid_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (rc > 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (rc < 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns True (1) if name is in the conditional expression identifier
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * AVL tree, and False (0) otherwise.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic int
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_test(const char *name)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_id_node_t node;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami node.ceid_name = name;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (avl_find(lms.lms_cexp_id, &node, 0) != NULL);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Add a new boolean identifier to the conditional expression identifier
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * AVL tree.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - If non-NULL, the mapfile descriptor for the mapfile
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * containing the $add directive. NULL if this is an
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * initialization call.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * name - Name of identifier. Must point at stable storage that will
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * not be moved or modified by the caller following this call.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, True (1) is returned and name has been entered.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, False (0) is returned and an error has been printed.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic int
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_add(Mapfile *mf, const char *name)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_id_node_t *node;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (mf != NULL) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_cexp_id(mf->mf_ofl->ofl_lml, 1,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_name, mf->mf_lineno, name));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* If is already known, don't do it again */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cexp_ident_test(name))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((node = libld_calloc(sizeof (*node), 1)) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami node->ceid_name = name;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami avl_add(lms.lms_cexp_id, node);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Remove a boolean identifier from the conditional expression identifier
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * AVL tree.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * name - Name of identifier.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the name was in the tree, it has been removed. If not,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * then this routine quietly returns.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic void
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_clear(Mapfile *mf, const char *name)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_id_node_t node;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_id_node_t *real_node;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_cexp_id(mf->mf_ofl->ofl_lml, 0,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_name, mf->mf_lineno, name));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami node.ceid_name = name;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami real_node = avl_find(lms.lms_cexp_id, &node, 0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (real_node != NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami avl_remove(lms.lms_cexp_id, real_node);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Initialize the AVL tree that holds the names of the currently defined
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * boolean identifiers for conditional expressions ($if/$elif).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ofl - Output file descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, TRUE (1) is returned and lms.lms_cexp_id is ready for use.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, FALSE (0) is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_init(void)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* If already done, use it */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_id != NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami lms.lms_cexp_id = libld_calloc(sizeof (*lms.lms_cexp_id), 1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_id == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami avl_create(lms.lms_cexp_id, cexp_ident_cmp, sizeof (cexp_id_node_t),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami SGSOFFSETOF(cexp_id_node_t, ceid_avlnode));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* ELFCLASS */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cexp_ident_add(NULL, (ld_targ.t_m.m_class == ELFCLASS32) ?
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_UELF32) : MSG_ORIG(MSG_STR_UELF64)) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Machine */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (ld_targ.t_m.m_mach) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case EM_386:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case EM_AMD64:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_UX86)) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case EM_SPARC:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case EM_SPARCV9:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_USPARC)) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* true is always defined */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cexp_ident_add(NULL, MSG_ORIG(MSG_STR_TRUE)) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Validate the string starting at mf->mf_next as being a
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * boolean conditional expression identifier.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * len - NULL, or address of variable to receive strlen() of identifier
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * directive - If (len == NULL), string giving name of directive being
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * processed. Ignored if (len != NULL).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - If len is NULL, a NULL is inserted following the final
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * character of the identifier, and the remainder of the string
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * is tested to ensure it is empty, or only contains whitespace.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - If len is non-NULL, *len is set to the number of characters
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * in the identifier, and the rest of the string is not modified.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - TRUE (1) is returned
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, returns FALSE (0).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_ident_validate(Mapfile *mf, size_t *len, const char *directive)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *tail;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((tail = ident_delimit(mf)) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If len is non-NULL, we simple count the number of characters
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * consumed by the identifier and are done. If len is NULL, then
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ensure there's nothing left but whitespace, and NULL terminate
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the identifier to remove it.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (len != NULL) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *len = tail - mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else if (*tail != '\0') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *tail++ = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (isspace(*tail))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tail++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*tail != '\0') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADEXTRA), directive);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Push a new operator onto the conditional expression operator stack.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * op - Operator to push
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, TRUE (1) is returned, otherwise FALSE (0).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_push_op(cexp_op_t op)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_RESERVE(lms.lms_cexp_op_stack, CEXP_OP_STACK_INIT) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_PUSH(lms.lms_cexp_op_stack) = op;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Evaluate the basic operator (non-paren) at the top of lms.lms_cexp_op_stack,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and push the results on lms.lms_cexp_val_stack.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, returns TRUE (1). On error, FALSE (0) is returned,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and the caller is responsible for issuing the error.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_eval_op(void)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_op_t op;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami uchar_t val;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami op = STACK_POP(lms.lms_cexp_op_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (op) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CEXP_OP_AND:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_val_stack.stk_n < 2)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami val = STACK_POP(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cexp_val_stack) = val &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CEXP_OP_OR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_val_stack.stk_n < 2)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami val = STACK_POP(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cexp_val_stack) = val ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CEXP_OP_NEG:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_val_stack.stk_n < 1)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cexp_val_stack) =
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami !STACK_TOP(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Evaluate an expression for a $if/$elif control directive.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor for NULL terminated string
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * containing the expression.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The contents of str are modified by this routine.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * One of the following values are returned:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * -1 Syntax error encountered (an error is printed)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 0 The expression evaluates to False
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 1 The expression evaluates to True.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * note:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * A simplified version of Dijkstra's Shunting Yard algorithm is used
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to convert this syntax into postfix form and then evaluate it.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Our version has no functions and a tiny set of operators.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The expressions consist of boolean identifiers, which can be
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * combined using the following operators, listed from highest
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * precedence to least:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Operator Meaning
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * -------------------------------------------------
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * (expr) sub-expression, non-associative
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ! logical negation, prefix, left associative
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * && || logical and/or, binary, left associative
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The operands manipulated by these operators are names, consisting of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a sequence of letters and digits. The first character must be a letter.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Underscore (_) and period (.) are also considered to be characters.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * An operand is considered True if it is found in our set of known
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * names (lms.lms_cexp_id), and False otherwise.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The Shunting Yard algorithm works using two stacks, one for operators,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and a second for operands. The infix input expression is tokenized from
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * left to right and processed in order. Issues of associativity and
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * precedence are managed by reducing (poping and evaluating) items with
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * higer precedence before pushing additional tokens with lower precedence.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic int
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicexp_eval_expr(Mapfile *mf)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *ident;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t len;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_op_t new_op = CEXP_OP_AND; /* to catch binop at start */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *str = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_RESET(lms.lms_cexp_op_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_RESET(lms.lms_cexp_val_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (; *str; str++) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Skip whitespace */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (isspace(*str))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!*str)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (*str) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case '&':
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case '|':
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*(str + 1) != *str)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto token_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((new_op != CEXP_OP_NONE) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (new_op != CEXP_OP_CPAR)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_BADOPUSE));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * As this is a left associative binary operator, we
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * need to process all operators of equal or higher
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * precedence before pushing the new operator.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_op_t op = STACK_TOP(lms.lms_cexp_op_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((op != CEXP_OP_AND) && (op != CEXP_OP_OR) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (op != CEXP_OP_NEG))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_eval_op())
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto semantic_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_op = (*str == '&') ? CEXP_OP_AND : CEXP_OP_OR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_push_op(new_op))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case '!':
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_op = CEXP_OP_NEG;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_push_op(new_op))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case '(':
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_op = CEXP_OP_OPAR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_push_op(new_op))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case ')':
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_op = CEXP_OP_CPAR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Evaluate the operator stack until reach '(' */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (STACK_TOP(lms.lms_cexp_op_stack) != CEXP_OP_OPAR))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_eval_op())
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto semantic_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the top of operator stack is not an open paren,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * when we have an error. In this case, the operator
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * stack will be empty due to the loop above.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_IS_EMPTY(lms.lms_cexp_op_stack))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto unbalpar_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami lms.lms_cexp_op_stack.stk_n--; /* Pop OPAR */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Ensure there's room to push another operand */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_RESERVE(lms.lms_cexp_val_stack,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CEXP_VAL_STACK_INIT) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami new_op = CEXP_OP_NONE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Operands cannot be numbers. However, we accept two
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * special cases: '0' means false, and '1' is true.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This is done to support the common C idiom of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * '#if 1' and '#if 0' to conditionalize code under
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * development.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((*str == '0') || (*str == '1')) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_PUSH(lms.lms_cexp_val_stack) =
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (*str == '1');
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Look up the identifier */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ident = mf->mf_next = str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_ident_validate(mf, &len, NULL))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str += len - 1; /* loop will advance past final ch */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_set(&ident[len], &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_PUSH(lms.lms_cexp_val_stack) =
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_ident_test(ident);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Evaluate the operator stack until empty */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (!STACK_IS_EMPTY(lms.lms_cexp_op_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_TOP(lms.lms_cexp_op_stack) == CEXP_OP_OPAR)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto unbalpar_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_eval_op())
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto semantic_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* There should be exactly one value left */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (lms.lms_cexp_val_stack.stk_n != 1)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto semantic_error;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Final value is the result */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (lms.lms_cexp_val_stack.stk_s[0]);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Errors issued more than once are handled below, accessed via goto */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramitoken_error: /* unexpected characters in input stream */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_CEXP_TOKERR), str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramisemantic_error: /* valid tokens, but in invalid arrangement */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_SEMERR));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiunbalpar_error: /* Extra or missing parenthesis */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_CEXP_UNBALPAR));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (-1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Process a mapfile control directive. These directives start with
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the dollar character, and are used to manage details of the mapfile
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * itself, such as version and conditional input.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns TRUE (1) for success, and FALSE (0) on error. In the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * error case, a descriptive error is issued.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramicdir_process(Mapfile *mf)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami typedef enum { /* Directive types */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_UNKNOWN = 0, /* Unrecognized control directive */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_ADD, /* $add */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_CLEAR, /* $clear */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_ERROR, /* $error */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_VERSION, /* $mapfile_version */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_IF, /* $if */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_ELIF, /* $elif */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_ELSE, /* $else */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami CDIR_T_ENDIF, /* $endif */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } cdir_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami typedef enum { /* Types of arguments accepted by directives */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_NONE, /* Directive takes no arguments */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_EXPR, /* Directive takes a conditional expression */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_ID, /* Conditional expression identifier */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_STR, /* Non-empty string */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_IGN /* Ignore the argument */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } cdir_arg_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami typedef struct {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami const char *md_name; /* Directive name */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t md_size; /* strlen(md_name) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_arg_t md_arg; /* Type of arguments */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_t md_op; /* CDIR_T_ code */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } cdir_match_t;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Control Directives: The most likely items are listed first */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami static cdir_match_t match_data[] = {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_IF), MSG_STR_CDIR_IF_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_EXPR, CDIR_T_IF },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_ENDIF), MSG_STR_CDIR_ENDIF_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_NONE, CDIR_T_ENDIF },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_ELSE), MSG_STR_CDIR_ELSE_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_NONE, CDIR_T_ELSE },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_ELIF), MSG_STR_CDIR_ELIF_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_EXPR, CDIR_T_ELIF },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_ERROR), MSG_STR_CDIR_ERROR_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_STR, CDIR_T_ERROR },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_ADD), MSG_STR_CDIR_ADD_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_ID, CDIR_T_ADD },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_CLEAR), MSG_STR_CDIR_CLEAR_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_ID, CDIR_T_CLEAR },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { MSG_ORIG(MSG_STR_CDIR_MFVER), MSG_STR_CDIR_MFVER_SIZE,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_IGN, CDIR_T_VERSION },
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami { NULL, 0,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ARG_T_IGN, CDIR_T_UNKNOWN }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami };
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_match_t *mdptr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *tail;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int expr_eval; /* Result of evaluating ARG_T_EXPR */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Mapfile arg_mf;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_level_t *level;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int pass, parent_pass; /* Currently accepting input */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramirestart:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Is the immediate context passing input? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami pass = STACK_IS_EMPTY(lms.lms_cdir_stack) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cdir_stack).cdl_pass;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Is the surrounding (parent) context passing input? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami parent_pass = (lms.lms_cdir_stack.stk_n <= 1) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami lms.lms_cdir_stack.stk_s[lms.lms_cdir_stack.stk_n - 2].cdl_pass;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (mdptr = match_data; mdptr->md_name; mdptr++) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Prefix must match, or we move on */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (strncmp(mf->mf_next, mdptr->md_name,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mdptr->md_size) != 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tail = mf->mf_next + mdptr->md_size;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If there isn't whitespace, or a NULL terminator following
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the prefix, then even though our prefix matched, the actual
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * token is longer, and we don't have a match.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!isspace(*tail) && (*tail != '\0'))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* We have matched a valid control directive */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Advance input to end of the current line */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami advance_to_eol(&mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Set up a temporary mapfile descriptor to reference the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * argument string. The benefit of this second block, is that
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * we can advance the real one to the next line now, which allows
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * us to return at any time knowing that the input has been moved
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to the proper spot. This simplifies the error cases.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If we had a match, tail points at the start of the string.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Otherwise, we want to point at the end of the line.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf = *mf;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (mdptr->md_name == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf.mf_text = arg_mf.mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami else
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf.mf_text = arg_mf.mf_next = tail;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Null terminate the arguments, and advance the main mapfile
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * state block to the next line.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*mf->mf_next == '\n') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *mf->mf_next++ = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_lineno++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Skip leading whitespace to arguments */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (isspace(*arg_mf.mf_next))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf.mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Strip off any comment present on the line */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (tail = arg_mf.mf_next; *tail; tail++)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*tail == '#') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *tail = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Process the arguments as necessary depending on their type.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If this control directive is nested inside a surrounding context
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * that is not currently passing text, then we skip the argument
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * evaluation. This follows the behavior of the C preprocessor,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * which only examines enough to detect the operation within
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a disabled section, without issuing errors about the arguments.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (pass || (parent_pass && (mdptr->md_op == CDIR_T_ELIF))) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (mdptr->md_arg) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case ARG_T_NONE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*arg_mf.mf_next == '\0')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Args are present, but not wanted */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REQNOARG),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mdptr->md_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case ARG_T_EXPR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Ensure that arguments are present */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*arg_mf.mf_next == '\0')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto error_reqarg;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami expr_eval = cexp_eval_expr(&arg_mf);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (expr_eval == -1)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case ARG_T_ID:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Ensure that arguments are present */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*arg_mf.mf_next == '\0')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto error_reqarg;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cexp_ident_validate(&arg_mf, NULL,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mdptr->md_name))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case ARG_T_STR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Ensure that arguments are present */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*arg_mf.mf_next == '\0')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto error_reqarg;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Remove trailing whitespace */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tail = arg_mf.mf_next + strlen(arg_mf.mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while ((tail > arg_mf.mf_next) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami isspace(*(tail -1)))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tail--;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *tail = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Carry out the specified control directive:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!STACK_IS_EMPTY(lms.lms_cdir_stack))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level = &STACK_TOP(lms.lms_cdir_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (mdptr->md_op) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_UNKNOWN: /* Unrecognized control directive */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(&arg_mf, MSG_INTL(MSG_MAP_CDIR_BAD));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_ADD:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (pass && !cexp_ident_add(&arg_mf, arg_mf.mf_next))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_CLEAR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cexp_ident_clear(&arg_mf, arg_mf.mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_ERROR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ERROR),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf.mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_VERSION:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * A $mapfile_version control directive can only appear
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * as the first directive in a mapfile, and is used to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * determine the syntax for the rest of the file. It's
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * too late to be using it here.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REPVER));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_IF:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Push a new level on the conditional input stack */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_RESERVE(lms.lms_cdir_stack, CDIR_STACK_INIT) == 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level = &lms.lms_cdir_stack.stk_s[lms.lms_cdir_stack.stk_n++];
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_if_lineno = arg_mf.mf_lineno;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_else_lineno = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If previous level is not passing, this level is disabled.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Otherwise, the expression value determines what happens.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (pass) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_done = level->cdl_pass = expr_eval;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_done = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_pass = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_ELIF:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* $elif requires an open $if construct */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_IS_EMPTY(lms.lms_cdir_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_ELIF));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* $elif cannot follow $else */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (level->cdl_else_lineno > 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ELSE),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_ELIF),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami EC_LINENO(level->cdl_else_lineno));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Accept text from $elif if the level isn't already
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * done and the expression evaluates to true.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_pass = !level->cdl_done && expr_eval;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (level->cdl_pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_done = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_ELSE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* $else requires an open $if construct */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_IS_EMPTY(lms.lms_cdir_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_ELSE));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* There can only be one $else in the chain */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (level->cdl_else_lineno > 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_ELSE),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_ELSE),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami EC_LINENO(level->cdl_else_lineno));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_else_lineno = arg_mf.mf_lineno;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Accept text from $else if the level isn't already done */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_pass = !level->cdl_done;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level->cdl_done = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case CDIR_T_ENDIF:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* $endif requires an open $if construct */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (STACK_IS_EMPTY(lms.lms_cdir_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_NOIF),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_ENDIF));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (--lms.lms_cdir_stack.stk_n > 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami level = &STACK_TOP(lms.lms_cdir_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Evaluating the control directive above can change pass status */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami expr_eval = STACK_IS_EMPTY(lms.lms_cdir_stack) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_TOP(lms.lms_cdir_stack).cdl_pass;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (expr_eval != pass) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami pass = expr_eval;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_pass(arg_mf.mf_ofl->ofl_lml, pass,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami arg_mf.mf_name, arg_mf.mf_lineno, mdptr->md_name));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * At this point, we have processed a control directive,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * updated our conditional state stack, and the input is
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * positioned at the start of the line following the directive.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the current level is accepting input, then give control
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * back to ld_map_gettoken() to resume its normal operation.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (pass)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The current level is not accepting input. Only another
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * control directive can change this, so read and discard input
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * until we encounter one of the following:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * EOF: Return and let ld_map_gettoken() report it
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Control Directive: Restart this function / evaluate new directive
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (*mf->mf_next != '\0') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Skip leading whitespace */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (isspace_nonl(*mf->mf_next))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Control directives start with a '$'. If we hit
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * one, restart the function at this point
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*mf->mf_next == '$')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto restart;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Not a control directive, so advance input to next line */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami advance_to_eol(&mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*mf->mf_next == '\n') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_lineno++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami assert(mf->mf_next == '\0');
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Control directives that require an argument that is not present
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * jump here to report the error and exit.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramierror_reqarg:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(&arg_mf, MSG_INTL(MSG_MAP_CDIR_REQARG), mdptr->md_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#ifndef _ELF64
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Convert a string to lowercase.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramivoid
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_lowercase(char *str)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (*str = tolower(*str))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#endif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Wrappper on strtoul()/strtoull(), adapted to return an Xword.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * str - Pointer to string to be converted.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * endptr - As documented for strtoul(3C). Either NULL, or
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * address of pointer to receive the address of the first
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * unused character in str (called "final" in strtoul(3C)).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ret_value - Address of Xword variable to receive result.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, *ret_value receives the result, *endptr is updated if
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * endptr is non-NULL, and STRTOXWORD_OK is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, STRTOXWORD_TOBIG is returned if an otherwise valid
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * value was too large, and STRTOXWORD_BAD is returned if the string
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * is malformed.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_strtoxword_t
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_strtoxword(const char *restrict str, char **restrict endptr,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Xword *ret_value)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#if defined(_ELF64) /* _ELF64 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define FUNC strtoull /* Function to use */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define FUNC_MAX ULLONG_MAX /* Largest value returned by FUNC */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define XWORD_MAX ULLONG_MAX /* Largest Xword value */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami uint64_t value; /* Variable of FUNC return type */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#else /* _ELF32 */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define FUNC strtoul
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define FUNC_MAX ULONG_MAX
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#define XWORD_MAX UINT_MAX
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ulong_t value;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#endif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *endptr_local; /* Used if endptr is NULL */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (endptr == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami endptr = &endptr_local;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami errno = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami value = FUNC(str, endptr, 0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((errno != 0) || (str == *endptr)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (value == FUNC_MAX)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (STRTOXWORD_TOOBIG);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami else
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (STRTOXWORD_BAD);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If this is a 64-bit linker building an ELFCLASS32 object,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the FUNC return type is a 64-bit value, while an Xword is
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 32-bit. It is possible for FUNC to be able to convert a value
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * too large for our return type.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#if FUNC_MAX != XWORD_MAX
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (value > XWORD_MAX)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (STRTOXWORD_TOOBIG);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#endif
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *ret_value = value;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (STRTOXWORD_OK);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#undef FUNC
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#undef FUNC_MAX
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami#undef XWORD_MAC
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Convert the unsigned integer value at the current mapfile input
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * into binary form. All numeric values in mapfiles are treated as
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * unsigned integers of the appropriate width for an address on the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * given target. Values can be decimal, hex, or octal.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * str - String to process.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * value - Address of variable to receive resulting value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * notail - If TRUE, an error is issued if non-whitespace
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * characters other than '#' (comment) are found following
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the numeric value before the end of line.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - *str is advanced to the next character following the value
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - *value receives the value
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Returns TRUE (1).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, returns FALSE (0).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_getint(Mapfile *mf, ld_map_tkval_t *value, Boolean notail)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_strtoxword_t s2xw_ret;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *endptr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *errstr = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami value->tkv_int.tkvi_str = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami s2xw_ret = ld_map_strtoxword(mf->mf_next, &endptr,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami &value->tkv_int.tkvi_value);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (s2xw_ret != STRTOXWORD_OK) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (s2xw_ret == STRTOXWORD_TOOBIG)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_VALUELIMIT), errstr);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami else
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_MALVALUE), errstr);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Advance position to item following value, skipping whitespace */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami value->tkv_int.tkvi_cnt = endptr - mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = endptr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (isspace_nonl(*mf->mf_next))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* If requested, ensure there's nothing left */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (notail && (*mf->mf_next != '\n') && (*mf->mf_next != '#') &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (*mf->mf_next != '\0')) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADVALUETAIL), errstr);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Convert a an unquoted identifier into a TK_STRING token, using the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * rules for syntax version in use. Used exclusively by ld_map_gettoken().
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor, positioned to the first character of
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the string.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flags - Bitmask of options to control ld_map_gettoken()s behavior
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tkv- Address of pointer to variable to receive token value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, mf is advanced past the token, tkv is updated with
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the string, and TK_STRING is returned. On error, TK_ERROR is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static Token
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramigettoken_ident(Mapfile *mf, int flags, ld_map_tkval_t *tkv)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *end;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Token tok;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tkv->tkv_str = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((end = ident_delimit(mf)) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = end;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * One advantage of reading the entire mapfile into memory is that
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * we can access the strings within it without having to allocate
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * more memory or make copies. In order to do that, we need to NULL
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * terminate this identifier. That is going to overwrite the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * following character. The problem this presents is that the next
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * character may well be the first character of a subsequent token.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The solution to this is:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 1) Disallow the case where the next character is able to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * start a string. This is not legal mapfile syntax anyway,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * so catching it here simplifies matters.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 2) Copy the character into the special mf->mf_next_ch
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 3) The next call to ld_map_gettoken() checks mf->mf_next_ch,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and if it is non-0, uses it instead of dereferencing the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf_next pointer.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tok = (*mf->mf_next & 0x80) ?
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR : mf->mf_tokdisp[*mf->mf_next];
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (tok) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_BADCHR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_SIMQUOTE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CQUOTE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CDIR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_NUM:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_ID:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_WSNEEDED), mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Null terminate, saving the replaced character */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next_ch = *mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *mf->mf_next = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (flags & TK_F_STRLC)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_lowercase(tkv->tkv_str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_STRING);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Convert a quoted string into a TK_STRING token, using simple
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * quoting rules:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Start and end quotes must be present and match
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - There are no special characters or escape sequences.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This function is used exclusively by ld_map_gettoken().
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor, positioned to the opening quote character.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flags - Bitmask of options to control ld_map_gettoken()s behavior
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tkv- Address of pointer to variable to receive token value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, mf is advanced past the token, tkv is updated with
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the string, and TK_STRING is returned. On error, TK_ERROR is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static Token
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramigettoken_simquote_str(Mapfile *mf, int flags, ld_map_tkval_t *tkv)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *str, *end;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char quote;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str = mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami quote = *str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami end = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while ((*end != '\0') && (*end != '\n') && (*end != quote))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami end++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*end != quote) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(end, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_NOTERM), str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * end is pointing at the closing quote. We can turn that into NULL
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * termination for the string without needing to restore it later.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *end = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = end + 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tkv->tkv_str = str + 1; /* Skip opening quote */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (flags & TK_F_STRLC)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_lowercase(tkv->tkv_str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_STRING);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Convert a quoted string into a TK_STRING token, using C string literal
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * quoting rules:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Start and end quotes must be present and match
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Backslash is an escape, used to introduce special characters
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This function is used exclusively by ld_map_gettoken().
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor, positioned to the opening quote character.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flags - Bitmask of options to control ld_map_gettoken()s behavior
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tkv- Address of pointer to variable to receive token value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, mf is advanced past the token, tkv is updated with
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the string, and TK_STRING is returned. On error, TK_ERROR is returned.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiinline static Token
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramigettoken_cquote_str(Mapfile *mf, int flags, ld_map_tkval_t *tkv)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *str, *cur, *end;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char quote;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int c;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * This function goes through the quoted string and copies
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * it on top of itself, replacing escape sequences with the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * characters they denote. There is always enough room for this,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * because escapes are multi-character sequences that are converted
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to single character results.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami str = mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami quote = *str;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cur = end = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (c = *end++; (c != '\0') && (c != '\n') && (c != quote);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami c = *end++) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (c == '\\') {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami c = conv_translate_c_esc(&end);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (c == -1) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCESC), *end);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *cur++ = c;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *cur = '\0'; /* terminate the result */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (c != quote) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(end, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_NOTERM), str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* end is pointing one character past the closing quote */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = end;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tkv->tkv_str = str + 1; /* Skip opening quote */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (flags & TK_F_STRLC)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_lowercase(tkv->tkv_str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_STRING);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Get a token from the mapfile.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flags - Bitmask of options to control ld_map_gettoken()s behavior
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tkv- Address of pointer to variable to receive token value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns one of the TK_* values, to report the result. If the resulting
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * token has a value (TK_STRING / TK_INT), and tkv is non-NULL, tkv
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * is filled in with the resulting value.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali BahramiToken
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_gettoken(Mapfile *mf, int flags, ld_map_tkval_t *tkv)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int cdir_allow, ch;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Token tok;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_npatch_t np;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Mapfile control directives all start with a '$' character. However,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * they are only valid when they are the first thing on a line. That
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * happens on the first call to ld_map_gettoken() for a new a new
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mapfile, as tracked with lms.lms_cdir_valid, and immediately
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * following each newline seen in the file.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_allow = lms.lms_cdir_valid;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami lms.lms_cdir_valid = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Cycle through the characters looking for tokens. */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (;;) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Process the next character. This is normally *mf->mf_next,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * but if mf->mf_next_ch is non-0, then it contains the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * character, and *mf->mf_next contains a NULL termination
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * from the TK_STRING token returned on the previous call.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * gettoken_ident() ensures that this is never done to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a character that starts a string.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (mf->mf_next_ch == 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ch = *mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ch = mf->mf_next_ch;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next_ch = 0; /* Reset */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Map the character to a dispatch action */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tok = (ch & 0x80) ? TK_OP_ILLCHR : mf->mf_tokdisp[ch];
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Items that require processing are identified as OP tokens.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We process them, and return a result non-OP token.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Non-OP tokens are single character tokens, and we return
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * them immediately.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (tok) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_EOF:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* If EOFOK is set, quietly report it as TK_EOF */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((flags & TK_F_EOFOK) != 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_EOF);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Treat it as a standard error */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal0(mf, MSG_INTL(MSG_MAP_PREMEOF));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_ILLCHR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_ILLCHAR), ch);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_BADCHR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tk_op_badchr:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADCHAR), mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_WS: /* White space */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_NL: /* White space too, but bump line number. */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_lineno++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_allow = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_SIMQUOTE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (flags & TK_F_KEYWORD)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto tk_op_badkwquote;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (gettoken_simquote_str(mf, flags, tkv));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CQUOTE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (flags & TK_F_KEYWORD) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tk_op_badkwquote:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_BADKWQUOTE),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (gettoken_cquote_str(mf, flags, tkv));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CMT:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami advance_to_eol(&mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CDIR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Control directives are only valid at the start
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * of a line.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cdir_allow) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_eol(mf->mf_next, &np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_CDIR_NOTBOL),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami null_patch_undo(&np);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!cdir_process(mf))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_NUM: /* Decimal, hex(0x...), or octal (0...) value */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!ld_map_getint(mf, tkv, FALSE))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_INT);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_ID: /* Unquoted identifier */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (gettoken_ident(mf, flags, tkv));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CEQUAL: /* += or -= */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*(mf->mf_next + 1) != '=')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami goto tk_op_badchr;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tok = (ch == '+') ? TK_PLUSEQ : TK_MINUSEQ;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next += 2;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (tok);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default: /* Non-OP token */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (tok);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*NOTREACHED*/
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami assert(0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TK_ERROR);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Given a token and value returned by ld_map_gettoken(), return a string
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * representation of it suitable for use in an error message.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tok - Token code. Must not be an OP-token
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * tkv - Token value
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramiconst char *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_tokenstr(Token tok, ld_map_tkval_t *tkv, Conv_inv_buf_t *inv_buf)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t cnt;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (tok) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_ERROR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_STR_ERROR));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_EOF:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_STR_EOF));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_STRING:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (tkv->tkv_str);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_COLON:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_COLON));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_SEMICOLON:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_SEMICOLON));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_EQUAL:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_EQUAL));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_PLUSEQ:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_PLUSEQ));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_MINUSEQ:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_MINUSEQ));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_ATSIGN:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_ATSIGN));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_DASH:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_DASH));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_LEFTBKT:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_LEFTBKT));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_RIGHTBKT:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_RIGHTBKT));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_PIPE:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_PIPE));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_INT:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cnt = tkv->tkv_int.tkvi_cnt;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (cnt >= sizeof (inv_buf->buf))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cnt = sizeof (inv_buf->buf) - 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) memcpy(inv_buf->buf, tkv->tkv_int.tkvi_str, cnt);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami inv_buf->buf[cnt] = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (inv_buf->buf);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_STAR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_STAR));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_BANG:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_ORIG(MSG_QSTR_BANG));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami assert(0);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*NOTREACHED*/
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (MSG_INTL(MSG_MAP_INTERR));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Advance the input to the first non-empty line, and determine
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the mapfile version. The version is specified by the mapfile
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * using a $mapfile_version directive. The original System V
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * syntax lacks this directive, and we use that fact to identify
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * such files. SysV mapfile are implicitly defined to have version 1.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entry:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ofl - Output file descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mf - Mapfile block
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On success, updates mf->mf_version, and returns TRUE (1).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * On failure, returns FALSE (0).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramimapfile_version(Mapfile *mf)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char *line_start = mf->mf_next;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Boolean cont = TRUE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Boolean status = TRUE; /* Assume success */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Token tok;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_version = MFV_SYSV;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Cycle through the characters looking for tokens. Although the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * true version is not known yet, we use the v2 dispatch table.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * It contains control directives, which we need for this search,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and the other TK_OP_ tokens we will recognize and act on are the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * same for both tables.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * It is important not to process any tokens that would lead to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a non-OP token:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - The version is required to interpret them
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Our mapfile descriptor is not fully initialized,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * attempts to run that code will crash the program.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (cont) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Map the character to a dispatch action */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami tok = (*mf->mf_next & 0x80) ?
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami TK_OP_ILLCHR : gettok_dispatch_v2[*mf->mf_next];
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (tok) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_WS: /* White space */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_NL: /* White space too, but bump line number. */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_lineno++;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CMT:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami advance_to_eol(&mf->mf_next);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case TK_OP_CDIR:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Control directives are only valid at the start
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * of a line. However, as we have not yet seen
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a token, we do not need to test for this, and
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * can safely assume that we are at the start.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!strncasecmp(mf->mf_next,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_ORIG(MSG_STR_CDIR_MFVER),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_STR_CDIR_MFVER_SIZE) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami isspace_nonl(*(mf->mf_next +
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_STR_CDIR_MFVER_SIZE))) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_map_tkval_t ver;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next += MSG_STR_CDIR_MFVER_SIZE + 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!ld_map_getint(mf, &ver, TRUE)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami status = cont = FALSE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Is it a valid version? Note that we
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * intentionally do not allow you to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * specify version 1 using the $mapfile_version
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * syntax, because that's reserved to version
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * 2 and up.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((ver.tkv_int.tkvi_value < 2) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (ver.tkv_int.tkvi_value >= MFV_NUM)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami const char *fmt;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami fmt = (ver.tkv_int.tkvi_value < 2) ?
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_INTL(MSG_MAP_CDIR_BADVDIR) :
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_INTL(MSG_MAP_CDIR_BADVER);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, fmt,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami EC_WORD(ver.tkv_int.tkvi_value));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami status = cont = FALSE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_version = ver.tkv_int.tkvi_value;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cont = FALSE; /* Version recovered. All done */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Not a version directive. Reset the current position
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to the start of the current line and stop here.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * SysV syntax applies.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = line_start;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cont = FALSE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami default:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If we see anything else, then stop at this point.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The file has System V syntax (version 1), and the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * next token should be interpreted as such.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cont = FALSE;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (status);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Parse the mapfile.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali BahramiBoolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_parse(const char *mapfile, Ofl_desc *ofl)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami struct stat stat_buf; /* stat of mapfile */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int mapfile_fd; /* descriptor for mapfile */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int err;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Mapfile *mf; /* Mapfile descriptor */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami size_t name_len; /* strlen(mapfile) */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Determine if we're dealing with a file or a directory.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (stat(mapfile, &stat_buf) == -1) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami err = errno;
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_STAT), mapfile,
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami strerror(err));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (S_ISDIR(stat_buf.st_mode)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DIR *dirp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami struct dirent *denp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Open the directory and interpret each visible file as a
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mapfile.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((dirp = opendir(mapfile)) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while ((denp = readdir(dirp)) != NULL) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami char path[PATH_MAX];
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Ignore any hidden filenames. Construct the full
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * pathname to the new mapfile.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (*denp->d_name == '.')
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) snprintf(path, PATH_MAX, MSG_ORIG(MSG_STR_PATH),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mapfile, denp->d_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!ld_map_parse(path, ofl))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) closedir(dirp);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else if (!S_ISREG(stat_buf.st_mode)) {
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_NOTREG), mapfile);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Open file */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((mapfile_fd = open(mapfile, O_RDONLY)) == -1) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami err = errno;
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), mapfile,
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami strerror(err));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Allocate enough memory to hold the state block, mapfile name,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and mapfile text. Text has alignment 1, so it can follow the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * state block without padding.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami name_len = strlen(mapfile) + 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf = libld_malloc(sizeof (*mf) + name_len + stat_buf.st_size + 1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (mf == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_ofl = ofl;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_name = (char *)(mf + 1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) strcpy(mf->mf_name, mapfile);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_text = mf->mf_name + name_len;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (read(mapfile_fd, mf->mf_text, stat_buf.st_size) !=
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami stat_buf.st_size) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami err = errno;
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_READ), mapfile,
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami strerror(err));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) close(mapfile_fd);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (void) close(mapfile_fd);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_text[stat_buf.st_size] = '\0';
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next = mf->mf_text;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_lineno = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_next_ch = 0; /* No "lookahead" character yet */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_ec_insndx = 0; /* Insert entrace criteria at top */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Read just enough from the mapfile to determine the version,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and then dispatch to the appropriate code for further processing
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!mapfile_version(mf))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Start and continuation masks for unquoted identifier at this
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mapfile version level.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_tkid_start = TKID_ATTR_START(mf->mf_version);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_tkid_cont = TKID_ATTR_CONT(mf->mf_version);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_parse(ofl->ofl_lml, mapfile, mf->mf_version));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami switch (mf->mf_version) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case MFV_SYSV:
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami /* Guidance: Use newer mapfile syntax */
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami if (OFL_GUIDANCE(ofl, FLG_OFG_NO_MF))
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_GUIDANCE,
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami MSG_INTL(MSG_GUIDE_MAPFILE), mapfile);
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_tokdisp = gettok_dispatch_v1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!ld_map_parse_v1(mf))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami case MFV_SOLARIS:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf->mf_tokdisp = gettok_dispatch_v2;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami STACK_RESET(lms.lms_cdir_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the conditional expression identifier tree has not been
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * initialized, set it up. This is only done on the first
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * mapfile, because the identifier control directives accumulate
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * across all the mapfiles.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((lms.lms_cexp_id == NULL) && !cexp_ident_init())
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Tell ld_map_gettoken() we will accept a '$' as starting a
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * control directive on the first call. Normally, they are
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * only allowed after a newline.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami lms.lms_cdir_valid = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!ld_map_parse_v2(mf))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Did we leave any open $if control directives? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!STACK_IS_EMPTY(lms.lms_cdir_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami while (!STACK_IS_EMPTY(lms.lms_cdir_stack)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami cdir_level_t *level =
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami &STACK_POP(lms.lms_cdir_stack);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami mf_fatal(mf, MSG_INTL(MSG_MAP_CDIR_NOEND),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami EC_LINENO(level->cdl_if_lineno));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Sort the segment list. This is necessary if a mapfile has set explicit
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * virtual addresses for segments, or defined a SEGMENT_ORDER directive.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Only PT_LOAD segments can be assigned a virtual address. These segments can
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * be one of two types:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Standard segments for text, data or bss. These segments will have been
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * inserted before the default text (first PT_LOAD) segment.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Empty (reservation) segments. These segment will have been inserted at
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the end of any default PT_LOAD segments.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Any standard segments that are assigned a virtual address will be sorted,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and as their definitions precede any default PT_LOAD segments, these segments
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * will be assigned sections before any defaults.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Any reservation segments are also sorted amoung themselves, as these segments
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * must still follow the standard default segments.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramistatic Boolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramisort_seg_list(Ofl_desc *ofl)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami APlist *sort_segs = NULL, *load_segs = NULL;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Sg_desc *sgp1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Aliste idx1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Aliste nsegs;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We know the number of elements in the sorted list will be
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the same as the original, so use this as the initial allocation
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * size for the replacement aplist.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami nsegs = aplist_nitems(ofl->ofl_segs);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Add the items below SGID_TEXT to the list */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp1->sg_id >= SGID_TEXT)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_append(&sort_segs, sgp1, nsegs) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If there are any SEGMENT_ORDER items, add them, and set their
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * FLG_SG_ORDERED flag to identify them in debug output, and to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * prevent them from being added again below.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs_order, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_append(&sort_segs, sgp1, nsegs) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp1->sg_flags |= FLG_SG_ORDERED;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Add the loadable segments to another list in sorted order.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_sort_title(ofl->ofl_lml, TRUE));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_sort_seg(ofl->ofl_lml, ELFOSABI_SOLARIS,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_targ.t_m.m_mach, sgp1));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Only interested in PT_LOAD items not in SEGMENT_ORDER list */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((sgp1->sg_phdr.p_type != PT_LOAD) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (sgp1->sg_flags & FLG_SG_ORDERED))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the loadable segment does not contain a vaddr, simply
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * append it to the new list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((sgp1->sg_flags & FLG_SG_P_VADDR) == 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_append(&load_segs, sgp1, AL_CNT_SEGMENTS) ==
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Aliste idx2;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Sg_desc *sgp2;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami int inserted = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Traverse the segment list we are creating, looking
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * for a segment that defines a vaddr.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(load_segs, idx2, sgp2)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Any real segments that contain vaddr's need
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to be sorted. Any reservation segments also
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * need to be sorted. However, any reservation
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * segments should be placed after any real
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * segments.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (((sgp2->sg_flags &
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (FLG_SG_P_VADDR | FLG_SG_EMPTY)) == 0) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (sgp1->sg_flags & FLG_SG_EMPTY))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((sgp2->sg_flags & FLG_SG_P_VADDR) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ((sgp2->sg_flags & FLG_SG_EMPTY) ==
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (sgp1->sg_flags & FLG_SG_EMPTY))) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp1->sg_phdr.p_vaddr ==
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp2->sg_phdr.p_vaddr) {
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_INTL(MSG_MAP_SEGSAME),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp1->sg_name,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp2->sg_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp1->sg_phdr.p_vaddr >
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp2->sg_phdr.p_vaddr)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Insert this segment before the segment on
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the load_segs list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_insert(&load_segs, sgp1,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami AL_CNT_SEGMENTS, idx2) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami inserted = 1;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the segment being inspected has not been inserted
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * in the segment list, simply append it to the list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((inserted == 0) && (aplist_append(&load_segs,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp1, AL_CNT_SEGMENTS) == NULL))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Add the sorted loadable segments to our initial segment list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(load_segs, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_append(&sort_segs, sgp1, AL_CNT_SEGMENTS) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Add all other segments to our list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((sgp1->sg_id < SGID_TEXT) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (sgp1->sg_phdr.p_type == PT_LOAD) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (sgp1->sg_flags & FLG_SG_ORDERED))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_append(&sort_segs, sgp1, AL_CNT_SEGMENTS) == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Free the original list, and the pt_load list, and use
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the new list as the segment list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami free(ofl->ofl_segs);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (load_segs) free(load_segs);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_segs = sort_segs;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (DBG_ENABLED) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Dbg_map_sort_title(ofl->ofl_lml, FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp1)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Dbg_map_sort_seg(ofl->ofl_lml, ELFOSABI_SOLARIS,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_targ.t_m.m_mach, sgp1);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami/*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * After all mapfiles have been processed, this routine is used to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * finish any remaining mapfile related work.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * exit:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Returns TRUE on success, and FALSE on failure.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali BahramiBoolean
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahramild_map_post_process(Ofl_desc *ofl)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami{
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Aliste idx, idx2;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Is_desc *isp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Sg_desc *sgp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Ent_desc *enp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Sg_desc *first_seg = NULL;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_post_title(ofl->ofl_lml));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Per-segment processing:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Identify segments with explicit virtual address
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Details of input and output section order
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We are looking for segments. Program headers that represent
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * segments are required to have a non-NULL name pointer,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * while that those that do not are required to have a
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * NULL name pointer.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp->sg_name == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Remember the first non-disabled segment */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((first_seg == NULL) && !(sgp->sg_flags & FLG_SG_DISABLED))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami first_seg = sgp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If a segment has an explicit virtual address, we will
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * need to sort the segments.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp->sg_flags & FLG_SG_P_VADDR)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_flags1 |= FLG_OF1_VADDR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The FLG_OF_OS_ORDER flag enables the code that does
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * output section ordering. Set if the segment has
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * a non-empty output section order list.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (alist_nitems(sgp->sg_os_order) > 0)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_flags |= FLG_OF_OS_ORDER;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * The version 1 and version 2 syntaxes for input section
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * ordering are different and incompatible enough that we
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * only allow the use of one or the other for a given segment:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * v1) The version 1 syntax has the user set the ?O flag on
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the segment. If this is done, all input sections placed
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * via an entrance criteria that has a section name are to
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * be sorted, using the order of the entrance criteria
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * as the sort key.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * v2) The version 2 syntax has the user specify a name for
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the entry criteria, and then provide a list of entry
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * criteria names via the IS_ORDER segment attribute.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Sections placed via the criteria listed in IS_ORDER
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * are sorted, and the others are not.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Regardless of the syntax version used, the section sorting
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * code expects the following:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Segments requiring input section sorting have the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * FLG_SG_IS_ORDER flag set
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Entrance criteria referencing the segment that
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * participate in input section sorting have a non-zero
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * sort key in their ec_ordndx field.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * At this point, the following are true:
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - All entrance criteria have ec_ordndx set to 0.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Segments that require the version 1 behavior have
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * the FLG_SG_IS_ORDER flag set, and the segments
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * sg_is_order list is empty.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * - Segments that require the version 2 behavior do not
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * have FLG_SG_IS_ORDER set, and the sg_is_order list is
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * non-empty. This list contains the names of the entrance
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * criteria that will participate in input section sorting,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * and their relative order in the list provides the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * sort key to use.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami *
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * We must detect these two cases, set the FLG_SG_IS_ORDER
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flag as necessary, and fill in all entrance criteria
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * sort keys. If any input section sorting is to be done,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * we also set the FLG_OF_IS_ORDER flag on the output descriptor
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * to enable the code that does that work.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Version 1: ?O flag? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp->sg_flags & FLG_SG_IS_ORDER) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Word index = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_flags |= FLG_OF_IS_ORDER;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_ent_ord_title(ofl->ofl_lml,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp->sg_name));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Give each user defined entrance criteria for this
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * segment that specifies a section name a
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * monotonically increasing sort key.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_ents, idx2, enp))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((enp->ec_segment == sgp) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (enp->ec_is_name != NULL) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ((enp->ec_flags & FLG_EC_BUILTIN) == 0))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami enp->ec_ordndx = ++index;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Version 2: SEGMENT IS_ORDER list? */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (aplist_nitems(sgp->sg_is_order) > 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Word index = 0;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_flags |= FLG_OF_IS_ORDER;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_map_ent_ord_title(ofl->ofl_lml,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami sgp->sg_name));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Give each entrance criteria in the sg_is_order
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * list a monotonically increasing sort key.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(sgp->sg_is_order, idx2, enp)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami enp->ec_ordndx = ++index;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami enp->ec_segment->sg_flags |= FLG_SG_IS_ORDER;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /* Sort the segment descriptors if necessary */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (((ofl->ofl_flags1 & FLG_OF1_VADDR) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (aplist_nitems(ofl->ofl_segs_order) > 0)) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami !sort_seg_list(ofl))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the output file is a static file without an interpreter, and
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * if any virtual address is specified, then set the NOHDR flag for
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * backward compatibility.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!(ofl->ofl_flags & (FLG_OF_DYNAMIC | FLG_OF_RELOBJ)) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami !(ofl->ofl_osinterp) && (ofl->ofl_flags1 & FLG_OF1_VADDR))
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_dtflags_1 |= DF_1_NOHDR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (ofl->ofl_flags & FLG_OF_RELOBJ) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * NOHDR has no effect on a relocatable file.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Make sure this flag isn't set.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_dtflags_1 &= ~DF_1_NOHDR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami } else if (first_seg != NULL) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * DF_1_NOHDR might have been set globally by the HDR_NOALLOC
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * directive. If not, then we want to check the per-segment
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * flag for the first loadable segment and propagate it
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * if set.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If we sorted the segments, the first segment
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * may have changed.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((ofl->ofl_flags1 & FLG_OF1_VADDR) ||
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (aplist_nitems(ofl->ofl_segs_order) > 0)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (sgp->sg_name == NULL)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami continue;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if ((sgp->sg_flags & FLG_SG_DISABLED) ==
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami 0) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami first_seg = sgp;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami break;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * If the per-segment NOHDR flag is set on our first
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * segment, then make it take effect.
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (first_seg->sg_flags & FLG_SG_NOHDR)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ofl->ofl_dtflags_1 |= DF_1_NOHDR;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * For executable and shared objects, the first segment must
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * be loadable unless NOHDR was specified, because the ELF
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * header must simultaneously lie at offset 0 of the file and
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * be included in the first loadable segment. This isn't
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * possible if some other segment type starts the file
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (!(ofl->ofl_dtflags_1 & DF_1_NOHDR) &&
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami (first_seg->sg_phdr.p_type != PT_LOAD)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami Conv_inv_buf_t inv_buf;
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
1007fd6fd24227460e77ce89f5ca85641a85a576Ali Bahrami ld_eprintf(ofl, ERR_FATAL,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami MSG_INTL(MSG_SEG_FIRNOTLOAD),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami conv_phdr_type(ELFOSABI_SOLARIS, ld_targ.t_m.m_mach,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami first_seg->sg_phdr.p_type, 0, &inv_buf),
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami first_seg->sg_name);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami /*
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * Mapfiles may have been used to create symbol definitions
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * with backing storage. Although the backing storage is
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * associated with an input section, the association of the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * section to an output section (and segment) is initially
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * deferred. Now that all mapfile processing is complete, any
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * entrance criteria requirements have been processed, and
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * these backing storage sections can be associated with the
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami * appropriate output section (and segment).
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami */
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (ofl->ofl_maptext || ofl->ofl_mapdata)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami DBG_CALL(Dbg_sec_backing(ofl->ofl_lml));
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_maptext, idx, isp)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (ld_place_section(ofl, isp, NULL,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_targ.t_id.id_text, NULL) == (Os_desc *)S_ERROR)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami for (APLIST_TRAVERSE(ofl->ofl_mapdata, idx, isp)) {
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami if (ld_place_section(ofl, isp, NULL,
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami ld_targ.t_id.id_data, NULL) == (Os_desc *)S_ERROR)
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (FALSE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami }
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami return (TRUE);
69112edd987c28fa551d4f8d9362a84a45365f17Ali Bahrami}