mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-30 19:08:12 +03:00
Use custom parser for System40.ini
This is not really a standard ini file, so a custom parser is needed to access all of the information stored in it (specifically, lists like "LoadDLL"). This commit also makes flex/bison a hard dependency.
This commit is contained in:
-148
@@ -1,148 +0,0 @@
|
||||
/* inih -- simple .INI file parser
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
Copyright (C) 2009-2019, Ben Hoyt
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
https://github.com/benhoyt/inih
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INI_H__
|
||||
#define __INI_H__
|
||||
|
||||
/* Make this header file easier to include in C++ code */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Nonzero if ini_handler callback should accept lineno parameter. */
|
||||
#ifndef INI_HANDLER_LINENO
|
||||
#define INI_HANDLER_LINENO 0
|
||||
#endif
|
||||
|
||||
/* Typedef for prototype of handler function. */
|
||||
#if INI_HANDLER_LINENO
|
||||
typedef int (*ini_handler)(void* user, const char* section,
|
||||
const char* name, const char* value,
|
||||
int lineno);
|
||||
#else
|
||||
typedef int (*ini_handler)(void* user, const char* section,
|
||||
const char* name, const char* value);
|
||||
#endif
|
||||
|
||||
/* Typedef for prototype of fgets-style reader function. */
|
||||
typedef char* (*ini_reader)(char* str, int num, void* stream);
|
||||
|
||||
/* Parse given INI-style file. May have [section]s, name=value pairs
|
||||
(whitespace stripped), and comments starting with ';' (semicolon). Section
|
||||
is "" if name=value pair parsed before any section heading. name:value
|
||||
pairs are also supported as a concession to Python's configparser.
|
||||
|
||||
For each name=value pair parsed, call handler function with given user
|
||||
pointer as well as section, name, and value (data only valid for duration
|
||||
of handler call). Handler should return nonzero on success, zero on error.
|
||||
|
||||
Returns 0 on success, line number of first error on parse error (doesn't
|
||||
stop on first error), -1 on file open error, or -2 on memory allocation
|
||||
error (only when INI_USE_STACK is zero).
|
||||
*/
|
||||
int ini_parse(const char* filename, ini_handler handler, void* user);
|
||||
|
||||
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
|
||||
close the file when it's finished -- the caller must do that. */
|
||||
int ini_parse_file(FILE* file, ini_handler handler, void* user);
|
||||
|
||||
/* Same as ini_parse(), but takes an ini_reader function pointer instead of
|
||||
filename. Used for implementing custom or string-based I/O (see also
|
||||
ini_parse_string). */
|
||||
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
|
||||
void* user);
|
||||
|
||||
/* Same as ini_parse(), but takes a zero-terminated string with the INI data
|
||||
instead of a file. Useful for parsing INI data from a network socket or
|
||||
already in memory. */
|
||||
int ini_parse_string(const char* string, ini_handler handler, void* user);
|
||||
|
||||
/* Nonzero to allow multi-line value parsing, in the style of Python's
|
||||
configparser. If allowed, ini_parse() will call the handler with the same
|
||||
name for each subsequent line parsed. */
|
||||
#ifndef INI_ALLOW_MULTILINE
|
||||
#define INI_ALLOW_MULTILINE 1
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
|
||||
the file. See https://github.com/benhoyt/inih/issues/21 */
|
||||
#ifndef INI_ALLOW_BOM
|
||||
#define INI_ALLOW_BOM 1
|
||||
#endif
|
||||
|
||||
/* Chars that begin a start-of-line comment. Per Python configparser, allow
|
||||
both ; and # comments at the start of a line by default. */
|
||||
#ifndef INI_START_COMMENT_PREFIXES
|
||||
#define INI_START_COMMENT_PREFIXES ";#"
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow inline comments (with valid inline comment characters
|
||||
specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match
|
||||
Python 3.2+ configparser behaviour. */
|
||||
#ifndef INI_ALLOW_INLINE_COMMENTS
|
||||
#define INI_ALLOW_INLINE_COMMENTS 1
|
||||
#endif
|
||||
#ifndef INI_INLINE_COMMENT_PREFIXES
|
||||
#define INI_INLINE_COMMENT_PREFIXES ";"
|
||||
#endif
|
||||
|
||||
/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */
|
||||
#ifndef INI_USE_STACK
|
||||
#define INI_USE_STACK 1
|
||||
#endif
|
||||
|
||||
/* Maximum line length for any line in INI file (stack or heap). Note that
|
||||
this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */
|
||||
#ifndef INI_MAX_LINE
|
||||
#define INI_MAX_LINE 200
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow heap line buffer to grow via realloc(), zero for a
|
||||
fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is
|
||||
zero. */
|
||||
#ifndef INI_ALLOW_REALLOC
|
||||
#define INI_ALLOW_REALLOC 0
|
||||
#endif
|
||||
|
||||
/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK
|
||||
is zero. */
|
||||
#ifndef INI_INITIAL_ALLOC
|
||||
#define INI_INITIAL_ALLOC 200
|
||||
#endif
|
||||
|
||||
/* Stop parsing on first error (default is to keep parsing). */
|
||||
#ifndef INI_STOP_ON_FIRST_ERROR
|
||||
#define INI_STOP_ON_FIRST_ERROR 0
|
||||
#endif
|
||||
|
||||
/* Nonzero to call the handler at the start of each new section (with
|
||||
name and value NULL). Default is to only call the handler on
|
||||
each name=value pair. */
|
||||
#ifndef INI_CALL_HANDLER_ON_NEW_SECTION
|
||||
#define INI_CALL_HANDLER_ON_NEW_SECTION 0
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow a name without a value (no '=' or ':' on the line) and
|
||||
call the handler with value NULL in this case. Default is to treat
|
||||
no-value lines as an error. */
|
||||
#ifndef INI_ALLOW_NO_VALUE
|
||||
#define INI_ALLOW_NO_VALUE 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INI_H__ */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM4_INI_H
|
||||
#define SYSTEM4_INI_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct string;
|
||||
|
||||
enum ini_value_type {
|
||||
INI_NULL,
|
||||
INI_INTEGER,
|
||||
INI_BOOLEAN,
|
||||
INI_STRING,
|
||||
INI_LIST,
|
||||
_INI_LIST_ENTRY,
|
||||
|
||||
INI_NR_TYPES
|
||||
};
|
||||
|
||||
struct ini_value {
|
||||
enum ini_value_type type;
|
||||
union {
|
||||
int i;
|
||||
struct string *s;
|
||||
struct {
|
||||
size_t list_size;
|
||||
struct ini_value *list;
|
||||
};
|
||||
struct {
|
||||
size_t _list_pos;
|
||||
struct ini_value *_list_value;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct ini_entry {
|
||||
struct string *name;
|
||||
struct ini_value value;
|
||||
};
|
||||
|
||||
struct ini_entry *ini_parse(const char *path, size_t *nr_entries);
|
||||
struct ini_entry *ini_make_entry(struct string *name, struct ini_value value);
|
||||
void ini_free_entry(struct ini_entry *entry);
|
||||
|
||||
static inline struct ini_value ini_make_integer(int n)
|
||||
{
|
||||
return (struct ini_value) { .type = INI_INTEGER, .i = n };
|
||||
}
|
||||
|
||||
static inline struct ini_value ini_make_boolean(int b)
|
||||
{
|
||||
return (struct ini_value) { .type = INI_BOOLEAN, .i = !!b };
|
||||
}
|
||||
|
||||
static inline struct ini_value ini_make_string(struct string *s)
|
||||
{
|
||||
return (struct ini_value) { .type = INI_STRING, .s = s };
|
||||
}
|
||||
|
||||
static inline struct ini_value ini_make_list(struct ini_value *values, size_t nr_values)
|
||||
{
|
||||
return (struct ini_value) { .type = INI_LIST, .list = values, .list_size = nr_values };
|
||||
}
|
||||
|
||||
#endif /* SYSTEM4_INI_H */
|
||||
@@ -13,6 +13,9 @@ glew = dependency('glew')
|
||||
tj = dependency('libturbojpeg')
|
||||
chibi = dependency('chibi-scheme', required : get_option('debugger'))
|
||||
|
||||
flex = find_program('flex')
|
||||
bison = find_program('bison')
|
||||
|
||||
incdir = include_directories('include')
|
||||
|
||||
subdir('src')
|
||||
|
||||
@@ -1,284 +1,81 @@
|
||||
/* inih -- simple .INI file parser
|
||||
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
Copyright (C) 2009-2019, Ben Hoyt
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
https://github.com/benhoyt/inih
|
||||
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ini.h"
|
||||
|
||||
#if !INI_USE_STACK
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "system4.h"
|
||||
#include "system4/ini.h"
|
||||
#include "system4/string.h"
|
||||
#include "ini_parser.tab.h"
|
||||
|
||||
#define MAX_SECTION 50
|
||||
#define MAX_NAME 50
|
||||
extern FILE *yini_in;
|
||||
|
||||
/* Used by ini_parse_string() to keep track of string parsing state. */
|
||||
typedef struct {
|
||||
const char* ptr;
|
||||
size_t num_left;
|
||||
} ini_parse_string_ctx;
|
||||
|
||||
/* Strip whitespace chars off end of given string, in place. Return s. */
|
||||
static char* rstrip(char* s)
|
||||
struct ini_entry *ini_parse(const char *path, size_t *nr_entries)
|
||||
{
|
||||
char* p = s + strlen(s);
|
||||
while (p > s && isspace((unsigned char)(*--p)))
|
||||
*p = '\0';
|
||||
return s;
|
||||
if (!(yini_in = fopen(path, "rb")))
|
||||
ERROR("failed to open '%s': %s", path, strerror(errno));
|
||||
yini_parse();
|
||||
|
||||
kvec_t(struct ini_entry) entries;
|
||||
kv_init(entries);
|
||||
|
||||
// TODO: combine _INI_LIST_ENTRY entries
|
||||
for (size_t i = 0; i < kv_size(*yini_entries); i++) {
|
||||
kv_push(struct ini_entry, entries, *kv_A(*yini_entries, i));
|
||||
free(kv_A(*yini_entries, i));
|
||||
}
|
||||
kv_destroy(*yini_entries);
|
||||
free(yini_entries);
|
||||
|
||||
*nr_entries = kv_size(entries);
|
||||
return kv_data(entries);
|
||||
}
|
||||
|
||||
/* Return pointer to first non-whitespace char in given string. */
|
||||
static char* lskip(const char* s)
|
||||
struct ini_entry *ini_make_entry(struct string *name, struct ini_value value)
|
||||
{
|
||||
while (*s && isspace((unsigned char)(*s)))
|
||||
s++;
|
||||
return (char*)s;
|
||||
struct ini_entry *entry = xmalloc(sizeof(struct ini_entry));
|
||||
entry->name = name;
|
||||
entry->value = value;
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Return pointer to first char (of chars) or inline comment in given string,
|
||||
or pointer to null at end of string if neither found. Inline comment must
|
||||
be prefixed by a whitespace character to register as a comment. */
|
||||
static char* find_chars_or_comment(const char* s, const char* chars)
|
||||
static void ini_free_value(struct ini_value *value)
|
||||
{
|
||||
#if INI_ALLOW_INLINE_COMMENTS
|
||||
int was_space = 0;
|
||||
while (*s && (!chars || !strchr(chars, *s)) &&
|
||||
!(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) {
|
||||
was_space = isspace((unsigned char)(*s));
|
||||
s++;
|
||||
}
|
||||
#else
|
||||
while (*s && (!chars || !strchr(chars, *s))) {
|
||||
s++;
|
||||
}
|
||||
#endif
|
||||
return (char*)s;
|
||||
switch (value->type) {
|
||||
case INI_STRING:
|
||||
free_string(value->s);
|
||||
break;
|
||||
case INI_LIST:
|
||||
for (size_t i = 0; i < value->list_size; i++) {
|
||||
ini_free_value(&value->list[i]);
|
||||
}
|
||||
free(value->list);
|
||||
break;
|
||||
case _INI_LIST_ENTRY:
|
||||
ini_free_value(value->_list_value);
|
||||
free(value->_list_value);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Version of strncpy that ensures dest (size bytes) is null-terminated. */
|
||||
static char* strncpy0(char* dest, const char* src, size_t size)
|
||||
void ini_free_entry(struct ini_entry *entry)
|
||||
{
|
||||
strncpy(dest, src, size - 1);
|
||||
dest[size - 1] = '\0';
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
|
||||
void* user)
|
||||
{
|
||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
||||
#if INI_USE_STACK
|
||||
char line[INI_MAX_LINE];
|
||||
int max_line = INI_MAX_LINE;
|
||||
#else
|
||||
char* line;
|
||||
size_t max_line = INI_INITIAL_ALLOC;
|
||||
#endif
|
||||
#if INI_ALLOW_REALLOC && !INI_USE_STACK
|
||||
char* new_line;
|
||||
size_t offset;
|
||||
#endif
|
||||
char section[MAX_SECTION] = "";
|
||||
char prev_name[MAX_NAME] = "";
|
||||
|
||||
char* start;
|
||||
char* end;
|
||||
char* name;
|
||||
char* value;
|
||||
int lineno = 0;
|
||||
int error = 0;
|
||||
|
||||
#if !INI_USE_STACK
|
||||
line = (char*)malloc(INI_INITIAL_ALLOC);
|
||||
if (!line) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if INI_HANDLER_LINENO
|
||||
#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno)
|
||||
#else
|
||||
#define HANDLER(u, s, n, v) handler(u, s, n, v)
|
||||
#endif
|
||||
|
||||
/* Scan through stream line by line */
|
||||
while (reader(line, (int)max_line, stream) != NULL) {
|
||||
#if INI_ALLOW_REALLOC && !INI_USE_STACK
|
||||
offset = strlen(line);
|
||||
while (offset == max_line - 1 && line[offset - 1] != '\n') {
|
||||
max_line *= 2;
|
||||
if (max_line > INI_MAX_LINE)
|
||||
max_line = INI_MAX_LINE;
|
||||
new_line = realloc(line, max_line);
|
||||
if (!new_line) {
|
||||
free(line);
|
||||
return -2;
|
||||
}
|
||||
line = new_line;
|
||||
if (reader(line + offset, (int)(max_line - offset), stream) == NULL)
|
||||
break;
|
||||
if (max_line >= INI_MAX_LINE)
|
||||
break;
|
||||
offset += strlen(line + offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
lineno++;
|
||||
|
||||
start = line;
|
||||
#if INI_ALLOW_BOM
|
||||
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
|
||||
(unsigned char)start[1] == 0xBB &&
|
||||
(unsigned char)start[2] == 0xBF) {
|
||||
start += 3;
|
||||
}
|
||||
#endif
|
||||
start = lskip(rstrip(start));
|
||||
|
||||
if (strchr(INI_START_COMMENT_PREFIXES, *start)) {
|
||||
/* Start-of-line comment */
|
||||
}
|
||||
#if INI_ALLOW_MULTILINE
|
||||
else if (*prev_name && *start && start > line) {
|
||||
/* Non-blank line with leading whitespace, treat as continuation
|
||||
of previous name's value (as per Python configparser). */
|
||||
if (!HANDLER(user, section, prev_name, start) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
#endif
|
||||
else if (*start == '[') {
|
||||
/* A "[section]" line */
|
||||
end = find_chars_or_comment(start + 1, "]");
|
||||
if (*end == ']') {
|
||||
*end = '\0';
|
||||
strncpy0(section, start + 1, sizeof(section));
|
||||
*prev_name = '\0';
|
||||
#if INI_CALL_HANDLER_ON_NEW_SECTION
|
||||
if (!HANDLER(user, section, NULL, NULL) && !error)
|
||||
error = lineno;
|
||||
#endif
|
||||
}
|
||||
else if (!error) {
|
||||
/* No ']' found on section line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
else if (*start) {
|
||||
/* Not a comment, must be a name[=:]value pair */
|
||||
end = find_chars_or_comment(start, "=:");
|
||||
if (*end == '=' || *end == ':') {
|
||||
*end = '\0';
|
||||
name = rstrip(start);
|
||||
value = end + 1;
|
||||
#if INI_ALLOW_INLINE_COMMENTS
|
||||
end = find_chars_or_comment(value, NULL);
|
||||
if (*end)
|
||||
*end = '\0';
|
||||
#endif
|
||||
value = lskip(value);
|
||||
rstrip(value);
|
||||
|
||||
/* Valid name[=:]value pair found, call handler */
|
||||
strncpy0(prev_name, name, sizeof(prev_name));
|
||||
if (!HANDLER(user, section, name, value) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
else if (!error) {
|
||||
/* No '=' or ':' found on name[=:]value line */
|
||||
#if INI_ALLOW_NO_VALUE
|
||||
*end = '\0';
|
||||
name = rstrip(start);
|
||||
if (!HANDLER(user, section, name, NULL) && !error)
|
||||
error = lineno;
|
||||
#else
|
||||
error = lineno;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if INI_STOP_ON_FIRST_ERROR
|
||||
if (error)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !INI_USE_STACK
|
||||
free(line);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_file(FILE* file, ini_handler handler, void* user)
|
||||
{
|
||||
return ini_parse_stream((ini_reader)fgets, file, handler, user);
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse(const char* filename, ini_handler handler, void* user)
|
||||
{
|
||||
FILE* file;
|
||||
int error;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
return -1;
|
||||
error = ini_parse_file(file, handler, user);
|
||||
fclose(file);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* An ini_reader function to read the next line from a string buffer. This
|
||||
is the fgets() equivalent used by ini_parse_string(). */
|
||||
static char* ini_reader_string(char* str, int num, void* stream) {
|
||||
ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream;
|
||||
const char* ctx_ptr = ctx->ptr;
|
||||
size_t ctx_num_left = ctx->num_left;
|
||||
char* strp = str;
|
||||
char c;
|
||||
|
||||
if (ctx_num_left == 0 || num < 2)
|
||||
return NULL;
|
||||
|
||||
while (num > 1 && ctx_num_left != 0) {
|
||||
c = *ctx_ptr++;
|
||||
ctx_num_left--;
|
||||
*strp++ = c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
num--;
|
||||
}
|
||||
|
||||
*strp = '\0';
|
||||
ctx->ptr = ctx_ptr;
|
||||
ctx->num_left = ctx_num_left;
|
||||
return str;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_string(const char* string, ini_handler handler, void* user) {
|
||||
ini_parse_string_ctx ctx;
|
||||
|
||||
ctx.ptr = string;
|
||||
ctx.num_left = strlen(string);
|
||||
return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler,
|
||||
user);
|
||||
free_string(entry->name);
|
||||
ini_free_value(&entry->value);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ini_parser.tab.h"
|
||||
#include "system4.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
char string_buf[65536];
|
||||
char *string_buf_ptr;
|
||||
|
||||
unsigned long yini_line = 1;
|
||||
|
||||
%}
|
||||
|
||||
%option noyywrap
|
||||
%option prefix="yini_"
|
||||
|
||||
%x str
|
||||
|
||||
%%
|
||||
|
||||
[ \t\r] ;
|
||||
\n yini_line++;
|
||||
;[^\n]*\n yini_line++;
|
||||
\{ return '{';
|
||||
\} return '}';
|
||||
\[ return '[';
|
||||
\] return ']';
|
||||
= return '=';
|
||||
, return ',';
|
||||
true return TRUE;
|
||||
false return FALSE;
|
||||
[0-9]+ yini_lval.i = atoi(yini_text); return INTEGER;
|
||||
[a-zA-Z]+[a-zA-Z0-9]* yini_lval.s = make_string(yini_text, yini_leng); return IDENTIFIER;
|
||||
|
||||
\" string_buf_ptr = string_buf; BEGIN(str);
|
||||
|
||||
<str>{
|
||||
\" {
|
||||
BEGIN(INITIAL);
|
||||
*string_buf_ptr = '\0';
|
||||
yini_lval.s = make_string(string_buf, string_buf_ptr - string_buf);
|
||||
return STRING;
|
||||
}
|
||||
|
||||
\n ERROR("Unterminated string literal at line %lu", yini_line);
|
||||
|
||||
\\n *string_buf_ptr++ = '\n';
|
||||
\\t *string_buf_ptr++ = '\t';
|
||||
\\r *string_buf_ptr++ = '\r';
|
||||
\\b *string_buf_ptr++ = '\b';
|
||||
\\f *string_buf_ptr++ = '\f';
|
||||
|
||||
\\(.|\n) *string_buf_ptr++ = yini_text[1];
|
||||
|
||||
[^\\\n\"]+ {
|
||||
char *yptr = yini_text;
|
||||
while (*yptr)
|
||||
*string_buf_ptr++ = *yptr++;
|
||||
}
|
||||
}
|
||||
|
||||
%%
|
||||
@@ -0,0 +1,116 @@
|
||||
%define api.prefix {yini_}
|
||||
|
||||
%union {
|
||||
int token;
|
||||
int i;
|
||||
struct string *s;
|
||||
struct ini_entry *entry;
|
||||
struct ini_value value;
|
||||
entry_list *entries;
|
||||
value_list *list;
|
||||
}
|
||||
|
||||
%code requires {
|
||||
#include "kvec.h"
|
||||
#include "system4/ini.h"
|
||||
|
||||
kv_decl(entry_list, struct ini_entry*);
|
||||
kv_decl(value_list, struct ini_value);
|
||||
entry_list *yini_entries;
|
||||
}
|
||||
|
||||
%{
|
||||
|
||||
#include <stdio.h>
|
||||
#include "system4.h"
|
||||
#include "system4/string.h"
|
||||
|
||||
extern unsigned long yini_line;
|
||||
extern int yini_lex();
|
||||
void yini_error(const char *s) { ERROR("at line %lu: %s", yini_line, s); }
|
||||
|
||||
static entry_list *make_ini(void)
|
||||
{
|
||||
entry_list *ini = xmalloc(sizeof(entry_list));
|
||||
kv_init(*ini);
|
||||
return ini;
|
||||
}
|
||||
|
||||
static void push_entry(entry_list *ini, struct ini_entry *entry)
|
||||
{
|
||||
kv_push(struct ini_entry*, *ini, entry);
|
||||
}
|
||||
|
||||
static struct ini_value make_list(value_list *values)
|
||||
{
|
||||
struct ini_value *vals = kv_data(*values);
|
||||
size_t nr_vals = kv_size(*values);
|
||||
free(values);
|
||||
return ini_make_list(vals, nr_vals);
|
||||
}
|
||||
|
||||
static value_list *make_value_list(void)
|
||||
{
|
||||
value_list *values = xmalloc(sizeof(value_list));
|
||||
kv_init(*values);
|
||||
return values;
|
||||
}
|
||||
|
||||
static void push_value(value_list *values, struct ini_value value)
|
||||
{
|
||||
kv_push(struct ini_value, *values, value);
|
||||
}
|
||||
|
||||
static struct ini_entry *make_list_assign(struct string *name, int i, struct ini_value value)
|
||||
{
|
||||
struct ini_value *val = xmalloc(sizeof(struct ini_value));
|
||||
*val = value;
|
||||
|
||||
struct ini_value wrapper = {
|
||||
.type = _INI_LIST_ENTRY,
|
||||
._list_pos = i,
|
||||
._list_value = val
|
||||
};
|
||||
return ini_make_entry(name, wrapper);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%token <token> TRUE FALSE
|
||||
%token <i> INTEGER
|
||||
%token <s> STRING IDENTIFIER
|
||||
|
||||
%type <entries> inifile
|
||||
%type <entries> entries
|
||||
%type <entry> entry
|
||||
%type <value> value
|
||||
%type <list> list
|
||||
|
||||
%start inifile
|
||||
|
||||
%%
|
||||
|
||||
inifile : entries { yini_entries = $1; }
|
||||
;
|
||||
|
||||
entries : entry { $$ = make_ini(); push_entry($$, $1); }
|
||||
| entries entry { push_entry($1, $2); }
|
||||
;
|
||||
|
||||
entry : IDENTIFIER '=' value { $$ = ini_make_entry($1, $3); }
|
||||
| IDENTIFIER '[' INTEGER ']' '=' value { $$ = make_list_assign($1, $3, $6); }
|
||||
;
|
||||
|
||||
value : INTEGER { $$ = ini_make_integer($1); }
|
||||
| TRUE { $$ = ini_make_boolean(true); }
|
||||
| FALSE { $$ = ini_make_boolean(false); }
|
||||
| STRING { $$ = ini_make_string($1); }
|
||||
| '{' list '}' { $$ = make_list($2); }
|
||||
| '{' list ',' '}' { $$ = make_list($2); }
|
||||
;
|
||||
|
||||
list : value { $$ = make_value_list(); push_value($$, $1); }
|
||||
| list ',' value { push_value($1, $3); }
|
||||
;
|
||||
|
||||
%%
|
||||
@@ -60,6 +60,17 @@ if chibi.found()
|
||||
add_project_arguments('-DDEBUGGER_ENABLED', language : 'c')
|
||||
endif
|
||||
|
||||
flexgen = generator(flex,
|
||||
output : '@BASENAME@.yy.c',
|
||||
arguments : ['-o', '@OUTPUT@', '@INPUT@'])
|
||||
|
||||
bisongen = generator(bison,
|
||||
output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
|
||||
arguments : ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'])
|
||||
|
||||
xsystem4 += flexgen.process('ini_lexer.l')
|
||||
xsystem4 += bisongen.process('ini_parser.y')
|
||||
|
||||
libsys4 = static_library('sys4', system4,
|
||||
dependencies : [libm, zlib, tj],
|
||||
include_directories : incdir)
|
||||
|
||||
+32
-26
@@ -25,12 +25,13 @@
|
||||
#include <getopt.h>
|
||||
#include "debugger.h"
|
||||
#include "file.h"
|
||||
#include "ini.h"
|
||||
#include "little_endian.h"
|
||||
#include "system4.h"
|
||||
#include "system4/ain.h"
|
||||
#include "system4/ald.h"
|
||||
#include "system4/ini.h"
|
||||
#include "system4/instructions.h"
|
||||
#include "system4/string.h"
|
||||
#include "system4/utfsjis.h"
|
||||
#include "vm.h"
|
||||
|
||||
@@ -44,34 +45,40 @@ struct config config = {
|
||||
.view_height = 600
|
||||
};
|
||||
|
||||
// XXX: need to remove quotes from ini strings
|
||||
static char *config_strdup(const char *str)
|
||||
static struct string *ini_string(struct ini_entry *entry)
|
||||
{
|
||||
if (*str != '"')
|
||||
ERROR("Not a string: %s", str);
|
||||
char *out = strdup(str+1);
|
||||
size_t len = strlen(out);
|
||||
if (!len || out[len-1] != '"')
|
||||
ERROR("Not a string: %s", str);
|
||||
out[len-1] = '\0';
|
||||
return out;
|
||||
if (entry->value.type != INI_STRING)
|
||||
ERROR("ini value for '%s' is not a string", entry->name->text);
|
||||
return entry->value.s;
|
||||
}
|
||||
|
||||
static int config_handler(void *user, possibly_unused const char *section, const char *name, const char *value)
|
||||
static int ini_integer(struct ini_entry *entry)
|
||||
{
|
||||
struct config *config = (struct config*)user;
|
||||
if (!strcmp(name, "GameName")) {
|
||||
config->game_name = config_strdup(value);
|
||||
} else if (!strcmp(name, "CodeName")) {
|
||||
config->ain_filename = config_strdup(value);
|
||||
} else if (!strcmp(name, "SaveFolder")) {
|
||||
config->save_dir = config_strdup(value);
|
||||
} else if (!strcmp(name, "ViewWidth")) {
|
||||
config->view_width = atoi(value);
|
||||
} else if (!strcmp(name, "ViewHeight")) {
|
||||
config->view_height = atoi(value);
|
||||
if (entry->value.type != INI_INTEGER)
|
||||
ERROR("ini value for '%s' is not an integer", entry->name->text);
|
||||
return entry->value.i;
|
||||
}
|
||||
|
||||
static void read_config(const char *path)
|
||||
{
|
||||
size_t ini_size;
|
||||
struct ini_entry *ini = ini_parse(path, &ini_size);
|
||||
|
||||
for (size_t i = 0; i < ini_size; i++) {
|
||||
if (!strcmp(ini[i].name->text, "GameName")) {
|
||||
config.game_name = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "CodeName")) {
|
||||
config.ain_filename = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "SaveFolder")) {
|
||||
config.save_dir = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "ViewWidth")) {
|
||||
config.view_width = ini_integer(&ini[i]);
|
||||
} else if (!strcmp(ini[i].name->text, "ViewHeight")) {
|
||||
config.view_height = ini_integer(&ini[i]);
|
||||
}
|
||||
ini_free_entry(&ini[i]);
|
||||
}
|
||||
return 1;
|
||||
free(ini);
|
||||
}
|
||||
|
||||
static char *ald_filenames[ALDFILETYPE_MAX][ALD_FILEMAX];
|
||||
@@ -299,8 +306,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
len = strlen(argv[0]);
|
||||
if (len > 4 && !strcasecmp(&argv[0][len - 4], ".ini")) {
|
||||
if (ini_parse(argv[0], config_handler, &config) < 0)
|
||||
ERROR("Can't parse %s as ini", argv[0]);
|
||||
read_config(argv[0]);
|
||||
if (!config.ain_filename)
|
||||
ERROR("No AIN filename specified in %s", argv[0]);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,106 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_YY_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_ASM_PARSER_TAB_H_INCLUDED
|
||||
# define YY_YY_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_ASM_PARSER_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int yydebug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 9 "../src/tools/ainedit/asm_parser.y" /* yacc.c:1921 */
|
||||
|
||||
#include <stdint.h>
|
||||
#include "khash.h"
|
||||
#include "kvec.h"
|
||||
|
||||
kv_decl(parse_instruction_list, struct parse_instruction*);
|
||||
kv_decl(parse_argument_list, struct string*);
|
||||
kv_decl(pointer_list, uint32_t*);
|
||||
|
||||
struct parse_instruction {
|
||||
uint16_t opcode;
|
||||
parse_argument_list *args;
|
||||
};
|
||||
|
||||
parse_instruction_list *parsed_code;
|
||||
|
||||
KHASH_MAP_INIT_STR(label_table, uint32_t);
|
||||
khash_t(label_table) *label_table;
|
||||
|
||||
#line 68 "src/tools/ainedit/659eb3d@@ainedit@exe/asm_parser.tab.h" /* yacc.c:1921 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
IDENTIFIER = 258,
|
||||
LABEL = 259,
|
||||
NEWLINE = 260
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 1 "../src/tools/ainedit/asm_parser.y" /* yacc.c:1921 */
|
||||
|
||||
int token;
|
||||
struct string *string;
|
||||
parse_argument_list *args;
|
||||
struct parse_instruction *instr;
|
||||
parse_instruction_list *program;
|
||||
|
||||
#line 94 "src/tools/ainedit/659eb3d@@ainedit@exe/asm_parser.tab.h" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int yyparse (void);
|
||||
|
||||
#endif /* !YY_YY_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_ASM_PARSER_TAB_H_INCLUDED */
|
||||
@@ -9,20 +9,10 @@ ainedit = ['../../cJSON.c',
|
||||
'transcode.c',
|
||||
]
|
||||
|
||||
if flex.found()
|
||||
lfiles = flexgen.process('asm_lexer.l', 'text_lexer.l')
|
||||
else
|
||||
lfiles = ['asm_lexer.yy.c', 'text_lexer.yy.c']
|
||||
endif
|
||||
ainedit += flexgen.process('asm_lexer.l', 'text_lexer.l')
|
||||
ainedit += bisongen.process('asm_parser.y', 'text_parser.y')
|
||||
|
||||
if bison.found()
|
||||
pfiles = bisongen.process('asm_parser.y', 'text_parser.y')
|
||||
else
|
||||
pfiles = ['asm_parser.tab.c', 'asm_parser.tab.h', 'text_parser.tab.c', 'text_parser.tab.h']
|
||||
endif
|
||||
|
||||
|
||||
executable('ainedit', ainedit, lfiles, pfiles,
|
||||
executable('ainedit', ainedit,
|
||||
dependencies : tool_deps,
|
||||
c_args : ['-Wno-unused-parameter'],
|
||||
include_directories : incdir,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_TEXT_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_TEXT_PARSER_TAB_H_INCLUDED
|
||||
# define YY_TEXT_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_TEXT_PARSER_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef TEXT_DEBUG
|
||||
# if defined YYDEBUG
|
||||
#if YYDEBUG
|
||||
# define TEXT_DEBUG 1
|
||||
# else
|
||||
# define TEXT_DEBUG 0
|
||||
# endif
|
||||
# else /* ! defined YYDEBUG */
|
||||
# define TEXT_DEBUG 0
|
||||
# endif /* ! defined YYDEBUG */
|
||||
#endif /* ! defined TEXT_DEBUG */
|
||||
#if TEXT_DEBUG
|
||||
extern int text_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 11 "../src/tools/ainedit/text_parser.y" /* yacc.c:1921 */
|
||||
|
||||
#include "kvec.h"
|
||||
|
||||
kv_decl(assignment_list, struct text_assignment*);
|
||||
|
||||
struct text_assignment {
|
||||
int type;
|
||||
int index;
|
||||
struct string *string;
|
||||
};
|
||||
|
||||
assignment_list *statements;
|
||||
|
||||
|
||||
#line 71 "src/tools/ainedit/659eb3d@@ainedit@exe/text_parser.tab.h" /* yacc.c:1921 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef TEXT_TOKENTYPE
|
||||
# define TEXT_TOKENTYPE
|
||||
enum text_tokentype
|
||||
{
|
||||
NEWLINE = 258,
|
||||
LBRACKET = 259,
|
||||
RBRACKET = 260,
|
||||
EQUAL = 261,
|
||||
MESSAGES = 262,
|
||||
STRINGS = 263,
|
||||
NUMBER = 264,
|
||||
STRING = 265
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined TEXT_STYPE && ! defined TEXT_STYPE_IS_DECLARED
|
||||
|
||||
union TEXT_STYPE
|
||||
{
|
||||
#line 3 "../src/tools/ainedit/text_parser.y" /* yacc.c:1921 */
|
||||
|
||||
int token;
|
||||
int integer;
|
||||
struct string *string;
|
||||
struct text_assignment *assign;
|
||||
assignment_list *program;
|
||||
|
||||
#line 102 "src/tools/ainedit/659eb3d@@ainedit@exe/text_parser.tab.h" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union TEXT_STYPE TEXT_STYPE;
|
||||
# define TEXT_STYPE_IS_TRIVIAL 1
|
||||
# define TEXT_STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern TEXT_STYPE text_lval;
|
||||
|
||||
int text_parse (void);
|
||||
|
||||
#endif /* !YY_TEXT_SRC_TOOLS_AINEDIT_659EB3D_AINEDIT_EXE_TEXT_PARSER_TAB_H_INCLUDED */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,125 +0,0 @@
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_YEX_SRC_TOOLS_EX_CF5F17F_EXBUILD_EXE_EX_PARSER_TAB_H_INCLUDED
|
||||
# define YY_YEX_SRC_TOOLS_EX_CF5F17F_EXBUILD_EXE_EX_PARSER_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YEX_DEBUG
|
||||
# if defined YYDEBUG
|
||||
#if YYDEBUG
|
||||
# define YEX_DEBUG 1
|
||||
# else
|
||||
# define YEX_DEBUG 0
|
||||
# endif
|
||||
# else /* ! defined YYDEBUG */
|
||||
# define YEX_DEBUG 0
|
||||
# endif /* ! defined YYDEBUG */
|
||||
#endif /* ! defined YEX_DEBUG */
|
||||
#if YEX_DEBUG
|
||||
extern int yex_debug;
|
||||
#endif
|
||||
/* "%code requires" blocks. */
|
||||
#line 22 "../src/tools/ex/ex_parser.y" /* yacc.c:1921 */
|
||||
|
||||
#include "kvec.h"
|
||||
#include "system4/ex.h"
|
||||
|
||||
kv_decl(block_list, struct ex_block*);
|
||||
kv_decl(field_list, struct ex_field*);
|
||||
kv_decl(value_list, struct ex_value*);
|
||||
kv_decl(row_list, value_list*);
|
||||
kv_decl(node_list, struct ex_tree*);
|
||||
|
||||
struct ex *ex_data;
|
||||
|
||||
|
||||
#line 70 "src/tools/ex/cf5f17f@@exbuild@exe/ex_parser.tab.h" /* yacc.c:1921 */
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YEX_TOKENTYPE
|
||||
# define YEX_TOKENTYPE
|
||||
enum yex_tokentype
|
||||
{
|
||||
INT = 258,
|
||||
FLOAT = 259,
|
||||
STRING = 260,
|
||||
TABLE = 261,
|
||||
LIST = 262,
|
||||
TREE = 263,
|
||||
CONST_INT = 264,
|
||||
CONST_FLOAT = 265,
|
||||
CONST_STRING = 266
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YEX_STYPE && ! defined YEX_STYPE_IS_DECLARED
|
||||
|
||||
union YEX_STYPE
|
||||
{
|
||||
#line 3 "../src/tools/ex/ex_parser.y" /* yacc.c:1921 */
|
||||
|
||||
int token;
|
||||
int i;
|
||||
float f;
|
||||
struct string *s;
|
||||
struct ex *ex;
|
||||
struct ex_block *block;
|
||||
struct ex_table *table;
|
||||
struct ex_field *field;
|
||||
struct ex_list *list;
|
||||
struct ex_tree *tree;
|
||||
struct ex_value *value;
|
||||
block_list *blocks;
|
||||
field_list *fields;
|
||||
row_list *rows;
|
||||
value_list *values;
|
||||
node_list *nodes;
|
||||
|
||||
#line 113 "src/tools/ex/cf5f17f@@exbuild@exe/ex_parser.tab.h" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union YEX_STYPE YEX_STYPE;
|
||||
# define YEX_STYPE_IS_TRIVIAL 1
|
||||
# define YEX_STYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
extern YEX_STYPE yex_lval;
|
||||
|
||||
int yex_parse (void);
|
||||
|
||||
#endif /* !YY_YEX_SRC_TOOLS_EX_CF5F17F_EXBUILD_EXE_EX_PARSER_TAB_H_INCLUDED */
|
||||
@@ -3,22 +3,22 @@ exdump = ['../conv.c',
|
||||
'exdump.c',
|
||||
]
|
||||
|
||||
lfiles = flexgen.process('ex_lexer.l')
|
||||
pfiles = bisongen.process('ex_parser.y')
|
||||
|
||||
exbuild = ['../conv.c',
|
||||
'ast.c',
|
||||
'exbuild.c',
|
||||
'pack.c',
|
||||
]
|
||||
|
||||
exbuild += flexgen.process('ex_lexer.l')
|
||||
exbuild += bisongen.process('ex_parser.y')
|
||||
|
||||
executable('exdump', exdump,
|
||||
dependencies : tool_deps,
|
||||
c_args : ['-Wno-unused-parameter'],
|
||||
include_directories : incdir,
|
||||
link_with : libsys4)
|
||||
|
||||
executable('exbuild', exbuild, lfiles, pfiles,
|
||||
executable('exbuild', exbuild,
|
||||
dependencies : tool_deps,
|
||||
c_args : ['-Wno-unused-parameter'],
|
||||
include_directories : incdir,
|
||||
|
||||
@@ -1,19 +1,3 @@
|
||||
|
||||
flex = find_program('flex', required: false)
|
||||
bison = find_program('bison', required: false)
|
||||
|
||||
if flex.found()
|
||||
flexgen = generator(flex,
|
||||
output : '@BASENAME@.yy.c',
|
||||
arguments : ['-o', '@OUTPUT@', '@INPUT@'])
|
||||
endif
|
||||
|
||||
if bison.found()
|
||||
bisongen = generator(bison,
|
||||
output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
|
||||
arguments : ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@'])
|
||||
endif
|
||||
|
||||
if build_machine.system() == 'windows'
|
||||
iconv = dependency('iconv')
|
||||
tool_deps = [libm, zlib, iconv]
|
||||
|
||||
Reference in New Issue
Block a user