diff --git a/D15067.id41365.diff b/D15067.id41365.diff deleted file mode 100644 index 2113b3e..0000000 --- a/D15067.id41365.diff +++ /dev/null @@ -1,3822 +0,0 @@ -Index: cmake/modules/LLDBStandalone.cmake -=================================================================== ---- cmake/modules/LLDBStandalone.cmake -+++ cmake/modules/LLDBStandalone.cmake -@@ -6,57 +6,77 @@ - - option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) - -- set(LLDB_PATH_TO_LLVM_SOURCE "" CACHE PATH -- "Path to LLVM source code. Not necessary if using an installed LLVM.") -- set(LLDB_PATH_TO_LLVM_BUILD "" CACHE PATH -- "Path to the directory where LLVM was built or installed.") -- -- set(LLDB_PATH_TO_CLANG_SOURCE "" CACHE PATH -- "Path to Clang source code. Not necessary if using an installed Clang.") -- set(LLDB_PATH_TO_CLANG_BUILD "" CACHE PATH -- "Path to the directory where Clang was built or installed.") -- -- if (LLDB_PATH_TO_LLVM_SOURCE) -- if (NOT EXISTS "${LLDB_PATH_TO_LLVM_SOURCE}/cmake/config-ix.cmake") -- message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_SOURCE to the root " -- "directory of LLVM source code.") -+ # Rely on llvm-config. -+ set(CONFIG_OUTPUT) -+ find_program(LLVM_CONFIG "llvm-config") -+ if(LLVM_CONFIG) -+ message(STATUS "Found LLVM_CONFIG as ${LLVM_CONFIG}") -+ set(CONFIG_COMMAND ${LLVM_CONFIG} -+ "--assertion-mode" -+ "--bindir" -+ "--libdir" -+ "--includedir" -+ "--prefix" -+ "--src-root") -+ execute_process( -+ COMMAND ${CONFIG_COMMAND} -+ RESULT_VARIABLE HAD_ERROR -+ OUTPUT_VARIABLE CONFIG_OUTPUT -+ ) -+ if(NOT HAD_ERROR) -+ string(REGEX REPLACE -+ "[ \t]*[\r\n]+[ \t]*" ";" -+ CONFIG_OUTPUT ${CONFIG_OUTPUT}) - else() -- get_filename_component(LLVM_MAIN_SRC_DIR ${LLDB_PATH_TO_LLVM_SOURCE} -- ABSOLUTE) -- set(LLVM_MAIN_INCLUDE_DIR "${LLVM_MAIN_SRC_DIR}/include") -- list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") -+ string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") -+ message(STATUS "${CONFIG_COMMAND_STR}") -+ message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") - endif() -+ else() -+ message(FATAL_ERROR "llvm-config not found -- ${LLVM_CONFIG}") - endif() - -- if (LLDB_PATH_TO_CLANG_SOURCE) -- get_filename_component(CLANG_MAIN_SRC_DIR ${LLDB_PATH_TO_CLANG_SOURCE} -- ABSOLUTE) -- set(CLANG_MAIN_INCLUDE_DIR "${CLANG_MAIN_SRC_DIR}/include") -+ list(GET CONFIG_OUTPUT 0 ENABLE_ASSERTIONS) -+ list(GET CONFIG_OUTPUT 1 TOOLS_BINARY_DIR) -+ list(GET CONFIG_OUTPUT 2 LIBRARY_DIR) -+ list(GET CONFIG_OUTPUT 3 INCLUDE_DIR) -+ list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT) -+ list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR) -+ -+ if(NOT MSVC_IDE) -+ set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} -+ CACHE BOOL "Enable assertions") -+ # Assertions should follow llvm-config's. -+ mark_as_advanced(LLVM_ENABLE_ASSERTIONS) - endif() - -- list(APPEND CMAKE_MODULE_PATH "${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake") -+ set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin") -+ set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib") -+ set(LLVM_MAIN_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") -+ set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") -+ set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") - -- if (LLDB_PATH_TO_LLVM_BUILD) -- get_filename_component(PATH_TO_LLVM_BUILD ${LLDB_PATH_TO_LLVM_BUILD} -- ABSOLUTE) -- else() -- message(FATAL_ERROR "Please set LLDB_PATH_TO_LLVM_BUILD to the root " -- "directory of LLVM build or install site.") -- endif() -+ find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} -+ NO_DEFAULT_PATH) - -- if (LLDB_PATH_TO_CLANG_BUILD) -- get_filename_component(PATH_TO_CLANG_BUILD ${LLDB_PATH_TO_CLANG_BUILD} -- ABSOLUTE) -+ set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/share/llvm/cmake") -+ set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake") -+ if(EXISTS ${LLVMCONFIG_FILE}) -+ list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") -+ include(${LLVMCONFIG_FILE}) - else() -- message(FATAL_ERROR "Please set LLDB_PATH_TO_CLANG_BUILD to the root " -- "directory of Clang build or install site.") -+ message(FATAL_ERROR "Not found: ${LLVMCONFIG_FILE}") - endif() - -- -- # These variables are used by add_llvm_library. -+ # They are used as destination of target generators. - set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) - set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) -- set(LLVM_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) -+ if(WIN32 OR CYGWIN) -+ # DLL platform -- put DLLs into bin. -+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) -+ else() -+ set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) -+ endif() - - include(AddLLVM) - include(HandleLLVMOptions) -@@ -73,23 +93,18 @@ - message("-- Found PythonInterp: ${PYTHON_EXECUTABLE}") - endif() - # Import CMake library targets from LLVM and Clang. -- include("${LLDB_PATH_TO_LLVM_BUILD}/share/llvm/cmake/LLVMConfig.cmake") -- if (EXISTS "${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake") -- include("${LLDB_PATH_TO_CLANG_BUILD}/share/clang/cmake/ClangConfig.cmake") -+ include("${LLVM_OBJ_ROOT}/share/llvm/cmake/LLVMConfig.cmake") -+ if (EXISTS "${LLVM_OBJ_ROOT}/share/clang/cmake/ClangConfig.cmake") -+ include("${LLVM_OBJ_ROOT}/share/clang/cmake/ClangConfig.cmake") - endif() - - set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}") - - set(LLVM_BINARY_DIR ${CMAKE_BINARY_DIR}) - - set(CMAKE_INCLUDE_CURRENT_DIR ON) -- include_directories("${PATH_TO_LLVM_BUILD}/include" -- "${LLVM_MAIN_INCLUDE_DIR}" -- "${PATH_TO_CLANG_BUILD}/include" -- "${CLANG_MAIN_INCLUDE_DIR}" -- "${CMAKE_CURRENT_SOURCE_DIR}/source") -- link_directories("${PATH_TO_LLVM_BUILD}/lib${LLVM_LIBDIR_SUFFIX}" -- "${PATH_TO_CLANG_BUILD}/lib${LLVM_LIBDIR_SUFFIX}") -+ include_directories("${LLVM_BINARY_DIR}/include" "${LLVM_MAIN_INCLUDE_DIR}") -+ link_directories("${LLVM_LIBRARY_DIR}") - - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}) -Index: include/lldb/Utility/regcclass.h -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regcclass.h -@@ -0,0 +1,75 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)cclass.h 8.3 (Berkeley) 3/20/94 -+ */ -+ -+#ifndef LLVM_SUPPORT_REGCCLASS_H -+#define LLVM_SUPPORT_REGCCLASS_H -+ -+/* character-class table */ -+static struct cclass { -+ const char *name; -+ const char *chars; -+ const char *multis; -+} cclasses[] = { -+ { "alnum", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -+0123456789", ""} , -+ { "alpha", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", -+ ""} , -+ { "blank", " \t", ""} , -+ { "cntrl", "\007\b\t\n\v\f\r\1\2\3\4\5\6\16\17\20\21\22\23\24\ -+\25\26\27\30\31\32\33\34\35\36\37\177", ""} , -+ { "digit", "0123456789", ""} , -+ { "graph", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", -+ ""} , -+ { "lower", "abcdefghijklmnopqrstuvwxyz", -+ ""} , -+ { "print", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ -+0123456789!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ ", -+ ""} , -+ { "punct", "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", -+ ""} , -+ { "space", "\t\n\v\f\r ", ""} , -+ { "upper", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", -+ ""} , -+ { "xdigit", "0123456789ABCDEFabcdef", -+ ""} , -+ { NULL, 0, "" } -+}; -+ -+#endif -Index: include/lldb/Utility/regcname.h -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regcname.h -@@ -0,0 +1,144 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)cname.h 8.3 (Berkeley) 3/20/94 -+ */ -+ -+#ifndef LLVM_SUPPORT_REGCNAME_H -+#define LLVM_SUPPORT_REGCNAME_H -+ -+/* character-name table */ -+static struct cname { -+ const char *name; -+ char code; -+} cnames[] = { -+ { "NUL", '\0' }, -+ { "SOH", '\001' }, -+ { "STX", '\002' }, -+ { "ETX", '\003' }, -+ { "EOT", '\004' }, -+ { "ENQ", '\005' }, -+ { "ACK", '\006' }, -+ { "BEL", '\007' }, -+ { "alert", '\007' }, -+ { "BS", '\010' }, -+ { "backspace", '\b' }, -+ { "HT", '\011' }, -+ { "tab", '\t' }, -+ { "LF", '\012' }, -+ { "newline", '\n' }, -+ { "VT", '\013' }, -+ { "vertical-tab", '\v' }, -+ { "FF", '\014' }, -+ { "form-feed", '\f' }, -+ { "CR", '\015' }, -+ { "carriage-return", '\r' }, -+ { "SO", '\016' }, -+ { "SI", '\017' }, -+ { "DLE", '\020' }, -+ { "DC1", '\021' }, -+ { "DC2", '\022' }, -+ { "DC3", '\023' }, -+ { "DC4", '\024' }, -+ { "NAK", '\025' }, -+ { "SYN", '\026' }, -+ { "ETB", '\027' }, -+ { "CAN", '\030' }, -+ { "EM", '\031' }, -+ { "SUB", '\032' }, -+ { "ESC", '\033' }, -+ { "IS4", '\034' }, -+ { "FS", '\034' }, -+ { "IS3", '\035' }, -+ { "GS", '\035' }, -+ { "IS2", '\036' }, -+ { "RS", '\036' }, -+ { "IS1", '\037' }, -+ { "US", '\037' }, -+ { "space", ' ' }, -+ { "exclamation-mark", '!' }, -+ { "quotation-mark", '"' }, -+ { "number-sign", '#' }, -+ { "dollar-sign", '$' }, -+ { "percent-sign", '%' }, -+ { "ampersand", '&' }, -+ { "apostrophe", '\'' }, -+ { "left-parenthesis", '(' }, -+ { "right-parenthesis", ')' }, -+ { "asterisk", '*' }, -+ { "plus-sign", '+' }, -+ { "comma", ',' }, -+ { "hyphen", '-' }, -+ { "hyphen-minus", '-' }, -+ { "period", '.' }, -+ { "full-stop", '.' }, -+ { "slash", '/' }, -+ { "solidus", '/' }, -+ { "zero", '0' }, -+ { "one", '1' }, -+ { "two", '2' }, -+ { "three", '3' }, -+ { "four", '4' }, -+ { "five", '5' }, -+ { "six", '6' }, -+ { "seven", '7' }, -+ { "eight", '8' }, -+ { "nine", '9' }, -+ { "colon", ':' }, -+ { "semicolon", ';' }, -+ { "less-than-sign", '<' }, -+ { "equals-sign", '=' }, -+ { "greater-than-sign", '>' }, -+ { "question-mark", '?' }, -+ { "commercial-at", '@' }, -+ { "left-square-bracket", '[' }, -+ { "backslash", '\\' }, -+ { "reverse-solidus", '\\' }, -+ { "right-square-bracket", ']' }, -+ { "circumflex", '^' }, -+ { "circumflex-accent", '^' }, -+ { "underscore", '_' }, -+ { "low-line", '_' }, -+ { "grave-accent", '`' }, -+ { "left-brace", '{' }, -+ { "left-curly-bracket", '{' }, -+ { "vertical-line", '|' }, -+ { "right-brace", '}' }, -+ { "right-curly-bracket", '}' }, -+ { "tilde", '~' }, -+ { "DEL", '\177' }, -+ { NULL, 0 } -+}; -+ -+#endif -Index: include/lldb/Utility/regengine.inc -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regengine.inc -@@ -0,0 +1,1034 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)engine.c 8.5 (Berkeley) 3/20/94 -+ */ -+ -+/* -+ * The matching engine and friends. This file is #included by regexec.c -+ * after suitable #defines of a variety of macros used herein, so that -+ * different state representations can be used without duplicating masses -+ * of code. -+ */ -+ -+#ifdef SNAMES -+#define matcher smatcher -+#define fast sfast -+#define slow sslow -+#define dissect sdissect -+#define backref sbackref -+#define step sstep -+#define print sprint -+#define at sat -+#define match smat -+#define nope snope -+#endif -+#ifdef LNAMES -+#define matcher lmatcher -+#define fast lfast -+#define slow lslow -+#define dissect ldissect -+#define backref lbackref -+#define step lstep -+#define print lprint -+#define at lat -+#define match lmat -+#define nope lnope -+#endif -+ -+/* another structure passed up and down to avoid zillions of parameters */ -+struct match { -+ struct re_guts *g; -+ int eflags; -+ llvm_regmatch_t *pmatch; /* [nsub+1] (0 element unused) */ -+ const char *offp; /* offsets work from here */ -+ const char *beginp; /* start of string -- virtual NUL precedes */ -+ const char *endp; /* end of string -- virtual NUL here */ -+ const char *coldp; /* can be no match starting before here */ -+ const char **lastpos; /* [nplus+1] */ -+ STATEVARS; -+ states st; /* current states */ -+ states fresh; /* states for a fresh start */ -+ states tmp; /* temporary */ -+ states empty; /* empty set of states */ -+}; -+ -+static int matcher(struct re_guts *, const char *, size_t, -+ llvm_regmatch_t[], int); -+static const char *dissect(struct match *, const char *, const char *, sopno, -+ sopno); -+static const char *backref(struct match *, const char *, const char *, sopno, -+ sopno, sopno, int); -+static const char *fast(struct match *, const char *, const char *, sopno, sopno); -+static const char *slow(struct match *, const char *, const char *, sopno, sopno); -+static states step(struct re_guts *, sopno, sopno, states, int, states); -+#define MAX_RECURSION 100 -+#define BOL (OUT+1) -+#define EOL (BOL+1) -+#define BOLEOL (BOL+2) -+#define NOTHING (BOL+3) -+#define BOW (BOL+4) -+#define EOW (BOL+5) -+#define CODEMAX (BOL+5) /* highest code used */ -+#define NONCHAR(c) ((c) > CHAR_MAX) -+#define NNONCHAR (CODEMAX-CHAR_MAX) -+#ifdef REDEBUG -+static void print(struct match *, char *, states, int, FILE *); -+#endif -+#ifdef REDEBUG -+static void at(struct match *, char *, char *, char *, sopno, sopno); -+#endif -+#ifdef REDEBUG -+static char *pchar(int); -+#endif -+ -+#ifdef REDEBUG -+#define SP(t, s, c) print(m, t, s, c, stdout) -+#define AT(t, p1, p2, s1, s2) at(m, t, p1, p2, s1, s2) -+#define NOTE(str) { if (m->eflags®_TRACE) (void)printf("=%s\n", (str)); } -+static int nope = 0; -+#else -+#define SP(t, s, c) /* nothing */ -+#define AT(t, p1, p2, s1, s2) /* nothing */ -+#define NOTE(s) /* nothing */ -+#endif -+ -+/* -+ - matcher - the actual matching engine -+ */ -+static int /* 0 success, REG_NOMATCH failure */ -+matcher(struct re_guts *g, const char *string, size_t nmatch, -+ llvm_regmatch_t pmatch[], -+ int eflags) -+{ -+ const char *endp; -+ size_t i; -+ struct match mv; -+ struct match *m = &mv; -+ const char *dp; -+ const sopno gf = g->firststate+1; /* +1 for OEND */ -+ const sopno gl = g->laststate; -+ const char *start; -+ const char *stop; -+ -+ /* simplify the situation where possible */ -+ if (g->cflags®_NOSUB) -+ nmatch = 0; -+ if (eflags®_STARTEND) { -+ start = string + pmatch[0].rm_so; -+ stop = string + pmatch[0].rm_eo; -+ } else { -+ start = string; -+ stop = start + strlen(start); -+ } -+ if (stop < start) -+ return(REG_INVARG); -+ -+ /* prescreening; this does wonders for this rather slow code */ -+ if (g->must != NULL) { -+ for (dp = start; dp < stop; dp++) -+ if (*dp == g->must[0] && stop - dp >= g->mlen && -+ memcmp(dp, g->must, (size_t)g->mlen) == 0) -+ break; -+ if (dp == stop) /* we didn't find g->must */ -+ return(REG_NOMATCH); -+ } -+ -+ /* match struct setup */ -+ m->g = g; -+ m->eflags = eflags; -+ m->pmatch = NULL; -+ m->lastpos = NULL; -+ m->offp = string; -+ m->beginp = start; -+ m->endp = stop; -+ STATESETUP(m, 4); -+ SETUP(m->st); -+ SETUP(m->fresh); -+ SETUP(m->tmp); -+ SETUP(m->empty); -+ CLEAR(m->empty); -+ -+ /* this loop does only one repetition except for backrefs */ -+ for (;;) { -+ endp = fast(m, start, stop, gf, gl); -+ if (endp == NULL) { /* a miss */ -+ free(m->pmatch); -+ free((void*)m->lastpos); -+ STATETEARDOWN(m); -+ return(REG_NOMATCH); -+ } -+ if (nmatch == 0 && !g->backrefs) -+ break; /* no further info needed */ -+ -+ /* where? */ -+ assert(m->coldp != NULL); -+ for (;;) { -+ NOTE("finding start"); -+ endp = slow(m, m->coldp, stop, gf, gl); -+ if (endp != NULL) -+ break; -+ assert(m->coldp < m->endp); -+ m->coldp++; -+ } -+ if (nmatch == 1 && !g->backrefs) -+ break; /* no further info needed */ -+ -+ /* oh my, they want the subexpressions... */ -+ if (m->pmatch == NULL) -+ m->pmatch = (llvm_regmatch_t *)malloc((m->g->nsub + 1) * -+ sizeof(llvm_regmatch_t)); -+ if (m->pmatch == NULL) { -+ STATETEARDOWN(m); -+ return(REG_ESPACE); -+ } -+ for (i = 1; i <= m->g->nsub; i++) -+ m->pmatch[i].rm_so = m->pmatch[i].rm_eo = -1; -+ if (!g->backrefs && !(m->eflags®_BACKR)) { -+ NOTE("dissecting"); -+ dp = dissect(m, m->coldp, endp, gf, gl); -+ } else { -+ if (g->nplus > 0 && m->lastpos == NULL) -+ m->lastpos = (const char **)malloc((g->nplus+1) * -+ sizeof(char *)); -+ if (g->nplus > 0 && m->lastpos == NULL) { -+ free(m->pmatch); -+ STATETEARDOWN(m); -+ return(REG_ESPACE); -+ } -+ NOTE("backref dissect"); -+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); -+ } -+ if (dp != NULL) -+ break; -+ -+ /* uh-oh... we couldn't find a subexpression-level match */ -+ assert(g->backrefs); /* must be back references doing it */ -+ assert(g->nplus == 0 || m->lastpos != NULL); -+ for (;;) { -+ if (dp != NULL || endp <= m->coldp) -+ break; /* defeat */ -+ NOTE("backoff"); -+ endp = slow(m, m->coldp, endp-1, gf, gl); -+ if (endp == NULL) -+ break; /* defeat */ -+ /* try it on a shorter possibility */ -+#ifndef NDEBUG -+ for (i = 1; i <= m->g->nsub; i++) { -+ assert(m->pmatch[i].rm_so == -1); -+ assert(m->pmatch[i].rm_eo == -1); -+ } -+#endif -+ NOTE("backoff dissect"); -+ dp = backref(m, m->coldp, endp, gf, gl, (sopno)0, 0); -+ } -+ assert(dp == NULL || dp == endp); -+ if (dp != NULL) /* found a shorter one */ -+ break; -+ -+ /* despite initial appearances, there is no match here */ -+ NOTE("false alarm"); -+ if (m->coldp == stop) -+ break; -+ start = m->coldp + 1; /* recycle starting later */ -+ } -+ -+ /* fill in the details if requested */ -+ if (nmatch > 0) { -+ pmatch[0].rm_so = m->coldp - m->offp; -+ pmatch[0].rm_eo = endp - m->offp; -+ } -+ if (nmatch > 1) { -+ assert(m->pmatch != NULL); -+ for (i = 1; i < nmatch; i++) -+ if (i <= m->g->nsub) -+ pmatch[i] = m->pmatch[i]; -+ else { -+ pmatch[i].rm_so = -1; -+ pmatch[i].rm_eo = -1; -+ } -+ } -+ -+ if (m->pmatch != NULL) -+ free((char *)m->pmatch); -+ if (m->lastpos != NULL) -+ free((char *)m->lastpos); -+ STATETEARDOWN(m); -+ return(0); -+} -+ -+/* -+ - dissect - figure out what matched what, no back references -+ */ -+static const char * /* == stop (success) always */ -+dissect(struct match *m, const char *start, const char *stop, sopno startst, -+ sopno stopst) -+{ -+ int i; -+ sopno ss; /* start sop of current subRE */ -+ sopno es; /* end sop of current subRE */ -+ const char *sp; /* start of string matched by it */ -+ const char *stp; /* string matched by it cannot pass here */ -+ const char *rest; /* start of rest of string */ -+ const char *tail; /* string unmatched by rest of RE */ -+ sopno ssub; /* start sop of subsubRE */ -+ sopno esub; /* end sop of subsubRE */ -+ const char *ssp; /* start of string matched by subsubRE */ -+ const char *sep; /* end of string matched by subsubRE */ -+ const char *oldssp; /* previous ssp */ -+ -+ AT("diss", start, stop, startst, stopst); -+ sp = start; -+ for (ss = startst; ss < stopst; ss = es) { -+ /* identify end of subRE */ -+ es = ss; -+ switch (OP(m->g->strip[es])) { -+ case OPLUS_: -+ case OQUEST_: -+ es += OPND(m->g->strip[es]); -+ break; -+ case OCH_: -+ while (OP(m->g->strip[es]) != O_CH) -+ es += OPND(m->g->strip[es]); -+ break; -+ } -+ es++; -+ -+ /* figure out what it matched */ -+ switch (OP(m->g->strip[ss])) { -+ case OEND: -+ assert(nope); -+ break; -+ case OCHAR: -+ sp++; -+ break; -+ case OBOL: -+ case OEOL: -+ case OBOW: -+ case OEOW: -+ break; -+ case OANY: -+ case OANYOF: -+ sp++; -+ break; -+ case OBACK_: -+ case O_BACK: -+ assert(nope); -+ break; -+ /* cases where length of match is hard to find */ -+ case OQUEST_: -+ stp = stop; -+ for (;;) { -+ /* how long could this one be? */ -+ rest = slow(m, sp, stp, ss, es); -+ assert(rest != NULL); /* it did match */ -+ /* could the rest match the rest? */ -+ tail = slow(m, rest, stop, es, stopst); -+ if (tail == stop) -+ break; /* yes! */ -+ /* no -- try a shorter match for this one */ -+ stp = rest - 1; -+ assert(stp >= sp); /* it did work */ -+ } -+ ssub = ss + 1; -+ esub = es - 1; -+ /* did innards match? */ -+ if (slow(m, sp, rest, ssub, esub) != NULL) { -+ const char *dp = dissect(m, sp, rest, ssub, esub); -+ (void)dp; /* avoid warning if assertions off */ -+ assert(dp == rest); -+ } else /* no */ -+ assert(sp == rest); -+ sp = rest; -+ break; -+ case OPLUS_: -+ stp = stop; -+ for (;;) { -+ /* how long could this one be? */ -+ rest = slow(m, sp, stp, ss, es); -+ assert(rest != NULL); /* it did match */ -+ /* could the rest match the rest? */ -+ tail = slow(m, rest, stop, es, stopst); -+ if (tail == stop) -+ break; /* yes! */ -+ /* no -- try a shorter match for this one */ -+ stp = rest - 1; -+ assert(stp >= sp); /* it did work */ -+ } -+ ssub = ss + 1; -+ esub = es - 1; -+ ssp = sp; -+ oldssp = ssp; -+ for (;;) { /* find last match of innards */ -+ sep = slow(m, ssp, rest, ssub, esub); -+ if (sep == NULL || sep == ssp) -+ break; /* failed or matched null */ -+ oldssp = ssp; /* on to next try */ -+ ssp = sep; -+ } -+ if (sep == NULL) { -+ /* last successful match */ -+ sep = ssp; -+ ssp = oldssp; -+ } -+ assert(sep == rest); /* must exhaust substring */ -+ assert(slow(m, ssp, sep, ssub, esub) == rest); -+ { -+ const char *dp = dissect(m, ssp, sep, ssub, esub); -+ (void)dp; /* avoid warning if assertions off */ -+ assert(dp == sep); -+ } -+ sp = rest; -+ break; -+ case OCH_: -+ stp = stop; -+ for (;;) { -+ /* how long could this one be? */ -+ rest = slow(m, sp, stp, ss, es); -+ assert(rest != NULL); /* it did match */ -+ /* could the rest match the rest? */ -+ tail = slow(m, rest, stop, es, stopst); -+ if (tail == stop) -+ break; /* yes! */ -+ /* no -- try a shorter match for this one */ -+ stp = rest - 1; -+ assert(stp >= sp); /* it did work */ -+ } -+ ssub = ss + 1; -+ esub = ss + OPND(m->g->strip[ss]) - 1; -+ assert(OP(m->g->strip[esub]) == OOR1); -+ for (;;) { /* find first matching branch */ -+ if (slow(m, sp, rest, ssub, esub) == rest) -+ break; /* it matched all of it */ -+ /* that one missed, try next one */ -+ assert(OP(m->g->strip[esub]) == OOR1); -+ esub++; -+ assert(OP(m->g->strip[esub]) == OOR2); -+ ssub = esub + 1; -+ esub += OPND(m->g->strip[esub]); -+ if (OP(m->g->strip[esub]) == OOR2) -+ esub--; -+ else -+ assert(OP(m->g->strip[esub]) == O_CH); -+ } -+ { -+ const char *dp = dissect(m, sp, rest, ssub, esub); -+ (void)dp; /* avoid warning if assertions off */ -+ assert(dp == rest); -+ } -+ sp = rest; -+ break; -+ case O_PLUS: -+ case O_QUEST: -+ case OOR1: -+ case OOR2: -+ case O_CH: -+ assert(nope); -+ break; -+ case OLPAREN: -+ i = OPND(m->g->strip[ss]); -+ assert(0 < i && i <= m->g->nsub); -+ m->pmatch[i].rm_so = sp - m->offp; -+ break; -+ case ORPAREN: -+ i = OPND(m->g->strip[ss]); -+ assert(0 < i && i <= m->g->nsub); -+ m->pmatch[i].rm_eo = sp - m->offp; -+ break; -+ default: /* uh oh */ -+ assert(nope); -+ break; -+ } -+ } -+ -+ assert(sp == stop); -+ return(sp); -+} -+ -+/* -+ - backref - figure out what matched what, figuring in back references -+ */ -+static const char * /* == stop (success) or NULL (failure) */ -+backref(struct match *m, const char *start, const char *stop, sopno startst, -+ sopno stopst, sopno lev, int rec) /* PLUS nesting level */ -+{ -+ int i; -+ sopno ss; /* start sop of current subRE */ -+ const char *sp; /* start of string matched by it */ -+ sopno ssub; /* start sop of subsubRE */ -+ sopno esub; /* end sop of subsubRE */ -+ const char *ssp; /* start of string matched by subsubRE */ -+ const char *dp; -+ size_t len; -+ int hard; -+ sop s; -+ llvm_regoff_t offsave; -+ cset *cs; -+ -+ AT("back", start, stop, startst, stopst); -+ sp = start; -+ -+ /* get as far as we can with easy stuff */ -+ hard = 0; -+ for (ss = startst; !hard && ss < stopst; ss++) -+ switch (OP(s = m->g->strip[ss])) { -+ case OCHAR: -+ if (sp == stop || *sp++ != (char)OPND(s)) -+ return(NULL); -+ break; -+ case OANY: -+ if (sp == stop) -+ return(NULL); -+ sp++; -+ break; -+ case OANYOF: -+ cs = &m->g->sets[OPND(s)]; -+ if (sp == stop || !CHIN(cs, *sp++)) -+ return(NULL); -+ break; -+ case OBOL: -+ if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || -+ (sp < m->endp && *(sp-1) == '\n' && -+ (m->g->cflags®_NEWLINE)) ) -+ { /* yes */ } -+ else -+ return(NULL); -+ break; -+ case OEOL: -+ if ( (sp == m->endp && !(m->eflags®_NOTEOL)) || -+ (sp < m->endp && *sp == '\n' && -+ (m->g->cflags®_NEWLINE)) ) -+ { /* yes */ } -+ else -+ return(NULL); -+ break; -+ case OBOW: -+ if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || -+ (sp < m->endp && *(sp-1) == '\n' && -+ (m->g->cflags®_NEWLINE)) || -+ (sp > m->beginp && -+ !ISWORD(*(sp-1))) ) && -+ (sp < m->endp && ISWORD(*sp)) ) -+ { /* yes */ } -+ else -+ return(NULL); -+ break; -+ case OEOW: -+ if (( (sp == m->endp && !(m->eflags®_NOTEOL)) || -+ (sp < m->endp && *sp == '\n' && -+ (m->g->cflags®_NEWLINE)) || -+ (sp < m->endp && !ISWORD(*sp)) ) && -+ (sp > m->beginp && ISWORD(*(sp-1))) ) -+ { /* yes */ } -+ else -+ return(NULL); -+ break; -+ case O_QUEST: -+ break; -+ case OOR1: /* matches null but needs to skip */ -+ ss++; -+ s = m->g->strip[ss]; -+ do { -+ assert(OP(s) == OOR2); -+ ss += OPND(s); -+ } while (OP(s = m->g->strip[ss]) != O_CH); -+ /* note that the ss++ gets us past the O_CH */ -+ break; -+ default: /* have to make a choice */ -+ hard = 1; -+ break; -+ } -+ if (!hard) { /* that was it! */ -+ if (sp != stop) -+ return(NULL); -+ return(sp); -+ } -+ ss--; /* adjust for the for's final increment */ -+ -+ /* the hard stuff */ -+ AT("hard", sp, stop, ss, stopst); -+ s = m->g->strip[ss]; -+ switch (OP(s)) { -+ case OBACK_: /* the vilest depths */ -+ i = OPND(s); -+ assert(0 < i && i <= m->g->nsub); -+ if (m->pmatch[i].rm_eo == -1) -+ return(NULL); -+ assert(m->pmatch[i].rm_so != -1); -+ len = m->pmatch[i].rm_eo - m->pmatch[i].rm_so; -+ if (len == 0 && rec++ > MAX_RECURSION) -+ return(NULL); -+ assert(stop - m->beginp >= len); -+ if (sp > stop - len) -+ return(NULL); /* not enough left to match */ -+ ssp = m->offp + m->pmatch[i].rm_so; -+ if (memcmp(sp, ssp, len) != 0) -+ return(NULL); -+ while (m->g->strip[ss] != SOP(O_BACK, i)) -+ ss++; -+ return(backref(m, sp+len, stop, ss+1, stopst, lev, rec)); -+ break; -+ case OQUEST_: /* to null or not */ -+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec); -+ if (dp != NULL) -+ return(dp); /* not */ -+ return(backref(m, sp, stop, ss+OPND(s)+1, stopst, lev, rec)); -+ break; -+ case OPLUS_: -+ assert(m->lastpos != NULL); -+ assert(lev+1 <= m->g->nplus); -+ m->lastpos[lev+1] = sp; -+ return(backref(m, sp, stop, ss+1, stopst, lev+1, rec)); -+ break; -+ case O_PLUS: -+ if (sp == m->lastpos[lev]) /* last pass matched null */ -+ return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); -+ /* try another pass */ -+ m->lastpos[lev] = sp; -+ dp = backref(m, sp, stop, ss-OPND(s)+1, stopst, lev, rec); -+ if (dp == NULL) -+ return(backref(m, sp, stop, ss+1, stopst, lev-1, rec)); -+ else -+ return(dp); -+ break; -+ case OCH_: /* find the right one, if any */ -+ ssub = ss + 1; -+ esub = ss + OPND(s) - 1; -+ assert(OP(m->g->strip[esub]) == OOR1); -+ for (;;) { /* find first matching branch */ -+ dp = backref(m, sp, stop, ssub, esub, lev, rec); -+ if (dp != NULL) -+ return(dp); -+ /* that one missed, try next one */ -+ if (OP(m->g->strip[esub]) == O_CH) -+ return(NULL); /* there is none */ -+ esub++; -+ assert(OP(m->g->strip[esub]) == OOR2); -+ ssub = esub + 1; -+ esub += OPND(m->g->strip[esub]); -+ if (OP(m->g->strip[esub]) == OOR2) -+ esub--; -+ else -+ assert(OP(m->g->strip[esub]) == O_CH); -+ } -+ break; -+ case OLPAREN: /* must undo assignment if rest fails */ -+ i = OPND(s); -+ assert(0 < i && i <= m->g->nsub); -+ offsave = m->pmatch[i].rm_so; -+ m->pmatch[i].rm_so = sp - m->offp; -+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec); -+ if (dp != NULL) -+ return(dp); -+ m->pmatch[i].rm_so = offsave; -+ return(NULL); -+ break; -+ case ORPAREN: /* must undo assignment if rest fails */ -+ i = OPND(s); -+ assert(0 < i && i <= m->g->nsub); -+ offsave = m->pmatch[i].rm_eo; -+ m->pmatch[i].rm_eo = sp - m->offp; -+ dp = backref(m, sp, stop, ss+1, stopst, lev, rec); -+ if (dp != NULL) -+ return(dp); -+ m->pmatch[i].rm_eo = offsave; -+ return(NULL); -+ break; -+ default: /* uh oh */ -+ assert(nope); -+ break; -+ } -+ -+ /* "can't happen" */ -+ assert(nope); -+ /* NOTREACHED */ -+ return NULL; -+} -+ -+/* -+ - fast - step through the string at top speed -+ */ -+static const char * /* where tentative match ended, or NULL */ -+fast(struct match *m, const char *start, const char *stop, sopno startst, -+ sopno stopst) -+{ -+ states st = m->st; -+ states fresh = m->fresh; -+ states tmp = m->tmp; -+ const char *p = start; -+ int c = (start == m->beginp) ? OUT : *(start-1); -+ int lastc; /* previous c */ -+ int flagch; -+ int i; -+ const char *coldp; /* last p after which no match was underway */ -+ -+ CLEAR(st); -+ SET1(st, startst); -+ st = step(m->g, startst, stopst, st, NOTHING, st); -+ ASSIGN(fresh, st); -+ SP("start", st, *p); -+ coldp = NULL; -+ for (;;) { -+ /* next character */ -+ lastc = c; -+ c = (p == m->endp) ? OUT : *p; -+ if (EQ(st, fresh)) -+ coldp = p; -+ -+ /* is there an EOL and/or BOL between lastc and c? */ -+ flagch = '\0'; -+ i = 0; -+ if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || -+ (lastc == OUT && !(m->eflags®_NOTBOL)) ) { -+ flagch = BOL; -+ i = m->g->nbol; -+ } -+ if ( (c == '\n' && m->g->cflags®_NEWLINE) || -+ (c == OUT && !(m->eflags®_NOTEOL)) ) { -+ flagch = (flagch == BOL) ? BOLEOL : EOL; -+ i += m->g->neol; -+ } -+ if (i != 0) { -+ for (; i > 0; i--) -+ st = step(m->g, startst, stopst, st, flagch, st); -+ SP("boleol", st, c); -+ } -+ -+ /* how about a word boundary? */ -+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && -+ (c != OUT && ISWORD(c)) ) { -+ flagch = BOW; -+ } -+ if ( (lastc != OUT && ISWORD(lastc)) && -+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) { -+ flagch = EOW; -+ } -+ if (flagch == BOW || flagch == EOW) { -+ st = step(m->g, startst, stopst, st, flagch, st); -+ SP("boweow", st, c); -+ } -+ -+ /* are we done? */ -+ if (ISSET(st, stopst) || p == stop) -+ break; /* NOTE BREAK OUT */ -+ -+ /* no, we must deal with this character */ -+ ASSIGN(tmp, st); -+ ASSIGN(st, fresh); -+ assert(c != OUT); -+ st = step(m->g, startst, stopst, tmp, c, st); -+ SP("aft", st, c); -+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); -+ p++; -+ } -+ -+ assert(coldp != NULL); -+ m->coldp = coldp; -+ if (ISSET(st, stopst)) -+ return(p+1); -+ else -+ return(NULL); -+} -+ -+/* -+ - slow - step through the string more deliberately -+ */ -+static const char * /* where it ended */ -+slow(struct match *m, const char *start, const char *stop, sopno startst, -+ sopno stopst) -+{ -+ states st = m->st; -+ states empty = m->empty; -+ states tmp = m->tmp; -+ const char *p = start; -+ int c = (start == m->beginp) ? OUT : *(start-1); -+ int lastc; /* previous c */ -+ int flagch; -+ int i; -+ const char *matchp; /* last p at which a match ended */ -+ -+ AT("slow", start, stop, startst, stopst); -+ CLEAR(st); -+ SET1(st, startst); -+ SP("sstart", st, *p); -+ st = step(m->g, startst, stopst, st, NOTHING, st); -+ matchp = NULL; -+ for (;;) { -+ /* next character */ -+ lastc = c; -+ c = (p == m->endp) ? OUT : *p; -+ -+ /* is there an EOL and/or BOL between lastc and c? */ -+ flagch = '\0'; -+ i = 0; -+ if ( (lastc == '\n' && m->g->cflags®_NEWLINE) || -+ (lastc == OUT && !(m->eflags®_NOTBOL)) ) { -+ flagch = BOL; -+ i = m->g->nbol; -+ } -+ if ( (c == '\n' && m->g->cflags®_NEWLINE) || -+ (c == OUT && !(m->eflags®_NOTEOL)) ) { -+ flagch = (flagch == BOL) ? BOLEOL : EOL; -+ i += m->g->neol; -+ } -+ if (i != 0) { -+ for (; i > 0; i--) -+ st = step(m->g, startst, stopst, st, flagch, st); -+ SP("sboleol", st, c); -+ } -+ -+ /* how about a word boundary? */ -+ if ( (flagch == BOL || (lastc != OUT && !ISWORD(lastc))) && -+ (c != OUT && ISWORD(c)) ) { -+ flagch = BOW; -+ } -+ if ( (lastc != OUT && ISWORD(lastc)) && -+ (flagch == EOL || (c != OUT && !ISWORD(c))) ) { -+ flagch = EOW; -+ } -+ if (flagch == BOW || flagch == EOW) { -+ st = step(m->g, startst, stopst, st, flagch, st); -+ SP("sboweow", st, c); -+ } -+ -+ /* are we done? */ -+ if (ISSET(st, stopst)) -+ matchp = p; -+ if (EQ(st, empty) || p == stop) -+ break; /* NOTE BREAK OUT */ -+ -+ /* no, we must deal with this character */ -+ ASSIGN(tmp, st); -+ ASSIGN(st, empty); -+ assert(c != OUT); -+ st = step(m->g, startst, stopst, tmp, c, st); -+ SP("saft", st, c); -+ assert(EQ(step(m->g, startst, stopst, st, NOTHING, st), st)); -+ p++; -+ } -+ -+ return(matchp); -+} -+ -+ -+/* -+ - step - map set of states reachable before char to set reachable after -+ */ -+static states -+step(struct re_guts *g, -+ sopno start, /* start state within strip */ -+ sopno stop, /* state after stop state within strip */ -+ states bef, /* states reachable before */ -+ int ch, /* character or NONCHAR code */ -+ states aft) /* states already known reachable after */ -+{ -+ cset *cs; -+ sop s; -+ sopno pc; -+ onestate here; /* note, macros know this name */ -+ sopno look; -+ int i; -+ -+ for (pc = start, INIT(here, pc); pc != stop; pc++, INC(here)) { -+ s = g->strip[pc]; -+ switch (OP(s)) { -+ case OEND: -+ assert(pc == stop-1); -+ break; -+ case OCHAR: -+ /* only characters can match */ -+ assert(!NONCHAR(ch) || ch != (char)OPND(s)); -+ if (ch == (char)OPND(s)) -+ FWD(aft, bef, 1); -+ break; -+ case OBOL: -+ if (ch == BOL || ch == BOLEOL) -+ FWD(aft, bef, 1); -+ break; -+ case OEOL: -+ if (ch == EOL || ch == BOLEOL) -+ FWD(aft, bef, 1); -+ break; -+ case OBOW: -+ if (ch == BOW) -+ FWD(aft, bef, 1); -+ break; -+ case OEOW: -+ if (ch == EOW) -+ FWD(aft, bef, 1); -+ break; -+ case OANY: -+ if (!NONCHAR(ch)) -+ FWD(aft, bef, 1); -+ break; -+ case OANYOF: -+ cs = &g->sets[OPND(s)]; -+ if (!NONCHAR(ch) && CHIN(cs, ch)) -+ FWD(aft, bef, 1); -+ break; -+ case OBACK_: /* ignored here */ -+ case O_BACK: -+ FWD(aft, aft, 1); -+ break; -+ case OPLUS_: /* forward, this is just an empty */ -+ FWD(aft, aft, 1); -+ break; -+ case O_PLUS: /* both forward and back */ -+ FWD(aft, aft, 1); -+ i = ISSETBACK(aft, OPND(s)); -+ BACK(aft, aft, OPND(s)); -+ if (!i && ISSETBACK(aft, OPND(s))) { -+ /* oho, must reconsider loop body */ -+ pc -= OPND(s) + 1; -+ INIT(here, pc); -+ } -+ break; -+ case OQUEST_: /* two branches, both forward */ -+ FWD(aft, aft, 1); -+ FWD(aft, aft, OPND(s)); -+ break; -+ case O_QUEST: /* just an empty */ -+ FWD(aft, aft, 1); -+ break; -+ case OLPAREN: /* not significant here */ -+ case ORPAREN: -+ FWD(aft, aft, 1); -+ break; -+ case OCH_: /* mark the first two branches */ -+ FWD(aft, aft, 1); -+ assert(OP(g->strip[pc+OPND(s)]) == OOR2); -+ FWD(aft, aft, OPND(s)); -+ break; -+ case OOR1: /* done a branch, find the O_CH */ -+ if (ISSTATEIN(aft, here)) { -+ for (look = 1; -+ OP(s = g->strip[pc+look]) != O_CH; -+ look += OPND(s)) -+ assert(OP(s) == OOR2); -+ FWD(aft, aft, look); -+ } -+ break; -+ case OOR2: /* propagate OCH_'s marking */ -+ FWD(aft, aft, 1); -+ if (OP(g->strip[pc+OPND(s)]) != O_CH) { -+ assert(OP(g->strip[pc+OPND(s)]) == OOR2); -+ FWD(aft, aft, OPND(s)); -+ } -+ break; -+ case O_CH: /* just empty */ -+ FWD(aft, aft, 1); -+ break; -+ default: /* ooooops... */ -+ assert(nope); -+ break; -+ } -+ } -+ -+ return(aft); -+} -+ -+#ifdef REDEBUG -+/* -+ - print - print a set of states -+ */ -+static void -+print(struct match *m, char *caption, states st, int ch, FILE *d) -+{ -+ struct re_guts *g = m->g; -+ int i; -+ int first = 1; -+ -+ if (!(m->eflags®_TRACE)) -+ return; -+ -+ (void)fprintf(d, "%s", caption); -+ if (ch != '\0') -+ (void)fprintf(d, " %s", pchar(ch)); -+ for (i = 0; i < g->nstates; i++) -+ if (ISSET(st, i)) { -+ (void)fprintf(d, "%s%d", (first) ? "\t" : ", ", i); -+ first = 0; -+ } -+ (void)fprintf(d, "\n"); -+} -+ -+/* -+ - at - print current situation -+ */ -+static void -+at(struct match *m, char *title, char *start, char *stop, sopno startst, -+ sopno stopst) -+{ -+ if (!(m->eflags®_TRACE)) -+ return; -+ -+ (void)printf("%s %s-", title, pchar(*start)); -+ (void)printf("%s ", pchar(*stop)); -+ (void)printf("%ld-%ld\n", (long)startst, (long)stopst); -+} -+ -+#ifndef PCHARDONE -+#define PCHARDONE /* never again */ -+/* -+ - pchar - make a character printable -+ * -+ * Is this identical to regchar() over in debug.c? Well, yes. But a -+ * duplicate here avoids having a debugging-capable regexec.o tied to -+ * a matching debug.o, and this is convenient. It all disappears in -+ * the non-debug compilation anyway, so it doesn't matter much. -+ */ -+static char * /* -> representation */ -+pchar(int ch) -+{ -+ static char pbuf[10]; -+ -+ if (isprint(ch) || ch == ' ') -+ (void)snprintf(pbuf, sizeof pbuf, "%c", ch); -+ else -+ (void)snprintf(pbuf, sizeof pbuf, "\\%o", ch); -+ return(pbuf); -+} -+#endif -+#endif -+ -+#undef matcher -+#undef fast -+#undef slow -+#undef dissect -+#undef backref -+#undef step -+#undef print -+#undef at -+#undef match -+#undef nope -Index: include/lldb/Utility/regex2.h -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regex2.h -@@ -0,0 +1,162 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regex2.h 8.4 (Berkeley) 3/20/94 -+ */ -+ -+#ifndef LLVM_SUPPORT_REGEX2_H -+#define LLVM_SUPPORT_REGEX2_H -+ -+/* -+ * internals of regex_t -+ */ -+#define MAGIC1 ((('r'^0200)<<8) | 'e') -+ -+/* -+ * The internal representation is a *strip*, a sequence of -+ * operators ending with an endmarker. (Some terminology etc. is a -+ * historical relic of earlier versions which used multiple strips.) -+ * Certain oddities in the representation are there to permit running -+ * the machinery backwards; in particular, any deviation from sequential -+ * flow must be marked at both its source and its destination. Some -+ * fine points: -+ * -+ * - OPLUS_ and O_PLUS are *inside* the loop they create. -+ * - OQUEST_ and O_QUEST are *outside* the bypass they create. -+ * - OCH_ and O_CH are *outside* the multi-way branch they create, while -+ * OOR1 and OOR2 are respectively the end and the beginning of one of -+ * the branches. Note that there is an implicit OOR2 following OCH_ -+ * and an implicit OOR1 preceding O_CH. -+ * -+ * In state representations, an operator's bit is on to signify a state -+ * immediately *preceding* "execution" of that operator. -+ */ -+typedef unsigned long sop; /* strip operator */ -+typedef long sopno; -+#define OPRMASK 0xf8000000LU -+#define OPDMASK 0x07ffffffLU -+#define OPSHIFT ((unsigned)27) -+#define OP(n) ((n)&OPRMASK) -+#define OPND(n) ((n)&OPDMASK) -+#define SOP(op, opnd) ((op)|(opnd)) -+/* operators meaning operand */ -+/* (back, fwd are offsets) */ -+#define OEND (1LU< uch [csetsize] */ -+ uch mask; /* bit within array */ -+ uch hash; /* hash code */ -+ size_t smultis; -+ char *multis; /* -> char[smulti] ab\0cd\0ef\0\0 */ -+} cset; -+/* note that CHadd and CHsub are unsafe, and CHIN doesn't yield 0/1 */ -+#define CHadd(cs, c) ((cs)->ptr[(uch)(c)] |= (cs)->mask, (cs)->hash += (c)) -+#define CHsub(cs, c) ((cs)->ptr[(uch)(c)] &= ~(cs)->mask, (cs)->hash -= (c)) -+#define CHIN(cs, c) ((cs)->ptr[(uch)(c)] & (cs)->mask) -+#define MCadd(p, cs, cp) mcadd(p, cs, cp) /* llvm_regcomp() internal fns */ -+#define MCsub(p, cs, cp) mcsub(p, cs, cp) -+#define MCin(p, cs, cp) mcin(p, cs, cp) -+ -+/* stuff for character categories */ -+typedef unsigned char cat_t; -+ -+/* -+ * main compiled-expression structure -+ */ -+struct re_guts { -+ int magic; -+# define MAGIC2 ((('R'^0200)<<8)|'E') -+ sop *strip; /* malloced area for strip */ -+ int csetsize; /* number of bits in a cset vector */ -+ int ncsets; /* number of csets in use */ -+ cset *sets; /* -> cset [ncsets] */ -+ uch *setbits; /* -> uch[csetsize][ncsets/CHAR_BIT] */ -+ int cflags; /* copy of llvm_regcomp() cflags argument */ -+ sopno nstates; /* = number of sops */ -+ sopno firststate; /* the initial OEND (normally 0) */ -+ sopno laststate; /* the final OEND */ -+ int iflags; /* internal flags */ -+# define USEBOL 01 /* used ^ */ -+# define USEEOL 02 /* used $ */ -+# define REGEX_BAD 04 /* something wrong */ -+ int nbol; /* number of ^ used */ -+ int neol; /* number of $ used */ -+ int ncategories; /* how many character categories */ -+ cat_t *categories; /* ->catspace[-CHAR_MIN] */ -+ char *must; /* match must contain this string */ -+ int mlen; /* length of must */ -+ size_t nsub; /* copy of re_nsub */ -+ int backrefs; /* does it use back references? */ -+ sopno nplus; /* how deep does it nest +s? */ -+ /* catspace must be last */ -+ cat_t catspace[1]; /* actually [NC] */ -+}; -+ -+/* misc utilities */ -+#define OUT (CHAR_MAX+1) /* a non-character value */ -+#define ISWORD(c) (isalnum(c&0xff) || (c) == '_') -+ -+#endif -Index: include/lldb/Utility/regex_impl.h -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regex_impl.h -@@ -0,0 +1,108 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992 Henry Spencer. -+ * Copyright (c) 1992, 1993 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer of the University of Toronto. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regex.h 8.1 (Berkeley) 6/2/93 -+ */ -+ -+#ifndef _REGEX_H_ -+#define _REGEX_H_ -+ -+#include -+typedef off_t llvm_regoff_t; -+typedef struct { -+ llvm_regoff_t rm_so; /* start of match */ -+ llvm_regoff_t rm_eo; /* end of match */ -+} llvm_regmatch_t; -+ -+typedef struct llvm_regex { -+ int re_magic; -+ size_t re_nsub; /* number of parenthesized subexpressions */ -+ const char *re_endp; /* end pointer for REG_PEND */ -+ struct re_guts *re_g; /* none of your business :-) */ -+} llvm_regex_t; -+ -+/* llvm_regcomp() flags */ -+#define REG_BASIC 0000 -+#define REG_EXTENDED 0001 -+#define REG_ICASE 0002 -+#define REG_NOSUB 0004 -+#define REG_NEWLINE 0010 -+#define REG_NOSPEC 0020 -+#define REG_PEND 0040 -+#define REG_DUMP 0200 -+ -+/* llvm_regerror() flags */ -+#define REG_NOMATCH 1 -+#define REG_BADPAT 2 -+#define REG_ECOLLATE 3 -+#define REG_ECTYPE 4 -+#define REG_EESCAPE 5 -+#define REG_ESUBREG 6 -+#define REG_EBRACK 7 -+#define REG_EPAREN 8 -+#define REG_EBRACE 9 -+#define REG_BADBR 10 -+#define REG_ERANGE 11 -+#define REG_ESPACE 12 -+#define REG_BADRPT 13 -+#define REG_EMPTY 14 -+#define REG_ASSERT 15 -+#define REG_INVARG 16 -+#define REG_ATOI 255 /* convert name to number (!) */ -+#define REG_ITOA 0400 /* convert number to name (!) */ -+ -+/* llvm_regexec() flags */ -+#define REG_NOTBOL 00001 -+#define REG_NOTEOL 00002 -+#define REG_STARTEND 00004 -+#define REG_TRACE 00400 /* tracing of execution */ -+#define REG_LARGE 01000 /* force large representation */ -+#define REG_BACKR 02000 /* force use of backref code */ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+int llvm_regcomp(llvm_regex_t *, const char *, int); -+size_t llvm_regerror(int, const llvm_regex_t *, char *, size_t); -+int llvm_regexec(const llvm_regex_t *, const char *, size_t, -+ llvm_regmatch_t [], int); -+void llvm_regfree(llvm_regex_t *); -+size_t llvm_strlcpy(char *dst, const char *src, size_t siz); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* !_REGEX_H_ */ -Index: include/lldb/Utility/regutils.h -=================================================================== ---- /dev/null -+++ include/lldb/Utility/regutils.h -@@ -0,0 +1,58 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)utils.h 8.3 (Berkeley) 3/20/94 -+ */ -+ -+#ifndef LLVM_SUPPORT_REGUTILS_H -+#define LLVM_SUPPORT_REGUTILS_H -+ -+/* utility definitions */ -+#define NC (CHAR_MAX - CHAR_MIN + 1) -+typedef unsigned char uch; -+ -+/* switch off assertions (if not already off) if no REDEBUG */ -+#ifndef REDEBUG -+#ifndef NDEBUG -+#define NDEBUG /* no assertions please */ -+#endif -+#endif -+#include -+ -+/* for old systems with bcopy() but no memmove() */ -+#ifdef USEBCOPY -+#define memmove(d, s, c) bcopy(s, d, c) -+#endif -+ -+#endif -Index: scripts/CMakeLists.txt -=================================================================== ---- scripts/CMakeLists.txt -+++ scripts/CMakeLists.txt -@@ -9,6 +9,8 @@ - ${LLDB_SOURCE_DIR}/include/lldb/lldb-versioning.h - ) - -+include(FindPythonInterp) -+ - find_package(SWIG REQUIRED) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp -Index: source/Utility/CMakeLists.txt -=================================================================== ---- source/Utility/CMakeLists.txt -+++ source/Utility/CMakeLists.txt -@@ -1,3 +1,5 @@ -+include_directories(../../include/lldb/Utility) -+ - add_lldb_library(lldbUtility - ARM_DWARF_Registers.cpp - ARM64_DWARF_Registers.cpp -@@ -17,4 +17,9 @@ - TaskPool.cpp - TimeSpecTimeout.cpp - UriParser.cpp -+ regcomp.c -+ regerror.c -+ regexec.c -+ regfree.c -+ regstrlcpy.c - ) -Index: source/Utility/regcomp.c -=================================================================== ---- /dev/null -+++ source/Utility/regcomp.c -@@ -0,0 +1,1570 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regcomp.c 8.5 (Berkeley) 3/20/94 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "regex_impl.h" -+ -+#include "regutils.h" -+#include "regex2.h" -+ -+#include "regcclass.h" -+#include "regcname.h" -+ -+#include -+/* Pessimistically bound memory use */ -+#define SIZE_MAX UINT_MAX -+ -+/* -+ * parse structure, passed up and down to avoid global variables and -+ * other clumsinesses -+ */ -+struct parse { -+ char *next; /* next character in RE */ -+ char *end; /* end of string (-> NUL normally) */ -+ int error; /* has an error been seen? */ -+ sop *strip; /* malloced strip */ -+ sopno ssize; /* malloced strip size (allocated) */ -+ sopno slen; /* malloced strip length (used) */ -+ int ncsalloc; /* number of csets allocated */ -+ struct re_guts *g; -+# define NPAREN 10 /* we need to remember () 1-9 for back refs */ -+ sopno pbegin[NPAREN]; /* -> ( ([0] unused) */ -+ sopno pend[NPAREN]; /* -> ) ([0] unused) */ -+}; -+ -+static void p_ere(struct parse *, int); -+static void p_ere_exp(struct parse *); -+static void p_str(struct parse *); -+static void p_bre(struct parse *, int, int); -+static int p_simp_re(struct parse *, int); -+static int p_count(struct parse *); -+static void p_bracket(struct parse *); -+static void p_b_term(struct parse *, cset *); -+static void p_b_cclass(struct parse *, cset *); -+static void p_b_eclass(struct parse *, cset *); -+static char p_b_symbol(struct parse *); -+static char p_b_coll_elem(struct parse *, int); -+static char othercase(int); -+static void bothcases(struct parse *, int); -+static void ordinary(struct parse *, int); -+static void nonnewline(struct parse *); -+static void repeat(struct parse *, sopno, int, int); -+static int seterr(struct parse *, int); -+static cset *allocset(struct parse *); -+static void freeset(struct parse *, cset *); -+static int freezeset(struct parse *, cset *); -+static int firstch(struct parse *, cset *); -+static int nch(struct parse *, cset *); -+static void mcadd(struct parse *, cset *, const char *); -+static void mcinvert(struct parse *, cset *); -+static void mccase(struct parse *, cset *); -+static int isinsets(struct re_guts *, int); -+static int samesets(struct re_guts *, int, int); -+static void categorize(struct parse *, struct re_guts *); -+static sopno dupl(struct parse *, sopno, sopno); -+static void doemit(struct parse *, sop, size_t); -+static void doinsert(struct parse *, sop, size_t, sopno); -+static void dofwd(struct parse *, sopno, sop); -+static void enlarge(struct parse *, sopno); -+static void stripsnug(struct parse *, struct re_guts *); -+static void findmust(struct parse *, struct re_guts *); -+static sopno pluscount(struct parse *, struct re_guts *); -+ -+static char nuls[10]; /* place to point scanner in event of error */ -+ -+/* -+ * macros for use with parse structure -+ * BEWARE: these know that the parse structure is named `p' !!! -+ */ -+#define PEEK() (*p->next) -+#define PEEK2() (*(p->next+1)) -+#define MORE() (p->next < p->end) -+#define MORE2() (p->next+1 < p->end) -+#define SEE(c) (MORE() && PEEK() == (c)) -+#define SEETWO(a, b) (MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b)) -+#define EAT(c) ((SEE(c)) ? (NEXT(), 1) : 0) -+#define EATTWO(a, b) ((SEETWO(a, b)) ? (NEXT2(), 1) : 0) -+#define NEXT() (p->next++) -+#define NEXT2() (p->next += 2) -+#define NEXTn(n) (p->next += (n)) -+#define GETNEXT() (*p->next++) -+#define SETERROR(e) seterr(p, (e)) -+#define REQUIRE(co, e) (void)((co) || SETERROR(e)) -+#define MUSTSEE(c, e) (REQUIRE(MORE() && PEEK() == (c), e)) -+#define MUSTEAT(c, e) (REQUIRE(MORE() && GETNEXT() == (c), e)) -+#define MUSTNOTSEE(c, e) (REQUIRE(!MORE() || PEEK() != (c), e)) -+#define EMIT(op, sopnd) doemit(p, (sop)(op), (size_t)(sopnd)) -+#define INSERT(op, pos) doinsert(p, (sop)(op), HERE()-(pos)+1, pos) -+#define AHEAD(pos) dofwd(p, pos, HERE()-(pos)) -+#define ASTERN(sop, pos) EMIT(sop, HERE()-pos) -+#define HERE() (p->slen) -+#define THERE() (p->slen - 1) -+#define THERETHERE() (p->slen - 2) -+#define DROP(n) (p->slen -= (n)) -+ -+#ifdef _POSIX2_RE_DUP_MAX -+#define DUPMAX _POSIX2_RE_DUP_MAX -+#else -+#define DUPMAX 255 -+#endif -+#define INFINITY (DUPMAX + 1) -+ -+#ifndef NDEBUG -+static int never = 0; /* for use in asserts; shuts lint up */ -+#else -+#define never 0 /* some s have bugs too */ -+#endif -+ -+/* -+ - llvm_regcomp - interface for parser and compilation -+ */ -+int /* 0 success, otherwise REG_something */ -+llvm_regcomp(llvm_regex_t *preg, const char *pattern, int cflags) -+{ -+ struct parse pa; -+ struct re_guts *g; -+ struct parse *p = &pa; -+ int i; -+ size_t len; -+#ifdef REDEBUG -+# define GOODFLAGS(f) (f) -+#else -+# define GOODFLAGS(f) ((f)&~REG_DUMP) -+#endif -+ -+ cflags = GOODFLAGS(cflags); -+ if ((cflags®_EXTENDED) && (cflags®_NOSPEC)) -+ return(REG_INVARG); -+ -+ if (cflags®_PEND) { -+ if (preg->re_endp < pattern) -+ return(REG_INVARG); -+ len = preg->re_endp - pattern; -+ } else -+ len = strlen((const char *)pattern); -+ -+ /* do the mallocs early so failure handling is easy */ -+ g = (struct re_guts *)malloc(sizeof(struct re_guts) + -+ (NC-1)*sizeof(cat_t)); -+ if (g == NULL) -+ return(REG_ESPACE); -+ p->ssize = len/(size_t)2*(size_t)3 + (size_t)1; /* ugh */ -+ p->strip = (sop *)calloc(p->ssize, sizeof(sop)); -+ p->slen = 0; -+ if (p->strip == NULL) { -+ free((char *)g); -+ return(REG_ESPACE); -+ } -+ -+ /* set things up */ -+ p->g = g; -+ p->next = (char *)pattern; /* convenience; we do not modify it */ -+ p->end = p->next + len; -+ p->error = 0; -+ p->ncsalloc = 0; -+ for (i = 0; i < NPAREN; i++) { -+ p->pbegin[i] = 0; -+ p->pend[i] = 0; -+ } -+ g->csetsize = NC; -+ g->sets = NULL; -+ g->setbits = NULL; -+ g->ncsets = 0; -+ g->cflags = cflags; -+ g->iflags = 0; -+ g->nbol = 0; -+ g->neol = 0; -+ g->must = NULL; -+ g->mlen = 0; -+ g->nsub = 0; -+ g->ncategories = 1; /* category 0 is "everything else" */ -+ g->categories = &g->catspace[-(CHAR_MIN)]; -+ (void) memset((char *)g->catspace, 0, NC*sizeof(cat_t)); -+ g->backrefs = 0; -+ -+ /* do it */ -+ EMIT(OEND, 0); -+ g->firststate = THERE(); -+ if (cflags®_EXTENDED) -+ p_ere(p, OUT); -+ else if (cflags®_NOSPEC) -+ p_str(p); -+ else -+ p_bre(p, OUT, OUT); -+ EMIT(OEND, 0); -+ g->laststate = THERE(); -+ -+ /* tidy up loose ends and fill things in */ -+ categorize(p, g); -+ stripsnug(p, g); -+ findmust(p, g); -+ g->nplus = pluscount(p, g); -+ g->magic = MAGIC2; -+ preg->re_nsub = g->nsub; -+ preg->re_g = g; -+ preg->re_magic = MAGIC1; -+#ifndef REDEBUG -+ /* not debugging, so can't rely on the assert() in llvm_regexec() */ -+ if (g->iflags®EX_BAD) -+ SETERROR(REG_ASSERT); -+#endif -+ -+ /* win or lose, we're done */ -+ if (p->error != 0) /* lose */ -+ llvm_regfree(preg); -+ return(p->error); -+} -+ -+/* -+ - p_ere - ERE parser top level, concatenation and alternation -+ */ -+static void -+p_ere(struct parse *p, int stop) /* character this ERE should end at */ -+{ -+ char c; -+ sopno prevback = 0; -+ sopno prevfwd = 0; -+ sopno conc; -+ int first = 1; /* is this the first alternative? */ -+ -+ for (;;) { -+ /* do a bunch of concatenated expressions */ -+ conc = HERE(); -+ while (MORE() && (c = PEEK()) != '|' && c != stop) -+ p_ere_exp(p); -+ REQUIRE(HERE() != conc, REG_EMPTY); /* require nonempty */ -+ -+ if (!EAT('|')) -+ break; /* NOTE BREAK OUT */ -+ -+ if (first) { -+ INSERT(OCH_, conc); /* offset is wrong */ -+ prevfwd = conc; -+ prevback = conc; -+ first = 0; -+ } -+ ASTERN(OOR1, prevback); -+ prevback = THERE(); -+ AHEAD(prevfwd); /* fix previous offset */ -+ prevfwd = HERE(); -+ EMIT(OOR2, 0); /* offset is very wrong */ -+ } -+ -+ if (!first) { /* tail-end fixups */ -+ AHEAD(prevfwd); -+ ASTERN(O_CH, prevback); -+ } -+ -+ assert(!MORE() || SEE(stop)); -+} -+ -+/* -+ - p_ere_exp - parse one subERE, an atom possibly followed by a repetition op -+ */ -+static void -+p_ere_exp(struct parse *p) -+{ -+ char c; -+ sopno pos; -+ int count; -+ int count2; -+ int backrefnum; -+ sopno subno; -+ int wascaret = 0; -+ -+ assert(MORE()); /* caller should have ensured this */ -+ c = GETNEXT(); -+ -+ pos = HERE(); -+ switch (c) { -+ case '(': -+ REQUIRE(MORE(), REG_EPAREN); -+ p->g->nsub++; -+ subno = p->g->nsub; -+ if (subno < NPAREN) -+ p->pbegin[subno] = HERE(); -+ EMIT(OLPAREN, subno); -+ if (!SEE(')')) -+ p_ere(p, ')'); -+ if (subno < NPAREN) { -+ p->pend[subno] = HERE(); -+ assert(p->pend[subno] != 0); -+ } -+ EMIT(ORPAREN, subno); -+ MUSTEAT(')', REG_EPAREN); -+ break; -+#ifndef POSIX_MISTAKE -+ case ')': /* happens only if no current unmatched ( */ -+ /* -+ * You may ask, why the ifndef? Because I didn't notice -+ * this until slightly too late for 1003.2, and none of the -+ * other 1003.2 regular-expression reviewers noticed it at -+ * all. So an unmatched ) is legal POSIX, at least until -+ * we can get it fixed. -+ */ -+ SETERROR(REG_EPAREN); -+ break; -+#endif -+ case '^': -+ EMIT(OBOL, 0); -+ p->g->iflags |= USEBOL; -+ p->g->nbol++; -+ wascaret = 1; -+ break; -+ case '$': -+ EMIT(OEOL, 0); -+ p->g->iflags |= USEEOL; -+ p->g->neol++; -+ break; -+ case '|': -+ SETERROR(REG_EMPTY); -+ break; -+ case '*': -+ case '+': -+ case '?': -+ SETERROR(REG_BADRPT); -+ break; -+ case '.': -+ if (p->g->cflags®_NEWLINE) -+ nonnewline(p); -+ else -+ EMIT(OANY, 0); -+ break; -+ case '[': -+ p_bracket(p); -+ break; -+ case '\\': -+ REQUIRE(MORE(), REG_EESCAPE); -+ c = GETNEXT(); -+ if (c >= '1' && c <= '9') { -+ /* \[0-9] is taken to be a back-reference to a previously specified -+ * matching group. backrefnum will hold the number. The matching -+ * group must exist (i.e. if \4 is found there must have been at -+ * least 4 matching groups specified in the pattern previously). -+ */ -+ backrefnum = c - '0'; -+ if (p->pend[backrefnum] == 0) { -+ SETERROR(REG_ESUBREG); -+ break; -+ } -+ -+ /* Make sure everything checks out and emit the sequence -+ * that marks a back-reference to the parse structure. -+ */ -+ assert(backrefnum <= p->g->nsub); -+ EMIT(OBACK_, backrefnum); -+ assert(p->pbegin[backrefnum] != 0); -+ assert(OP(p->strip[p->pbegin[backrefnum]]) != OLPAREN); -+ assert(OP(p->strip[p->pend[backrefnum]]) != ORPAREN); -+ (void) dupl(p, p->pbegin[backrefnum]+1, p->pend[backrefnum]); -+ EMIT(O_BACK, backrefnum); -+ p->g->backrefs = 1; -+ } else { -+ /* Other chars are simply themselves when escaped with a backslash. -+ */ -+ ordinary(p, c); -+ } -+ break; -+ case '{': /* okay as ordinary except if digit follows */ -+ REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); -+ /* FALLTHROUGH */ -+ default: -+ ordinary(p, c); -+ break; -+ } -+ -+ if (!MORE()) -+ return; -+ c = PEEK(); -+ /* we call { a repetition if followed by a digit */ -+ if (!( c == '*' || c == '+' || c == '?' || -+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) )) -+ return; /* no repetition, we're done */ -+ NEXT(); -+ -+ REQUIRE(!wascaret, REG_BADRPT); -+ switch (c) { -+ case '*': /* implemented as +? */ -+ /* this case does not require the (y|) trick, noKLUDGE */ -+ INSERT(OPLUS_, pos); -+ ASTERN(O_PLUS, pos); -+ INSERT(OQUEST_, pos); -+ ASTERN(O_QUEST, pos); -+ break; -+ case '+': -+ INSERT(OPLUS_, pos); -+ ASTERN(O_PLUS, pos); -+ break; -+ case '?': -+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ -+ INSERT(OCH_, pos); /* offset slightly wrong */ -+ ASTERN(OOR1, pos); /* this one's right */ -+ AHEAD(pos); /* fix the OCH_ */ -+ EMIT(OOR2, 0); /* offset very wrong... */ -+ AHEAD(THERE()); /* ...so fix it */ -+ ASTERN(O_CH, THERETHERE()); -+ break; -+ case '{': -+ count = p_count(p); -+ if (EAT(',')) { -+ if (isdigit((uch)PEEK())) { -+ count2 = p_count(p); -+ REQUIRE(count <= count2, REG_BADBR); -+ } else /* single number with comma */ -+ count2 = INFINITY; -+ } else /* just a single number */ -+ count2 = count; -+ repeat(p, pos, count, count2); -+ if (!EAT('}')) { /* error heuristics */ -+ while (MORE() && PEEK() != '}') -+ NEXT(); -+ REQUIRE(MORE(), REG_EBRACE); -+ SETERROR(REG_BADBR); -+ } -+ break; -+ } -+ -+ if (!MORE()) -+ return; -+ c = PEEK(); -+ if (!( c == '*' || c == '+' || c == '?' || -+ (c == '{' && MORE2() && isdigit((uch)PEEK2())) ) ) -+ return; -+ SETERROR(REG_BADRPT); -+} -+ -+/* -+ - p_str - string (no metacharacters) "parser" -+ */ -+static void -+p_str(struct parse *p) -+{ -+ REQUIRE(MORE(), REG_EMPTY); -+ while (MORE()) -+ ordinary(p, GETNEXT()); -+} -+ -+/* -+ - p_bre - BRE parser top level, anchoring and concatenation -+ * Giving end1 as OUT essentially eliminates the end1/end2 check. -+ * -+ * This implementation is a bit of a kludge, in that a trailing $ is first -+ * taken as an ordinary character and then revised to be an anchor. The -+ * only undesirable side effect is that '$' gets included as a character -+ * category in such cases. This is fairly harmless; not worth fixing. -+ * The amount of lookahead needed to avoid this kludge is excessive. -+ */ -+static void -+p_bre(struct parse *p, -+ int end1, /* first terminating character */ -+ int end2) /* second terminating character */ -+{ -+ sopno start = HERE(); -+ int first = 1; /* first subexpression? */ -+ int wasdollar = 0; -+ -+ if (EAT('^')) { -+ EMIT(OBOL, 0); -+ p->g->iflags |= USEBOL; -+ p->g->nbol++; -+ } -+ while (MORE() && !SEETWO(end1, end2)) { -+ wasdollar = p_simp_re(p, first); -+ first = 0; -+ } -+ if (wasdollar) { /* oops, that was a trailing anchor */ -+ DROP(1); -+ EMIT(OEOL, 0); -+ p->g->iflags |= USEEOL; -+ p->g->neol++; -+ } -+ -+ REQUIRE(HERE() != start, REG_EMPTY); /* require nonempty */ -+} -+ -+/* -+ - p_simp_re - parse a simple RE, an atom possibly followed by a repetition -+ */ -+static int /* was the simple RE an unbackslashed $? */ -+p_simp_re(struct parse *p, -+ int starordinary) /* is a leading * an ordinary character? */ -+{ -+ int c; -+ int count; -+ int count2; -+ sopno pos; -+ int i; -+ sopno subno; -+# define BACKSL (1<g->cflags®_NEWLINE) -+ nonnewline(p); -+ else -+ EMIT(OANY, 0); -+ break; -+ case '[': -+ p_bracket(p); -+ break; -+ case BACKSL|'{': -+ SETERROR(REG_BADRPT); -+ break; -+ case BACKSL|'(': -+ p->g->nsub++; -+ subno = p->g->nsub; -+ if (subno < NPAREN) -+ p->pbegin[subno] = HERE(); -+ EMIT(OLPAREN, subno); -+ /* the MORE here is an error heuristic */ -+ if (MORE() && !SEETWO('\\', ')')) -+ p_bre(p, '\\', ')'); -+ if (subno < NPAREN) { -+ p->pend[subno] = HERE(); -+ assert(p->pend[subno] != 0); -+ } -+ EMIT(ORPAREN, subno); -+ REQUIRE(EATTWO('\\', ')'), REG_EPAREN); -+ break; -+ case BACKSL|')': /* should not get here -- must be user */ -+ case BACKSL|'}': -+ SETERROR(REG_EPAREN); -+ break; -+ case BACKSL|'1': -+ case BACKSL|'2': -+ case BACKSL|'3': -+ case BACKSL|'4': -+ case BACKSL|'5': -+ case BACKSL|'6': -+ case BACKSL|'7': -+ case BACKSL|'8': -+ case BACKSL|'9': -+ i = (c&~BACKSL) - '0'; -+ assert(i < NPAREN); -+ if (p->pend[i] != 0) { -+ assert(i <= p->g->nsub); -+ EMIT(OBACK_, i); -+ assert(p->pbegin[i] != 0); -+ assert(OP(p->strip[p->pbegin[i]]) == OLPAREN); -+ assert(OP(p->strip[p->pend[i]]) == ORPAREN); -+ (void) dupl(p, p->pbegin[i]+1, p->pend[i]); -+ EMIT(O_BACK, i); -+ } else -+ SETERROR(REG_ESUBREG); -+ p->g->backrefs = 1; -+ break; -+ case '*': -+ REQUIRE(starordinary, REG_BADRPT); -+ /* FALLTHROUGH */ -+ default: -+ ordinary(p, (char)c); -+ break; -+ } -+ -+ if (EAT('*')) { /* implemented as +? */ -+ /* this case does not require the (y|) trick, noKLUDGE */ -+ INSERT(OPLUS_, pos); -+ ASTERN(O_PLUS, pos); -+ INSERT(OQUEST_, pos); -+ ASTERN(O_QUEST, pos); -+ } else if (EATTWO('\\', '{')) { -+ count = p_count(p); -+ if (EAT(',')) { -+ if (MORE() && isdigit((uch)PEEK())) { -+ count2 = p_count(p); -+ REQUIRE(count <= count2, REG_BADBR); -+ } else /* single number with comma */ -+ count2 = INFINITY; -+ } else /* just a single number */ -+ count2 = count; -+ repeat(p, pos, count, count2); -+ if (!EATTWO('\\', '}')) { /* error heuristics */ -+ while (MORE() && !SEETWO('\\', '}')) -+ NEXT(); -+ REQUIRE(MORE(), REG_EBRACE); -+ SETERROR(REG_BADBR); -+ } -+ } else if (c == '$') /* $ (but not \$) ends it */ -+ return(1); -+ -+ return(0); -+} -+ -+/* -+ - p_count - parse a repetition count -+ */ -+static int /* the value */ -+p_count(struct parse *p) -+{ -+ int count = 0; -+ int ndigits = 0; -+ -+ while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) { -+ count = count*10 + (GETNEXT() - '0'); -+ ndigits++; -+ } -+ -+ REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR); -+ return(count); -+} -+ -+/* -+ - p_bracket - parse a bracketed character list -+ * -+ * Note a significant property of this code: if the allocset() did SETERROR, -+ * no set operations are done. -+ */ -+static void -+p_bracket(struct parse *p) -+{ -+ cset *cs; -+ int invert = 0; -+ -+ /* Dept of Truly Sickening Special-Case Kludges */ -+ if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) { -+ EMIT(OBOW, 0); -+ NEXTn(6); -+ return; -+ } -+ if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) { -+ EMIT(OEOW, 0); -+ NEXTn(6); -+ return; -+ } -+ -+ if ((cs = allocset(p)) == NULL) { -+ /* allocset did set error status in p */ -+ return; -+ } -+ -+ if (EAT('^')) -+ invert++; /* make note to invert set at end */ -+ if (EAT(']')) -+ CHadd(cs, ']'); -+ else if (EAT('-')) -+ CHadd(cs, '-'); -+ while (MORE() && PEEK() != ']' && !SEETWO('-', ']')) -+ p_b_term(p, cs); -+ if (EAT('-')) -+ CHadd(cs, '-'); -+ MUSTEAT(']', REG_EBRACK); -+ -+ if (p->error != 0) { /* don't mess things up further */ -+ freeset(p, cs); -+ return; -+ } -+ -+ if (p->g->cflags®_ICASE) { -+ int i; -+ int ci; -+ -+ for (i = p->g->csetsize - 1; i >= 0; i--) -+ if (CHIN(cs, i) && isalpha(i)) { -+ ci = othercase(i); -+ if (ci != i) -+ CHadd(cs, ci); -+ } -+ if (cs->multis != NULL) -+ mccase(p, cs); -+ } -+ if (invert) { -+ int i; -+ -+ for (i = p->g->csetsize - 1; i >= 0; i--) -+ if (CHIN(cs, i)) -+ CHsub(cs, i); -+ else -+ CHadd(cs, i); -+ if (p->g->cflags®_NEWLINE) -+ CHsub(cs, '\n'); -+ if (cs->multis != NULL) -+ mcinvert(p, cs); -+ } -+ -+ assert(cs->multis == NULL); /* xxx */ -+ -+ if (nch(p, cs) == 1) { /* optimize singleton sets */ -+ ordinary(p, firstch(p, cs)); -+ freeset(p, cs); -+ } else -+ EMIT(OANYOF, freezeset(p, cs)); -+} -+ -+/* -+ - p_b_term - parse one term of a bracketed character list -+ */ -+static void -+p_b_term(struct parse *p, cset *cs) -+{ -+ char c; -+ char start, finish; -+ int i; -+ -+ /* classify what we've got */ -+ switch ((MORE()) ? PEEK() : '\0') { -+ case '[': -+ c = (MORE2()) ? PEEK2() : '\0'; -+ break; -+ case '-': -+ SETERROR(REG_ERANGE); -+ return; /* NOTE RETURN */ -+ break; -+ default: -+ c = '\0'; -+ break; -+ } -+ -+ switch (c) { -+ case ':': /* character class */ -+ NEXT2(); -+ REQUIRE(MORE(), REG_EBRACK); -+ c = PEEK(); -+ REQUIRE(c != '-' && c != ']', REG_ECTYPE); -+ p_b_cclass(p, cs); -+ REQUIRE(MORE(), REG_EBRACK); -+ REQUIRE(EATTWO(':', ']'), REG_ECTYPE); -+ break; -+ case '=': /* equivalence class */ -+ NEXT2(); -+ REQUIRE(MORE(), REG_EBRACK); -+ c = PEEK(); -+ REQUIRE(c != '-' && c != ']', REG_ECOLLATE); -+ p_b_eclass(p, cs); -+ REQUIRE(MORE(), REG_EBRACK); -+ REQUIRE(EATTWO('=', ']'), REG_ECOLLATE); -+ break; -+ default: /* symbol, ordinary character, or range */ -+/* xxx revision needed for multichar stuff */ -+ start = p_b_symbol(p); -+ if (SEE('-') && MORE2() && PEEK2() != ']') { -+ /* range */ -+ NEXT(); -+ if (EAT('-')) -+ finish = '-'; -+ else -+ finish = p_b_symbol(p); -+ } else -+ finish = start; -+/* xxx what about signed chars here... */ -+ REQUIRE(start <= finish, REG_ERANGE); -+ for (i = start; i <= finish; i++) -+ CHadd(cs, i); -+ break; -+ } -+} -+ -+/* -+ - p_b_cclass - parse a character-class name and deal with it -+ */ -+static void -+p_b_cclass(struct parse *p, cset *cs) -+{ -+ char *sp = p->next; -+ struct cclass *cp; -+ size_t len; -+ const char *u; -+ char c; -+ -+ while (MORE() && isalpha((uch)PEEK())) -+ NEXT(); -+ len = p->next - sp; -+ for (cp = cclasses; cp->name != NULL; cp++) -+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') -+ break; -+ if (cp->name == NULL) { -+ /* oops, didn't find it */ -+ SETERROR(REG_ECTYPE); -+ return; -+ } -+ -+ u = cp->chars; -+ while ((c = *u++) != '\0') -+ CHadd(cs, c); -+ for (u = cp->multis; *u != '\0'; u += strlen(u) + 1) -+ MCadd(p, cs, u); -+} -+ -+/* -+ - p_b_eclass - parse an equivalence-class name and deal with it -+ * -+ * This implementation is incomplete. xxx -+ */ -+static void -+p_b_eclass(struct parse *p, cset *cs) -+{ -+ char c; -+ -+ c = p_b_coll_elem(p, '='); -+ CHadd(cs, c); -+} -+ -+/* -+ - p_b_symbol - parse a character or [..]ed multicharacter collating symbol -+ */ -+static char /* value of symbol */ -+p_b_symbol(struct parse *p) -+{ -+ char value; -+ -+ REQUIRE(MORE(), REG_EBRACK); -+ if (!EATTWO('[', '.')) -+ return(GETNEXT()); -+ -+ /* collating symbol */ -+ value = p_b_coll_elem(p, '.'); -+ REQUIRE(EATTWO('.', ']'), REG_ECOLLATE); -+ return(value); -+} -+ -+/* -+ - p_b_coll_elem - parse a collating-element name and look it up -+ */ -+static char /* value of collating element */ -+p_b_coll_elem(struct parse *p, -+ int endc) /* name ended by endc,']' */ -+{ -+ char *sp = p->next; -+ struct cname *cp; -+ int len; -+ -+ while (MORE() && !SEETWO(endc, ']')) -+ NEXT(); -+ if (!MORE()) { -+ SETERROR(REG_EBRACK); -+ return(0); -+ } -+ len = p->next - sp; -+ for (cp = cnames; cp->name != NULL; cp++) -+ if (strncmp(cp->name, sp, len) == 0 && cp->name[len] == '\0') -+ return(cp->code); /* known name */ -+ if (len == 1) -+ return(*sp); /* single character */ -+ SETERROR(REG_ECOLLATE); /* neither */ -+ return(0); -+} -+ -+/* -+ - othercase - return the case counterpart of an alphabetic -+ */ -+static char /* if no counterpart, return ch */ -+othercase(int ch) -+{ -+ ch = (uch)ch; -+ assert(isalpha(ch)); -+ if (isupper(ch)) -+ return ((uch)tolower(ch)); -+ else if (islower(ch)) -+ return ((uch)toupper(ch)); -+ else /* peculiar, but could happen */ -+ return(ch); -+} -+ -+/* -+ - bothcases - emit a dualcase version of a two-case character -+ * -+ * Boy, is this implementation ever a kludge... -+ */ -+static void -+bothcases(struct parse *p, int ch) -+{ -+ char *oldnext = p->next; -+ char *oldend = p->end; -+ char bracket[3]; -+ -+ ch = (uch)ch; -+ assert(othercase(ch) != ch); /* p_bracket() would recurse */ -+ p->next = bracket; -+ p->end = bracket+2; -+ bracket[0] = ch; -+ bracket[1] = ']'; -+ bracket[2] = '\0'; -+ p_bracket(p); -+ assert(p->next == bracket+2); -+ p->next = oldnext; -+ p->end = oldend; -+} -+ -+/* -+ - ordinary - emit an ordinary character -+ */ -+static void -+ordinary(struct parse *p, int ch) -+{ -+ cat_t *cap = p->g->categories; -+ -+ if ((p->g->cflags®_ICASE) && isalpha((uch)ch) && othercase(ch) != ch) -+ bothcases(p, ch); -+ else { -+ EMIT(OCHAR, (uch)ch); -+ if (cap[ch] == 0) -+ cap[ch] = p->g->ncategories++; -+ } -+} -+ -+/* -+ - nonnewline - emit REG_NEWLINE version of OANY -+ * -+ * Boy, is this implementation ever a kludge... -+ */ -+static void -+nonnewline(struct parse *p) -+{ -+ char *oldnext = p->next; -+ char *oldend = p->end; -+ char bracket[4]; -+ -+ p->next = bracket; -+ p->end = bracket+3; -+ bracket[0] = '^'; -+ bracket[1] = '\n'; -+ bracket[2] = ']'; -+ bracket[3] = '\0'; -+ p_bracket(p); -+ assert(p->next == bracket+3); -+ p->next = oldnext; -+ p->end = oldend; -+} -+ -+/* -+ - repeat - generate code for a bounded repetition, recursively if needed -+ */ -+static void -+repeat(struct parse *p, -+ sopno start, /* operand from here to end of strip */ -+ int from, /* repeated from this number */ -+ int to) /* to this number of times (maybe INFINITY) */ -+{ -+ sopno finish = HERE(); -+# define N 2 -+# define INF 3 -+# define REP(f, t) ((f)*8 + (t)) -+# define MAP(n) (((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N) -+ sopno copy; -+ -+ if (p->error != 0) /* head off possible runaway recursion */ -+ return; -+ -+ assert(from <= to); -+ -+ switch (REP(MAP(from), MAP(to))) { -+ case REP(0, 0): /* must be user doing this */ -+ DROP(finish-start); /* drop the operand */ -+ break; -+ case REP(0, 1): /* as x{1,1}? */ -+ case REP(0, N): /* as x{1,n}? */ -+ case REP(0, INF): /* as x{1,}? */ -+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ -+ INSERT(OCH_, start); /* offset is wrong... */ -+ repeat(p, start+1, 1, to); -+ ASTERN(OOR1, start); -+ AHEAD(start); /* ... fix it */ -+ EMIT(OOR2, 0); -+ AHEAD(THERE()); -+ ASTERN(O_CH, THERETHERE()); -+ break; -+ case REP(1, 1): /* trivial case */ -+ /* done */ -+ break; -+ case REP(1, N): /* as x?x{1,n-1} */ -+ /* KLUDGE: emit y? as (y|) until subtle bug gets fixed */ -+ INSERT(OCH_, start); -+ ASTERN(OOR1, start); -+ AHEAD(start); -+ EMIT(OOR2, 0); /* offset very wrong... */ -+ AHEAD(THERE()); /* ...so fix it */ -+ ASTERN(O_CH, THERETHERE()); -+ copy = dupl(p, start+1, finish+1); -+ assert(copy == finish+4); -+ repeat(p, copy, 1, to-1); -+ break; -+ case REP(1, INF): /* as x+ */ -+ INSERT(OPLUS_, start); -+ ASTERN(O_PLUS, start); -+ break; -+ case REP(N, N): /* as xx{m-1,n-1} */ -+ copy = dupl(p, start, finish); -+ repeat(p, copy, from-1, to-1); -+ break; -+ case REP(N, INF): /* as xx{n-1,INF} */ -+ copy = dupl(p, start, finish); -+ repeat(p, copy, from-1, to); -+ break; -+ default: /* "can't happen" */ -+ SETERROR(REG_ASSERT); /* just in case */ -+ break; -+ } -+} -+ -+/* -+ - seterr - set an error condition -+ */ -+static int /* useless but makes type checking happy */ -+seterr(struct parse *p, int e) -+{ -+ if (p->error == 0) /* keep earliest error condition */ -+ p->error = e; -+ p->next = nuls; /* try to bring things to a halt */ -+ p->end = nuls; -+ return(0); /* make the return value well-defined */ -+} -+ -+/* -+ - allocset - allocate a set of characters for [] -+ */ -+static cset * -+allocset(struct parse *p) -+{ -+ int no = p->g->ncsets++; -+ size_t nc; -+ size_t nbytes; -+ cset *cs; -+ size_t css = (size_t)p->g->csetsize; -+ int i; -+ -+ if (no >= p->ncsalloc) { /* need another column of space */ -+ void *ptr; -+ -+ p->ncsalloc += CHAR_BIT; -+ nc = p->ncsalloc; -+ if (nc > SIZE_MAX / sizeof(cset)) -+ goto nomem; -+ assert(nc % CHAR_BIT == 0); -+ nbytes = nc / CHAR_BIT * css; -+ -+ ptr = (cset *)realloc((char *)p->g->sets, nc * sizeof(cset)); -+ if (ptr == NULL) -+ goto nomem; -+ p->g->sets = ptr; -+ -+ ptr = (uch *)realloc((char *)p->g->setbits, nbytes); -+ if (ptr == NULL) -+ goto nomem; -+ p->g->setbits = ptr; -+ -+ for (i = 0; i < no; i++) -+ p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT); -+ -+ (void) memset((char *)p->g->setbits + (nbytes - css), 0, css); -+ } -+ /* XXX should not happen */ -+ if (p->g->sets == NULL || p->g->setbits == NULL) -+ goto nomem; -+ -+ cs = &p->g->sets[no]; -+ cs->ptr = p->g->setbits + css*((no)/CHAR_BIT); -+ cs->mask = 1 << ((no) % CHAR_BIT); -+ cs->hash = 0; -+ cs->smultis = 0; -+ cs->multis = NULL; -+ -+ return(cs); -+nomem: -+ free(p->g->sets); -+ p->g->sets = NULL; -+ free(p->g->setbits); -+ p->g->setbits = NULL; -+ -+ SETERROR(REG_ESPACE); -+ /* caller's responsibility not to do set ops */ -+ return(NULL); -+} -+ -+/* -+ - freeset - free a now-unused set -+ */ -+static void -+freeset(struct parse *p, cset *cs) -+{ -+ size_t i; -+ cset *top = &p->g->sets[p->g->ncsets]; -+ size_t css = (size_t)p->g->csetsize; -+ -+ for (i = 0; i < css; i++) -+ CHsub(cs, i); -+ if (cs == top-1) /* recover only the easy case */ -+ p->g->ncsets--; -+} -+ -+/* -+ - freezeset - final processing on a set of characters -+ * -+ * The main task here is merging identical sets. This is usually a waste -+ * of time (although the hash code minimizes the overhead), but can win -+ * big if REG_ICASE is being used. REG_ICASE, by the way, is why the hash -+ * is done using addition rather than xor -- all ASCII [aA] sets xor to -+ * the same value! -+ */ -+static int /* set number */ -+freezeset(struct parse *p, cset *cs) -+{ -+ uch h = cs->hash; -+ size_t i; -+ cset *top = &p->g->sets[p->g->ncsets]; -+ cset *cs2; -+ size_t css = (size_t)p->g->csetsize; -+ -+ /* look for an earlier one which is the same */ -+ for (cs2 = &p->g->sets[0]; cs2 < top; cs2++) -+ if (cs2->hash == h && cs2 != cs) { -+ /* maybe */ -+ for (i = 0; i < css; i++) -+ if (!!CHIN(cs2, i) != !!CHIN(cs, i)) -+ break; /* no */ -+ if (i == css) -+ break; /* yes */ -+ } -+ -+ if (cs2 < top) { /* found one */ -+ freeset(p, cs); -+ cs = cs2; -+ } -+ -+ return((int)(cs - p->g->sets)); -+} -+ -+/* -+ - firstch - return first character in a set (which must have at least one) -+ */ -+static int /* character; there is no "none" value */ -+firstch(struct parse *p, cset *cs) -+{ -+ size_t i; -+ size_t css = (size_t)p->g->csetsize; -+ -+ for (i = 0; i < css; i++) -+ if (CHIN(cs, i)) -+ return((char)i); -+ assert(never); -+ return(0); /* arbitrary */ -+} -+ -+/* -+ - nch - number of characters in a set -+ */ -+static int -+nch(struct parse *p, cset *cs) -+{ -+ size_t i; -+ size_t css = (size_t)p->g->csetsize; -+ int n = 0; -+ -+ for (i = 0; i < css; i++) -+ if (CHIN(cs, i)) -+ n++; -+ return(n); -+} -+ -+/* -+ - mcadd - add a collating element to a cset -+ */ -+static void -+mcadd( struct parse *p, cset *cs, const char *cp) -+{ -+ size_t oldend = cs->smultis; -+ void *np; -+ -+ cs->smultis += strlen(cp) + 1; -+ np = realloc(cs->multis, cs->smultis); -+ if (np == NULL) { -+ if (cs->multis) -+ free(cs->multis); -+ cs->multis = NULL; -+ SETERROR(REG_ESPACE); -+ return; -+ } -+ cs->multis = np; -+ -+ llvm_strlcpy(cs->multis + oldend - 1, cp, cs->smultis - oldend + 1); -+} -+ -+/* -+ - mcinvert - invert the list of collating elements in a cset -+ * -+ * This would have to know the set of possibilities. Implementation -+ * is deferred. -+ */ -+/* ARGSUSED */ -+static void -+mcinvert(struct parse *p, cset *cs) -+{ -+ assert(cs->multis == NULL); /* xxx */ -+} -+ -+/* -+ - mccase - add case counterparts of the list of collating elements in a cset -+ * -+ * This would have to know the set of possibilities. Implementation -+ * is deferred. -+ */ -+/* ARGSUSED */ -+static void -+mccase(struct parse *p, cset *cs) -+{ -+ assert(cs->multis == NULL); /* xxx */ -+} -+ -+/* -+ - isinsets - is this character in any sets? -+ */ -+static int /* predicate */ -+isinsets(struct re_guts *g, int c) -+{ -+ uch *col; -+ int i; -+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; -+ unsigned uc = (uch)c; -+ -+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) -+ if (col[uc] != 0) -+ return(1); -+ return(0); -+} -+ -+/* -+ - samesets - are these two characters in exactly the same sets? -+ */ -+static int /* predicate */ -+samesets(struct re_guts *g, int c1, int c2) -+{ -+ uch *col; -+ int i; -+ int ncols = (g->ncsets+(CHAR_BIT-1)) / CHAR_BIT; -+ unsigned uc1 = (uch)c1; -+ unsigned uc2 = (uch)c2; -+ -+ for (i = 0, col = g->setbits; i < ncols; i++, col += g->csetsize) -+ if (col[uc1] != col[uc2]) -+ return(0); -+ return(1); -+} -+ -+/* -+ - categorize - sort out character categories -+ */ -+static void -+categorize(struct parse *p, struct re_guts *g) -+{ -+ cat_t *cats = g->categories; -+ int c; -+ int c2; -+ cat_t cat; -+ -+ /* avoid making error situations worse */ -+ if (p->error != 0) -+ return; -+ -+ for (c = CHAR_MIN; c <= CHAR_MAX; c++) -+ if (cats[c] == 0 && isinsets(g, c)) { -+ cat = g->ncategories++; -+ cats[c] = cat; -+ for (c2 = c+1; c2 <= CHAR_MAX; c2++) -+ if (cats[c2] == 0 && samesets(g, c, c2)) -+ cats[c2] = cat; -+ } -+} -+ -+/* -+ - dupl - emit a duplicate of a bunch of sops -+ */ -+static sopno /* start of duplicate */ -+dupl(struct parse *p, -+ sopno start, /* from here */ -+ sopno finish) /* to this less one */ -+{ -+ sopno ret = HERE(); -+ sopno len = finish - start; -+ -+ assert(finish >= start); -+ if (len == 0) -+ return(ret); -+ enlarge(p, p->ssize + len); /* this many unexpected additions */ -+ assert(p->ssize >= p->slen + len); -+ (void) memmove((char *)(p->strip + p->slen), -+ (char *)(p->strip + start), (size_t)len*sizeof(sop)); -+ p->slen += len; -+ return(ret); -+} -+ -+/* -+ - doemit - emit a strip operator -+ * -+ * It might seem better to implement this as a macro with a function as -+ * hard-case backup, but it's just too big and messy unless there are -+ * some changes to the data structures. Maybe later. -+ */ -+static void -+doemit(struct parse *p, sop op, size_t opnd) -+{ -+ /* avoid making error situations worse */ -+ if (p->error != 0) -+ return; -+ -+ /* deal with oversize operands ("can't happen", more or less) */ -+ assert(opnd < 1<slen >= p->ssize) -+ enlarge(p, (p->ssize+1) / 2 * 3); /* +50% */ -+ assert(p->slen < p->ssize); -+ -+ /* finally, it's all reduced to the easy case */ -+ p->strip[p->slen++] = SOP(op, opnd); -+} -+ -+/* -+ - doinsert - insert a sop into the strip -+ */ -+static void -+doinsert(struct parse *p, sop op, size_t opnd, sopno pos) -+{ -+ sopno sn; -+ sop s; -+ int i; -+ -+ /* avoid making error situations worse */ -+ if (p->error != 0) -+ return; -+ -+ sn = HERE(); -+ EMIT(op, opnd); /* do checks, ensure space */ -+ assert(HERE() == sn+1); -+ s = p->strip[sn]; -+ -+ /* adjust paren pointers */ -+ assert(pos > 0); -+ for (i = 1; i < NPAREN; i++) { -+ if (p->pbegin[i] >= pos) { -+ p->pbegin[i]++; -+ } -+ if (p->pend[i] >= pos) { -+ p->pend[i]++; -+ } -+ } -+ -+ memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos], -+ (HERE()-pos-1)*sizeof(sop)); -+ p->strip[pos] = s; -+} -+ -+/* -+ - dofwd - complete a forward reference -+ */ -+static void -+dofwd(struct parse *p, sopno pos, sop value) -+{ -+ /* avoid making error situations worse */ -+ if (p->error != 0) -+ return; -+ -+ assert(value < 1<strip[pos] = OP(p->strip[pos]) | value; -+} -+ -+/* -+ - enlarge - enlarge the strip -+ */ -+static void -+enlarge(struct parse *p, sopno size) -+{ -+ sop *sp; -+ -+ if (p->ssize >= size) -+ return; -+ -+ if ((uintptr_t)size > SIZE_MAX / sizeof(sop)) { -+ SETERROR(REG_ESPACE); -+ return; -+ } -+ -+ sp = (sop *)realloc(p->strip, size*sizeof(sop)); -+ if (sp == NULL) { -+ SETERROR(REG_ESPACE); -+ return; -+ } -+ p->strip = sp; -+ p->ssize = size; -+} -+ -+/* -+ - stripsnug - compact the strip -+ */ -+static void -+stripsnug(struct parse *p, struct re_guts *g) -+{ -+ g->nstates = p->slen; -+ if ((uintptr_t)p->slen > SIZE_MAX / sizeof(sop)) { -+ g->strip = p->strip; -+ SETERROR(REG_ESPACE); -+ return; -+ } -+ -+ g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop)); -+ if (g->strip == NULL) { -+ SETERROR(REG_ESPACE); -+ g->strip = p->strip; -+ } -+} -+ -+/* -+ - findmust - fill in must and mlen with longest mandatory literal string -+ * -+ * This algorithm could do fancy things like analyzing the operands of | -+ * for common subsequences. Someday. This code is simple and finds most -+ * of the interesting cases. -+ * -+ * Note that must and mlen got initialized during setup. -+ */ -+static void -+findmust(struct parse *p, struct re_guts *g) -+{ -+ sop *scan; -+ sop *start = 0; /* start initialized in the default case, after that */ -+ sop *newstart = 0; /* newstart was initialized in the OCHAR case */ -+ sopno newlen; -+ sop s; -+ char *cp; -+ sopno i; -+ -+ /* avoid making error situations worse */ -+ if (p->error != 0) -+ return; -+ -+ /* find the longest OCHAR sequence in strip */ -+ newlen = 0; -+ scan = g->strip + 1; -+ do { -+ s = *scan++; -+ switch (OP(s)) { -+ case OCHAR: /* sequence member */ -+ if (newlen == 0) /* new sequence */ -+ newstart = scan - 1; -+ newlen++; -+ break; -+ case OPLUS_: /* things that don't break one */ -+ case OLPAREN: -+ case ORPAREN: -+ break; -+ case OQUEST_: /* things that must be skipped */ -+ case OCH_: -+ scan--; -+ do { -+ scan += OPND(s); -+ s = *scan; -+ /* assert() interferes w debug printouts */ -+ if (OP(s) != O_QUEST && OP(s) != O_CH && -+ OP(s) != OOR2) { -+ g->iflags |= REGEX_BAD; -+ return; -+ } -+ } while (OP(s) != O_QUEST && OP(s) != O_CH); -+ /* fallthrough */ -+ default: /* things that break a sequence */ -+ if (newlen > g->mlen) { /* ends one */ -+ start = newstart; -+ g->mlen = newlen; -+ } -+ newlen = 0; -+ break; -+ } -+ } while (OP(s) != OEND); -+ -+ if (g->mlen == 0) /* there isn't one */ -+ return; -+ -+ /* turn it into a character string */ -+ g->must = malloc((size_t)g->mlen + 1); -+ if (g->must == NULL) { /* argh; just forget it */ -+ g->mlen = 0; -+ return; -+ } -+ cp = g->must; -+ scan = start; -+ for (i = g->mlen; i > 0; i--) { -+ while (OP(s = *scan++) != OCHAR) -+ continue; -+ assert(cp < g->must + g->mlen); -+ *cp++ = (char)OPND(s); -+ } -+ assert(cp == g->must + g->mlen); -+ *cp++ = '\0'; /* just on general principles */ -+} -+ -+/* -+ - pluscount - count + nesting -+ */ -+static sopno /* nesting depth */ -+pluscount(struct parse *p, struct re_guts *g) -+{ -+ sop *scan; -+ sop s; -+ sopno plusnest = 0; -+ sopno maxnest = 0; -+ -+ if (p->error != 0) -+ return(0); /* there may not be an OEND */ -+ -+ scan = g->strip + 1; -+ do { -+ s = *scan++; -+ switch (OP(s)) { -+ case OPLUS_: -+ plusnest++; -+ break; -+ case O_PLUS: -+ if (plusnest > maxnest) -+ maxnest = plusnest; -+ plusnest--; -+ break; -+ } -+ } while (OP(s) != OEND); -+ if (plusnest != 0) -+ g->iflags |= REGEX_BAD; -+ return(maxnest); -+} -Index: source/Utility/regerror.c -=================================================================== ---- /dev/null -+++ source/Utility/regerror.c -@@ -0,0 +1,135 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regerror.c 8.4 (Berkeley) 3/20/94 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "regex_impl.h" -+ -+#include "regutils.h" -+ -+#ifdef _MSC_VER -+#define snprintf _snprintf -+#endif -+ -+static const char *regatoi(const llvm_regex_t *, char *, int); -+ -+static struct rerr { -+ int code; -+ const char *name; -+ const char *explain; -+} rerrs[] = { -+ { REG_NOMATCH, "REG_NOMATCH", "llvm_regexec() failed to match" }, -+ { REG_BADPAT, "REG_BADPAT", "invalid regular expression" }, -+ { REG_ECOLLATE, "REG_ECOLLATE", "invalid collating element" }, -+ { REG_ECTYPE, "REG_ECTYPE", "invalid character class" }, -+ { REG_EESCAPE, "REG_EESCAPE", "trailing backslash (\\)" }, -+ { REG_ESUBREG, "REG_ESUBREG", "invalid backreference number" }, -+ { REG_EBRACK, "REG_EBRACK", "brackets ([ ]) not balanced" }, -+ { REG_EPAREN, "REG_EPAREN", "parentheses not balanced" }, -+ { REG_EBRACE, "REG_EBRACE", "braces not balanced" }, -+ { REG_BADBR, "REG_BADBR", "invalid repetition count(s)" }, -+ { REG_ERANGE, "REG_ERANGE", "invalid character range" }, -+ { REG_ESPACE, "REG_ESPACE", "out of memory" }, -+ { REG_BADRPT, "REG_BADRPT", "repetition-operator operand invalid" }, -+ { REG_EMPTY, "REG_EMPTY", "empty (sub)expression" }, -+ { REG_ASSERT, "REG_ASSERT", "\"can't happen\" -- you found a bug" }, -+ { REG_INVARG, "REG_INVARG", "invalid argument to regex routine" }, -+ { 0, "", "*** unknown regexp error code ***" } -+}; -+ -+/* -+ - llvm_regerror - the interface to error numbers -+ = extern size_t llvm_regerror(int, const llvm_regex_t *, char *, size_t); -+ */ -+/* ARGSUSED */ -+size_t -+llvm_regerror(int errcode, const llvm_regex_t *preg, char *errbuf, size_t errbuf_size) -+{ -+ struct rerr *r; -+ size_t len; -+ int target = errcode &~ REG_ITOA; -+ const char *s; -+ char convbuf[50]; -+ -+ if (errcode == REG_ATOI) -+ s = regatoi(preg, convbuf, sizeof convbuf); -+ else { -+ for (r = rerrs; r->code != 0; r++) -+ if (r->code == target) -+ break; -+ -+ if (errcode®_ITOA) { -+ if (r->code != 0) { -+ assert(strlen(r->name) < sizeof(convbuf)); -+ (void) llvm_strlcpy(convbuf, r->name, sizeof convbuf); -+ } else -+ (void)snprintf(convbuf, sizeof convbuf, -+ "REG_0x%x", target); -+ s = convbuf; -+ } else -+ s = r->explain; -+ } -+ -+ len = strlen(s) + 1; -+ if (errbuf_size > 0) { -+ llvm_strlcpy(errbuf, s, errbuf_size); -+ } -+ -+ return(len); -+} -+ -+/* -+ - regatoi - internal routine to implement REG_ATOI -+ */ -+static const char * -+regatoi(const llvm_regex_t *preg, char *localbuf, int localbufsize) -+{ -+ struct rerr *r; -+ -+ for (r = rerrs; r->code != 0; r++) -+ if (strcmp(r->name, preg->re_endp) == 0) -+ break; -+ if (r->code == 0) -+ return("0"); -+ -+ (void)snprintf(localbuf, localbufsize, "%d", r->code); -+ return(localbuf); -+} -Index: source/Utility/regexec.c -=================================================================== ---- /dev/null -+++ source/Utility/regexec.c -@@ -0,0 +1,162 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regexec.c 8.3 (Berkeley) 3/20/94 -+ */ -+ -+/* -+ * the outer shell of llvm_regexec() -+ * -+ * This file includes engine.inc *twice*, after muchos fiddling with the -+ * macros that code uses. This lets the same code operate on two different -+ * representations for state sets. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "regex_impl.h" -+ -+#include "regutils.h" -+#include "regex2.h" -+ -+/* macros for manipulating states, small version */ -+/* FIXME: 'states' is assumed as 'long' on small version. */ -+#define states1 long /* for later use in llvm_regexec() decision */ -+#define states states1 -+#define CLEAR(v) ((v) = 0) -+#define SET0(v, n) ((v) &= ~((unsigned long)1 << (n))) -+#define SET1(v, n) ((v) |= (unsigned long)1 << (n)) -+#define ISSET(v, n) (((v) & ((unsigned long)1 << (n))) != 0) -+#define ASSIGN(d, s) ((d) = (s)) -+#define EQ(a, b) ((a) == (b)) -+#define STATEVARS long dummy /* dummy version */ -+#define STATESETUP(m, n) /* nothing */ -+#define STATETEARDOWN(m) /* nothing */ -+#define SETUP(v) ((v) = 0) -+#define onestate long -+#define INIT(o, n) ((o) = (unsigned long)1 << (n)) -+#define INC(o) ((o) = (unsigned long)(o) << 1) -+#define ISSTATEIN(v, o) (((v) & (o)) != 0) -+/* some abbreviations; note that some of these know variable names! */ -+/* do "if I'm here, I can also be there" etc without branches */ -+#define FWD(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) << (n)) -+#define BACK(dst, src, n) ((dst) |= ((unsigned long)(src)&(here)) >> (n)) -+#define ISSETBACK(v, n) (((v) & ((unsigned long)here >> (n))) != 0) -+/* function names */ -+#define SNAMES /* engine.inc looks after details */ -+ -+#include "regengine.inc" -+ -+/* now undo things */ -+#undef states -+#undef CLEAR -+#undef SET0 -+#undef SET1 -+#undef ISSET -+#undef ASSIGN -+#undef EQ -+#undef STATEVARS -+#undef STATESETUP -+#undef STATETEARDOWN -+#undef SETUP -+#undef onestate -+#undef INIT -+#undef INC -+#undef ISSTATEIN -+#undef FWD -+#undef BACK -+#undef ISSETBACK -+#undef SNAMES -+ -+/* macros for manipulating states, large version */ -+#define states char * -+#define CLEAR(v) memset(v, 0, m->g->nstates) -+#define SET0(v, n) ((v)[n] = 0) -+#define SET1(v, n) ((v)[n] = 1) -+#define ISSET(v, n) ((v)[n]) -+#define ASSIGN(d, s) memmove(d, s, m->g->nstates) -+#define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) -+#define STATEVARS long vn; char *space -+#define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ -+ if ((m)->space == NULL) return(REG_ESPACE); \ -+ (m)->vn = 0; } -+#define STATETEARDOWN(m) { free((m)->space); } -+#define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) -+#define onestate long -+#define INIT(o, n) ((o) = (n)) -+#define INC(o) ((o)++) -+#define ISSTATEIN(v, o) ((v)[o]) -+/* some abbreviations; note that some of these know variable names! */ -+/* do "if I'm here, I can also be there" etc without branches */ -+#define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) -+#define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) -+#define ISSETBACK(v, n) ((v)[here - (n)]) -+/* function names */ -+#define LNAMES /* flag */ -+ -+#include "regengine.inc" -+ -+/* -+ - llvm_regexec - interface for matching -+ * -+ * We put this here so we can exploit knowledge of the state representation -+ * when choosing which matcher to call. Also, by this point the matchers -+ * have been prototyped. -+ */ -+int /* 0 success, REG_NOMATCH failure */ -+llvm_regexec(const llvm_regex_t *preg, const char *string, size_t nmatch, -+ llvm_regmatch_t pmatch[], int eflags) -+{ -+ struct re_guts *g = preg->re_g; -+#ifdef REDEBUG -+# define GOODFLAGS(f) (f) -+#else -+# define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) -+#endif -+ -+ if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) -+ return(REG_BADPAT); -+ assert(!(g->iflags®EX_BAD)); -+ if (g->iflags®EX_BAD) /* backstop for no-debug case */ -+ return(REG_BADPAT); -+ eflags = GOODFLAGS(eflags); -+ -+ if (g->nstates <= (long)(CHAR_BIT*sizeof(states1)) && !(eflags®_LARGE)) -+ return(smatcher(g, string, nmatch, pmatch, eflags)); -+ else -+ return(lmatcher(g, string, nmatch, pmatch, eflags)); -+} -Index: source/Utility/regfree.c -=================================================================== ---- /dev/null -+++ source/Utility/regfree.c -@@ -0,0 +1,72 @@ -+/*- -+ * This code is derived from OpenBSD's libc/regex, original license follows: -+ * -+ * Copyright (c) 1992, 1993, 1994 Henry Spencer. -+ * Copyright (c) 1992, 1993, 1994 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * This code is derived from software contributed to Berkeley by -+ * Henry Spencer. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ * -+ * @(#)regfree.c 8.3 (Berkeley) 3/20/94 -+ */ -+ -+#include -+#include -+#include -+#include "regex_impl.h" -+ -+#include "regutils.h" -+#include "regex2.h" -+ -+/* -+ - llvm_regfree - free everything -+ */ -+void -+llvm_regfree(llvm_regex_t *preg) -+{ -+ struct re_guts *g; -+ -+ if (preg->re_magic != MAGIC1) /* oops */ -+ return; /* nice to complain, but hard */ -+ -+ g = preg->re_g; -+ if (g == NULL || g->magic != MAGIC2) /* oops again */ -+ return; -+ preg->re_magic = 0; /* mark it invalid */ -+ g->magic = 0; /* mark it invalid */ -+ -+ if (g->strip != NULL) -+ free((char *)g->strip); -+ if (g->sets != NULL) -+ free((char *)g->sets); -+ if (g->setbits != NULL) -+ free((char *)g->setbits); -+ if (g->must != NULL) -+ free(g->must); -+ free((char *)g); -+} -Index: source/Utility/regstrlcpy.c -=================================================================== ---- /dev/null -+++ source/Utility/regstrlcpy.c -@@ -0,0 +1,52 @@ -+/* -+ * This code is derived from OpenBSD's libc, original license follows: -+ * -+ * Copyright (c) 1998 Todd C. Miller -+ * -+ * Permission to use, copy, modify, and distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include -+#include -+ -+#include "regex_impl.h" -+/* -+ * Copy src to string dst of size siz. At most siz-1 characters -+ * will be copied. Always NUL terminates (unless siz == 0). -+ * Returns strlen(src); if retval >= siz, truncation occurred. -+ */ -+size_t -+llvm_strlcpy(char *dst, const char *src, size_t siz) -+{ -+ char *d = dst; -+ const char *s = src; -+ size_t n = siz; -+ -+ /* Copy as many bytes as will fit */ -+ if (n != 0) { -+ while (--n != 0) { -+ if ((*d++ = *s++) == '\0') -+ break; -+ } -+ } -+ -+ /* Not enough room in dst, add NUL and traverse rest of src */ -+ if (n == 0) { -+ if (siz != 0) -+ *d = '\0'; /* NUL-terminate dst */ -+ while (*s++) -+ ; -+ } -+ -+ return(s - src - 1); /* count does not include NUL */ -+} -Index: tools/lldb-mi/MIUtilParse.h -=================================================================== ---- tools/lldb-mi/MIUtilParse.h -+++ tools/lldb-mi/MIUtilParse.h -@@ -10,7 +10,7 @@ - #pragma once - - // Third party headers: --#include "../lib/Support/regex_impl.h" -+#include "../include/lldb/Utility/regex_impl.h" - - // In-house headers: - #include "MIUtilString.h" diff --git a/README.packaging b/README.packaging new file mode 100644 index 0000000..d50535a --- /dev/null +++ b/README.packaging @@ -0,0 +1,139 @@ +======== +OVERVIEW + +This package is a dummy package that always depends on the +version of corresponding LLVM packages that openSUSE +currently supports. This file documents the procedure for +updating the various LLVM components. + +There are three major update scenarios that will be addressed +here, patch-level updates to the current LLVM version, +patch-level updates to older LLVM versions, and major/minor +version updates. + +LLVM version numbers come in three levels. For version +X.Y.Z, changes to the X level are major updates, changes to +the Y level are minor updates, and changes to the Z level +are patch-level updates. Library .so numbers are based on +the major and minor version, for example libllvm.so.X.Y. +Patch-level updates do not update the version number of +libraries. For this reason, only changes to major and minor +version numbers get a new llvm package. + +There are up to three packages that need to be handled in a +given update. This package, the base "llvm" package, the +current "llvmX_Y" package (X and Y are the major and minor +version numbers, respectively), and the next "llvmX_Y" +package if the major or minor version has been changed. + +NOTE: This package should always have the same "License" +tag as the currently-supported version of the llvmX_Y +package. + +=========================================== +PATCH-LEVEL UPDATES TO CURRENT LLVM VERSION + +For patch level updates, this package (llvm) and the current +llvmX_Y package need to be updated. + +1. llvmX_Y package: + 1. Add the new sources to the package and delete the old + ones + 2. Update the "Version" tag in llvmX_Y.spec and + lldbX_Y.spec to match the new sources. + 3. Update the "_revsn" tag in llvmX_Y.spec and + lldbX_Y.spec to match the revision number of the + tag. This can be found on + http://lists.llvm.org/pipermail/llvm-branch-commits + and should have like "[llvm-tag]" and + "Creating release candidate final" in the subject + line. You want to find the one for the current LLVM + release. + 4. Update the "_relver" tag in llvmX_Y.spec to match + the "Version" tag. + 5. Confirm everything builds successfully and there are + no new rpmlint issues. +2. llvm package: + 1. Update the "Version" tag to match the new llvmX_Y + version. + +======================================== +PATCH-LEVEL UPDATES TO OLD LLVM VERSIONS + +For patch-level updates to versions of LLVM before the +current version, only the corresponding llvmX_Y package +needs to be updated. + +1. llvmX_Y package: + 1. Add the new sources to the package and delete the old + ones + 2. Update the "Version" tag in llvmX_Y.spec and + lldbX_Y.spec to match the new sources. + 3. Update the "_revsn" tag in llvmX_Y.spec and + lldbX_Y.spec to match the revision number of the + tag. This can be found on + http://lists.llvm.org/pipermail/llvm-branch-commits + and should have like "[llvm-tag]" and + "Creating release candidate final" in the subject + line. You want to find the one for the current LLVM + release. + 4. Update the "_relver" tag in llvmX_Y.spec to match + the "Version" tag. + 5. Confirm everything builds successfully and there are + no new rpmlint issues. + + +=============================== +MAJOR AND MINOR VERSION UPDATES + +For updates that change the major or minor version number, +this package (llvm) needs to be updated, a new llvmX_Y +package needs to be created, and the old llvmX_Y package +needs to be modified. + +1. New llvmX_Y package: + 1. Copy (do not link) the old llvmX_Y to the new + major/minor version number. + 2. Rename the .spec, .changes, and rpmlintrc files in the + new llvmX_Y package to the new major/minor version + number + 3. Rename the base llvm and lldb package in their + respective .spec files to match the new package name. + 4. Change the "_sonum" tag in llvmX_Y.spec and + lldbX_Y.spec to match the new major/minor versions. + It should be of the form "X" if if the "X" minor + version is 0 or "X_Y" if theminor version is greater + than 0. + 5. Change the "_minor" tag in llvmX_Y.spec to match + the new major/minor versions. It should be of the + form "X.Y". + 6. Update the "Version", "_revsn", and "_relver" tags + as described in PATCH-LEVEL UPDATES above. + 7. Confirm llvmX_Y.spec builds successfully and there are + no new rpmlint issues. + 8. Check whether the .so number of "libc++.so.W.V" has + changed. If so, change "_socxx" tag to match. + It should be of the form "W" if the "V" value is 0 + or "W_V" if the "V" value is greater than 0. + 9. Confirm everything builds successfully and there are + no new rpmlint issues. +2. Old llvmX_Y package: + 1. If the .so number of libc++.so.W.V has not changed, + remove the "%if" and %ifarch" tests around + %bcond_without/%bcond_with libcxx in llvmX_Y.spec + and make it always %bcond_with. If the .so numbers + have changed, these can be left-as-is. + 2. Remove the "%if" and %ifarch" tests around + %bcond_without/%bcond_with libomp in llvmX_Y.spec + and make it always %bcond_with. + 3. Change "%bcond_without pyclang" to + "%bcond_with pyclang" in llvmX_Y.spec. + 4. Change BuildRequires "llvm%{_sonum}-gold = %{version}" + to "llvm-gold" in lldbX_Y.spec. + 5. Confirm everything builds successfully and there are + no new rpmlint issues. +3. llvm package: + 1. update the "Version" tag to match the new llvmX_Y + version. + 2. Change the "_sonum" tag to match the one in the + new "llvmX_Y.spec" and "lldbX_Y.spec" files. diff --git a/_constraints b/_constraints deleted file mode 100644 index 13a8856..0000000 --- a/_constraints +++ /dev/null @@ -1,32 +0,0 @@ - - - - - 20 - - - 4000 - - - - - armv6l - armv7l - - - - 768 - - - - - - ppc64le - - - - 4096 - - - - diff --git a/arm_suse_support.diff b/arm_suse_support.diff deleted file mode 100644 index 3ff24f5..0000000 --- a/arm_suse_support.diff +++ /dev/null @@ -1,24 +0,0 @@ -Index: cfe-3.8.1.src/lib/Driver/ToolChains.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Driver/ToolChains.cpp.orig -+++ cfe-3.8.1.src/lib/Driver/ToolChains.cpp -@@ -1418,7 +1418,7 @@ bool Generic_GCC::GCCInstallationDetecto - static const char *const AArch64LibDirs[] = {"/lib64", "/lib"}; - static const char *const AArch64Triples[] = { - "aarch64-none-linux-gnu", "aarch64-linux-gnu", "aarch64-linux-android", -- "aarch64-redhat-linux"}; -+ "aarch64-redhat-linux", "aarch64-suse-linux"}; - static const char *const AArch64beLibDirs[] = {"/lib"}; - static const char *const AArch64beTriples[] = {"aarch64_be-none-linux-gnu", - "aarch64_be-linux-gnu"}; -@@ -1427,7 +1427,9 @@ bool Generic_GCC::GCCInstallationDetecto - static const char *const ARMTriples[] = {"arm-linux-gnueabi", - "arm-linux-androideabi"}; - static const char *const ARMHFTriples[] = {"arm-linux-gnueabihf", -- "armv7hl-redhat-linux-gnueabi"}; -+ "armv7hl-redhat-linux-gnueabi", -+ "armv6hl-suse-linux-gnueabi", -+ "armv7hl-suse-linux-gnueabi"}; - static const char *const ARMebLibDirs[] = {"/lib"}; - static const char *const ARMebTriples[] = {"armeb-linux-gnueabi", - "armeb-linux-androideabi"}; diff --git a/assume-opensuse.patch b/assume-opensuse.patch deleted file mode 100644 index df4f67f..0000000 --- a/assume-opensuse.patch +++ /dev/null @@ -1,21 +0,0 @@ -Index: cfe-3.8.1.src/lib/Driver/ToolChains.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Driver/ToolChains.cpp.orig -+++ cfe-3.8.1.src/lib/Driver/ToolChains.cpp -@@ -3422,6 +3422,7 @@ static bool IsUbuntu(enum Distro Distro) - } - - static Distro DetectDistro(const Driver &D, llvm::Triple::ArchType Arch) { -+#if 0 - llvm::ErrorOr> File = - llvm::MemoryBuffer::getFile("/etc/lsb-release"); - if (File) { -@@ -3498,6 +3499,8 @@ static Distro DetectDistro(const Driver - return ArchLinux; - - return UnknownDistro; -+#endif -+ return OpenSUSE; - } - - /// \brief Get our best guess at the multiarch triple for a target. diff --git a/baselibs.conf b/baselibs.conf index 61b8de7..5df4764 100644 --- a/baselibs.conf +++ b/baselibs.conf @@ -1,4 +1,5 @@ -libLLVM3_8 -libclang3_8 llvm-devel +lldb-devel clang-devel +llvm-LTO-devel +llvm-gold diff --git a/cfe-3.8.1.src.tar.xz b/cfe-3.8.1.src.tar.xz deleted file mode 100644 index 6e8371d..0000000 --- a/cfe-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4cd3836dfb4b88b597e075341cae86d61c63ce3963e45c7fe6a8bf59bb382cdf -size 9605548 diff --git a/cfe-docs-3.8.1.src.tar.xz b/cfe-docs-3.8.1.src.tar.xz deleted file mode 100644 index dbf61fb..0000000 --- a/cfe-docs-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5656cc4d88e364f4d8ec30a16f051296a0ae10b15ce67e439b4c4caf3a6a9d2a -size 671716 diff --git a/clang-resourcedirs.patch b/clang-resourcedirs.patch deleted file mode 100644 index a1e642a..0000000 --- a/clang-resourcedirs.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: cfe-3.8.1.src/lib/Driver/Driver.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Driver/Driver.cpp -+++ cfe-3.8.1.src/lib/Driver/Driver.cpp -@@ -64,7 +64,7 @@ Driver::Driver(StringRef ClangExecutable - - // Compute the path to the resource directory. - StringRef ClangResourceDir(CLANG_RESOURCE_DIR); -- SmallString<128> P(Dir); -+ SmallString<128> P((Dir != "") ? Dir : "/usr/bin/"); - if (ClangResourceDir != "") { - llvm::sys::path::append(P, ClangResourceDir); - } else { diff --git a/clang-tools-extra-3.8.1.src.tar.xz b/clang-tools-extra-3.8.1.src.tar.xz deleted file mode 100644 index fcbcc33..0000000 --- a/clang-tools-extra-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:664a5c60220de9c290bf2a5b03d902ab731a4f95fe73a00856175ead494ec396 -size 334768 diff --git a/compiler-rt-3.8.1.src.tar.xz b/compiler-rt-3.8.1.src.tar.xz deleted file mode 100644 index d93c763..0000000 --- a/compiler-rt-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0df011dae14d8700499dfc961602ee0a9572fef926202ade5dcdfe7858411e5c -size 1263312 diff --git a/default-to-i586.patch b/default-to-i586.patch deleted file mode 100644 index fa4168d..0000000 --- a/default-to-i586.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: cfe-3.8.1.src/lib/Driver/Tools.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Driver/Tools.cpp.orig -+++ cfe-3.8.1.src/lib/Driver/Tools.cpp -@@ -1680,8 +1680,8 @@ static const char *getX86TargetCPU(const - case llvm::Triple::Bitrig: - return "i686"; - default: -- // Fallback to p4. -- return "pentium4"; -+ // Fallback to i586. -+ return "i586"; - } - } - diff --git a/glibc-2.23-libcxx.patch b/glibc-2.23-libcxx.patch deleted file mode 100644 index a4fd5d7..0000000 --- a/glibc-2.23-libcxx.patch +++ /dev/null @@ -1,59 +0,0 @@ -Index: libcxx-3.8.1.src/test/std/numerics/c.math/cmath_isinf.pass.cpp -=================================================================== ---- libcxx-3.8.1.src.orig/test/std/numerics/c.math/cmath_isinf.pass.cpp -+++ libcxx-3.8.1.src/test/std/numerics/c.math/cmath_isinf.pass.cpp -@@ -11,8 +11,6 @@ - - // isinf - --// XFAIL: linux -- - #include - #include - #include -@@ -27,4 +25,4 @@ int main() - static_assert((std::is_same::value), ""); - static_assert((std::is_same::value), ""); - assert(std::isinf(-1.0) == false); --} -\ No newline at end of file -+} -Index: libcxx-3.8.1.src/test/std/numerics/c.math/cmath_isnan.pass.cpp -=================================================================== ---- libcxx-3.8.1.src.orig/test/std/numerics/c.math/cmath_isnan.pass.cpp -+++ libcxx-3.8.1.src/test/std/numerics/c.math/cmath_isnan.pass.cpp -@@ -11,8 +11,6 @@ - - // isnan - --// XFAIL: linux -- - #include - #include - #include -Index: libcxx-3.8.1.src/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp -=================================================================== ---- libcxx-3.8.1.src.orig/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp -+++ libcxx-3.8.1.src/test/std/depr/depr.c.headers/math_h_isinf.pass.cpp -@@ -11,8 +11,6 @@ - - // isinf - --// XFAIL: linux -- - #include - #include - #include -Index: libcxx-3.8.1.src/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp -=================================================================== ---- libcxx-3.8.1.src.orig/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp -+++ libcxx-3.8.1.src/test/std/depr/depr.c.headers/math_h_isnan.pass.cpp -@@ -11,8 +11,6 @@ - - // isnan - --// XFAIL: linux -- - #include - #include - #include diff --git a/glibc-2.24-libcxx.patch b/glibc-2.24-libcxx.patch deleted file mode 100644 index 29f7a55..0000000 --- a/glibc-2.24-libcxx.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: libcxx-3.8.1.src/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp -=================================================================== ---- libcxx-3.8.1.src/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp.orig -+++ libcxx-3.8.1.src/test/std/localization/locale.categories/category.monetary/locale.moneypunct.byname/curr_symbol.pass.cpp -@@ -113,7 +113,7 @@ int main() - - { - Fnf f(LOCALE_ru_RU_UTF_8, 1); -- assert(f.curr_symbol() == " \xD1\x80\xD1\x83\xD0\xB1"); -+ assert(f.curr_symbol() == " \xD1\x80\xD1\x83\xD0\xB1" || f.curr_symbol() == " \u20bd"); - } - { - Fnt f(LOCALE_ru_RU_UTF_8, 1); -@@ -121,7 +121,7 @@ int main() - } - { - Fwf f(LOCALE_ru_RU_UTF_8, 1); -- assert(f.curr_symbol() == L" \x440\x443\x431"); -+ assert(f.curr_symbol() == L" \x440\x443\x431" || f.curr_symbol() == L" \u20bd"); - } - { - Fwt f(LOCALE_ru_RU_UTF_8, 1); diff --git a/libcxx-3.8.1.src.tar.xz b/libcxx-3.8.1.src.tar.xz deleted file mode 100644 index 958a2c3..0000000 --- a/libcxx-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:77d7f3784c88096d785bd705fa1bab7031ce184cd91ba8a7008abf55264eeecc -size 1074164 diff --git a/libcxxabi-3.8.1.src.tar.xz b/libcxxabi-3.8.1.src.tar.xz deleted file mode 100644 index 4376d08..0000000 --- a/libcxxabi-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e1b55f7be3fad746bdd3025f43e42d429fb6194aac5919c2be17c4a06314dae1 -size 508392 diff --git a/lldb-3.8.1.src.tar.xz b/lldb-3.8.1.src.tar.xz deleted file mode 100644 index dc67bfd..0000000 --- a/lldb-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:349148116a47e39dcb5d5042f10d8a6357d2c865034563283ca512f81cdce8a3 -size 10928220 diff --git a/lldb-add-pthread-dl-libs.patch b/lldb-add-pthread-dl-libs.patch deleted file mode 100644 index ba9f7d1..0000000 --- a/lldb-add-pthread-dl-libs.patch +++ /dev/null @@ -1,20 +0,0 @@ -Index: lldb-3.8.1.src/cmake/modules/LLDBConfig.cmake -=================================================================== ---- lldb-3.8.1.src.orig/cmake/modules/LLDBConfig.cmake -+++ lldb-3.8.1.src/cmake/modules/LLDBConfig.cmake -@@ -323,13 +323,9 @@ else() - - endif() - --if (HAVE_LIBPTHREAD) -- list(APPEND system_libs pthread) --endif(HAVE_LIBPTHREAD) -+list(APPEND system_libs pthread) - --if (HAVE_LIBDL) -- list(APPEND system_libs ${CMAKE_DL_LIBS}) --endif() -+list(APPEND system_libs ${CMAKE_DL_LIBS}) - - if(LLDB_REQUIRES_EH) - set(LLDB_REQUIRES_RTTI ON) diff --git a/lldb-cmake.patch b/lldb-cmake.patch deleted file mode 100644 index 54b765d..0000000 --- a/lldb-cmake.patch +++ /dev/null @@ -1,31 +0,0 @@ -Index: lldb-3.8.1.src/source/lldb.cpp -=================================================================== ---- lldb-3.8.1.src.orig/source/lldb.cpp -+++ lldb-3.8.1.src/source/lldb.cpp -@@ -21,11 +21,7 @@ extern "C" const unsigned char liblldb_c - static const char * - GetLLDBRevision() - { --#ifdef LLDB_REVISION - return LLDB_REVISION; --#else -- return NULL; --#endif - } - - static const char * -Index: lldb-3.8.1.src/source/Core/IOHandler.cpp -=================================================================== ---- lldb-3.8.1.src.orig/source/Core/IOHandler.cpp -+++ lldb-3.8.1.src/source/Core/IOHandler.cpp -@@ -9,8 +9,8 @@ - - // C Includes - #ifndef LLDB_DISABLE_CURSES --#include --#include -+#include -+#include - #endif - - // C++ Includes diff --git a/lldb.changes b/lldb.changes deleted file mode 100644 index f4a05be..0000000 --- a/lldb.changes +++ /dev/null @@ -1,129 +0,0 @@ -------------------------------------------------------------------- -Wed Sep 7 10:01:47 UTC 2016 - tchvatal@suse.com - -- Sort out with spec-cleaner - -------------------------------------------------------------------- -Thu Aug 31 20:36:58 UTC 2016 - toddrme2178@gmail.com - -- Update to llvm 3.8.1 - * See http://llvm.org/releases/3.8.1/docs/ReleaseNotes.html and - http://llvm.org/releases/3.8.1/tools/docs/ReleaseNotes.html -- Use versioned libLLVM (to libLLVM3_8) and libclang (to libclang3_8) -- Change versioning of liblldb3_8 to liblldb-3_8 and use a variable - to control the name instead of hard-coding it. -- Use bcond_with and bcond_without to enable/disable build options - instead of hard-coding them. -- Put buildrequires as requires in -devel packages to avoid linker errors - when building packages against the -devel packages. -- Add ffi support (disabled by default). -- Add oprofile support (disabled by default). -- Add valgrind support (disabled by default). -- Link cmake files to the normal cmake file directory to allow autodetection - of cmake interfaces. -- Remove unused lldb components from main spec file. -- Split llvm python bindings into own subpackage. -- Split emacs plugin into own subpackage -- Move additional vim plugins into vim plugins package -- Split libc++, libLTO, LLVMgold, libomp, clang-chekers into own subpackages -- Make python-clang, llvm-vim-plugins, and llvm-emacs-plugins noarch since - they aren't architecture-specific. -- Make packages besides llvm, llvm-clang, and the shared libraries conflict - with other versions. This will be important when multiple LLVM versions - are supported. -- Various spec file cleanups -- Rebase patches: - * arm_suse_support.diff - * assume-opensuse.patch - * clang-resourcedirs.patch - * default-to-i586.patch - * glibc-2.23-libcxx.patch - * glibc-2.24-libcxx.patch - * lldb-add-pthread-dl-libs.patch - * lldb-cmake.patch - * llvm-fix-find-gcc5-install.patch - * llvm-nonvoid-return.patch - * llvm-remove-clang-only-flags.patch - * revert-cmake-soname.patch - * set-revision.patch - -------------------------------------------------------------------- -Wed Aug 31 10:24:31 UTC 2016 - tchvatal@suse.com - -- Convert to use %cmake macros - -------------------------------------------------------------------- -Thu Aug 25 16:42:02 UTC 2016 - ronisbr@gmail.com - -- Add a symlink of liblldb file to %{python_sitearch}/_lldb.so. - Otherwise, `import lldb` will fail with the message: - - ImportError: No module named _lldb - -------------------------------------------------------------------- -Fri May 20 07:44:49 UTC 2016 - jengelh@inai.de - -- Set RPM group, drop marketing words from summary in lieu of - something useful. Implement shared library guideline. - -------------------------------------------------------------------- -Sun May 15 17:13:24 UTC 2016 - ronisbr@gmail.com - -- Update to version 3.8.0 - * No upstream changelog. -- Refresh `lldb-cmake.patch`. -- Add patch `D15067.id41365.diff` from upstream review system to - fix out of tree build (http://reviews.llvm.org/D15067). -- Add patch `lldb-add-pthread-dl-libs.patch` to force CMake to add - the options `-lpthread` and `-ldl` to the end of linking command. - Otherwise, LLDB linking will fail with these errors: - - undefined reference to symbol 'pthread_setname_np@@GLIBC_2.12' - undefined reference to symbol 'dladdr@@GLIBC_2.2.5' - -- Run spec-cleaner. -- Add `fdupes` to remove duplicated files. - -------------------------------------------------------------------- -Wed Sep 2 08:23:08 UTC 2015 - idonmez@suse.com - -- Update to version 3.7.0 - * No changelog upstream -- Refresh lldb-cmake.patch - -------------------------------------------------------------------- -Mon Jun 22 09:45:33 UTC 2015 - idonmez@suse.com - -- Update lldb-cmake.patch to fix compilation on Factory - -------------------------------------------------------------------- -Mon May 25 13:59:56 UTC 2015 - idonmez@suse.com - -- Update to version 3.6.1 - * No changelog upstream - -------------------------------------------------------------------- -Mon Mar 2 10:14:22 UTC 2015 - idonmez@suse.com - -- Update to version 3.6.0 - * No changelog upstream -- Merge lldb-underlink.patch into lldb-cmake.patch -- Swich to static library build, shared build is not supported - -------------------------------------------------------------------- -Wed Sep 17 13:26:34 UTC 2014 - idonmez@suse.com - -- Add BuildRequires on ncurses-devel - -------------------------------------------------------------------- -Sat Sep 6 14:59:58 UTC 2014 - idonmez@suse.com - -- Update to version 3.5.0 - * No changelog upstream -- Add lldb-underlink.patch to link to LLVMSupport - -------------------------------------------------------------------- -Mon Mar 17 09:02:51 UTC 2014 - idonmez@suse.com - -- First release on build.opensuse.org - diff --git a/lldb.spec b/lldb.spec deleted file mode 100644 index 8cd1f07..0000000 --- a/lldb.spec +++ /dev/null @@ -1,177 +0,0 @@ -# -# spec file for package lldb -# -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. -# -# All modifications and additions to the file contributed by third parties -# remain the property of their copyright owners, unless otherwise agreed -# upon. The license for this file, and modifications and additions to the -# file, is the same license as for the pristine package itself (unless the -# license for the pristine package is not an Open Source License, in which -# case the license is the MIT License). An "Open Source License" is a -# license that conforms to the Open Source Definition (Version 1.9) -# published by the Open Source Initiative. - -# Please submit bugfixes or comments via http://bugs.opensuse.org/ -# - - -%define _sonum 3_8 -%define _revsn 273405 -Name: lldb -Version: 3.8.1 -Release: 0 -Summary: Software debugger built using LLVM libraries -License: NCSA -Group: Development/Tools/Debuggers -Url: http://lldb.llvm.org -Source: http://llvm.org/releases/%{version}/lldb-%{version}.src.tar.xz -# PATCH-FIX-OPENSUSE lldb-cmake.patch -- Let us set LLDB_REVISION and fix ncurses include path. -Patch0: lldb-cmake.patch -# PATCH-FIX-UPSTREAM D15067.id41365.diff -- Patch from upstream review system to fix out of tree build (http://reviews.llvm.org/D15067) -Patch1: D15067.id41365.diff -# PATCH-FIX-OPENSUSE lldb-add-pthread-dl-libs.patch -- Add -lpthread and -ldl options to the end of LDFLAGS to fix linking problems. -Patch2: lldb-add-pthread-dl-libs.patch -BuildRequires: cmake -BuildRequires: fdupes -BuildRequires: llvm-gold -BuildRequires: ncurses-devel -BuildRequires: ninja -BuildRequires: pkgconfig -BuildRequires: swig -BuildRequires: cmake(Clang) = %{version} -BuildRequires: cmake(LLVM) = %{version} -BuildRequires: pkgconfig(libedit) -BuildRequires: pkgconfig(libffi) -BuildRequires: pkgconfig(libxml-2.0) -BuildRequires: pkgconfig(python2) -BuildRequires: pkgconfig(zlib) -# Avoid multiple provider errors -Requires: liblldb%{_sonum} = %{version} -Requires: python -Requires: python-six -ExclusiveArch: arm x86_64 - -%description -LLDB is a next generation, high-performance debugger. It is built as a set -of reusable components which highly leverage existing libraries in the -larger LLVM Project, such as the Clang expression parser and LLVM -disassembler. - -%package -n liblldb%{_sonum} -Summary: LLDB software debugger runtime library -Group: System/Libraries -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} = %{version} -Requires: libclang%{_sonum} = %{version} - -%description -n liblldb%{_sonum} -This subpackage contains the main LLDB component. - -%package devel -Summary: Development files for LLDB -Group: Development/Languages/Other -Requires: cmake -Requires: liblldb%{_sonum} = %{version} -Requires: ncurses-devel -Requires: swig -Requires: cmake(Clang) = %{version} -Requires: cmake(LLVM) = %{version} -Requires: pkgconfig(libedit) -Requires: pkgconfig(libffi) -Requires: pkgconfig(libxml-2.0) -Requires: pkgconfig(zlib) - -%description devel -This package contains the development files for LLDB. - -%package -n python-lldb -Summary: Python bindings for liblldb -Group: Development/Languages/Python -Requires: liblldb%{_sonum} = %{version} -Requires: python - -%description -n python-lldb -This package contains the Python bindings to clang (C language) frontend for LLVM. - -%prep -%setup -q -n %{name}-%{version}.src -%patch0 -p1 -%patch1 -%patch2 -p1 - -# Set LLDB revision -sed -i s,LLDB_REVISION,\"%{_revsn}\",g source/lldb.cpp #" - -%build -%define __builder ninja -%cmake \ - -DCMAKE_C_COMPILER=clang \ - -DCMAKE_CXX_COMPILER=clang++ \ - -DLLVM_LINK_LLVM_DYLIB:BOOL=ON \ - -DBUILD_SHARED_LIBS=OFF \ -%if "%{_lib}" == "lib64" - -DLLVM_LIBDIR_SUFFIX=64 \ -%endif - -DLLVM_RUNTIME_OUTPUT_INTDIR=$PWD/bin \ - -DLLVM_LIBRARY_OUTPUT_INTDIR=$PWD/%{_lib} \ - -DPYTHON_VERSION_MAJOR=%{py_major} \ - -DPYTHON_VERSION_MINOR=%{py_minor} -%make_jobs - -%install -%cmake_install - -# Python: fix binary libraries location. -rm %{buildroot}%{python_sitearch}/lldb/_lldb.so -liblldb=$(basename $(readlink -e %{buildroot}%{_libdir}/liblldb.so)) -ln -vsf "../../../${liblldb}" %{buildroot}%{python_sitearch}/lldb/_lldb.so -ln -vsf "../../${liblldb}" %{buildroot}%{python_sitearch}/_lldb.so - -# Remove bundled six.py. -rm -f %{buildroot}%{python_sitearch}/six.* - -# Remove static libraries. -rm %{buildroot}%{_libdir}/liblldb*.a - -# Fix duplicated files. -%fdupes %{_includedir}/%{name}/Host/ - -mkdir -p %{buildroot}%{_libdir}/cmake/lldb/ -cp cmake/modules/*.cmake %{buildroot}%{_libdir}/cmake/lldb/ - -# Make consistent with the rest of the executables -mv %{buildroot}%{_bindir}/lldb-argdumper %{buildroot}%{_bindir}/lldb-argdumper-%{version} -ln -s %{_bindir}/lldb-argdumper-%{version} %{buildroot}%{_bindir}/lldb-argdumper - -%post -n liblldb%{_sonum} -p /sbin/ldconfig -%postun -n liblldb%{_sonum} -p /sbin/ldconfig - -%files -%defattr(-,root,root,-) -%{_bindir}/lldb -%{_bindir}/lldb-argdumper -%{_bindir}/lldb-mi -%{_bindir}/lldb-server -%{_bindir}/lldb-%{version} -%{_bindir}/lldb-argdumper-%{version} -%{_bindir}/lldb-mi-%{version} -%{_bindir}/lldb-server-%{version} - -%files -n python-lldb -%defattr(-,root,root) -%{python_sitearch}/_lldb.so -%{python_sitearch}/lldb/ -%{python_sitearch}/readline.so - -%files -n liblldb%{_sonum} -%defattr(-,root,root) -%{_libdir}/liblldb.so.* - -%files devel -%defattr(-,root,root,-) -%{_libdir}/cmake/lldb/ -%{_includedir}/lldb/ -%{_libdir}/liblldb.so - -%changelog diff --git a/llvm-3.8.1.src.tar.xz b/llvm-3.8.1.src.tar.xz deleted file mode 100644 index ea82f9b..0000000 --- a/llvm-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6e82ce4adb54ff3afc18053d6981b6aed1406751b8742582ed50f04b5ab475f9 -size 16551472 diff --git a/llvm-docs-3.8.1.src.tar.xz b/llvm-docs-3.8.1.src.tar.xz deleted file mode 100644 index 1f91674..0000000 --- a/llvm-docs-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1d7d51c4bc0946e3392fe1c71c0afe1be6b120f4423a1c10f3b1210f10853119 -size 1664880 diff --git a/llvm-fix-find-gcc5-install.patch b/llvm-fix-find-gcc5-install.patch deleted file mode 100644 index 58779c2..0000000 --- a/llvm-fix-find-gcc5-install.patch +++ /dev/null @@ -1,14 +0,0 @@ -Index: cfe-3.8.1.src/lib/Driver/ToolChains.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Driver/ToolChains.cpp -+++ cfe-3.8.1.src/lib/Driver/ToolChains.cpp -@@ -1091,7 +1091,8 @@ Generic_GCC::GCCVersion Linux::GCCVersio - if (First.first.getAsInteger(10, GoodVersion.Major) || GoodVersion.Major < 0) - return BadVersion; - GoodVersion.MajorStr = First.first.str(); -- if (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0) -+ if (!Second.first.str().empty() && -+ (Second.first.getAsInteger(10, GoodVersion.Minor) || GoodVersion.Minor < 0)) - return BadVersion; - GoodVersion.MinorStr = Second.first.str(); - diff --git a/llvm-nonvoid-return.patch b/llvm-nonvoid-return.patch deleted file mode 100644 index 79ce43d..0000000 --- a/llvm-nonvoid-return.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: llvm-3.8.1.src/openmp-3.8.1.src/runtime/src/kmp_dispatch.cpp -=================================================================== ---- llvm-3.8.1.src.orig/openmp-3.8.1.src/runtime/src/kmp_dispatch.cpp -+++ llvm-3.8.1.src/openmp-3.8.1.src/runtime/src/kmp_dispatch.cpp -@@ -254,7 +254,7 @@ test_then_inc< kmp_int64 >( volatile kmp - // compare_and_swap template (general template should NOT be used) - template< typename T > - static __forceinline kmp_int32 --compare_and_swap( volatile T *p, T c, T s ) { KMP_ASSERT(0); }; -+compare_and_swap( volatile T *p, T c, T s ); - - template<> - __forceinline kmp_int32 diff --git a/llvm-remove-clang-only-flags.patch b/llvm-remove-clang-only-flags.patch deleted file mode 100644 index 2759173..0000000 --- a/llvm-remove-clang-only-flags.patch +++ /dev/null @@ -1,36 +0,0 @@ -Index: llvm-3.8.1.src/cmake/modules/HandleLLVMOptions.cmake -=================================================================== ---- llvm-3.8.1.src.orig/cmake/modules/HandleLLVMOptions.cmake -+++ llvm-3.8.1.src/cmake/modules/HandleLLVMOptions.cmake -@@ -417,7 +417,6 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE - - append_if(LLVM_ENABLE_PEDANTIC "-pedantic" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) - append_if(LLVM_ENABLE_PEDANTIC "-Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) -- add_flag_if_supported("-Wcovered-switch-default" COVERED_SWITCH_DEFAULT_FLAG) - append_if(USE_NO_UNINITIALIZED "-Wno-uninitialized" CMAKE_CXX_FLAGS) - append_if(USE_NO_MAYBE_UNINITIALIZED "-Wno-maybe-uninitialized" CMAKE_CXX_FLAGS) - -@@ -454,9 +453,6 @@ elseif( LLVM_COMPILER_IS_GCC_COMPATIBLE - endif() - endif (LLVM_ENABLE_WARNINGS) - append_if(LLVM_ENABLE_WERROR "-Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) -- if (NOT LLVM_ENABLE_TIMESTAMPS) -- add_flag_if_supported("-Werror=date-time" WERROR_DATE_TIME) -- endif () - if (LLVM_ENABLE_CXX1Y) - check_cxx_compiler_flag("-std=c++1y" CXX_SUPPORTS_CXX1Y) - append_if(CXX_SUPPORTS_CXX1Y "-std=c++1y" CMAKE_CXX_FLAGS) -@@ -578,13 +574,6 @@ add_llvm_definitions( -D__STDC_CONSTANT_ - add_llvm_definitions( -D__STDC_FORMAT_MACROS ) - add_llvm_definitions( -D__STDC_LIMIT_MACROS ) - --# clang doesn't print colored diagnostics when invoked from Ninja --if (UNIX AND -- CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND -- CMAKE_GENERATOR STREQUAL "Ninja") -- append("-fcolor-diagnostics" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) --endif() -- - # Add flags for add_dead_strip(). - # FIXME: With MSVS, consider compiling with /Gy and linking with /OPT:REF? - # But MinSizeRel seems to add that automatically, so maybe disable these diff --git a/llvm-rpmlintrc b/llvm-rpmlintrc deleted file mode 100644 index 5d34887..0000000 --- a/llvm-rpmlintrc +++ /dev/null @@ -1,9 +0,0 @@ -# This line is mandatory to access the configuration functions -from Config import * - -addFilter("devel-file-in-non-devel-package .*/clang/.*/include/.*") -addFilter("devel-file-in-non-devel-package .*/clang/.*/lib/.*") -addFilter("devel-file-in-non-devel-package .*/usr/include/.*") - -addFilter("devel-file-in-non-devel-package .*/lib.*/*.a") -addFilter("devel-file-in-non-devel-package .*/lib.*/*.so") diff --git a/llvm.changes b/llvm.changes index b9e08cd..b507518 100644 --- a/llvm.changes +++ b/llvm.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Fri Sep 9 18:26:41 UTC 2016 - toddrme2178@gmail.com + +- Split out llvm and lldb into a version-specific package. +- Turn this package into a wrapper around the version-specific + packages. + ------------------------------------------------------------------- Wed Sep 7 10:05:32 UTC 2016 - tchvatal@suse.com diff --git a/llvm.spec b/llvm.spec index aa83870..92f50c2 100644 --- a/llvm.spec +++ b/llvm.spec @@ -16,24 +16,7 @@ # -%define _relver 3.8.1 -%define _minor 3.8 %define _sonum 3_8 -%define _socxx 1 -%define _revsn 273405 -%ifarch x86_64 -%bcond_without libcxx -%else -%bcond_with libcxx -%endif -%ifarch ppc64 ppc64le %{ix86} x86_64 -%bcond_without openmp -%else -%bcond_with openmp -%endif -%bcond_with ffi -%bcond_with oprofile -%bcond_with valgrind Name: llvm Version: 3.8.1 Release: 0 @@ -41,64 +24,26 @@ Summary: Low Level Virtual Machine License: NCSA Group: Development/Languages/Other Url: http://www.llvm.org -Source0: http://llvm.org/releases/%{version}/llvm-%{version}.src.tar.xz -Source1: http://llvm.org/releases/%{version}/cfe-%{version}.src.tar.xz -Source2: http://llvm.org/releases/%{version}/clang-tools-extra-%{version}.src.tar.xz -Source3: http://llvm.org/releases/%{version}/compiler-rt-%{version}.src.tar.xz -Source4: http://llvm.org/releases/%{version}/libcxx-%{version}.src.tar.xz -Source5: http://llvm.org/releases/%{version}/libcxxabi-%{version}.src.tar.xz -Source6: http://llvm.org/releases/%{version}/openmp-%{version}.src.tar.xz -# Docs are created manually, see below -Source50: llvm-docs-%{version}.src.tar.xz -Source51: cfe-docs-%{version}.src.tar.xz -Source100: %{name}-rpmlintrc +# This file documents the process for updating llvm +Source0: README.packaging Source101: baselibs.conf -# PATCH-FIX-OPENSUSE set-revision.patch idoenmez@suse.de -- Allow us to set revision -Patch1: set-revision.patch -# PATCH-FIX-OPENSUSE assume-opensuse.patch idoenmez@suse.de -- Always enable openSUSE/SUSE features -Patch2: assume-opensuse.patch -# PATCH-FIX-OPENSUSE default-to-i586.patch -- Use i586 as default target for 32bit -Patch3: default-to-i586.patch -# PATCH-FIX-OPENSUSE arm_suse_support.diff --Enable ARM suse toolchain support -Patch4: arm_suse_support.diff -Patch5: clang-resourcedirs.patch -Patch6: llvm-remove-clang-only-flags.patch -Patch7: llvm-fix-find-gcc5-install.patch -Patch8: revert-cmake-soname.patch -Patch9: llvm-nonvoid-return.patch -Patch20: glibc-2.23-libcxx.patch -Patch21: glibc-2.24-libcxx.patch -BuildRequires: binutils-devel >= 2.21.90 -BuildRequires: bison -BuildRequires: cmake -BuildRequires: fdupes -BuildRequires: flex -BuildRequires: gcc -BuildRequires: gcc-c++ -BuildRequires: groff -BuildRequires: libstdc++-devel -BuildRequires: libtool -BuildRequires: ncurses-devel -BuildRequires: ninja -BuildRequires: pkgconfig -BuildRequires: procps -BuildRequires: python-base -BuildRequires: python-xml -BuildRequires: pkgconfig(libedit) -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} -BuildRoot: %{_tmppath}/%{name}-%{version}-build -# llvm does not work on ppc or s390 -ExcludeArch: ppc s390 -%if %{with ffi} -BuildRequires: pkgconfig(libffi) -%endif -%if %{with valgrind} -BuildRequires: pkgconfig(valgrind) -%endif -%if %{with oprofile} -BuildRequires: oprofile-devel +# Avoid multiple providers error +BuildRequires: clang%{_sonum} = %{version} +BuildRequires: clang%{_sonum}-checker = %{version} +BuildRequires: clang%{_sonum}-devel = %{version} +BuildRequires: emacs-nox +BuildRequires: llvm%{_sonum} = %{version} +BuildRequires: llvm%{_sonum}-LTO-devel = %{version} +BuildRequires: llvm%{_sonum}-devel = %{version} +BuildRequires: llvm%{_sonum}-emacs-plugins = %{version} +BuildRequires: llvm%{_sonum}-gold = %{version} +BuildRequires: llvm%{_sonum}-vim-plugins = %{version} +%ifarch arm x86_64 +BuildRequires: lldb%{_sonum} = %{version} +BuildRequires: lldb%{_sonum}-devel = %{version} +BuildRequires: python%{_sonum}-lldb = %{version} %endif +Requires: llvm%{_sonum} = %{version} %description LLVM is a compiler infrastructure designed for compile-time, @@ -108,93 +53,60 @@ arbitrary programming languages. The compiler infrastructure includes mirror sets of programming tools as well as libraries with equivalent functionality. -%package -n libLLVM%{_sonum} -Summary: Libraries for LLVM -Group: Development/Libraries/C and C++ +This package is a dummy package that depends on the version of +llvm that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. -%description -n libLLVM%{_sonum} -This package contains the shared libraries needed for LLVM. %package devel Summary: Header Files for LLVM Group: Development/Languages/Other -Requires: %{name} = %{version} -Requires: binutils-devel >= 2.21.90 -Requires: bison -Requires: flex -Requires: groff -Requires: libstdc++-devel -Requires: libtool -Requires: ncurses-devel -Requires: pkgconfig -Requires: pkgconfig(libedit) -Conflicts: otherproviders(cmake(LLVM)) -%if %{with ffi} -Requires: pkgconfig(libffi) -%endif -%if %{with valgrind} -Requires: pkgconfig(valgrind) -%endif -%if %{with oprofile} -Requires: oprofile-devel -%endif +Requires: llvm%{_sonum}-devel = %{version} %description devel This package contains library and header files needed to develop new native programs that use the LLVM infrastructure. +This package is a dummy package that depends on the version of +llvm-devel that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. + + %package -n clang Summary: CLANG frontend for LLVM Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libLTO%{_sonum} -Requires: libclang%{_sonum} -Recommends: LLVMgold.so()(64bit) -Recommends: scan-build -Recommends: scan-view -%if %{with openmp} -Recommends: libomp -%endif -%if %{with libcxx} -Requires: libc++%{_socxx} -Recommends: libc++-devel -%endif +Requires: clang%{_sonum} = %{version} Provides: llvm-clang = %{version} Obsoletes: llvm-clang < %{version} %description -n clang This package contains the clang (C language) frontend for LLVM. +This package is a dummy package that depends on the version of +clang that openSUSE currently supports. Packages that +don't require a specific Clang version should depend on this. + + %package -n clang-checker Summary: Static code analyzer for CLANG Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libclang%{_sonum} -Conflicts: otherproviders(scan-build) -Conflicts: otherproviders(scan-view) -Provides: scan-build -Provides: scan-view +Requires: clang%{_sonum}-checker = %{version} +Provides: llvm-clang-checker = %{version} +Obsoletes: llvm-clang-checker < %{version} %description -n clang-checker This package contains scan-build and scan-view, command line static code analyzers for CLANG. -%package -n libclang%{_sonum} -Summary: Library files needed for clang -Group: Development/Libraries/C and C++ -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} -Requires: libstdc++-devel +This package is a dummy package that depends on the version of +clang-checker that openSUSE currently supports. Packages that +don't require a specific Clang version should depend on this. -%description -n libclang%{_sonum} -This package contains the shared libraries needed for clang. %package -n clang-devel Summary: CLANG frontend for LLVM (devel package) Group: Development/Languages/Other -Requires: llvm-clang = %{version} -Requires: cmake(LLVM) = %{version} -Conflicts: otherproviders(cmake(Clang)) +Requires: clang%{_sonum}-devel = %{version} Provides: llvm-clang-devel = %{version} Obsoletes: llvm-clang-devel < %{version} @@ -202,517 +114,167 @@ Obsoletes: llvm-clang-devel < %{version} This package contains the clang (C language) frontend for LLVM. (development files) -%package -n libLTO%{_sonum} -Summary: Link-time optimizer for LLVM -Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} +This package is a dummy package that depends on the version of +clang-devel that openSUSE currently supports. Packages that +don't require a specific Clang version should depend on this. -%description -n libLTO%{_sonum} -This package contains the link-time optimizer for LLVM. %package LTO-devel Summary: Link-time optimizer for LLVM (devel package) Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libLTO%{_sonum} -Requires: cmake(LLVM) = %{version} -Conflicts: otherproviders(libLTO.so) -Provides: libLTO.so +Requires: llvm%{_sonum}-LTO-devel = %{version} %description LTO-devel This package contains the link-time optimizer for LLVM. (development files) +This package is a dummy package that depends on the version of +llvm-LTO-devel that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. + + %package gold Summary: Gold linker plugin for LLVM Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} -Requires: cmake(LLVM) = %{version} -Conflicts: otherproviders(LLVMgold.so()(64bit)) -Provides: LLVMgold.so()(64bit) +Requires: llvm%{_sonum}-gold = %{version} %description gold This package contains the Gold linker plugin for LLVM. -%package -n libomp -Summary: MPI plugin for LLVM -Group: Development/Languages/Other -# Avoid multiple provider errors -Requires: libLLVM%{_sonum} -Conflicts: otherproviders(libomp.so()(64bit)) -Provides: libomp.so()(64bit) +This package is a dummy package that depends on the version of +llvm-gold that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. -%description -n libomp -This package contains the OpenMP MPI plugin for LLVM. - -%package -n libc++%{_socxx} -Summary: C++ standard library implementation -Group: Development/Libraries/C and C++ - -%description -n libc++%{_socxx} -This package contains libc++, a new implementation of the C++ -standard library, targeting C++11. - -%package -n libc++-devel -Summary: C++ standard library implementation (devel package) -Group: Development/Languages/C and C++ -Conflicts: otherproviders(libc++.so) -Provides: libc++.so - -%description -n libc++-devel -This package contains libc++, a new implementation of the C++ -standard library, targeting C++11. (development files) - -%package -n libc++abi%{_socxx} -Summary: C++ standard library ABI -Group: Development/Libraries/C and C++ - -%description -n libc++abi%{_socxx} -This package contains the ABI for libc++, a new implementation -of the C++ standard library, targeting C++11. - -%package -n libc++abi-devel -Summary: C++ standard library ABI (devel package) -Group: Development/Languages/C and C++ -# Avoid multiple provider errors -Requires: libc++-devel -Conflicts: otherproviders(libc++abi.so) -Provides: libc++abi.so - -%description -n libc++abi-devel -This package contains the ABI for libc++, a new implementation -of the C++ standard library, targeting C++11. -(development files) %package vim-plugins Summary: Vim plugins for LLVM Group: Productivity/Text/Editors -Requires: vim -Conflicts: otherproviders(vim-plugin-llvm) -Provides: vim-plugin-llvm +Requires: llvm%{_sonum}-vim-plugins = %{version} BuildArch: noarch %description vim-plugins This package contains vim plugins for LLVM like syntax highlighting. +This package is a dummy package that depends on the version of +llvm-vim-plugins that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. + + %package emacs-plugins Summary: Emacs plugins for LLVM Group: Productivity/Text/Editors -Requires: emacs -Conflicts: otherproviders(emacs-llvm) -Provides: emacs-llvm +Requires: llvm%{_sonum}-emacs-plugins = %{version} BuildArch: noarch %description emacs-plugins This package contains Emacs plugins for LLVM like syntax highlighting. -%package -n python-clang -Summary: Python 2 bindings for libclang -Group: Development/Languages/Python -Requires: %{name}-clang-devel = %{version} -Requires: python -BuildArch: noarch +This package is a dummy package that depends on the version of +llvm-emacs-plugins that openSUSE currently supports. Packages that +don't require a specific LLVM version should depend on this. + + +%package -n lldb +Summary: Software debugger built using LLVM libraries +Group: Development/Tools/Debuggers +Requires: lldb%{_sonum} = %{version} + +%description -n lldb +LLDB is a next generation, high-performance debugger. It is built as a set +of reusable components which highly leverage existing libraries in the +larger LLVM Project, such as the Clang expression parser and LLVM +disassembler. + +This package is a dummy package that depends on the version of +lldb that openSUSE currently supports. Packages that +don't require a specific LLDB version should depend on this. + + +%package -n lldb-devel +Summary: Development files for LLDB +Group: Development/Languages/Other +Requires: lldb%{_sonum}-devel = %{version} + +%description -n lldb-devel +This package contains the development files for LLDB. + +This package is a dummy package that depends on the version of +lldb-devel that openSUSE currently supports. Packages that +don't require a specific LLDB version should depend on this. + + +%package -n python-lldb +Summary: Python bindings for liblldb +Group: Development/Languages/Python +Requires: python%{_sonum}-lldb = %{version} + +%description -n python-lldb +This package contains the Python bindings to clang (C language) frontend for LLVM. + +This package is a dummy package that depends on the version of +python-lldb that openSUSE currently supports. Packages that +don't require a specific LLDB version should depend on this. -%description -n python-clang -This package contains the Python 2.x bindings to clang (C language) -frontend for LLVM. %prep -%setup -q -a 1 -a 2 -a 3 -a 4 -a 5 -a 6 -b 50 -a 51 -n llvm-%{version}.src -%patch1 -%patch2 -%patch3 -%patch4 -%patch5 -%patch6 -p1 -%patch7 -%patch8 -p1 -%patch9 -p1 -%if 0%{?suse_version} > 1320 -%patch20 -%patch21 -%endif - -# Move into right place -mv cfe-%{version}.src tools/clang -mv compiler-rt-%{version}.src projects/compiler-rt -mv clang-tools-extra-%{version}.src tools/clang/tools/extra - -%if %{with openmp} -mv openmp-%{version}.src projects/openmp -%endif - -%if %{with libcxx} -mv libcxx-%{version}.src projects/libcxx -mv libcxxabi-%{version}.src projects/libcxxabi - -rm projects/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname.pass.cpp -rm projects/libcxx/test/std/localization/locale.categories/category.time/locale.time.get.byname/get_monthname_wide.pass.cpp -%endif - -# We hardcode i586 -rm tools/clang/test/Driver/x86_features.c -rm tools/clang/test/Driver/nacl-direct.c - -sed -i s,SVN_REVISION,\"%{_revsn}\",g tools/clang/lib/Basic/Version.cpp -sed -i s,LLVM_REVISION,\"%{_revsn}\",g tools/clang/lib/Basic/Version.cpp - -# ARMv6 needs this exact host triple -%ifarch armv6hl -cat > autoconf/config.guess << EOF -#!/bin/sh -echo armv6hl-suse-linux-gnueabi -EOF -%endif +# Not needed %build -# Disable c/xx/flags as the clang fails to build with hardening right now -#flags="%%{optflags} -fno-strict-aliasing" -flags="-fno-strict-aliasing" -%ifarch armv6hl -flags+=" -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s -mfpu=vfp" -%endif -%ifarch armv7hl -flags+=" -mfloat-abi=hard -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16" -%endif -%ifarch %{ix86} x86_64 -TARGETS_TO_BUILD="all" -%else -TARGETS_TO_BUILD=host -%endif - -# do not eat all memory -ninjaproc="%{?jobs:%{jobs}}" -echo "Available memory:" -free -echo "System limits:" -ulimit -a -if test -n "$ninjaproc" -a "$ninjaproc" -gt 1 ; then - mem_per_process=1000 - max_mem=`LANG=C free -t -m | sed -n "s|^Mem: *\([0-9]*\).*$|\1|p"` - max_jobs="$(($max_mem / $mem_per_process))" - test "$ninjaproc" -gt "$max_jobs" && ninjaproc="$max_jobs" && echo "Warning: Reducing number of jobs to $max_jobs because of memory limits" - test "$ninjaproc" -le 0 && ninjaproc=1 && echo "Warning: Do not use the parallel build at all becuse of memory limits" -fi - -%define __builder ninja -%define __builddir stage1 -# -z,now is breaking now, it needs to be fixed -%cmake \ - -DCMAKE_C_FLAGS="$flags" \ - -DCMAKE_CXX_FLAGS="$flags" \ - -DLLVM_ENABLE_ASSERTIONS=OFF \ - -DLLVM_TARGETS_TO_BUILD=host \ - -DLLDB_DISABLE_PYTHON=ON \ - -DCMAKE_SKIP_RPATH:BOOL=OFF \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--as-needed" \ - -DCMAKE_MODULE_LINKER_FLAGS="-Wl,--as-needed" \ - -DCMAKE_SHARED_LINKER_FLAGS="-Wl,--as-needed" -ninja -v -j $ninjaproc -cd .. - -%define __builddir build -export CC=${PWD}/stage1/bin/clang -export CXX=${PWD}/stage1/bin/clang++ -# -z,now is breaking now, it needs to be fixed -%cmake \ - -DCMAKE_C_FLAGS="$flags" \ - -DCMAKE_CXX_FLAGS="$flags" \ - -DLLVM_REQUIRES_RTTI=ON \ - -DLLVM_ENABLE_TIMESTAMPS=OFF \ - -DLLVM_ENABLE_ASSERTIONS=OFF \ - -DLLVM_ENABLE_PIC=ON \ - -DLLVM_BINUTILS_INCDIR=%{_includedir} \ - -DLLVM_TARGETS_TO_BUILD=${TARGETS_TO_BUILD} \ -%if "%{_lib}" == "lib64" - -DLLVM_LIBDIR_SUFFIX=64 \ -%endif -%if %{with ffi} - -DLLVM_ENABLE_FFI=ON \ -%endif -%if %{with oprofile} - -DLLVM_USE_OPROFILE=ON \ -%endif - -DCMAKE_SKIP_RPATH:BOOL=OFF \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--as-needed" \ - -DCMAKE_MODULE_LINKER_FLAGS="-Wl,--as-needed" \ - -DCMAKE_SHARED_LINKER_FLAGS="-Wl,--as-needed" -ninja -v -j $ninjaproc +echo "This is a dummy package to provide a dependency on the system compiler." > README %install -%cmake_install - -# Docs are prebuilt due to sphinx dependency -# -# pushd llvm-3.8.1.src/docs -# make -f Makefile.sphinx man html -# popd -# pushd cfe-3.8.1.src/docs -# make -f Makefile.sphinx man html -# popd -# tar cvJf llvm-docs-3.8.1.src.tar.xz llvm-3.8.1.src/docs/_build/{man,html} -# tar cvJf cfe-docs-3.8.1.src.tar.xz cfe-3.8.1.src/docs/_build/{man,html} - -# Build man/html pages -pushd docs -rm -rf %{buildroot}%{_prefix}/docs -mkdir -p %{buildroot}%{_docdir}/llvm/html -mkdir -p %{buildroot}%{_mandir}/man1 -cp -r _build/man/* %{buildroot}%{_mandir}/man1 -cp -r _build/html/* %{buildroot}%{_docdir}/llvm/html -popd - -pushd tools/clang/docs -mkdir -p %{buildroot}%{_docdir}/llvm-clang/html -cp -r _build/man/* %{buildroot}%{_mandir}/man1 -cp -r _build/html/* %{buildroot}%{_docdir}/llvm-clang/html -popd - -# install python bindings -# The python bindings use the unversioned libclang.so, -# so it doesn't make sense to have multiple versions of it -install -d %{buildroot}%{python_sitelib}/clang -pushd tools/clang/bindings/python -cp clang/*.py %{buildroot}%{python_sitelib}/clang -install -d %{buildroot}%{_docdir}/python-clang/examples/cindex -cp -r examples %{buildroot}%{_docdir}/python-clang -install -d %{buildroot}%{_docdir}/python-clang/tests/cindex/INPUTS -cp -r tests %{buildroot}%{_docdir}/python-clang -popd - -mkdir -p %{buildroot}%{_libdir}/bfd-plugins -ln -s %{_libdir}/LLVMgold.so %{buildroot}%{_libdir}/bfd-plugins/ - -install -m 755 -d %{buildroot}%{_datadir}/vim/site/ -for i in ftdetect ftplugin indent syntax; do - cp -r utils/vim/$i %{buildroot}%{_datadir}/vim/site/ -done -mv utils/vim/README utils/vim/README.vim - -mv %{buildroot}%{_prefix}/libexec/{c++,ccc}-analyzer %{buildroot}%{_bindir} -mv %{buildroot}%{_datadir}/clang/clang-format-diff.py %{buildroot}%{_bindir}/clang-format-diff -mv %{buildroot}%{_datadir}/clang/clang-tidy-diff.py %{buildroot}%{_bindir}/clang-tidy-diff -mv %{buildroot}%{_datadir}/clang/run-clang-tidy.py %{buildroot}%{_bindir}/run-clang-tidy -chmod -x %{buildroot}%{_mandir}/man1/scan-build.1 - -# Stuff we don't want to include -rm %{buildroot}%{_mandir}/man1/lit.1 - -# Put cmake files where they can be detected -mkdir -p %{buildroot}%{_libdir}/cmake/llvm/ -pushd %{buildroot}%{_datadir}/llvm/cmake/ -for f in * ; do -ln -s %{_datadir}/llvm/cmake/$f %{buildroot}%{_libdir}/cmake/llvm/$f -done -# This confuses the rpm cmake provides detection -rm %{buildroot}%{_libdir}/cmake/llvm/LLVM-Config.cmake - -mkdir -p %{buildroot}%{_libdir}/cmake/clang/ -pushd %{buildroot}%{_datadir}/clang/cmake/ -for f in * ; do -ln -s %{_datadir}/clang/cmake/$f %{buildroot}%{_libdir}/cmake/clang/$f -done - -%if %{with libcxx} -rm %{buildroot}%{_libdir}/libc++abi.a -%endif - -%if %{with openmp} -rm %{buildroot}%{_libdir}/libgomp.so -rm %{buildroot}%{_libdir}/libiomp*.so -%endif - -# We don't care about applescript or sublime text -rm %{buildroot}%{_datadir}/clang/*.applescript -rm %{buildroot}%{_datadir}/clang/clang-format-sublime.py - -%fdupes -s %{buildroot}%{_docdir}/%{name} -%fdupes -s %{buildroot}%{_docdir}/%{name}-doc - -%check -cd build -%ifnarch armv7hl armv7l -%if !0%{?qemu_user_space_build:1} -# we just do not have enough memory with qemu emulation - -ninja -v %{?_smp_mflags} check -ninja -v %{?_smp_mflags} clang-test - -%if %{with libcxx} -ninja -v %{?_smp_mflags} check-libcxx -ninja -v %{?_smp_mflags} check-libcxxabi -%endif - -%endif -%endif - -%post -n libLLVM%{_sonum} -p /sbin/ldconfig -%postun -n libLLVM%{_sonum} -p /sbin/ldconfig -%post -n libclang%{_sonum} -p /sbin/ldconfig -%postun -n libclang%{_sonum} -p /sbin/ldconfig -%post -n libLTO%{_sonum} -p /sbin/ldconfig -%postun -n libLTO%{_sonum} -p /sbin/ldconfig -%post gold -p /sbin/ldconfig -%postun gold -p /sbin/ldconfig -%post devel -p /sbin/ldconfig -%postun devel -p /sbin/ldconfig -%post -n clang-devel -p /sbin/ldconfig -%postun -n clang-devel -p /sbin/ldconfig -%post LTO-devel -p /sbin/ldconfig -%postun LTO-devel -p /sbin/ldconfig - -%if %{with openmp} -%post -n libomp -p /sbin/ldconfig -%postun -n libomp -p /sbin/ldconfig -%endif - -%if %{with libcxx} -%post -n libc++%{_socxx} -p /sbin/ldconfig -%postun -n libc++%{_socxx} -p /sbin/ldconfig -%post -n libc++abi%{_socxx} -p /sbin/ldconfig -%postun -n libc++abi%{_socxx} -p /sbin/ldconfig -%post -n libc++-devel -p /sbin/ldconfig -%postun -n libc++-devel -p /sbin/ldconfig -%post -n libc++abi-devel -p /sbin/ldconfig -%postun -n libc++abi-devel -p /sbin/ldconfig -%endif +# Not needed %files %defattr(-,root,root) -%{_bindir}/bugpoint -%{_bindir}/llc -%{_bindir}/lli -%{_bindir}/llvm-* -%{_bindir}/obj2yaml -%{_bindir}/opt -%{_bindir}/sancov -%{_bindir}/verify-uselistorder -%{_bindir}/yaml2obj -%{_mandir}/man1/FileCheck.1%{ext_man} -%{_mandir}/man1/bugpoint.1%{ext_man} -%{_mandir}/man1/llc.1%{ext_man} -%{_mandir}/man1/lli.1%{ext_man} -%{_mandir}/man1/llvm-*.1%{ext_man} -%{_mandir}/man1/opt.1%{ext_man} -%{_mandir}/man1/tblgen.1%{ext_man} -%exclude %{_bindir}/llvm-config -%exclude %{_mandir}/man1/llvm-config.1%{ext_man} +%doc README %files -n clang %defattr(-,root,root) -%{_bindir}/c-index-test -%{_bindir}/c++-analyzer -%{_bindir}/ccc-analyzer -%{_bindir}/clang -%{_bindir}/clang-* -%{_bindir}/clang++ -%{_bindir}/git-clang-format -%{_bindir}/modularize -%{_bindir}/run-clang-tidy -%{_mandir}/man1/clang.1%{ext_man} -%dir %{_libdir}/clang/ -%{_libdir}/clang/%{_relver}/ +%doc README %files -n clang-checker %defattr(-,root,root) -%{_bindir}/scan-build -%{_bindir}/scan-view -%{_datadir}/scan-build/ -%{_datadir}/scan-view/ -%{_mandir}/man1/scan-build.1%{ext_man} - -%files -n libLLVM%{_sonum} -%defattr(-,root,root,-) -%{_libdir}/libLLVM*.so.* - -%files -n libclang%{_sonum} -%defattr(-,root,root,-) -%{_libdir}/libclang*.so.* - -%files -n libLTO%{_sonum} -%defattr(-,root,root) -%{_libdir}/libLTO.so.* +%doc README %files gold %defattr(-,root,root) -%{_libdir}/LLVMgold.so -%dir %{_libdir}/bfd-plugins/ -%{_libdir}/bfd-plugins/LLVMgold.so - -%if %{with openmp} -%files -n libomp -%defattr(-,root,root) -%{_libdir}/libomp.so -%endif - -%if %{with libcxx} -%files -n libc++%{_socxx} -%defattr(-,root,root) -%{_libdir}/libc++.so.* - -%files -n libc++abi%{_socxx} -%defattr(-,root,root) -%{_libdir}/libc++abi.so.* - -%files -n libc++-devel -%defattr(-,root,root) -%{_libdir}/libc++.so -%{_libdir}/libc++abi.so -%{_includedir}/c++/ - -%files -n libc++abi-devel -%defattr(-,root,root) -%{_libdir}/libc++abi.so -%endif +%doc README %files devel %defattr(-,root,root,-) -%{_bindir}/llvm-config -%{_libdir}/libLLVM*.so -%{_libdir}/BugpointPasses.* -%{_libdir}/LLVMHello.* -%{_includedir}/llvm/ -%{_includedir}/llvm-c/ -%dir %{_datadir}/llvm/ -%{_datadir}/llvm/cmake -%{_libdir}/cmake/llvm -%{_docdir}/llvm/ -%{_mandir}/man1/llvm-config.1%{ext_man} +%doc README %files -n clang-devel %defattr(-,root,root) -%{_libdir}/libclang*.so -%{_includedir}/clang/ -%{_includedir}/clang-c/ -%dir %{_datadir}/clang/ -%{_datadir}/clang/cmake -%{_libdir}/cmake/clang -%{_docdir}/llvm-clang/ +%doc README %files LTO-devel %defattr(-,root,root) -%{_libdir}/libLTO.so +%doc README %files emacs-plugins %defattr(-,root,root,-) -%dir %{_datadir}/clang/ -%{_datadir}/clang/clang-format.el +%doc README %files vim-plugins %defattr(-,root,root,-) -%doc utils/vim/README.vim -%{_datadir}/vim/ -%dir %{_datadir}/clang/ -%{_datadir}/clang/clang-format.py +%doc README -%files -n python-clang +%ifarch arm x86_64 + +%files -n lldb %defattr(-,root,root) -%{python_sitelib}/clang/ -%{python_sitelib}/clang/__init__.py -%{python_sitelib}/clang/cindex.py -%{python_sitelib}/clang/enumerations.py -%{_docdir}/python-clang/ +%doc README + +%files -n lldb-devel +%defattr(-,root,root) +%doc README + +%files -n python-lldb +%defattr(-,root,root) +%doc README + +%endif %changelog diff --git a/openmp-3.8.1.src.tar.xz b/openmp-3.8.1.src.tar.xz deleted file mode 100644 index 3a11ae7..0000000 --- a/openmp-3.8.1.src.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:68fcde6ef34e0275884a2de3450a31e931caf1d6fda8606ef14f89c4123617dc -size 2009572 diff --git a/revert-cmake-soname.patch b/revert-cmake-soname.patch deleted file mode 100644 index 2049551..0000000 --- a/revert-cmake-soname.patch +++ /dev/null @@ -1,110 +0,0 @@ -Index: llvm-3.8.1.src/cmake/modules/AddLLVM.cmake -=================================================================== ---- llvm-3.8.1.src.orig/cmake/modules/AddLLVM.cmake -+++ llvm-3.8.1.src/cmake/modules/AddLLVM.cmake -@@ -326,12 +326,10 @@ endfunction(set_windows_version_resource - # Same semantics as target_link_libraries(). - # ADDITIONAL_HEADERS - # May specify header files for IDE generators. --# SONAME --# Should set SONAME link flags and create symlinks - # ) - function(llvm_add_library name) - cmake_parse_arguments(ARG -- "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB;SONAME" -+ "MODULE;SHARED;STATIC;OBJECT;DISABLE_LLVM_LINK_LLVM_DYLIB" - "OUTPUT_NAME" - "ADDITIONAL_HEADERS;DEPENDS;LINK_COMPONENTS;LINK_LIBS;OBJLIBS" - ${ARGN}) -@@ -436,6 +434,11 @@ function(llvm_add_library name) - PREFIX "" - ) - endif() -+ -+ set_target_properties(${name} -+ PROPERTIES -+ SOVERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR} -+ VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}) - endif() - - if(ARG_MODULE OR ARG_SHARED) -@@ -450,24 +453,6 @@ function(llvm_add_library name) - endif() - endif() - -- if(ARG_SHARED AND UNIX) -- if(NOT APPLE AND ARG_SONAME) -- get_target_property(output_name ${name} OUTPUT_NAME) -- if(${output_name} STREQUAL "output_name-NOTFOUND") -- set(output_name ${name}) -- endif() -- set(library_name ${output_name}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}${LLVM_VERSION_SUFFIX}) -- set(api_name ${output_name}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}${LLVM_VERSION_SUFFIX}) -- set_target_properties(${name} PROPERTIES OUTPUT_NAME ${library_name}) -- llvm_install_library_symlink(${api_name} ${library_name} SHARED -- COMPONENT ${name} -- ALWAYS_GENERATE) -- llvm_install_library_symlink(${output_name} ${library_name} SHARED -- COMPONENT ${name} -- ALWAYS_GENERATE) -- endif() -- endif() -- - if (DEFINED LLVM_LINK_COMPONENTS OR DEFINED ARG_LINK_COMPONENTS) - if (LLVM_LINK_LLVM_DYLIB AND NOT ARG_DISABLE_LLVM_LINK_LLVM_DYLIB) - set(llvm_libs LLVM) -@@ -1073,41 +1058,6 @@ function(add_lit_testsuites project dire - endif() - endfunction() - --function(llvm_install_library_symlink name dest type) -- cmake_parse_arguments(ARG "ALWAYS_GENERATE" "COMPONENT" "" ${ARGN}) -- foreach(path ${CMAKE_MODULE_PATH}) -- if(EXISTS ${path}/LLVMInstallSymlink.cmake) -- set(INSTALL_SYMLINK ${path}/LLVMInstallSymlink.cmake) -- break() -- endif() -- endforeach() -- -- set(component ${ARG_COMPONENT}) -- if(NOT component) -- set(component ${name}) -- endif() -- -- set(full_name ${CMAKE_${type}_LIBRARY_PREFIX}${name}${CMAKE_${type}_LIBRARY_SUFFIX}) -- set(full_dest ${CMAKE_${type}_LIBRARY_PREFIX}${dest}${CMAKE_${type}_LIBRARY_SUFFIX}) -- -- set(output_dir lib${LLVM_LIBDIR_SUFFIX}) -- if(WIN32 AND "${type}" STREQUAL "SHARED") -- set(output_dir bin) -- endif() -- -- install(SCRIPT ${INSTALL_SYMLINK} -- CODE "install_symlink(${full_name} ${full_dest} ${output_dir})" -- COMPONENT ${component}) -- -- if (NOT CMAKE_CONFIGURATION_TYPES AND NOT ARG_ALWAYS_GENERATE) -- add_custom_target(install-${name} -- DEPENDS ${name} ${dest} install-${dest} -- COMMAND "${CMAKE_COMMAND}" -- -DCMAKE_INSTALL_COMPONENT=${name} -- -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") -- endif() --endfunction() -- - function(llvm_install_symlink name dest) - cmake_parse_arguments(ARG "ALWAYS_GENERATE" "" "" ${ARGN}) - foreach(path ${CMAKE_MODULE_PATH}) -Index: llvm-3.8.1.src/tools/llvm-shlib/CMakeLists.txt -=================================================================== ---- llvm-3.8.1.src.orig/tools/llvm-shlib/CMakeLists.txt -+++ llvm-3.8.1.src/tools/llvm-shlib/CMakeLists.txt -@@ -38,7 +38,7 @@ if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) - add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE}) - endif() - --add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${SOURCES}) -+add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB ${SOURCES}) - - list(REMOVE_DUPLICATES LIB_NAMES) - if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") # FIXME: It should be "GNU ld for elf" diff --git a/set-revision.patch b/set-revision.patch deleted file mode 100644 index 1ddeee4..0000000 --- a/set-revision.patch +++ /dev/null @@ -1,24 +0,0 @@ -Index: cfe-3.8.1.src/lib/Basic/Version.cpp -=================================================================== ---- cfe-3.8.1.src/lib/Basic/Version.cpp.orig -+++ cfe-3.8.1.src/lib/Basic/Version.cpp -@@ -72,19 +72,11 @@ std::string getLLVMRepositoryPath() { - } - - std::string getClangRevision() { --#ifdef SVN_REVISION - return SVN_REVISION; --#else -- return ""; --#endif - } - - std::string getLLVMRevision() { --#ifdef LLVM_REVISION - return LLVM_REVISION; --#else -- return ""; --#endif - } - - std::string getClangFullRepositoryVersion() {