[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] tools: move libxlutil to tools/libs/util
commit 3ae0d316f01c08903a96f6b5b39275c67b823264 Author: Juergen Gross <jgross@xxxxxxxx> AuthorDate: Wed Sep 23 06:57:20 2020 +0200 Commit: Juergen Gross <jgross@xxxxxxxx> CommitDate: Thu Oct 1 13:26:17 2020 +0200 tools: move libxlutil to tools/libs/util Move the libxlutil source to tools/libs/util and delete tools/libxl. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> Acked-by: Wei Liu <wl@xxxxxxx> --- .gitignore | 6 +- tools/Makefile | 1 - tools/Rules.mk | 7 - tools/libs/Makefile | 1 + tools/libs/uselibs.mk | 3 + tools/libs/util/CODING_STYLE | 330 ++++ tools/libs/util/Makefile | 63 + tools/libs/util/include/libxlutil.h | 136 ++ tools/libs/util/libxlu_cfg.c | 712 +++++++++ tools/libs/util/libxlu_cfg_i.h | 59 + tools/libs/util/libxlu_cfg_l.c | 2375 ++++++++++++++++++++++++++++ tools/libs/util/libxlu_cfg_l.h | 734 +++++++++ tools/libs/util/libxlu_cfg_l.l | 104 ++ tools/libs/util/libxlu_cfg_y.c | 1705 ++++++++++++++++++++ tools/libs/util/libxlu_cfg_y.h | 96 ++ tools/libs/util/libxlu_cfg_y.y | 79 + tools/libs/util/libxlu_disk.c | 102 ++ tools/libs/util/libxlu_disk_i.h | 29 + tools/libs/util/libxlu_disk_l.c | 2944 +++++++++++++++++++++++++++++++++++ tools/libs/util/libxlu_disk_l.h | 701 +++++++++ tools/libs/util/libxlu_disk_l.l | 289 ++++ tools/libs/util/libxlu_internal.h | 84 + tools/libs/util/libxlu_pci.c | 264 ++++ tools/libs/util/libxlu_vif.c | 149 ++ tools/libxl/CODING_STYLE | 330 ---- tools/libxl/Makefile | 124 -- tools/libxl/libxlu_cfg.c | 712 --------- tools/libxl/libxlu_cfg_i.h | 59 - tools/libxl/libxlu_cfg_l.c | 2375 ---------------------------- tools/libxl/libxlu_cfg_l.h | 734 --------- tools/libxl/libxlu_cfg_l.l | 104 -- tools/libxl/libxlu_cfg_y.c | 1705 -------------------- tools/libxl/libxlu_cfg_y.h | 96 -- tools/libxl/libxlu_cfg_y.y | 79 - tools/libxl/libxlu_disk.c | 102 -- tools/libxl/libxlu_disk_i.h | 29 - tools/libxl/libxlu_disk_l.c | 2944 ----------------------------------- tools/libxl/libxlu_disk_l.h | 701 --------- tools/libxl/libxlu_disk_l.l | 289 ---- tools/libxl/libxlu_internal.h | 84 - tools/libxl/libxlu_pci.c | 264 ---- tools/libxl/libxlu_vif.c | 149 -- tools/libxl/libxlutil.h | 136 -- 43 files changed, 10963 insertions(+), 11026 deletions(-) diff --git a/.gitignore b/.gitignore index f30550255f..188495783e 100644 --- a/.gitignore +++ b/.gitignore @@ -154,6 +154,10 @@ tools/libs/store/utils.h tools/libs/store/xenstore.pc tools/libs/store/xs_lib.c tools/libs/store/include/xenstore_lib.h +tools/libs/util/*.pc +tools/libs/util/_paths.h +tools/libs/util/libxlu_cfg_y.output +tools/libs/util/libxenutil.map tools/libs/vchan/headers.chk tools/libs/vchan/libxenvchan.map tools/libs/vchan/xenvchan.pc @@ -232,8 +236,6 @@ tools/include/xen/* tools/include/xen-xsm/* tools/include/xen-foreign/*.(c|h|size) tools/include/xen-foreign/checker -tools/libxl/*.pc -tools/libxl/libxlu_cfg_y.output tools/misc/cpuperf/cpuperf-perfcntr tools/misc/cpuperf/cpuperf-xen tools/misc/xc_shadow diff --git a/tools/Makefile b/tools/Makefile index c1eba22c0c..ed71474421 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -29,7 +29,6 @@ SUBDIRS-$(CONFIG_QEMU_XEN) += qemu-xen-dir endif SUBDIRS-y += xenpmd -SUBDIRS-y += libxl SUBDIRS-$(CONFIG_GOLANG) += golang SUBDIRS-y += xl SUBDIRS-y += helpers diff --git a/tools/Rules.mk b/tools/Rules.mk index 75d44c4a4b..f3e0078927 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -15,8 +15,6 @@ XEN_INCLUDE = $(XEN_ROOT)/tools/include include $(XEN_ROOT)/tools/libs/uselibs.mk -XEN_libxenutil = $(XEN_ROOT)/tools/libxl - CFLAGS_xeninclude = -I$(XEN_INCLUDE) XENSTORE_XENSTORED ?= y @@ -117,11 +115,6 @@ else CFLAGS += -O2 -fomit-frame-pointer endif -CFLAGS_libxenutil = -I$(XEN_libxenutil) -SHDEPS_libxenutil = $(SHLIB_libxenlight) -LDLIBS_libxenutil = $(SHDEPS_libxenutil) $(XEN_libxenutil)/libxlutil$(libextension) -SHLIB_libxenutil = $(SHDEPS_libxenutil) -Wl,-rpath-link=$(XEN_libxenutil) - CFLAGS += -D__XEN_INTERFACE_VERSION__=__XEN_LATEST_INTERFACE_VERSION__ # Get gcc to generate the dependencies for us. diff --git a/tools/libs/Makefile b/tools/libs/Makefile index c41455c604..1afcd12e2b 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -16,6 +16,7 @@ SUBDIRS-y += store SUBDIRS-y += stat SUBDIRS-$(CONFIG_Linux) += vchan SUBDIRS-y += light +SUBDIRS-y += util ifeq ($(CONFIG_RUMP),y) SUBDIRS-y := toolcore diff --git a/tools/libs/uselibs.mk b/tools/libs/uselibs.mk index 685f368aed..efd7a475ba 100644 --- a/tools/libs/uselibs.mk +++ b/tools/libs/uselibs.mk @@ -28,3 +28,6 @@ LIBS_LIBS += stat USELIBS_stat := ctrl store LIBS_LIBS += light USELIBS_light := toollog evtchn toolcore ctrl store hypfs guest +LIBS_LIBS += util +USELIBS_util := light +FILENAME_util := xlutil diff --git a/tools/libs/util/CODING_STYLE b/tools/libs/util/CODING_STYLE new file mode 100644 index 0000000000..3d572f6925 --- /dev/null +++ b/tools/libs/util/CODING_STYLE @@ -0,0 +1,330 @@ +LIBXENLIGHT CODING STYLE +======================== + + +AN APOLOGY AND WARNING +---------------------- + +Much of the code in libxl does not yet follow this coding style +document in every respect. However, new code is expected to conform. + +Patches to improve the style of existing code are welcome. Please +separate these out from functional changes. + +If it is not feasible to conform fully to the style while patching old +code, without doing substantial style reengineering first, we may +accept patches which contain nonconformant elements, provided that +they don't make the coding style problem worse overall. + +In this case, the new code should conform to the prevailing style in +the area being touched. + + +MEMORY ALLOCATION +----------------- + +Memory allocation for libxl-internal purposes should normally be done +with the provided gc mechanisms; there is then no need to free. See +"libxl memory management" in libxl.h. + + +CONVENTIONAL VARIABLE NAMES +--------------------------- + +The following local variable names should be used where applicable: + + int rc; /* a libxl error code - and not anything else */ + int r; /* the return value from a system call (or libxc call) */ + bool ok; /* the success return value from a boolean function */ + + uint32_t domid; + libxl__gc *gc; + libxl__egc *egc; + libxl__ao *ao; + + libxl_foo_bar_state *fbs; /* local variable */ + libxl_foo_bar_state foo_bar; /* inside another state struct */ + + +CONVENIENCE MACROS +------------------ + +There are a number of convenience macros which shorten the program and +avoid opportunity for mistakes. In some cases non-use of the macros +produces functional bugs or incorrect error handling. Use the macros +whenever they are applicable. For example: + + Usually, don't use: Instead, use (see libxl_internal.h): + libxl__log[v] LOG, LOGE, LOGEV + libxl__sprintf GCSPRINTF + libxl__*alloc et al. GCNEW, GCNEW_ARRAY, GCREALLOC_ARRAY + isalnum etc. directly CTYPE + libxl__ctx_[un]lock CTX_LOCK, CTX_UNLOCK + gc=...; ao=...; EGC_GC, AO_GC, STATE_AO_GC + explicit gc creation GC_INIT, GC_FREE + memset(..,0,sizeof..) FILLZERO + +Instead of malloc et al one should (as an exception to the above) use +libxl__{zalloc,calloc,realloc} etc but passing NOGC. + +ERROR HANDLING +-------------- + +Unless, there are good reasons to do otherwise, the following error +handling and cleanup paradigm should be used: + + * All local variables referring to resources which might need + cleaning up are declared at the top of the function, and + initialised to a sentinel value indicating "nothing allocated". + For example, + libxl_evgen_disk_eject *evg = NULL; + int nullfd = -1; + + * If the function is to return a libxl error value, `rc' is + used to contain the error code, but it is NOT initialised: + int rc; + + * There is only one error cleanup path out of the function. It + starts with a label `out:'. That error cleanup path checks for + each allocated resource and frees it iff necessary. It then + returns rc. For example, + out: + if (evg) libxl__evdisable_disk_eject(gc, evg); + if (nullfd >= 0) close(nullfd); + return rc; + + * Function calls which might fail (ie most function calls) are + handled by putting the return/status value into a variable, and + then checking it in a separate statement: + char *dompath = libxl__xs_get_dompath(gc, bl->domid); + if (!dompath) { rc = ERROR_FAIL; goto out; } + + * If a resource is freed in the main body of the function (for + example, in a loop), the corresponding variable has to be reset to + the sentinel at the point where it's freed. + +Whether to use the `out' path for successful returns as well as error +returns is a matter of taste and convenience for the specific +function. Not reusing the out path is fine if the duplicated function +exit code is only `CTX_UNLOCK; GC_FREE;' (or similar). + +If you reuse the `out' path for successful returns, there may be +resources which are to be returned to the caller rather than freed. +In that case you have to reset the local variable to `nothing here', +to avoid the resource being freed on the out path. That resetting +should be done immediately after the resource value is stored at the +applicable _r function parameter (or equivalent). Do not test `rc' in +the out section, to discover whether to free things. + +The uses of the single-line formatting in the examples above are +permitted exceptions to the usual libxl code formatting rules. + + + +IDEMPOTENT DATA STRUCTURE CONSTRUCTION/DESTRUCTION +-------------------------------------------------- + +Nontrivial data structures (in structs) should come with an idempotent +_dispose function, which must free all resources associated with the +data structure (but not free the struct itself). + +Such a struct should also come with an _init function which +initialises the struct so that _dispose is a no-op. + + +ASYNCHRONOUS/LONG-RUNNING OPERATIONS +------------------------------------ + +All long-running operations in libxl need to use the asynchronous +operation machinery. Consult the programmer documentation in +libxl_internal.h for details - search for "Machinery for asynchronous +operations". + +The code for asynchronous operations should be laid out in +chronological order. That is, where there is a chain of callback +functions, each subsequent function should be, textually, the next +function in the file. This will normally involve predeclaring the +callback functions. Synchronous helper functions should be separated +out into a section preceding the main callback chain. + +Control flow arrangements in asynchronous operations should be made as +simple as possible, because it can otherwise be very hard to see +through the tangle. + + +When inventing a new sub-operation in asynchronous code, consider +whether to structure it formally as a sub-operation with its own state +structure. (See, for example, libxl__datacopier_*.) + +An ao-suboperation state structure should contain, in this order: + * fields that the caller must fill in, and which are, + effectively, the parameters to the operation, including: + - libxl__ao *ao + - the callback function pointer(s), which + should be named callback or callback_*. + * shared information fields or ones used for returning information + to the calling operation + * private fields +These sections should be clearly demarcated by comments. + +An asynchronous operation should normally have an idempotent stop or +cancel function. It should normally also have an _init function for +its state struct, which arranges that the stop is a no-op. + +The permitted order of calls into your ao operation's methods must be +documented in comments, if it is nontrivial. + + +When using an ao sub-operation, you should normally: + * Physically include the sub-operation state struct in your + own state struct; + * Use CONTAINER_OF to find your own state struct at the start of + your implementations of the sub-operation callback functions; + * Unconditionally initialise the sub-operation's struct (with its + _init method) in your own _init method. + * Unconditionally cancel or destroy the sub-operation in your own + cancel or destroy method. + + +FORMATTING AND NAMING +--------------------- + +Blatantly copied from qemu and linux with few modifications. + + +1. Whitespace + +Of course, the most important aspect in any coding style is whitespace. +Crusty old coders who have trouble spotting the glasses on their noses +can tell the difference between a tab and eight spaces from a distance +of approximately fifteen parsecs. Many a flamewar have been fought and +lost on this issue. + +Libxenlight indents are four spaces. Tabs are never used, except in +Makefiles where they have been irreversibly coded into the syntax. +Spaces of course are superior to tabs because: + + - You have just one way to specify whitespace, not two. Ambiguity breeds + mistakes. + - The confusion surrounding 'use tabs to indent, spaces to justify' is gone. + - Tab indents push your code to the right, making your screen seriously + unbalanced. + - Tabs will be rendered incorrectly on editors who are misconfigured not + to use tab stops of eight positions. + - Tabs are rendered badly in patches, causing off-by-one errors in almost + every line. + - It is the libxenlight coding style. + +Do not leave whitespace dangling off the ends of lines. + + +2. Line width + +Lines are limited to 75 characters. + +Rationale: + - Some people like to tile their 24" screens with a 6x4 matrix of 80x24 + xterms and use vi in all of them. The best way to punish them is to + let them keep doing it. + - In an 80 column terminal, some room needs to be left for > quoting + characters, +/- diff characters, and so on, in emails. + - Code and especially patches is much more readable if limited to a sane + line length. Eighty is traditional. + - It is the libxenlight coding style. + + +3. Naming + +C is a Spartan language, and so should your naming be. Unlike Modula-2 +and Pascal programmers, C programmers do not use cute names like +ThisVariableIsATemporaryCounter. A C programmer would call that +variable "tmp", which is much easier to write, and not the least more +difficult to understand. + +HOWEVER, while mixed-case names are frowned upon, descriptive names for +global variables are a must. To call a global function "foo" is a +shooting offense. + +GLOBAL variables (to be used only if you _really_ need them) need to +have descriptive names, as do global functions. If you have a function +that counts the number of active users, you should call that +"count_active_users()" or similar, you should _not_ call it "cntusr()". + +Encoding the type of a function into the name (so-called Hungarian +notation) is brain damaged - the compiler knows the types anyway and can +check those, and it only confuses the programmer. + +LOCAL variable names should be short, and to the point. If you have +some random integer loop counter, it should probably be called "i". +Calling it "loop_counter" is non-productive, if there is no chance of it +being mis-understood. Similarly, "tmp" can be just about any type of +variable that is used to hold a temporary value. + +Local variables used to store return values should have descriptive name +like "rc" or "ret". Following the same reasoning the label used as exit +path should be called "out". + +Function arguments which are used to return values to the caller +should be suffixed `_r' or `_out'. + +Variables, type names and function names are +lower_case_with_underscores. +Type names and function names use the prefix libxl__ when internal to +libxenlight and libxl_ when exported in libxl.h. +Xl should avoid using libxl_ and libxl__ as prefix for its own function +names. + +When wrapping standard library functions, use the prefix libxl_ to alert +readers that they are seeing a wrapped version; otherwise avoid this prefix. + +Typedefs are used to eliminate the redundant 'struct' keyword. +It is the libxenlight coding style. + + +4. Statements + +Don't put multiple statements on a single line. +Don't put multiple assignments on a single line either. +Error code paths with an if statement and a goto or a return on the same +line are allowed. Examples: + + if (rc) goto out; + if (rc < 0) return; + +Libxenlight coding style is super simple. Avoid tricky expressions. + + +5. Block structure + +Every indented statement is braced, but blocks that contain just one +statement may have the braces omitted. To avoid confusion, either all +the blocks in an if...else chain have braces, or none of them do. + +The opening brace is on the line that contains the control flow +statement that introduces the new block; the closing brace is on the +same line as the else keyword, or on a line by itself if there is no +else keyword. Examples: + + if (a == 5) { + printf("a was 5.\n"); + } else if (a == 6) { + printf("a was 6.\n"); + } else { + printf("a was something else entirely.\n"); + } + + if (a == 5) + printf("a was 5.\n"); + +An exception is the opening brace for a function; for reasons of tradition +and clarity it comes on a line by itself: + + void a_function(void) + { + do_something(); + } + +Rationale: a consistent (except for functions...) bracing style reduces +ambiguity and avoids needless churn when lines are added or removed. +Furthermore, it is the libxenlight coding style. + diff --git a/tools/libs/util/Makefile b/tools/libs/util/Makefile new file mode 100644 index 0000000000..0c9db8027d --- /dev/null +++ b/tools/libs/util/Makefile @@ -0,0 +1,63 @@ +XEN_ROOT = $(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +SRCS-y += libxlu_cfg_y.c +SRCS-y += libxlu_cfg_l.c +SRCS-y += libxlu_cfg.c +SRCS-y += libxlu_disk_l.c +SRCS-y += libxlu_disk.c +SRCS-y += libxlu_vif.c +SRCS-y += libxlu_pci.c + +CFLAGS += -Wno-format-zero-length -Wmissing-declarations \ + -Wno-declaration-after-statement -Wformat-nonliteral +CFLAGS += -I. $(CFLAGS_libxenctrl) + +CFLAGS += $(PTHREAD_CFLAGS) +LDFLAGS += $(PTHREAD_LDFLAGS) + +ifeq ($(FLEX),) +%.c %.h:: %.l + $(warning Flex is needed to rebuild some libxl parsers and \ + scanners, please install it and rerun configure) +endif + +ifeq ($(BISON),) +%.c %.h:: %.y + $(warning Bison is needed to rebuild some libxl parsers and \ + scanners, please install it and rerun configure) +endif + +AUTOINCS = libxlu_cfg_y.h libxlu_cfg_l.h libxlu_disk_l.h +AUTOSRCS = libxlu_cfg_y.c libxlu_cfg_l.c + +LIBHEADER := libxlutil.h +PKG_CONFIG_NAME := Xlutil +PKG_CONFIG_DESC := The xl utility library for Xen hypervisor + +NO_HEADERS_CHK := y + +include $(XEN_ROOT)/tools/libs/libs.mk + +$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_libxenutil)/include +$(PKG_CONFIG_LOCAL): PKG_CONFIG_CFLAGS_LOCAL = $(CFLAGS_xeninclude) + +$(LIB_OBJS) $(PIC_OBJS): $(AUTOINCS) _paths.h + +%.c %.h:: %.y + @rm -f $*.[ch] + $(BISON) --output=$*.c $< + +%.c %.h:: %.l + @rm -f $*.[ch] + $(FLEX) --header-file=$*.h --outfile=$*.c $< + +genpath-target = $(call buildmakevars2header,_paths.h) +$(eval $(genpath-target)) + +clean: cleanlocal + +.PHONY: cleanlocal +cleanlocal: + $(RM) -f _*.h + $(RM) -f libxlutil.map diff --git a/tools/libs/util/include/libxlutil.h b/tools/libs/util/include/libxlutil.h new file mode 100644 index 0000000000..92e35c5462 --- /dev/null +++ b/tools/libs/util/include/libxlutil.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2010 Citrix Ltd. + * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * 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 Lesser General Public License for more details. + */ + +#ifndef LIBXLUTIL_H +#define LIBXLUTIL_H + +#include <stdio.h> + +#include "libxl.h" + +enum XLU_ConfigValueType { + XLU_STRING, + XLU_LIST, +}; + +enum XLU_Operation { + XLU_OP_ASSIGNMENT = 0, + XLU_OP_ADDITION, +}; + +/* Unless otherwise stated, all functions return an errno value. */ +typedef struct XLU_Config XLU_Config; +typedef struct XLU_ConfigList XLU_ConfigList; +typedef struct XLU_ConfigValue XLU_ConfigValue; + +XLU_Config *xlu_cfg_init(FILE *report, const char *report_filename); + /* 0 means we got ENOMEM. */ + /* report_filename is copied; report is saved and must remain valid + * until the Config is destroyed. */ + +int xlu_cfg_readfile(XLU_Config*, const char *real_filename); +int xlu_cfg_readdata(XLU_Config*, const char *data, int length); + /* If these fail, then it is undefined behaviour to call xlu_cfg_get_... + * functions. You have to just xlu_cfg_destroy. */ + +void xlu_cfg_destroy(XLU_Config*); + + +/* All of the following print warnings to "report" if there is a problem. + * Return values are: + * 0 OK + * ESRCH not defined + * EINVAL value found but wrong format for request (prints warning unless dont_warn=true) + * ERANGE value out of range (from strtol) + */ + +int xlu_cfg_get_string(const XLU_Config*, const char *n, const char **value_r, + int dont_warn); +/* free/strdup version */ +int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, + char **value_r, int dont_warn); +int xlu_cfg_get_long(const XLU_Config*, const char *n, long *value_r, + int dont_warn); +int xlu_cfg_get_bounded_long(const XLU_Config*, const char *n, long min, + long max, long *value_r, int dont_warn); +int xlu_cfg_get_defbool(const XLU_Config*, const char *n, libxl_defbool *b, + int dont_warn); + +int xlu_cfg_get_list(const XLU_Config*, const char *n, + XLU_ConfigList **list_r /* may be 0 */, + int *entries_r /* may be 0 */, + int dont_warn); + /* there is no need to free *list_r; lifetime is that of the XLU_Config */ +int xlu_cfg_get_list_as_string_list(const XLU_Config *cfg, const char *n, + libxl_string_list *sl, int dont_warn); +const char *xlu_cfg_get_listitem(const XLU_ConfigList*, int entry); + /* xlu_cfg_get_listitem cannot fail, except that if entry is + * out of range it returns 0 (not setting errno) */ + +enum XLU_ConfigValueType xlu_cfg_value_type(const XLU_ConfigValue *value); +int xlu_cfg_value_get_string(const XLU_Config *cfg, XLU_ConfigValue *value, + char **value_r, int dont_warn); +int xlu_cfg_value_get_list(const XLU_Config *cfg, XLU_ConfigValue *value, + XLU_ConfigList **value_r, int dont_warn); +XLU_ConfigValue *xlu_cfg_get_listitem2(const XLU_ConfigList *list, + int entry); + +/* + * Disk specification parsing. + */ + +int xlu_disk_parse(XLU_Config *cfg, int nspecs, const char *const *specs, + libxl_device_disk *disk); + /* disk must have been initialised. + * + * On error, returns errno value. Bad strings cause EINVAL and + * print a message to cfg's report (that's all cfg is used for). + * + * Normally one would pass nspecs==1 and only specs[0]. But it is + * permitted to pass more strings in which case each is parsed as a + * string containing a collection of parameters (but they all refer + * to of the configuration for a single disk). + * + * nspecs==0 is permitted but since it does not specify some mandatory + * properties, it produces a run-time configuration error if the + * resulting disk struct is used with libxl. + */ + +/* + * PCI specification parsing + */ +int xlu_pci_parse_bdf(XLU_Config *cfg, libxl_device_pci *pcidev, const char *str); + +/* + * RDM parsing + */ +int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str); + +/* + * Vif rate parsing. + */ + +int xlu_vif_parse_rate(XLU_Config *cfg, const char *rate, + libxl_device_nic *nic); + +#endif /* LIBXLUTIL_H */ + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/util/libxlu_cfg.c b/tools/libs/util/libxlu_cfg.c new file mode 100644 index 0000000000..874f5abfb9 --- /dev/null +++ b/tools/libs/util/libxlu_cfg.c @@ -0,0 +1,712 @@ +/* + * libxlu_cfg.c - xl configuration file parsing: setup and helper functions + * + * Copyright (C) 2010 Citrix Ltd. + * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * 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 Lesser General Public License for more details. + */ + +#define _GNU_SOURCE + +#include <limits.h> + +#include "libxlu_internal.h" +#include "libxlu_cfg_y.h" +#include "libxlu_cfg_l.h" +#include "libxlu_cfg_i.h" + +XLU_Config *xlu_cfg_init(FILE *report, const char *report_source) { + XLU_Config *cfg; + + cfg= malloc(sizeof(*cfg)); + if (!cfg) return 0; + + cfg->report= report; + cfg->config_source= strdup(report_source); + if (!cfg->config_source) { free(cfg); return 0; } + + cfg->settings= 0; + return cfg; +} + +static int ctx_prep(CfgParseContext *ctx, XLU_Config *cfg) { + int e; + + ctx->cfg= cfg; + ctx->err= 0; + ctx->lexerrlineno= -1; + ctx->likely_python= 0; + ctx->scanner= 0; + + e= xlu__cfg_yylex_init_extra(ctx, &ctx->scanner); + if (e) { + fprintf(cfg->report,"%s: unable to create scanner: %s\n", + cfg->config_source, strerror(e)); + return e; + } + return 0; +} + +static void ctx_dispose(CfgParseContext *ctx) { + if (ctx->scanner) xlu__cfg_yylex_destroy(ctx->scanner); +} + +static void parse(CfgParseContext *ctx) { + /* On return, ctx.err will be updated with the error status. */ + int r; + + xlu__cfg_yyset_lineno(1, ctx->scanner); + + r= xlu__cfg_yyparse(ctx); + if (r) assert(ctx->err); + + if (ctx->err && ctx->likely_python) { + fputs( + "warning: Config file looks like it contains Python code.\n" + "warning: Arbitrary Python is no longer supported.\n" + "warning: See https://wiki.xen.org/wiki/PythonInXlConfig\n", + ctx->cfg->report); + } +} + +int xlu_cfg_readfile(XLU_Config *cfg, const char *real_filename) { + FILE *f = 0; + int e; + + CfgParseContext ctx; + e = ctx_prep(&ctx, cfg); + if (e) { ctx.err= e; goto xe; } + + f= fopen(real_filename, "r"); + if (!f) { + ctx.err = errno; + fprintf(cfg->report,"%s: unable to open configuration file: %s\n", + real_filename, strerror(e)); + goto xe; + } + + xlu__cfg_yyrestart(f, ctx.scanner); + + parse(&ctx); + + xe: + ctx_dispose(&ctx); + if (f) fclose(f); + + return ctx.err; +} + +int xlu_cfg_readdata(XLU_Config *cfg, const char *data, int length) { + int e; + YY_BUFFER_STATE buf= 0; + + CfgParseContext ctx; + e= ctx_prep(&ctx, cfg); + if (e) { ctx.err= e; goto xe; } + + buf = xlu__cfg_yy_scan_bytes(data, length, ctx.scanner); + if (!buf) { + fprintf(cfg->report,"%s: unable to allocate scanner buffer\n", + cfg->config_source); + ctx.err= ENOMEM; + goto xe; + } + + parse(&ctx); + + xe: + if (buf) xlu__cfg_yy_delete_buffer(buf, ctx.scanner); + ctx_dispose(&ctx); + + return ctx.err; +} + +void xlu__cfg_value_free(XLU_ConfigValue *value) +{ + int i; + + if (!value) return; + + switch (value->type) { + case XLU_STRING: + free(value->u.string); + break; + case XLU_LIST: + for (i = 0; i < value->u.list.nvalues; i++) + xlu__cfg_value_free(value->u.list.values[i]); + free(value->u.list.values); + } + free(value); +} + +void xlu__cfg_set_free(XLU_ConfigSetting *set) { + if (!set) return; + free(set->name); + xlu__cfg_value_free(set->value); + free(set); +} + +void xlu_cfg_destroy(XLU_Config *cfg) { + XLU_ConfigSetting *set, *set_next; + + if (!cfg) return; + for (set= cfg->settings; + set; + set= set_next) { + set_next= set->next; + xlu__cfg_set_free(set); + } + free(cfg->config_source); + free(cfg); +} + +static XLU_ConfigSetting *find(const XLU_Config *cfg, const char *n) { + XLU_ConfigSetting *set; + + for (set= cfg->settings; + set; + set= set->next) + if (!strcmp(set->name, n)) + return set; + return 0; +} + +static int find_atom(const XLU_Config *cfg, const char *n, + XLU_ConfigSetting **set_r, int dont_warn) { + XLU_ConfigSetting *set; + + set= find(cfg,n); + if (!set) return ESRCH; + + if (set->value->type!=XLU_STRING) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: parameter `%s' is" + " a list but should be a single value\n", + cfg->config_source, set->lineno, n); + return EINVAL; + } + *set_r= set; + return 0; +} + + +enum XLU_ConfigValueType xlu_cfg_value_type(const XLU_ConfigValue *value) +{ + return value->type; +} + +int xlu_cfg_value_get_string(const XLU_Config *cfg, XLU_ConfigValue *value, + char **value_r, int dont_warn) +{ + if (value->type != XLU_STRING) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d:%d: warning: value is not a string\n", + cfg->config_source, value->loc.first_line, + value->loc.first_column); + *value_r = NULL; + return EINVAL; + } + + *value_r = value->u.string; + return 0; +} + +int xlu_cfg_value_get_list(const XLU_Config *cfg, XLU_ConfigValue *value, + XLU_ConfigList **value_r, int dont_warn) +{ + if (value->type != XLU_LIST) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d:%d: warning: value is not a list\n", + cfg->config_source, value->loc.first_line, + value->loc.first_column); + *value_r = NULL; + return EINVAL; + } + + *value_r = &value->u.list; + return 0; +} + +XLU_ConfigValue *xlu_cfg_get_listitem2(const XLU_ConfigList *list, + int entry) +{ + if (entry < 0 || entry >= list->nvalues) return NULL; + return list->values[entry]; +} + +int xlu_cfg_get_string(const XLU_Config *cfg, const char *n, + const char **value_r, int dont_warn) { + XLU_ConfigSetting *set; + int e; + + e= find_atom(cfg,n,&set,dont_warn); if (e) return e; + *value_r= set->value->u.string; + return 0; +} + +int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, + char **value_r, int dont_warn) { + XLU_ConfigSetting *set; + int e; + + e= find_atom(cfg,n,&set,dont_warn); if (e) return e; + free(*value_r); + *value_r= strdup(set->value->u.string); + return 0; +} + +int xlu_cfg_get_bounded_long(const XLU_Config *cfg, const char *n, + long min, long max, long *value_r, + int dont_warn) { + long l; + XLU_ConfigSetting *set; + int e; + char *ep; + + e= find_atom(cfg,n,&set,dont_warn); if (e) return e; + if (set->op == XLU_OP_ADDITION) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: can't use += with numbers" + " for parameter `%s'\n", + cfg->config_source, set->lineno, n); + return EINVAL; + } + errno= 0; l= strtol(set->value->u.string, &ep, 0); + e= errno; + if (errno) { + e= errno; + assert(e==EINVAL || e==ERANGE); + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: parameter `%s' could not be parsed" + " as a number: %s\n", + cfg->config_source, set->lineno, n, strerror(e)); + return e; + } + if (*ep || ep==set->value->u.string) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: parameter `%s' is not a valid number\n", + cfg->config_source, set->lineno, n); + return EINVAL; + } + if (l < min) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is smaller than minimum bound '%ld'\n", + cfg->config_source, set->lineno, l, min); + return EINVAL; + } + if (l > max) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is greater than maximum bound '%ld'\n", + cfg->config_source, set->lineno, l, max); + return EINVAL; + } + + *value_r= l; + return 0; +} + +int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, + long *value_r, int dont_warn) { + return xlu_cfg_get_bounded_long(cfg, n, LONG_MIN, LONG_MAX, value_r, + dont_warn); +} + +int xlu_cfg_get_defbool(const XLU_Config *cfg, const char *n, libxl_defbool *b, + int dont_warn) +{ + int ret; + long l; + + ret = xlu_cfg_get_long(cfg, n, &l, dont_warn); + if (ret) return ret; + libxl_defbool_set(b, !!l); + return 0; +} + +int xlu_cfg_get_list(const XLU_Config *cfg, const char *n, + XLU_ConfigList **list_r, int *entries_r, int dont_warn) { + XLU_ConfigSetting *set; + set= find(cfg,n); if (!set) return ESRCH; + if (set->value->type!=XLU_LIST) { + if (!dont_warn) { + fprintf(cfg->report, + "%s:%d: warning: parameter `%s' is a single value" + " but should be a list\n", + cfg->config_source, set->lineno, n); + } + return EINVAL; + } + if (list_r) *list_r= &set->value->u.list; + if (entries_r) *entries_r= set->value->u.list.nvalues; + return 0; +} + +int xlu_cfg_get_list_as_string_list(const XLU_Config *cfg, const char *n, + libxl_string_list *psl, int dont_warn) { + int i, rc, nr; + XLU_ConfigList *list; + libxl_string_list sl; + + rc = xlu_cfg_get_list(cfg, n, &list, &nr, dont_warn); + if (rc) return rc; + + sl = malloc(sizeof(char*)*(nr + 1)); + if (sl == NULL) return ENOMEM; + + for (i=0; i<nr; i++) { + const char *a = xlu_cfg_get_listitem(list, i); + sl[i] = a ? strdup(a) : NULL; + } + + sl[nr] = NULL; + + *psl = sl; + return 0; +} + +const char *xlu_cfg_get_listitem(const XLU_ConfigList *list, int entry) { + if (entry < 0 || entry >= list->nvalues) return 0; + if (list->values[entry]->type != XLU_STRING) return 0; + return list->values[entry]->u.string; +} + + +XLU_ConfigValue *xlu__cfg_string_mk(CfgParseContext *ctx, char *atom, + YYLTYPE *loc) +{ + XLU_ConfigValue *value = NULL; + + if (ctx->err) goto x; + + value = malloc(sizeof(*value)); + if (!value) goto xe; + value->type = XLU_STRING; + value->u.string = atom; + memcpy(&value->loc, loc, sizeof(*loc)); + + return value; + + xe: + ctx->err= errno; + x: + free(value); + free(atom); + return NULL; +} + +XLU_ConfigValue *xlu__cfg_list_mk(CfgParseContext *ctx, + XLU_ConfigValue *val, + YYLTYPE *loc) +{ + XLU_ConfigValue *value = NULL; + XLU_ConfigValue **values = NULL; + + if (ctx->err) goto x; + + values = malloc(sizeof(*values)); + if (!values) goto xe; + values[0] = val; + + value = malloc(sizeof(*value)); + if (!value) goto xe; + value->type = XLU_LIST; + value->u.list.nvalues = !!val; + value->u.list.avalues = 1; + value->u.list.values = values; + memcpy(&value->loc, loc, sizeof(*loc)); + + return value; + + xe: + ctx->err= errno; + x: + free(value); + free(values); + xlu__cfg_value_free(val); + return NULL; +} + +void xlu__cfg_list_append(CfgParseContext *ctx, + XLU_ConfigValue *list, + XLU_ConfigValue *val) +{ + if (ctx->err) return; + + assert(val); + assert(list->type == XLU_LIST); + + if (list->u.list.nvalues >= list->u.list.avalues) { + int new_avalues; + XLU_ConfigValue **new_values = NULL; + + if (list->u.list.avalues > INT_MAX / 100) { + ctx->err = ERANGE; + xlu__cfg_value_free(val); + return; + } + + new_avalues = list->u.list.avalues * 4; + new_values = realloc(list->u.list.values, + sizeof(*new_values) * new_avalues); + if (!new_values) { + ctx->err = errno; + xlu__cfg_value_free(val); + return; + } + + list->u.list.avalues = new_avalues; + list->u.list.values = new_values; + } + + list->u.list.values[list->u.list.nvalues] = val; + list->u.list.nvalues++; +} + +static int xlu__cfg_concat_vals(CfgParseContext *ctx, + XLU_ConfigValue *prev, + XLU_ConfigValue *to_add) +{ + int r; + + if (prev->type != to_add->type) { + xlu__cfgl_lexicalerror(ctx, + "can't add [list] to \"string\" or vice versa"); + return EINVAL; + } + + switch (to_add->type) { + case XLU_STRING: { + char *new_string = NULL; + + r = asprintf(&new_string, "%s%s", prev->u.string, + to_add->u.string); + if (r < 0) { + return errno; + } + free(to_add->u.string); + to_add->u.string = new_string; + return 0; + } + case XLU_LIST: { + XLU_ConfigList *const prev_list = &prev->u.list; + XLU_ConfigList *const cur_list = &to_add->u.list; + int nvalues; + + if (prev->u.list.nvalues > INT_MAX - to_add->u.list.nvalues) { + return ERANGE; + } + nvalues = prev->u.list.nvalues + to_add->u.list.nvalues; + + if (nvalues >= cur_list->avalues) { + XLU_ConfigValue **new_vals; + new_vals = realloc(cur_list->values, + nvalues * sizeof(*new_vals)); + if (!new_vals) { + return ENOMEM; + } + cur_list->avalues = nvalues; + cur_list->values = new_vals; + } + + /* make space for `prev' into `to_add' */ + memmove(cur_list->values + prev_list->nvalues, + cur_list->values, + cur_list->nvalues * sizeof(XLU_ConfigValue *)); + /* move values from `prev' to `to_add' as the list in `prev' will + * not be reachable by find(). */ + memcpy(cur_list->values, + prev_list->values, + prev_list->nvalues * sizeof(XLU_ConfigValue *)); + cur_list->nvalues = nvalues; + prev_list->nvalues = 0; + memset(prev_list->values, 0, + prev_list->nvalues * sizeof(XLU_ConfigValue *)); + return 0; + } + default: + abort(); + } + return -1; +} + +void xlu__cfg_set_store(CfgParseContext *ctx, char *name, + enum XLU_Operation op, + XLU_ConfigValue *val, int lineno) { + XLU_ConfigSetting *set; + int r; + + if (ctx->err) goto out; + + assert(name); + + if (op == XLU_OP_ADDITION) { + /* If we have += concatenate with previous value with same name */ + XLU_ConfigSetting *prev_set = find(ctx->cfg, name); + if (prev_set) { + r = xlu__cfg_concat_vals(ctx, prev_set->value, val); + if (r) { + ctx->err = r; + goto out; + } + } + } + + set = malloc(sizeof(*set)); + if (!set) { + ctx->err = errno; + goto out; + } + set->name= name; + set->value = val; + set->op = op; + set->lineno= lineno; + set->next= ctx->cfg->settings; + ctx->cfg->settings= set; + return; +out: + assert(ctx->err); + free(name); + xlu__cfg_value_free(val); +} + +char *xlu__cfgl_strdup(CfgParseContext *ctx, const char *src) { + char *result; + + if (ctx->err) return 0; + result= strdup(src); + if (!result) ctx->err= errno; + return result; +} + +char *xlu__cfgl_dequote(CfgParseContext *ctx, const char *src) { + char *result; + const char *p; + char *q; + int len, c, nc; + + if (ctx->err) return 0; + + len= strlen(src); + assert(len>=2 && src[0]==src[len-1]); + + result= malloc(len-1); + if (!result) { ctx->err= errno; return 0; } + + q= result; + + for (p= src+1; + p < src+len-1; + ) { + c= *p++; + if (c=='\\') { + assert(p < src+len-1); + nc= *p++; + if (nc=='"' || nc=='\'' || nc=='\\') { + *q++= nc; + } else if (nc=='a') { *q++= '\007'; + } else if (nc=='b') { *q++= '\010'; + } else if (nc=='f') { *q++= '\014'; + } else if (nc=='n') { *q++= '\n'; + } else if (nc=='r') { *q++= '\r'; + } else if (nc=='t') { *q++= '\t'; + } else if (nc=='v') { *q++= '\013'; + } else if (nc=='x') { + +#define NUMERIC_CHAR(minlen,maxlen,base,basetext) do{ \ + char numbuf[(maxlen)+1], *ep; \ + unsigned long val; \ + \ + strncpy(numbuf,p,(maxlen)); \ + numbuf[(maxlen)]= 0; \ + val= strtoul(numbuf, &ep, (base)); \ + if (ep <= numbuf+(minlen)) { \ + xlu__cfgl_lexicalerror(ctx,"invalid digit after" \ + " backslash " basetext "numerical character escape" \ + " in quoted string"); \ + ctx->err= EINVAL; \ + goto x; \ + } \ + p += (ep - numbuf); \ + }while(0) + + p++; + NUMERIC_CHAR(2,2,16,"hex"); + } else if (nc>='0' && nc<='7') { + NUMERIC_CHAR(1,3,10,"octal"); + } else { + xlu__cfgl_lexicalerror(ctx, + "invalid character after backlash in quoted string"); + ctx->err= EINVAL; + goto x; + } + assert(p <= src+len-1); + } else { + *q++= c; + } + } + + x: + *q++= 0; + return result; +} + +void xlu__cfgl_lexicalerror(CfgParseContext *ctx, char const *msg) { + YYLTYPE loc; + loc.first_line= xlu__cfg_yyget_lineno(ctx->scanner); + xlu__cfg_yyerror(&loc, ctx, msg); + ctx->lexerrlineno= loc.first_line; +} + +void xlu__cfg_yyerror(YYLTYPE *loc, CfgParseContext *ctx, char const *msg) { + const char *text, *newline; + int len, lineno; + + lineno= loc->first_line; + if (lineno <= ctx->lexerrlineno) return; + + text= xlu__cfg_yyget_text(ctx->scanner); + len= xlu__cfg_yyget_leng(ctx->scanner); + newline= ""; + if (len>0 && text[len-1]=='\n') { + len--; + lineno--; + if (!len) { + newline= "<newline>"; + } + } + while (len>0 && (text[len-1]=='\t' || text[len-1]==' ')) { + len--; + } + + fprintf(ctx->cfg->report, + "%s:%d: config parsing error near %s%.*s%s%s: %s\n", + ctx->cfg->config_source, lineno, + len?"`":"", len, text, len?"'":"", newline, + msg); + if (!ctx->err) ctx->err= EINVAL; +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/util/libxlu_cfg_i.h b/tools/libs/util/libxlu_cfg_i.h new file mode 100644 index 0000000000..4217f5b28d --- /dev/null +++ b/tools/libs/util/libxlu_cfg_i.h @@ -0,0 +1,59 @@ +/* + * libxlu_cfg_i.h - xl configuration file parsing: parser-internal declarations + * + * Copyright (C) 2010 Citrix Ltd. + * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * 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 Lesser General Public License for more details. + */ + +#ifndef LIBXLU_CFG_I_H +#define LIBXLU_CFG_I_H + +#include "libxlu_internal.h" +#include "libxlu_cfg_y.h" + +void xlu__cfg_set_free(XLU_ConfigSetting *set); +void xlu__cfg_set_store(CfgParseContext*, char *name, + enum XLU_Operation op, + XLU_ConfigValue *val, int lineno); +XLU_ConfigValue *xlu__cfg_string_mk(CfgParseContext *ctx, + char *atom, YYLTYPE *loc); +XLU_ConfigValue *xlu__cfg_list_mk(CfgParseContext *ctx, + XLU_ConfigValue *val, + YYLTYPE *loc); +void xlu__cfg_list_append(CfgParseContext *ctx, + XLU_ConfigValue *list, + XLU_ConfigValue *val); +void xlu__cfg_value_free(XLU_ConfigValue *value); +char *xlu__cfgl_strdup(CfgParseContext*, const char *src); +char *xlu__cfgl_dequote(CfgParseContext*, const char *src); + +void xlu__cfg_yyerror(YYLTYPE *locp, CfgParseContext*, char const *msg); +void xlu__cfgl_lexicalerror(CfgParseContext*, char const *msg); + +void xlu__cfgl_likely_python(CfgParseContext *ctx); + + + +/* Why oh why does bison not declare this in its autogenerated .h ? */ +int xlu__cfg_yyparse(CfgParseContext *ctx); + + +#endif /*LIBXLU_CFG_I_H*/ + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libs/util/libxlu_cfg_l.c b/tools/libs/util/libxlu_cfg_l.c new file mode 100644 index 0000000000..406b50a037 --- /dev/null +++ b/tools/libs/util/libxlu_cfg_l.c @@ -0,0 +1,2375 @@ +#line 2 "libxlu_cfg_l.c" + +#line 4 "libxlu_cfg_l.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yy_create_buffer +#define xlu__cfg_yy_create_buffer_ALREADY_DEFINED +#else +#define yy_create_buffer xlu__cfg_yy_create_buffer +#endif + +#ifdef yy_delete_buffer +#define xlu__cfg_yy_delete_buffer_ALREADY_DEFINED +#else +#define yy_delete_buffer xlu__cfg_yy_delete_buffer +#endif + +#ifdef yy_scan_buffer +#define xlu__cfg_yy_scan_buffer_ALREADY_DEFINED +#else +#define yy_scan_buffer xlu__cfg_yy_scan_buffer +#endif + +#ifdef yy_scan_string +#define xlu__cfg_yy_scan_string_ALREADY_DEFINED +#else +#define yy_scan_string xlu__cfg_yy_scan_string +#endif + +#ifdef yy_scan_bytes +#define xlu__cfg_yy_scan_bytes_ALREADY_DEFINED +#else +#define yy_scan_bytes xlu__cfg_yy_scan_bytes +#endif + +#ifdef yy_init_buffer +#define xlu__cfg_yy_init_buffer_ALREADY_DEFINED +#else +#define yy_init_buffer xlu__cfg_yy_init_buffer +#endif + +#ifdef yy_flush_buffer +#define xlu__cfg_yy_flush_buffer_ALREADY_DEFINED +#else +#define yy_flush_buffer xlu__cfg_yy_flush_buffer +#endif + +#ifdef yy_load_buffer_state +#define xlu__cfg_yy_load_buffer_state_ALREADY_DEFINED +#else +#define yy_load_buffer_state xlu__cfg_yy_load_buffer_state +#endif + +#ifdef yy_switch_to_buffer +#define xlu__cfg_yy_switch_to_buffer_ALREADY_DEFINED +#else +#define yy_switch_to_buffer xlu__cfg_yy_switch_to_buffer +#endif + +#ifdef yypush_buffer_state +#define xlu__cfg_yypush_buffer_state_ALREADY_DEFINED +#else +#define yypush_buffer_state xlu__cfg_yypush_buffer_state +#endif + +#ifdef yypop_buffer_state +#define xlu__cfg_yypop_buffer_state_ALREADY_DEFINED +#else +#define yypop_buffer_state xlu__cfg_yypop_buffer_state +#endif + +#ifdef yyensure_buffer_stack +#define xlu__cfg_yyensure_buffer_stack_ALREADY_DEFINED +#else +#define yyensure_buffer_stack xlu__cfg_yyensure_buffer_stack +#endif + +#ifdef yylex +#define xlu__cfg_yylex_ALREADY_DEFINED +#else +#define yylex xlu__cfg_yylex +#endif + +#ifdef yyrestart +#define xlu__cfg_yyrestart_ALREADY_DEFINED +#else +#define yyrestart xlu__cfg_yyrestart +#endif + +#ifdef yylex_init +#define xlu__cfg_yylex_init_ALREADY_DEFINED +#else +#define yylex_init xlu__cfg_yylex_init +#endif + +#ifdef yylex_init_extra +#define xlu__cfg_yylex_init_extra_ALREADY_DEFINED +#else +#define yylex_init_extra xlu__cfg_yylex_init_extra +#endif + +#ifdef yylex_destroy +#define xlu__cfg_yylex_destroy_ALREADY_DEFINED +#else +#define yylex_destroy xlu__cfg_yylex_destroy +#endif + +#ifdef yyget_debug +#define xlu__cfg_yyget_debug_ALREADY_DEFINED +#else +#define yyget_debug xlu__cfg_yyget_debug +#endif + +#ifdef yyset_debug +#define xlu__cfg_yyset_debug_ALREADY_DEFINED +#else +#define yyset_debug xlu__cfg_yyset_debug +#endif + +#ifdef yyget_extra +#define xlu__cfg_yyget_extra_ALREADY_DEFINED +#else +#define yyget_extra xlu__cfg_yyget_extra +#endif + +#ifdef yyset_extra +#define xlu__cfg_yyset_extra_ALREADY_DEFINED +#else +#define yyset_extra xlu__cfg_yyset_extra +#endif + +#ifdef yyget_in +#define xlu__cfg_yyget_in_ALREADY_DEFINED +#else +#define yyget_in xlu__cfg_yyget_in +#endif + +#ifdef yyset_in +#define xlu__cfg_yyset_in_ALREADY_DEFINED +#else +#define yyset_in xlu__cfg_yyset_in +#endif + +#ifdef yyget_out +#define xlu__cfg_yyget_out_ALREADY_DEFINED +#else +#define yyget_out xlu__cfg_yyget_out +#endif + +#ifdef yyset_out +#define xlu__cfg_yyset_out_ALREADY_DEFINED +#else +#define yyset_out xlu__cfg_yyset_out +#endif + +#ifdef yyget_leng +#define xlu__cfg_yyget_leng_ALREADY_DEFINED +#else +#define yyget_leng xlu__cfg_yyget_leng +#endif + +#ifdef yyget_text +#define xlu__cfg_yyget_text_ALREADY_DEFINED +#else +#define yyget_text xlu__cfg_yyget_text +#endif + +#ifdef yyget_lineno +#define xlu__cfg_yyget_lineno_ALREADY_DEFINED +#else +#define yyget_lineno xlu__cfg_yyget_lineno +#endif + +#ifdef yyset_lineno +#define xlu__cfg_yyset_lineno_ALREADY_DEFINED +#else +#define yyset_lineno xlu__cfg_yyset_lineno +#endif + +#ifdef yyget_column +#define xlu__cfg_yyget_column_ALREADY_DEFINED +#else +#define yyget_column xlu__cfg_yyget_column +#endif + +#ifdef yyset_column +#define xlu__cfg_yyset_column_ALREADY_DEFINED +#else +#define yyset_column xlu__cfg_yyset_column +#endif + +#ifdef yywrap +#define xlu__cfg_yywrap_ALREADY_DEFINED +#else +#define yywrap xlu__cfg_yywrap +#endif + +#ifdef yyget_lval +#define xlu__cfg_yyget_lval_ALREADY_DEFINED +#else +#define yyget_lval xlu__cfg_yyget_lval +#endif + +#ifdef yyset_lval +#define xlu__cfg_yyset_lval_ALREADY_DEFINED +#else +#define yyset_lval xlu__cfg_yyset_lval +#endif + +#ifdef yyget_lloc +#define xlu__cfg_yyget_lloc_ALREADY_DEFINED +#else +#define yyget_lloc xlu__cfg_yyget_lloc +#endif + +#ifdef yyset_lloc +#define xlu__cfg_yyset_lloc_ALREADY_DEFINED +#else +#define yyset_lloc xlu__cfg_yyset_lloc +#endif + +#ifdef yyalloc +#define xlu__cfg_yyalloc_ALREADY_DEFINED +#else +#define yyalloc xlu__cfg_yyalloc +#endif + +#ifdef yyrealloc +#define xlu__cfg_yyrealloc_ALREADY_DEFINED +#else +#define yyrealloc xlu__cfg_yyrealloc +#endif + +#ifdef yyfree +#define xlu__cfg_yyfree_ALREADY_DEFINED +#else +#define yyfree xlu__cfg_yyfree +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin , yyscanner ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void yyrestart ( FILE *input_file , yyscan_t yyscanner ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner ); +void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner ); +void yypop_buffer_state ( yyscan_t yyscanner ); + +static void yyensure_buffer_stack ( yyscan_t yyscanner ); +static void yy_load_buffer_state ( yyscan_t yyscanner ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner ); + +void *yyalloc ( yy_size_t , yyscan_t yyscanner ); +void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner ); +void yyfree ( void * , yyscan_t yyscanner ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +#define xlu__cfg_yywrap(yyscanner) (/*CONSTCOND*/1) +#define YY_SKIP_YYWRAP +typedef flex_uint8_t YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state ( yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner); +static int yy_get_next_buffer ( yyscan_t yyscanner ); +static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyg->yytext_ptr -= yyg->yy_more_len; \ + yyleng = (int) (yy_cp - yyg->yytext_ptr); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[37] = + { 0, + 0, 0, 15, 15, 18, 14, 3, 10, 14, 14, + 14, 13, 13, 4, 2, 9, 8, 5, 6, 1, + 15, 15, 16, 0, 12, 0, 0, 10, 0, 11, + 0, 7, 2, 1, 15, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 4, 5, 1, 1, 1, 6, 7, + 7, 1, 8, 9, 7, 10, 1, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 7, 12, 1, + 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 14, 15, 16, 1, 17, 1, 18, 18, 18, 18, + + 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 18, + 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[20] = + { 0, + 1, 2, 3, 1, 1, 1, 1, 1, 1, 4, + 4, 1, 1, 1, 1, 1, 4, 4, 4 + } ; + +static const flex_int16_t yy_base[43] = + { 0, + 0, 0, 18, 20, 53, 59, 59, 59, 20, 42, + 19, 59, 19, 59, 15, 59, 59, 59, 59, 0, + 0, 59, 59, 23, 59, 0, 28, 59, 22, 59, + 0, 59, 18, 0, 0, 59, 38, 42, 46, 50, + 26, 54 + } ; + +static const flex_int16_t yy_def[43] = + { 0, + 36, 1, 37, 37, 36, 36, 36, 36, 38, 39, + 40, 36, 36, 36, 36, 36, 36, 36, 36, 41, + 42, 36, 36, 38, 36, 38, 39, 36, 40, 36, + 40, 36, 36, 41, 42, 0, 36, 36, 36, 36, + 36, 36 + } ; + +static const flex_int16_t yy_nxt[79] = + { 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 12, + 15, 16, 17, 18, 6, 19, 6, 20, 20, 22, + 23, 22, 23, 25, 30, 33, 25, 30, 33, 34, + 28, 32, 33, 31, 26, 33, 31, 26, 21, 21, + 21, 21, 24, 24, 28, 24, 27, 27, 27, 27, + 29, 29, 36, 29, 35, 36, 36, 35, 5, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36 + } ; + +static const flex_int16_t yy_chk[79] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 4, 4, 9, 11, 15, 24, 29, 33, 41, + 27, 13, 15, 11, 9, 33, 29, 24, 37, 37, + 37, 37, 38, 38, 10, 38, 39, 39, 39, 39, + 40, 40, 5, 40, 42, 0, 0, 42, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[18] = + { 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, }; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() (yyg->yy_more_flag = 1) +#define YY_MORE_ADJ yyg->yy_more_len +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "libxlu_cfg_l.l" +/* -*- fundamental -*- */ +/* + * libxlu_cfg_l.l - xl configuration file parsing: lexer + * + * Copyright (C) 2010 Citrix Ltd. + * Author Ian Jackson <ian.jackson@xxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; version 2.1 only. with the special + * exception on linking described in file LICENSE. + * + * 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 Lesser General Public License for more details. + */ +#line 20 "libxlu_cfg_l.l" +#include "libxlu_cfg_i.h" + +#define ctx ((CfgParseContext*)yyextra) +#define YY_NO_INPUT + +#define GOT(x) do{ \ + yylloc->first_line= yylineno; \ + return (x); \ + }while(0) + +/* Some versions of flex have a bug (Fedora bugzilla 612465) which causes + * it to fail to declare these functions, which it defines. So declare + * them ourselves. Hopefully we won't have to simultaneously support + * a flex version which declares these differently somehow. */ +int xlu__cfg_yyget_column(yyscan_t yyscanner); +void xlu__cfg_yyset_column(int column_no, yyscan_t yyscanner); + +#line 740 "libxlu_cfg_l.c" + +#line 742 "libxlu_cfg_l.c" + +#define INITIAL 0 +#define lexerr 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals ( yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( yyscan_t yyscanner ); + +int yyget_debug ( yyscan_t yyscanner ); + +void yyset_debug ( int debug_flag , yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner ); + +FILE *yyget_in ( yyscan_t yyscanner ); + +void yyset_in ( FILE * _in_str , yyscan_t yyscanner ); + +FILE *yyget_out ( yyscan_t yyscanner ); + +void yyset_out ( FILE * _out_str , yyscan_t yyscanner ); + + int yyget_leng ( yyscan_t yyscanner ); + +char *yyget_text ( yyscan_t yyscanner ); + +int yyget_lineno ( yyscan_t yyscanner ); + +void yyset_lineno ( int _line_number , yyscan_t yyscanner ); + +int yyget_column ( yyscan_t yyscanner ); + +void yyset_column ( int _column_no , yyscan_t yyscanner ); + +YYSTYPE * yyget_lval ( yyscan_t yyscanner ); + +void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner ); + + YYLTYPE *yyget_lloc ( yyscan_t yyscanner ); + + void yyset_lloc ( YYLTYPE * yylloc_param , yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( yyscan_t yyscanner ); +#else +extern int yywrap ( yyscan_t yyscanner ); +#endif +#endif + +#ifndef YY_NO_UNPUT + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * , yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( yyscan_t yyscanner ); +#else +static int input ( yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); + } + + yy_load_buffer_state( yyscanner ); + } + + { +#line 53 "libxlu_cfg_l.l" + + +#line 1028 "libxlu_cfg_l.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yyg->yy_more_len = 0; + if ( yyg->yy_more_flag ) + { + yyg->yy_more_len = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr); + yyg->yy_more_flag = 0; + } + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 37 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_current_state != 36 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = yyg->yy_more_len; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + do{ yylineno++; + yycolumn=0; + }while(0) +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 55 "libxlu_cfg_l.l" +{ + yylval->string= xlu__cfgl_strdup(ctx,yytext); + GOT(IDENT); + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 59 "libxlu_cfg_l.l" +{ + yylval->string= xlu__cfgl_strdup(ctx,yytext); + GOT(NUMBER); + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 64 "libxlu_cfg_l.l" + + YY_BREAK +case 4: +YY_RULE_SETUP +#line 66 "libxlu_cfg_l.l" +{ GOT(','); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 67 "libxlu_cfg_l.l" +{ GOT('['); } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 68 "libxlu_cfg_l.l" +{ GOT(']'); } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 69 "libxlu_cfg_l.l" +{ GOT(OP_ADD); } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 70 "libxlu_cfg_l.l" +{ GOT('='); } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 71 "libxlu_cfg_l.l" +{ GOT(';'); } + YY_BREAK +case 10: +/* rule 10 can match eol */ +YY_RULE_SETUP +#line 73 "libxlu_cfg_l.l" +{ yylloc->first_line= yylineno-1; return NEWLINE; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 75 "libxlu_cfg_l.l" +{ + yylval->string= xlu__cfgl_dequote(ctx,yytext); + GOT(STRING); + } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 79 "libxlu_cfg_l.l" +{ + yylval->string= xlu__cfgl_dequote(ctx,yytext); + GOT(STRING); + } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 84 "libxlu_cfg_l.l" +{ + ctx->likely_python= 1; + BEGIN(lexerr); + yymore(); + } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 90 "libxlu_cfg_l.l" +{ + BEGIN(lexerr); + yymore(); + } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 95 "libxlu_cfg_l.l" +{ + xlu__cfgl_lexicalerror(ctx,"lexical error"); + BEGIN(0); + } + YY_BREAK +case 16: +/* rule 16 can match eol */ +YY_RULE_SETUP +#line 100 "libxlu_cfg_l.l" +{ + xlu__cfgl_lexicalerror(ctx,"lexical error"); + BEGIN(0); + GOT(NEWLINE); + } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 105 "libxlu_cfg_l.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 1212 "libxlu_cfg_l.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(lexerr): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( yywrap( yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = yyg->yytext_ptr; + int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) , yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin , yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + yy_state_type yy_current_state; + char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 37 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } +
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |