|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] 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 |