d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * CDDL HEADER START
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * The contents of this file are subject to the terms of the
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Common Development and Distribution License (the "License").
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * You may not use this file except in compliance with the License.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * or http://www.opensolaris.org/os/licensing.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * See the License for the specific language governing permissions
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * and limitations under the License.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * When distributing Covered Code, include this CDDL HEADER in each
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * If applicable, add the following below this CDDL HEADER, with the
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * fields enclosed by brackets "[]" replaced with your own identifying
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * information: Portions Copyright [yyyy] [name of copyright owner]
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * CDDL HEADER END
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Use is subject to license terms.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#include <errno.h>
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#include <stdarg.h>
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#include "ndrgen.h"
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#include "y.tab.h"
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * C-like lexical analysis.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 1. Define a "struct node"
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 2. Define a "struct symbol" that encapsulates a struct node.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 3. Define a "struct integer" that encapsulates a struct node.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 4. Set the YACC stack type in the grammar:
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * #define YYSTYPE struct node *
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 5. Define %token's in the grammer for IDENTIFIER, STRING and INTEGER.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Using "_KW" as a suffix for keyword tokens, i.e. "struct" is
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * "%token STRUCT_KW":
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * // atomic values
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %token INTEGER STRING IDENTIFIER
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * // keywords
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %token STRUCT_KW CASE_KW
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * // operators
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %token PLUS MINUS ASSIGN ARROW
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * // overloaded tokens (++ --, < > <= >=, == !=, += -= *= ...)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %token INCOP RELOP EQUOP ASSOP
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 6. It's easiest to use the yacc(1) generated token numbers for node
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * labels. For node labels that are not actually part of the grammer,
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * use a %token with an L_ prefix:
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * // node labels (can't be generated by lex)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * %token L_LT L_LTE L_GT L_GTE L_EQU L_NEQ
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * 7. Call set_lex_input() before parsing.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define SQ '\''
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define DQ '"'
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define isquote(c) ((c) == SQ || (c) == DQ)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define iswhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\f')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_between(c, l, u) ((l) <= (c) && (c) <= (u))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_white(c) ((c) == ' ' || c == '\r' || c == '\t' || c == '\f')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_lower(c) is_between((c), 'a', 'z')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_upper(c) is_between((c), 'A', 'Z')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_alpha(c) (is_lower(c) || is_upper(c))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_digit(c) is_between((c), '0', '9')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_sstart(c) (is_alpha(c) || (c) == '_')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_sfollow(c) (is_sstart(c) || is_digit(c))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw#define is_xdigit(c) \
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (is_digit(c) || is_between((c), 'A', 'F') || is_between((c), 'a', 'f'))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwndr_symbol_t *symbol_list;
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_integer_t *integer_list;
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic FILE *lex_infp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_symbol_t *file_name;
d0e518695adc90b82233b99af7dffbb3d3f92c00amwint line_number;
d0e518695adc90b82233b99af7dffbb3d3f92c00amwint n_compile_error;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic int lex_at_bol;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/* In yacc(1) generated parser */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwextern struct node *yylval;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * The keywtab[] and optable[] could be external to this lex
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * and it would all still work.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_keyword_t keywtable[] = {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "struct", STRUCT_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "union", UNION_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "typedef", TYPEDEF_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "interface", INTERFACE_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "uuid", UUID_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "_no_reorder", _NO_REORDER_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "extern", EXTERN_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "reference", REFERENCE_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "align", ALIGN_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "operation", OPERATION_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "in", IN_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "out", OUT_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "string", STRING_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "size_is", SIZE_IS_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "length_is", LENGTH_IS_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "switch_is", SWITCH_IS_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "case", CASE_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "default", DEFAULT_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "transmit_as", TRANSMIT_AS_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "arg_is", ARG_IS_KW, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "char", BASIC_TYPE, 1 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "uchar", BASIC_TYPE, 1 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "wchar", BASIC_TYPE, 2 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "short", BASIC_TYPE, 2 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "ushort", BASIC_TYPE, 2 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "long", BASIC_TYPE, 4 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "ulong", BASIC_TYPE, 4 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw {0}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw};
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_keyword_t optable[] = {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "{", LC, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "}", RC, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "(", LP, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { ")", RP, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "[", LB, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "]", RB, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { "*", STAR, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "/", DIV, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "%", MOD, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "-", MINUS, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "+", PLUS, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "&", AND, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "|", OR, 0 },
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright { "^", XOR, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw { ";", SEMI, 0 },
d0e518695adc90b82233b99af7dffbb3d3f92c00amw {0}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw};
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic int getch(FILE *fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_integer_t *int_enter(long);
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wrightstatic ndr_symbol_t *sym_enter(char *);
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_symbol_t *sym_find(char *);
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic int str_to_sv(char *, char *sv[]);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Enter the symbols for keyword.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic void
d0e518695adc90b82233b99af7dffbb3d3f92c00amwkeyw_tab_init(ndr_keyword_t kwtable[])
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int i;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_keyword_t *kw;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t *sym;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw for (i = 0; kwtable[i].name; i++) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw kw = &kwtable[i];
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sym = sym_enter(kw->name);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sym->kw = kw;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwvoid
d0e518695adc90b82233b99af7dffbb3d3f92c00amwset_lex_input(FILE *fp, char *name)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw keyw_tab_init(keywtable);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw keyw_tab_init(optable);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lex_infp = fp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw file_name = sym_enter(name);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw line_number = 1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lex_at_bol = 1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic int
d0e518695adc90b82233b99af7dffbb3d3f92c00amwgetch(FILE *fp)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (getc(fp));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwint
d0e518695adc90b82233b99af7dffbb3d3f92c00amwyylex(void)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char lexeme[512];
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char *p = lexeme;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw FILE *fp = lex_infp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int c, xc;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t *sym;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_integer_t *intg;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwtop:
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p = lexeme;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == EOF)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (EOF);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '\n') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw line_number++;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lex_at_bol = 1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Handle preprocessor lines. This just notes
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * which file we're processing.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '#' && lex_at_bol) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char *sv[10];
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int sc;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while ((c = getch(fp)) != EOF && c != '\n')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* note: no ungetc() of newline, we don't want to count it */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (*lexeme != ' ') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* not a line we know */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sc = str_to_sv(lexeme, sv);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (sc < 2)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw file_name = sym_enter(sv[1]);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw line_number = atoi(sv[0]); /* for next input line */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lex_at_bol = 1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lex_at_bol = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Skip white space
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (is_white(c))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Symbol? Might be a keyword or just an identifier
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (is_sstart(c)) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* we got a symbol */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw do {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } while (is_sfollow(c));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) ungetc(c, fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sym = sym_enter(lexeme);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw yylval = &sym->s_node;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (sym->kw) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (sym->kw->token);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } else {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (IDENTIFIER);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Integer constant?
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (is_digit(c)) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* we got a number */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '0') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == 'x' || c == 'X') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* handle hex specially */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw do {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } while (is_xdigit(c));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto convert_icon;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } else if (c == 'b' || c == 'B' ||
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c == 'd' || c == 'D' ||
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c == 'o' || c == 'O') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw do {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } while (is_digit(c));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto convert_icon;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) ungetc(c, fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* could be anything */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while (is_digit(c)) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = getch(fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwconvert_icon:
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *p = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) ungetc(c, fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw intg = int_enter(strtol(lexeme, 0, 0));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw yylval = &intg->s_node;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (INTEGER);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* Could handle strings. We don't seem to need them yet */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw yylval = 0; /* operator tokens have no value */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw xc = getch(fp); /* get look-ahead for two-char lexemes */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lexeme[0] = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lexeme[1] = xc;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lexeme[2] = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Look for to-end-of-line comment
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '/' && xc == '/') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* eat the comment */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while ((c = getch(fp)) != EOF && c != '\n')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) ungetc(c, fp); /* put back newline */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Look for multi-line comment
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '/' && xc == '*') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* eat the comment */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw xc = -1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while ((c = getch(fp)) != EOF) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (xc == '*' && c == '/') {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* that's it */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw break;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw xc = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == '\n')
d0e518695adc90b82233b99af7dffbb3d3f92c00amw line_number++;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Use symbol table lookup for two-character and
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * one character operator tokens.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sym = sym_find(lexeme);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (sym) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* there better be a keyword attached */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw yylval = &sym->s_node;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (sym->kw->token);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* Try a one-character form */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) ungetc(xc, fp);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw lexeme[1] = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw sym = sym_find(lexeme);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (sym) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* there better be a keyword attached */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw yylval = &sym->s_node;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (sym->kw->token);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright if (is_between(c, ' ', '~'))
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright compile_error("unrecognized character: 0x%02x (%c)", c, c);
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright else
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wright compile_error("unrecognized character: 0x%02x", c);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw goto top;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_symbol_t *
d0e518695adc90b82233b99af7dffbb3d3f92c00amwsym_find(char *name)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t **pp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t *p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw for (pp = &symbol_list; (p = *pp) != 0; pp = &p->next) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (strcmp(p->name, name) == 0)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (0);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
a0b6e447978c306e15941d158bf6939a42ed2726Alan Wrightstatic ndr_symbol_t *
d0e518695adc90b82233b99af7dffbb3d3f92c00amwsym_enter(char *name)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t **pp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_symbol_t *p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw for (pp = &symbol_list; (p = *pp) != 0; pp = &p->next) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (strcmp(p->name, name) == 0)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p = ndr_alloc(1, sizeof (ndr_symbol_t));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if ((p->name = strdup(name)) == NULL)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw fatal_error("%s", strerror(ENOMEM));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p->s_node.label = IDENTIFIER;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p->s_node.n_sym = p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *pp = p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic ndr_integer_t *
d0e518695adc90b82233b99af7dffbb3d3f92c00amwint_enter(long value)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_integer_t **pp;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_integer_t *p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw for (pp = &integer_list; (p = *pp) != 0; pp = &p->next) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (p->value == value)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p = ndr_alloc(1, sizeof (ndr_integer_t));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p->value = value;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p->s_node.label = INTEGER;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw p->s_node.n_int = value;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *pp = p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwvoid *
d0e518695adc90b82233b99af7dffbb3d3f92c00amwndr_alloc(size_t nelem, size_t elsize)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw void *p;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if ((p = calloc(nelem, elsize)) == NULL) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw fatal_error("%s", strerror(ENOMEM));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* NOTREACHED */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (p);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * The input context (filename, line number) is maintained by the
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * lexical analysis, and we generally want such info reported for
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * errors in a consistent manner.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwvoid
d0e518695adc90b82233b99af7dffbb3d3f92c00amwcompile_error(const char *fmt, ...)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char buf[NDLBUFSZ];
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_list ap;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_start(ap, fmt);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) vsnprintf(buf, NDLBUFSZ, fmt, ap);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_end(ap);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) fprintf(stderr, "ndrgen: compile error: %s:%d: %s\n",
d0e518695adc90b82233b99af7dffbb3d3f92c00amw file_name->name, line_number, buf);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw n_compile_error++;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amwvoid
d0e518695adc90b82233b99af7dffbb3d3f92c00amwfatal_error(const char *fmt, ...)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char buf[NDLBUFSZ];
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_list ap;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_start(ap, fmt);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) vsnprintf(buf, NDLBUFSZ, fmt, ap);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_end(ap);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw (void) fprintf(stderr, "ndrgen: fatal error: %s\n", buf);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw exit(1);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Setup nodes for the lexical analyzer.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstruct node *
d0e518695adc90b82233b99af7dffbb3d3f92c00amwn_cons(int label, ...)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw ndr_node_t *np;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_list ap;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np = ndr_alloc(1, sizeof (ndr_node_t));
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_start(ap, label);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->label = label;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->n_arg[0] = va_arg(ap, void *);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->n_arg[1] = va_arg(ap, void *);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->n_arg[2] = va_arg(ap, void *);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw va_end(ap);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->line_number = line_number;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np->file_name = file_name;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (np);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * list: item
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * | list item ={ n_splice($1, $2); }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * ;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwvoid
d0e518695adc90b82233b99af7dffbb3d3f92c00amwn_splice(struct node *np1, struct node *np2)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while (np1->n_next)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np1 = np1->n_next;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw np1->n_next = np2;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw/*
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Convert a string of words to a vector of strings.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw * Returns the number of words.
d0e518695adc90b82233b99af7dffbb3d3f92c00amw */
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstatic int
d0e518695adc90b82233b99af7dffbb3d3f92c00amwstr_to_sv(char *buf, char *sv[])
d0e518695adc90b82233b99af7dffbb3d3f92c00amw{
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char **pp = sv;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char *p = buf;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw char *q = buf;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int in_word = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw for (;;) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw c = *p++;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == 0)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw break;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (!in_word) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (iswhite(c))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw continue;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *pp++ = q;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw in_word = 1;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (isquote(c)) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw int qc = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw while (((c = *p++) != 0) && (c != qc))
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *q++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (c == 0)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw break;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } else if (iswhite(c)) {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* end of word */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *q++ = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw in_word = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw } else {
d0e518695adc90b82233b99af7dffbb3d3f92c00amw /* still inside word */
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *q++ = c;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw }
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw if (in_word)
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *q++ = 0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw
d0e518695adc90b82233b99af7dffbb3d3f92c00amw *pp = (char *)0;
d0e518695adc90b82233b99af7dffbb3d3f92c00amw return (pp - sv);
d0e518695adc90b82233b99af7dffbb3d3f92c00amw}