Advertisement
class101

Patches for http://goo.gl/miqX5L

Jan 20th, 2014
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 165.75 KB | None | 0 0
  1. Index: scripts/build/cc/100-gcc.sh
  2. --- scripts/build/cc/100-gcc.sh.orig    2014-01-21 02:35:40.807607900 +0100
  3. +++ scripts/build/cc/100-gcc.sh         2014-01-21 00:18:05.877908400 +0100
  4. @@ -233,7 +233,7 @@
  5.          CT_Pushd "${CT_HEADERS_DIR}/.."
  6.          sysroot_dirs=$(find . -mindepth 1 -maxdepth 1 -type d \( -name "lib*" -or -name "include" \) -exec basename {} \;)
  7.          for sysroot_dir in $sysroot_dirs; do
  8. -          CT_DoExecLog ALL cp -a "${sysroot_dir}" "${prefix}/${CT_TARGET}/${sysroot_dir}"
  9. +          CT_DoExecLog ALL cp -a "${sysroot_dir}" "${prefix}/${CT_TARGET}/"
  10.          done
  11.          CT_Popd
  12.      fi
  13. Index: config/libc/glibc.in
  14. --- config/libc/glibc.in.orig   2014-01-20 21:54:24.525859600 +0100
  15. +++ config/libc/glibc.in        2014-01-20 22:37:00.939587300 +0100
  16. @@ -4,7 +4,6 @@
  17.  ##
  18.  ## select LIBC_SUPPORT_NPTL
  19.  ## select CC_CORE_PASSES_NEEDED
  20. -## select GETTEXT_NEEDED
  21.  ##
  22.  ## help The de-facto standard for Linux distributions.
  23.  ## help Feature-rich, but large...  Most usefull for desktop-like systems.
  24. Index: scripts/build/libc/glibc-eglibc.sh-common
  25. --- scripts/build/libc/glibc-eglibc.sh-common.orig  2014-01-20 21:33:49.681905100 +0100
  26. +++ scripts/build/libc/glibc-eglibc.sh-common       2014-01-20 21:47:39.100613300 +0100
  27. @@ -403,19 +403,24 @@
  28.              # When installing headers on MinGW-w64, sunrpc needs gettext for building
  29.              # cross-rpcgen.
  30.              # used to parse the output of the C-preprocessor.
  31. -            extra_make_args+=( BUILD_CPPFLAGS="-I${CT_BUILDTOOLS_PREFIX_DIR}/include/" )
  32. -            extra_make_args+=( BUILD_LDFLAGS="-L${CT_BUILDTOOLS_PREFIX_DIR}/lib -Wl,-Bstatic -lintl -Wl,-Bdynamic" )
  33. +            extra_make_args+=( BUILD_CPPFLAGS="-I/mingw${CT_ARCH_BITNESS}/include -I/mingw${CT_ARCH_BITNESS}/${CT_REAL_BUILD}/include" )
  34. +            extra_make_args+=( BUILD_LDFLAGS="-L/mingw${CT_ARCH_BITNESS}/lib -Wl,-Bstatic -lintl -Wl,-Bdynamic" )
  35.              ;;
  36.          *darwin*)
  37.              # .. same goes for Darwin.
  38. -            extra_make_args+=( BUILD_CPPFLAGS="-I${CT_BUILDTOOLS_PREFIX_DIR}/include/" )
  39. -            extra_make_args+=( BUILD_LDFLAGS="-L${CT_BUILDTOOLS_PREFIX_DIR}/lib -lintl" )
  40. +            extra_make_args+=( BUILD_CPPFLAGS="-I/mingw${CT_ARCH_BITNESS}/include -I/mingw${CT_ARCH_BITNESS}/${CT_REAL_BUILD}/include" )
  41. +            extra_make_args+=( BUILD_LDFLAGS="-L/mingw${CT_ARCH_BITNESS}/lib -Wl,-Bstatic -lintl -Wl,-Bdynamic" )
  42.              ;;
  43.      esac
  44.  
  45.      if [ "${libc_headers}" = "y" ]; then
  46.          CT_DoLog EXTRA "Installing C library headers"
  47.  
  48. +        if [ "${CT_LIBC}" = "glibc" ]; then
  49. +             mkdir -p "${CT_HEADERS_DIR}/gnu"
  50. +            CT_DoExecLog ALL touch "${CT_HEADERS_DIR}/gnu/stubs.h"
  51. +        fi # Required by next make install-headers
  52. +
  53.          # use the 'install-headers' makefile target to install the
  54.          # headers
  55.          CT_DoExecLog ALL make ${JOBSFLAGS}                                        \
  56. @@ -429,8 +434,6 @@
  57.              # Two headers -- stubs.h and features.h -- aren't installed by install-headers,
  58.              # so do them by hand.  We can tolerate an empty stubs.h for the moment.
  59.              # See e.g. http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html
  60. -            mkdir -p "${CT_HEADERS_DIR}/gnu"
  61. -            CT_DoExecLog ALL touch "${CT_HEADERS_DIR}/gnu/stubs.h"
  62.              CT_DoExecLog ALL cp -v "${CT_SRC_DIR}/glibc-${CT_LIBC_VERSION}/include/features.h"  \
  63.                                     "${CT_HEADERS_DIR}/features.h"
  64. Index: config/companion_libs/cloog.in
  65. ===================================================================
  66. --- config/companion_libs/cloog.in  (revision 272)
  67. +++ config/companion_libs/cloog.in  (working copy)
  68. @@ -9,6 +9,11 @@
  69.  # Don't remove next line
  70.  # CT_INSERT_VERSION_BELOW
  71.  
  72. +config CLOOG_V_0_18_1
  73. +    bool
  74. +    prompt "0.18.1"
  75. +    select CLOOG_0_18_or_later
  76. +
  77.  config CLOOG_V_0_18_0
  78.      bool
  79.      prompt "0.18.0"
  80. @@ -52,6 +57,7 @@
  81.      string
  82.  # Don't remove next line
  83.  # CT_INSERT_VERSION_STRING_BELOW
  84. +    default "0.18.1" if CLOOG_V_0_18_1
  85.      default "0.18.0" if CLOOG_V_0_18_0
  86.      default "0.15.11" if CLOOG_V_0_15_11
  87.      default "0.15.10" if CLOOG_V_0_15_10
  88. Index: config/companion_libs/gmp.in
  89. ===================================================================
  90. --- config/companion_libs/gmp.in    (revision 272)
  91. +++ config/companion_libs/gmp.in    (working copy)
  92. @@ -6,6 +6,14 @@
  93.  # Don't remove next line
  94.  # CT_INSERT_VERSION_BELOW
  95.  
  96. +config GMP_V_5_1_3
  97. +    bool
  98. +    prompt "5.1.3"
  99. +
  100. +config GMP_V_5_1_2
  101. +    bool
  102. +    prompt "5.1.2"
  103. +
  104.  config GMP_V_5_1_1
  105.      bool
  106.      prompt "5.1.1"
  107. @@ -36,6 +44,8 @@
  108.      string
  109.  # Don't remove next line
  110.  # CT_INSERT_VERSION_STRING_BELOW
  111. +    default "5.1.3" if GMP_V_5_1_3
  112. +    default "5.1.2" if GMP_V_5_1_2
  113.      default "5.1.1" if GMP_V_5_1_1
  114.      default "5.0.2" if GMP_V_5_0_2
  115.      default "5.0.1" if GMP_V_5_0_1
  116. Index: config/debug/gdb.in
  117. ===================================================================
  118. --- config/debug/gdb.in (revision 272)
  119. +++ config/debug/gdb.in (working copy)
  120. @@ -34,6 +34,12 @@
  121.  # CT_INSERT_VERSION_BELOW
  122.  
  123.  
  124. +config GDB_V_7_6_2
  125. +    bool
  126. +    prompt "7.6.2"
  127. +    select GDB_7_0_or_later
  128. +    select GDB_7_2_or_later
  129. +
  130.  config GDB_V_7_6_1
  131.      bool
  132.      prompt "7.6.1"
  133. @@ -157,6 +163,7 @@
  134.      string
  135.  # Don't remove next line
  136.  # CT_INSERT_VERSION_STRING_BELOW
  137. +    default "7.6.2" if GDB_V_7_6_2
  138.      default "7.6.1" if GDB_V_7_6_1
  139.      default "linaro-7.6-2013.05" if GDB_V_linaro_7_6_2013_05
  140.      default "7.5.1" if GDB_V_7_5_1
  141. Index: config/kernel/linux.in
  142. ===================================================================
  143. --- config/kernel/linux.in  (revision 272)
  144. +++ config/kernel/linux.in  (working copy)
  145. @@ -26,6 +26,10 @@
  146.  # Don't remove next line
  147.  # CT_INSERT_VERSION_BELOW
  148.  
  149. +config KERNEL_V_3_12_8
  150. +    bool
  151. +    prompt "3.12.8"
  152. +
  153.  config KERNEL_V_3_12
  154.      bool
  155.      prompt "3.12"
  156. @@ -167,6 +171,7 @@
  157.      string
  158.  # Don't remove next line
  159.  # CT_INSERT_VERSION_STRING_BELOW
  160. +    default "3.12.8" if KERNEL_V_3_12_8
  161.      default "3.12" if KERNEL_V_3_12
  162.      default "3.11.8" if KERNEL_V_3_11
  163.      default "3.10.19" if KERNEL_V_3_10
  164. Index: config/libc/mingw.in
  165. ===================================================================
  166. --- config/libc/mingw.in    (revision 272)
  167. +++ config/libc/mingw.in    (working copy)
  168. @@ -14,6 +14,14 @@
  169.  # Don't remove next line
  170.  # CT_INSERT_VERSION_BELOW
  171.  
  172. +config WINAPI_V_3_1_0
  173. +    bool
  174. +    prompt "3.1.0"
  175. +
  176. +config WINAPI_V_3_0_0
  177. +    bool
  178. +    prompt "3.0.0"
  179. +
  180.  config WINAPI_V_2_0_8
  181.      bool
  182.      prompt "2.0.8"
  183. @@ -22,10 +30,6 @@
  184.      bool
  185.      prompt "2.0.7"
  186.  
  187. -config WINAPI_V_3_0_0
  188. -    bool
  189. -    prompt "3.0.0"
  190. -
  191.  config WINAPI_V_select
  192.      bool
  193.      prompt "Other version"
  194. @@ -37,6 +41,7 @@
  195.      prompt "Windows API version" if WINAPI_V_select
  196.  # Don't remove next line
  197.  # CT_INSERT_VERSION_STRING_BELOW
  198. +    default "3.1.0" if WINAPI_V_3_1_0
  199.      default "3.0.0" if WINAPI_V_3_0_0
  200.      default "2.0.8" if WINAPI_V_2_0_8
  201.      default "2.0.7" if WINAPI_V_2_0_7
  202. Index: kconfig/nconf.c
  203. ===================================================================
  204. --- kconfig/nconf.c (revision 272)
  205. +++ kconfig/nconf.c (working copy)
  206. @@ -1544,7 +1544,8 @@
  207.     }
  208.  
  209.     notimeout(stdscr, FALSE);
  210. -   ESCDELAY = 1;
  211. +   //ESCDELAY = 1;
  212. +   set_escdelay(1);
  213.  
  214.     /* set btns menu */
  215.     curses_menu = new_menu(curses_menu_items);
  216. Index: patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch
  217. ===================================================================
  218. --- patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch (revision 0)
  219. +++ patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch (working copy)
  220. @@ -0,0 +1,35 @@
  221. +--- a/gdb/windows-termcap.c.orig   2013-12-08 05:11:51.000000000 +0100
  222. ++++ b/gdb/windows-termcap.c    2014-01-18 21:55:31.443185000 +0100
  223. +@@ -20,13 +20,16 @@
  224. +    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  225. +
  226. + #include <stdlib.h>
  227. ++#include <config.h>
  228. +
  229. + /* -Wmissing-prototypes */
  230. + extern int tgetent (char *buffer, char *termtype);
  231. + extern int tgetnum (char *name);
  232. + extern int tgetflag (char *name);
  233. + extern char* tgetstr (char *name, char **area);
  234. ++#ifndef HAVE_NCURSES_NCURSES_H
  235. + extern int tputs (char *string, int nlines, int (*outfun) ());
  236. ++#endif
  237. + extern char *tgoto (const char *cap, int col, int row);
  238. +
  239. + /* Each of the files below is a minimal implementation of the standard
  240. +@@ -57,6 +60,7 @@
  241. +   return NULL;
  242. + }
  243. +
  244. ++#ifndef HAVE_NCURSES_NCURSES_H
  245. + int
  246. + tputs (char *string, int nlines, int (*outfun) ())
  247. + {
  248. +@@ -65,6 +69,7 @@
  249. +
  250. +   return 0;
  251. + }
  252. ++#endif
  253. +
  254. + char *
  255. + tgoto (const char *cap, int col, int row)
  256. Index: patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch
  257. ===================================================================
  258. --- patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch (revision 0)
  259. +++ patches/gdb/7.6.2/100-gdb-mingw-ncurse-compat.patch (working copy)
  260. @@ -0,0 +1,35 @@
  261. +--- a/gdb/windows-termcap.c.orig   2013-12-08 05:11:51.000000000 +0100
  262. ++++ b/gdb/windows-termcap.c    2014-01-18 21:55:31.443185000 +0100
  263. +@@ -20,13 +20,16 @@
  264. +    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
  265. +
  266. + #include <stdlib.h>
  267. ++#include <config.h>
  268. +
  269. + /* -Wmissing-prototypes */
  270. + extern int tgetent (char *buffer, char *termtype);
  271. + extern int tgetnum (char *name);
  272. + extern int tgetflag (char *name);
  273. + extern char* tgetstr (char *name, char **area);
  274. ++#ifndef HAVE_NCURSES_NCURSES_H
  275. + extern int tputs (char *string, int nlines, int (*outfun) ());
  276. ++#endif
  277. + extern char *tgoto (const char *cap, int col, int row);
  278. +
  279. + /* Each of the files below is a minimal implementation of the standard
  280. +@@ -57,6 +60,7 @@
  281. +   return NULL;
  282. + }
  283. +
  284. ++#ifndef HAVE_NCURSES_NCURSES_H
  285. + int
  286. + tputs (char *string, int nlines, int (*outfun) ())
  287. + {
  288. +@@ -65,6 +69,7 @@
  289. +
  290. +   return 0;
  291. + }
  292. ++#endif
  293. +
  294. + char *
  295. + tgoto (const char *cap, int col, int row)
  296. Index: patches/glibc/2.18/130-Fix-crossrpc-to-build-on-non-Linux.patch
  297. ===================================================================
  298. --- patches/glibc/2.18/130-Fix-crossrpc-to-build-on-non-Linux.patch (revision 0)
  299. +++ patches/glibc/2.18/130-Fix-crossrpc-to-build-on-non-Linux.patch (working copy)
  300. @@ -0,0 +1,251 @@
  301. +diff -urN a/sunrpc/rpc/types.h b/sunrpc/rpc/types.h
  302. +--- a/sunrpc/rpc/types.h   2013-12-15 14:25:49.275123500 +0000
  303. ++++ b/sunrpc/rpc/types.h   2013-12-15 14:26:20.677919600 +0000
  304. +@@ -69,6 +69,7 @@
  305. + #include <sys/types.h>
  306. + #endif
  307. +
  308. ++#ifdef __linux__
  309. + #ifndef __u_char_defined
  310. + typedef __u_char u_char;
  311. + typedef __u_short u_short;
  312. +@@ -84,11 +85,14 @@
  313. + typedef __caddr_t caddr_t;
  314. + # define __daddr_t_defined
  315. + #endif
  316. ++#endif
  317. +
  318. + #include <sys/time.h>
  319. + #include <sys/param.h>
  320. +
  321. ++#ifndef _WIN32
  322. + #include <netinet/in.h>
  323. ++#endif
  324. +
  325. + #ifndef INADDR_LOOPBACK
  326. + #define       INADDR_LOOPBACK         (u_long)0x7F000001
  327. +diff -urN a/sunrpc/rpc_main.c b/sunrpc/rpc_main.c
  328. +--- a/sunrpc/rpc_main.c    2013-12-15 14:25:49.285124000 +0000
  329. ++++ b/sunrpc/rpc_main.c    2013-12-15 14:26:29.327414300 +0000
  330. +@@ -38,14 +38,20 @@
  331. + #include <stdio.h>
  332. + #include <string.h>
  333. + #include <unistd.h>
  334. ++#ifndef IS_IN_build
  335. + #include <libintl.h>
  336. ++#endif
  337. + #include <locale.h>
  338. + #include <ctype.h>
  339. + #include <sys/types.h>
  340. + #include <sys/param.h>
  341. + #include <sys/file.h>
  342. + #include <sys/stat.h>
  343. ++#ifndef _WIN32
  344. + #include <sys/wait.h>
  345. ++#else
  346. ++#include <windows.h>
  347. ++#endif
  348. + #include "rpc_parse.h"
  349. + #include "rpc_util.h"
  350. + #include "rpc_scan.h"
  351. +@@ -54,6 +60,33 @@
  352. + #include "../version.h"
  353. + #define PACKAGE _libc_intl_domainname
  354. +
  355. ++#ifdef _WIN32
  356. ++#define rindex(_dest, _src) strrchr((_dest), (_src))
  357. ++
  358. ++char* __cdecl stpcpy(char* __restrict__ dest, char const* __restrict__ src);
  359. ++
  360. ++char* __cdecl stpcpy(char* __restrict__ dest, char const* __restrict__ src)
  361. ++{
  362. ++  if (src == NULL)
  363. ++      return NULL;
  364. ++  return strcpy(dest, src) + strlen(dest);
  365. ++}
  366. ++#endif /* _WIN32 */
  367. ++
  368. ++#if defined(_WIN32) || defined(__BSD__)
  369. ++
  370. ++char* __cdecl stpncpy(char* __restrict__ dest, char const* __restrict__ src, size_t len);
  371. ++
  372. ++char* __cdecl stpncpy(char* __restrict__ dest, char const* __restrict__ src, size_t len)
  373. ++{
  374. ++  size_t min_len = strlen(src);
  375. ++  if (min_len > len)
  376. ++    min_len = len;
  377. ++  return strncpy(dest, src, len) + min_len;
  378. ++}
  379. ++
  380. ++#endif /* defined(_WIN32) || defined(__BSD__) */
  381. ++
  382. + #define EXTEND    1       /* alias for TRUE */
  383. + #define DONT_EXTEND   0   /* alias for FALSE */
  384. +
  385. +@@ -81,7 +114,11 @@
  386. + static const char *CPP = "/lib/cpp";
  387. + static const char CPPFLAGS[] = "-C";
  388. + static char *pathbuf;
  389. ++#ifdef _WIN32
  390. ++static HANDLE cpp_pid;
  391. ++#else
  392. + static int cpp_pid;
  393. ++#endif
  394. + static const char *allv[] =
  395. + {
  396. +   "rpcgen", "-s", "udp", "-s", "tcp"
  397. +@@ -328,6 +365,20 @@
  398. + {
  399. +   struct stat64 buf;
  400. +
  401. ++  /* Avoid trying to directly execute a bash script on Windows. */
  402. ++#ifdef _WIN32
  403. ++  char* CPPENVV = getenv("CPP");
  404. ++  if (CPPENVV)
  405. ++    {
  406. ++      CPP = (char*)malloc(strlen(CPPENVV)+1);
  407. ++      strcpy((char*)CPP, CPPENVV);
  408. ++      /* Don't bother checking that it exists with stat64 as
  409. ++       * we'd have to check in the path, also it usually ends
  410. ++       * with a few arguments. */
  411. ++      return;
  412. ++    }
  413. ++#endif
  414. ++
  415. +   if (stat64 (CPP, &buf) == 0)
  416. +     return;
  417. +
  418. +@@ -341,12 +392,125 @@
  419. +   CPP = "cpp";
  420. + }
  421. +
  422. ++#ifdef _WIN32
  423. + /*
  424. +  * Open input file with given define for C-preprocessor
  425. +  */
  426. + static void
  427. + open_input (const char *infile, const char *define)
  428. + {
  429. ++  int argi;
  430. ++  int argcc = 0;
  431. ++  LPSTR argsall;
  432. ++  HANDLE StdOutHandle;
  433. ++  HANDLE StdErrHandle;
  434. ++  HANDLE ReadPipe;
  435. ++  HANDLE WritePipe;
  436. ++  SECURITY_ATTRIBUTES SecAttr;
  437. ++  STARTUPINFO StartupInfo;
  438. ++  PROCESS_INFORMATION ProcessInfo;
  439. ++  DWORD Status;
  440. ++
  441. ++  find_cpp ();
  442. ++  putarg (0, CPP);
  443. ++  putarg (1, CPPFLAGS);
  444. ++  addarg (define);
  445. ++  if (infile)
  446. ++    addarg (infile);
  447. ++  addarg ((char *) NULL);
  448. ++  for (argi = 0; argi < argcount - 1; ++argi)
  449. ++    {
  450. ++      argcc += strlen(arglist[argi])+2;
  451. ++    }
  452. ++  argsall = (LPSTR)alloca(argcc + 1);
  453. ++  if (!argsall)
  454. ++    {
  455. ++      fprintf (stderr, _ ("cannot alloca for argsall\n"));
  456. ++      exit (1);
  457. ++    }
  458. ++  argsall[0] = '\0';
  459. ++  for (argi = 0; argi < argcount - 1; ++argi)
  460. ++    {
  461. ++      strcat((char*)argsall, arglist[argi]);
  462. ++      strcat((char*)argsall, " ");
  463. ++    }
  464. ++
  465. ++  memset(&SecAttr,     0, sizeof(SecAttr));
  466. ++  memset(&StartupInfo, 0, sizeof(StartupInfo));
  467. ++  memset(&ProcessInfo, 0, sizeof(ProcessInfo));
  468. ++
  469. ++  SecAttr.nLength = sizeof(SecAttr);
  470. ++  SecAttr.bInheritHandle = TRUE;
  471. ++
  472. ++  Status = CreatePipe( &ReadPipe, &WritePipe, &SecAttr, 0 );
  473. ++  if (!Status)
  474. ++    {
  475. ++      fprintf (stderr, _ ("cannot CreatePipe: GetLastError() -> %d\n"), GetLastError());
  476. ++      exit (1);
  477. ++    }
  478. ++
  479. ++  SetHandleInformation( ReadPipe, HANDLE_FLAG_INHERIT, 0 );
  480. ++
  481. ++  /*
  482. ++  StdOutHandle = GetStdHandle( STD_OUTPUT_HANDLE );
  483. ++  StdErrHandle = GetStdHandle( STD_ERROR_HANDLE );
  484. ++  if (StdOutHandle != INVALID_HANDLE_VALUE) {
  485. ++      SetHandleInformation( StdOutHandle, HANDLE_FLAG_INHERIT, 0 );
  486. ++  }
  487. ++  if (StdErrHandle != INVALID_HANDLE_VALUE) {
  488. ++      SetHandleInformation( StdErrHandle, HANDLE_FLAG_INHERIT, 0 );
  489. ++  }
  490. ++  */
  491. ++
  492. ++  StartupInfo.cb         = sizeof(StartupInfo);
  493. ++  StartupInfo.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
  494. ++  StartupInfo.hStdOutput = WritePipe;
  495. ++  StartupInfo.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
  496. ++  StartupInfo.dwFlags    = STARTF_USESTDHANDLES;
  497. ++
  498. ++  Status = CreateProcess(
  499. ++          NULL,           /* lpApplicationName */
  500. ++          argsall,        /* lpCommandLine */
  501. ++          NULL,           /* lpProcessAttributes */
  502. ++          NULL,           /* lpThreadAttributes */
  503. ++          TRUE,           /* bInheritHandles */
  504. ++          0,              /* dwCreationFlags */
  505. ++          NULL,           /* lpEnvironment */
  506. ++          NULL,           /* lpCurrentDirectory */
  507. ++          &StartupInfo,   /* lpStartupInfo */
  508. ++          &ProcessInfo ); /* lpProcessInformation */
  509. ++
  510. ++  CloseHandle( WritePipe );
  511. ++  if (!Status)
  512. ++    {
  513. ++      fprintf (stderr, _ ("cannot find C preprocessor: %s, GetLastError() -> %d\n"), CPP, GetLastError());
  514. ++      exit (1);
  515. ++    }
  516. ++  int fd = _open_osfhandle((intptr_t)ReadPipe, _O_APPEND | _O_RDONLY);
  517. ++  if(fd != -1)
  518. ++    {
  519. ++      fin = _fdopen(fd, "a+");
  520. ++    }
  521. ++  cpp_pid = ProcessInfo.hProcess;
  522. ++}
  523. ++
  524. ++/* Close the connection to the C-preprocessor and check for successfull
  525. ++   termination.  */
  526. ++static void
  527. ++close_input (void)
  528. ++{
  529. ++  WaitForSingleObject(cpp_pid, INFINITE);
  530. ++}
  531. ++
  532. ++#else
  533. ++
  534. ++/*
  535. ++ * Open input file with given define for C-preprocessor
  536. ++ */
  537. ++
  538. ++static void
  539. ++open_input (const char *infile, const char *define)
  540. ++{
  541. +   int pd[2];
  542. +
  543. +   infilename = (infile == NULL) ? "<stdin>" : infile;
  544. +@@ -416,6 +580,7 @@
  545. +       crash ();
  546. +     }
  547. + }
  548. ++#endif
  549. +
  550. + /* valid tirpc nettypes */
  551. + static const char *valid_ti_nettypes[] =
  552. Index: patches/glibc/2.18/140-glibc-disable-install-symlink-script-rellns.patch
  553. ===================================================================
  554. --- patches/glibc/2.18/140-glibc-disable-install-symlink-script-rellns.patch    (revision 0)
  555. +++ patches/glibc/2.18/140-glibc-disable-install-symlink-script-rellns.patch    (working copy)
  556. @@ -0,0 +1,11 @@
  557. +--- a/scripts/rellns-sh.orig   2013-08-11 00:52:55.000000000 +0200
  558. ++++ b/scripts/rellns-sh            2014-01-21 02:28:19.502305700 +0100
  559. +@@ -18,6 +18,8 @@
  560. +
  561. + # With -p, instead of creating the link print the computed relative link
  562. + # name.
  563. ++echo $2
  564. ++exit 1
  565. + do_print=false
  566. + case $1 in
  567. +   -p)
  568. Index: patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch
  569. ===================================================================
  570. --- patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch (revision 0)
  571. +++ patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch (working copy)
  572. @@ -0,0 +1,154 @@
  573. +--- linux-3.12.orig/scripts/basic/fixdep.c 2013-11-13 03:05:59.000000000 +0000
  574. +--- linux-3.12/scripts/basic/fixdep.c  2013-12-04 00:21:00.303303000 +0000
  575. +@@ -105,7 +105,9 @@
  576. +
  577. + #include <sys/types.h>
  578. + #include <sys/stat.h>
  579. ++#ifndef __MINGW32__
  580. + #include <sys/mman.h>
  581. ++#endif
  582. + #include <unistd.h>
  583. + #include <fcntl.h>
  584. + #include <string.h>
  585. +@@ -113,13 +115,77 @@
  586. + #include <stdio.h>
  587. + #include <limits.h>
  588. + #include <ctype.h>
  589. ++#ifndef __MINGW32__
  590. + #include <arpa/inet.h>
  591. ++#define O_BINARY 0
  592. ++#else
  593. ++inline unsigned int ntohl(unsigned int val);
  594. ++inline unsigned int ntohl(unsigned int val)
  595. ++{
  596. ++  return (((val&0xff      ) << 24) |
  597. ++          ((val&0xff00    ) << 8 ) |
  598. ++          ((val&0xff0000  ) >> 8 ) |
  599. ++          ((val&0xff000000) >> 24) );
  600. ++}
  601. ++#endif
  602. +
  603. + #define INT_CONF ntohl(0x434f4e46)
  604. + #define INT_ONFI ntohl(0x4f4e4649)
  605. + #define INT_NFIG ntohl(0x4e464947)
  606. + #define INT_FIG_ ntohl(0x4649475f)
  607. +
  608. ++#ifdef __MINGW32__
  609. ++#define UNUSED __attribute__ ((__unused__))
  610. ++
  611. ++void *mmap(void *start UNUSED, size_t size, int prot UNUSED,
  612. ++     int flags UNUSED, int fd, off_t offset UNUSED);
  613. ++
  614. ++void munmap(void *p, size_t size UNUSED);
  615. ++
  616. ++/* Workaround specifically for fixdep */
  617. ++#define PROT_READ 0
  618. ++#define MAP_PRIVATE 0
  619. ++void *mmap(void *start UNUSED, size_t size, int prot UNUSED,
  620. ++     int flags UNUSED, int fd, off_t offset UNUSED)
  621. ++{
  622. ++  void *p;
  623. ++  void *curP;
  624. ++  ssize_t readB;
  625. ++
  626. ++  p = malloc(size);
  627. ++  if (!p)
  628. ++      return (void*)((long)-1);
  629. ++
  630. ++  curP = p;
  631. ++
  632. ++  while (size > 0)
  633. ++  {
  634. ++      readB = read(fd, curP, size);
  635. ++
  636. ++      if (readB == 0)
  637. ++      {
  638. ++          /* EOF reached */
  639. ++          break;
  640. ++      }
  641. ++      else if (readB < 0)
  642. ++      {
  643. ++          perror("fixdep: read config");
  644. ++          free(p);
  645. ++          return (void*)((long)-1);
  646. ++      }
  647. ++
  648. ++      size -= readB;
  649. ++      curP += readB;
  650. ++  }
  651. ++
  652. ++  return p;
  653. ++}
  654. ++void munmap(void *p, size_t size UNUSED)
  655. ++{
  656. ++  free(p);
  657. ++}
  658. ++#endif
  659. ++
  660. + char *target;
  661. + char *depfile;
  662. + char *cmdline;
  663. +@@ -284,7 +350,7 @@
  664. +   int fd;
  665. +   void *map;
  666. +
  667. +-  fd = open(filename, O_RDONLY);
  668. ++  fd = open(filename, O_RDONLY|O_BINARY);
  669. +   if (fd < 0) {
  670. +       fprintf(stderr, "fixdep: error opening config file: ");
  671. +       perror(filename);
  672. +@@ -319,6 +385,7 @@
  673. +   char *m = map;
  674. +   char *end = m + len;
  675. +   char *p;
  676. ++  char *slash;
  677. +   char s[PATH_MAX];
  678. +   int is_target;
  679. +   int saw_any_target = 0;
  680. +@@ -328,11 +395,11 @@
  681. +
  682. +   while (m < end) {
  683. +       /* Skip any "white space" */
  684. +-      while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
  685. ++      while (m < end && (*m == ' ' || *m == '\\' || *m == '\r' || *m == '\n'))
  686. +           m++;
  687. +       /* Find next "white space" */
  688. +       p = m;
  689. +-      while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
  690. ++      while (p < end && *p != ' ' && *p != '\r' && *p != '\n')
  691. +           p++;
  692. +       /* Is the token we found a target name? */
  693. +       is_target = (*(p-1) == ':');
  694. +@@ -344,6 +411,14 @@
  695. +           /* Save this token/filename */
  696. +           memcpy(s, m, p-m);
  697. +           s[p - m] = 0;
  698. ++          /* Apply some Windows fixups */
  699. ++          if (s[0]>='a' && s[0]<='z' && s[1]==':')
  700. ++              s[0] = s[0]&~32;
  701. ++          slash = strchr(s, '\\');
  702. ++          while (slash) {
  703. ++              *slash = '/';
  704. ++              slash = strchr(slash, '\\');
  705. ++          }
  706. +
  707. +           /* Ignore certain dependencies */
  708. +           if (strrcmp(s, "include/generated/autoconf.h") &&
  709. +@@ -385,6 +460,8 @@
  710. +        * "whitespace" character that follows this token.
  711. +        */
  712. +       m = p + 1;
  713. ++      while (*m && (*m == '\r' || *m == '\n'))
  714. ++          ++m;
  715. +   }
  716. +
  717. +   if (!saw_any_target) {
  718. +@@ -402,7 +479,7 @@
  719. +   int fd;
  720. +   void *map;
  721. +
  722. +-  fd = open(depfile, O_RDONLY);
  723. ++  fd = open(depfile, O_RDONLY|O_BINARY);
  724. +   if (fd < 0) {
  725. +       fprintf(stderr, "fixdep: error opening depfile: ");
  726. +       perror(depfile);
  727. Index: patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch
  728. ===================================================================
  729. --- patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch   (revision 0)
  730. +++ patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch   (working copy)
  731. @@ -0,0 +1,2086 @@
  732. +diff -urN linux-3.12.orig/scripts/Makefile linux-3.12/scripts/Makefile
  733. +--- linux-3.12.orig/scripts/Makefile   2013-12-06 19:36:35.000000000 +0000
  734. ++++ linux-3.12/scripts/Makefile    2013-12-06 19:36:46.000000000 +0000
  735. +@@ -26,6 +26,15 @@
  736. + # The following hostprogs-y programs are only build on demand
  737. + hostprogs-y += unifdef docproc
  738. +
  739. ++cc_machine := $(shell $(CC) -dumpmachine)
  740. ++ifneq (, $(findstring linux, $(cc_machine)))
  741. ++  unifdef-objs := unifdef.o
  742. ++else
  743. ++  ifneq (, $(findstring mingw, $(cc_machine)))
  744. ++    unifdef-objs := unifdef-upstream/win32/unifdef.o unifdef-upstream/win32/err.o unifdef-upstream/win32/getopt.o unifdef-upstream/win32/win32.o
  745. ++  endif
  746. ++endif
  747. ++
  748. + # These targets are used internally to avoid "is up to date" messages
  749. + PHONY += build_unifdef
  750. + build_unifdef: scripts/unifdef FORCE
  751. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/COPYING linux-3.12/scripts/unifdef-upstream/COPYING
  752. +--- linux-3.12.orig/scripts/unifdef-upstream/COPYING   1970-01-01 01:00:00.000000000 +0100
  753. ++++ linux-3.12/scripts/unifdef-upstream/COPYING    2013-12-06 19:36:46.000000000 +0000
  754. +@@ -0,0 +1,85 @@
  755. ++unifdef copyright licence
  756. ++-------------------------
  757. ++
  758. ++All files in this package are distributed under the two-clause BSD
  759. ++copyright licence, except for the manual page unifdef.1 and the
  760. ++portability support code in the FreeBSD subdirectory, which all have
  761. ++a three-clause BSD copyright licence.
  762. ++
  763. ++Unifdef was derived from software contributed to Berkeley by Dave
  764. ++Yost. It was rewritten to support ANSI C by Tony Finch. The original
  765. ++version of unifdef.c carried the four-clause BSD copyright licence.
  766. ++None of its code remains in this version (though some of the names
  767. ++remain) so it now carries the more liberal two-clause licence.
  768. ++
  769. ++Unless otherwise stated, the files in this package are:
  770. ++
  771. ++  Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  772. ++
  773. ++unifdefall.sh is:
  774. ++
  775. ++  Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  776. ++  Copyright (c) 2009 - 2010 Jonathan Nieder <jrnieder@gmail.com>
  777. ++
  778. ++Some files in the tests directory are:
  779. ++
  780. ++  Copyright 2004, 2008 Bob Proulx <bob@proulx.com>
  781. ++
  782. ++The two-clause BSD copyright licence applying to all the above files is:
  783. ++
  784. ++  Redistribution and use in source and binary forms, with or without
  785. ++  modification, are permitted provided that the following conditions
  786. ++  are met:
  787. ++  1. Redistributions of source code must retain the above copyright
  788. ++     notice, this list of conditions and the following disclaimer.
  789. ++  2. Redistributions in binary form must reproduce the above copyright
  790. ++     notice, this list of conditions and the following disclaimer in the
  791. ++     documentation and/or other materials provided with the distribution.
  792. ++
  793. ++  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  794. ++  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  795. ++  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  796. ++  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  797. ++  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  798. ++  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  799. ++  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  800. ++  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  801. ++  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  802. ++  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  803. ++  SUCH DAMAGE.
  804. ++
  805. ++The three-clause BSD copyright licence for the manual page unifdef.1
  806. ++and the portability support code from FreeBSD is below. The fourth
  807. ++advertising clause that used to appear between clauses 2 and 3 was
  808. ++rescinded by the University of California Berkeley in 1999.
  809. ++ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
  810. ++
  811. ++  Copyright (c) 1985 - 1994
  812. ++  The Regents of the University of California.  All rights reserved.
  813. ++  Copyright (c) 2002 - 2012 Tony Finch <dot@dotat.at>.  All rights reserved.
  814. ++
  815. ++  Redistribution and use in source and binary forms, with or without
  816. ++  modification, are permitted provided that the following conditions
  817. ++  are met:
  818. ++  1. Redistributions of source code must retain the above copyright
  819. ++     notice, this list of conditions and the following disclaimer.
  820. ++  2. Redistributions in binary form must reproduce the above copyright
  821. ++     notice, this list of conditions and the following disclaimer in the
  822. ++     documentation and/or other materials provided with the distribution.
  823. ++  3. Neither the name of the University nor the names of its contributors
  824. ++     may be used to endorse or promote products derived from this software
  825. ++     without specific prior written permission.
  826. ++
  827. ++  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  828. ++  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  829. ++  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  830. ++  ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  831. ++  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  832. ++  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  833. ++  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  834. ++  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  835. ++  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  836. ++  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  837. ++  SUCH DAMAGE.
  838. ++
  839. ++- end -
  840. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/err.c linux-3.12/scripts/unifdef-upstream/win32/err.c
  841. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/err.c   1970-01-01 01:00:00.000000000 +0100
  842. ++++ linux-3.12/scripts/unifdef-upstream/win32/err.c    2013-12-06 19:36:46.000000000 +0000
  843. +@@ -0,0 +1,138 @@
  844. ++/*-
  845. ++ * Copyright (c) 1993
  846. ++ *    The Regents of the University of California.  All rights reserved.
  847. ++ *
  848. ++ * Redistribution and use in source and binary forms, with or without
  849. ++ * modification, are permitted provided that the following conditions
  850. ++ * are met:
  851. ++ * 1. Redistributions of source code must retain the above copyright
  852. ++ *    notice, this list of conditions and the following disclaimer.
  853. ++ * 2. Redistributions in binary form must reproduce the above copyright
  854. ++ *    notice, this list of conditions and the following disclaimer in the
  855. ++ *    documentation and/or other materials provided with the distribution.
  856. ++ * 4. Neither the name of the University nor the names of its contributors
  857. ++ *    may be used to endorse or promote products derived from this software
  858. ++ *    without specific prior written permission.
  859. ++ *
  860. ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  861. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  862. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  863. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  864. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  865. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  866. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  867. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  868. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  869. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  870. ++ * SUCH DAMAGE.
  871. ++ */
  872. ++
  873. ++#include "unifdef.h"
  874. ++
  875. ++void
  876. ++err(int eval, const char *fmt, ...)
  877. ++{
  878. ++  va_list ap;
  879. ++  va_start(ap, fmt);
  880. ++  verrc(eval, errno, fmt, ap);
  881. ++  va_end(ap);
  882. ++}
  883. ++
  884. ++void
  885. ++verr(int eval, const char *fmt, va_list ap)
  886. ++{
  887. ++  verrc(eval, errno, fmt, ap);
  888. ++}
  889. ++
  890. ++void
  891. ++errc(int eval, int code, const char *fmt, ...)
  892. ++{
  893. ++  va_list ap;
  894. ++  va_start(ap, fmt);
  895. ++  verrc(eval, code, fmt, ap);
  896. ++  va_end(ap);
  897. ++}
  898. ++
  899. ++void
  900. ++verrc(int eval, int code, const char *fmt, va_list ap)
  901. ++{
  902. ++  fprintf(stderr, "%s: ", _getprogname());
  903. ++  if (fmt != NULL) {
  904. ++      vfprintf(stderr, fmt, ap);
  905. ++      fprintf(stderr, ": ");
  906. ++  }
  907. ++  fprintf(stderr, "%s\n", strerror(code));
  908. ++  exit(eval);
  909. ++}
  910. ++
  911. ++void
  912. ++errx(int eval, const char *fmt, ...)
  913. ++{
  914. ++  va_list ap;
  915. ++  va_start(ap, fmt);
  916. ++  verrx(eval, fmt, ap);
  917. ++  va_end(ap);
  918. ++}
  919. ++
  920. ++void
  921. ++verrx(int eval, const char *fmt, va_list ap)
  922. ++{
  923. ++  fprintf(stderr, "%s: ", _getprogname());
  924. ++  if (fmt != NULL)
  925. ++      vfprintf(stderr, fmt, ap);
  926. ++  fprintf(stderr, "\n");
  927. ++  exit(eval);
  928. ++}
  929. ++
  930. ++void
  931. ++warn(const char *fmt, ...)
  932. ++{
  933. ++  va_list ap;
  934. ++  va_start(ap, fmt);
  935. ++  vwarnc(errno, fmt, ap);
  936. ++  va_end(ap);
  937. ++}
  938. ++
  939. ++void
  940. ++vwarn(const char *fmt, va_list ap)
  941. ++{
  942. ++  vwarnc(errno, fmt, ap);
  943. ++}
  944. ++
  945. ++void
  946. ++warnc(int code, const char *fmt, ...)
  947. ++{
  948. ++  va_list ap;
  949. ++  va_start(ap, fmt);
  950. ++  vwarnc(code, fmt, ap);
  951. ++  va_end(ap);
  952. ++}
  953. ++
  954. ++void
  955. ++vwarnc(int code, const char *fmt, va_list ap)
  956. ++{
  957. ++  fprintf(stderr, "%s: ", _getprogname());
  958. ++  if (fmt != NULL) {
  959. ++      vfprintf(stderr, fmt, ap);
  960. ++      fprintf(stderr, ": ");
  961. ++  }
  962. ++  fprintf(stderr, "%s\n", strerror(code));
  963. ++}
  964. ++
  965. ++void
  966. ++warnx(const char *fmt, ...)
  967. ++{
  968. ++  va_list ap;
  969. ++  va_start(ap, fmt);
  970. ++  vwarnx(fmt, ap);
  971. ++  va_end(ap);
  972. ++}
  973. ++
  974. ++void
  975. ++vwarnx(const char *fmt, va_list ap)
  976. ++{
  977. ++  fprintf(stderr, "%s: ", _getprogname());
  978. ++  if (fmt != NULL)
  979. ++      vfprintf(stderr, fmt, ap);
  980. ++  fprintf(stderr, "\n");
  981. ++}
  982. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/getopt.c linux-3.12/scripts/unifdef-upstream/win32/getopt.c
  983. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/getopt.c    1970-01-01 01:00:00.000000000 +0100
  984. ++++ linux-3.12/scripts/unifdef-upstream/win32/getopt.c 2013-12-06 19:36:46.000000000 +0000
  985. +@@ -0,0 +1,118 @@
  986. ++/*
  987. ++ * Copyright (c) 1987, 1993, 1994
  988. ++ *    The Regents of the University of California.  All rights reserved.
  989. ++ *
  990. ++ * Redistribution and use in source and binary forms, with or without
  991. ++ * modification, are permitted provided that the following conditions
  992. ++ * are met:
  993. ++ * 1. Redistributions of source code must retain the above copyright
  994. ++ *    notice, this list of conditions and the following disclaimer.
  995. ++ * 2. Redistributions in binary form must reproduce the above copyright
  996. ++ *    notice, this list of conditions and the following disclaimer in the
  997. ++ *    documentation and/or other materials provided with the distribution.
  998. ++ * 4. Neither the name of the University nor the names of its contributors
  999. ++ *    may be used to endorse or promote products derived from this software
  1000. ++ *    without specific prior written permission.
  1001. ++ *
  1002. ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1003. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1004. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1005. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1006. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1007. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1008. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1009. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1010. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1011. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1012. ++ * SUCH DAMAGE.
  1013. ++ */
  1014. ++
  1015. ++#include "unifdef.h"
  1016. ++
  1017. ++int   opterr = 1,     /* if error message should be printed */
  1018. ++  optind = 1,     /* index into parent argv vector */
  1019. ++  optopt,         /* character checked for validity */
  1020. ++  optreset;       /* reset getopt */
  1021. ++char  *optarg;        /* argument associated with option */
  1022. ++
  1023. ++#define   BADCH   (int)'?'
  1024. ++#define   BADARG  (int)':'
  1025. ++
  1026. ++static char EMSG[] = "";
  1027. ++
  1028. ++/*
  1029. ++ * getopt --
  1030. ++ *    Parse argc/argv argument vector.
  1031. ++ */
  1032. ++int
  1033. ++getopt(int nargc, char *nargv[], const char *ostr)
  1034. ++{
  1035. ++  static char *place = EMSG;      /* option letter processing */
  1036. ++  const char *oli;            /* option letter list index */
  1037. ++
  1038. ++  if (optreset || *place == 0) {      /* update scanning pointer */
  1039. ++      optreset = 0;
  1040. ++      place = nargv[optind];
  1041. ++      if (optind >= nargc || *place++ != '-') {
  1042. ++          /* Argument is absent or is not an option */
  1043. ++          place = EMSG;
  1044. ++          return (-1);
  1045. ++      }
  1046. ++      optopt = *place++;
  1047. ++      if (optopt == '-' && *place == 0) {
  1048. ++          /* "--" => end of options */
  1049. ++          ++optind;
  1050. ++          place = EMSG;
  1051. ++          return (-1);
  1052. ++      }
  1053. ++      if (optopt == 0) {
  1054. ++          /* Solitary '-', treat as a '-' option
  1055. ++             if the program (eg su) is looking for it. */
  1056. ++          place = EMSG;
  1057. ++          if (strchr(ostr, '-') == NULL)
  1058. ++              return (-1);
  1059. ++          optopt = '-';
  1060. ++      }
  1061. ++  } else
  1062. ++      optopt = *place++;
  1063. ++
  1064. ++  /* See if option letter is one the caller wanted... */
  1065. ++  if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
  1066. ++      if (*place == 0)
  1067. ++          ++optind;
  1068. ++      if (opterr && *ostr != ':')
  1069. ++          (void)fprintf(stderr,
  1070. ++              "%s: illegal option -- %c\n", _getprogname(),
  1071. ++              optopt);
  1072. ++      return (BADCH);
  1073. ++  }
  1074. ++
  1075. ++  /* Does this option need an argument? */
  1076. ++  if (oli[1] != ':') {
  1077. ++      /* don't need argument */
  1078. ++      optarg = NULL;
  1079. ++      if (*place == 0)
  1080. ++          ++optind;
  1081. ++  } else {
  1082. ++      /* Option-argument is either the rest of this argument or the
  1083. ++         entire next argument. */
  1084. ++      if (*place)
  1085. ++          optarg = place;
  1086. ++      else if (nargc > ++optind)
  1087. ++          optarg = nargv[optind];
  1088. ++      else {
  1089. ++          /* option-argument absent */
  1090. ++          place = EMSG;
  1091. ++          if (*ostr == ':')
  1092. ++              return (BADARG);
  1093. ++          if (opterr)
  1094. ++              (void)fprintf(stderr,
  1095. ++                  "%s: option requires an argument -- %c\n",
  1096. ++                  _getprogname(), optopt);
  1097. ++          return (BADCH);
  1098. ++      }
  1099. ++      place = EMSG;
  1100. ++      ++optind;
  1101. ++  }
  1102. ++  return (optopt);            /* return option letter */
  1103. ++}
  1104. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.c linux-3.12/scripts/unifdef-upstream/win32/unifdef.c
  1105. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.c   1970-01-01 01:00:00.000000000 +0100
  1106. ++++ linux-3.12/scripts/unifdef-upstream/win32/unifdef.c    2013-12-06 19:36:46.000000000 +0000
  1107. +@@ -0,0 +1,1571 @@
  1108. ++/*
  1109. ++ * Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  1110. ++ *
  1111. ++ * Redistribution and use in source and binary forms, with or without
  1112. ++ * modification, are permitted provided that the following conditions
  1113. ++ * are met:
  1114. ++ * 1. Redistributions of source code must retain the above copyright
  1115. ++ *    notice, this list of conditions and the following disclaimer.
  1116. ++ * 2. Redistributions in binary form must reproduce the above copyright
  1117. ++ *    notice, this list of conditions and the following disclaimer in the
  1118. ++ *    documentation and/or other materials provided with the distribution.
  1119. ++ *
  1120. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  1121. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1122. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1123. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  1124. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1125. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1126. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1127. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1128. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1129. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1130. ++ * SUCH DAMAGE.
  1131. ++ */
  1132. ++
  1133. ++/*
  1134. ++ * unifdef - remove ifdef'ed lines
  1135. ++ *
  1136. ++ * This code was derived from software contributed to Berkeley by Dave Yost.
  1137. ++ * It was rewritten to support ANSI C by Tony Finch. The original version
  1138. ++ * of unifdef carried the 4-clause BSD copyright licence. None of its code
  1139. ++ * remains in this version (though some of the names remain) so it now
  1140. ++ * carries a more liberal licence.
  1141. ++ *
  1142. ++ *  Wishlist:
  1143. ++ *      provide an option which will append the name of the
  1144. ++ *        appropriate symbol after #else's and #endif's
  1145. ++ *      provide an option which will check symbols after
  1146. ++ *        #else's and #endif's to see that they match their
  1147. ++ *        corresponding #ifdef or #ifndef
  1148. ++ *
  1149. ++ *   These require better buffer handling, which would also make
  1150. ++ *   it possible to handle all "dodgy" directives correctly.
  1151. ++ */
  1152. ++
  1153. ++#include "unifdef.h"
  1154. ++
  1155. ++static const char copyright[] =
  1156. ++    #include "version.h"
  1157. ++    "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
  1158. ++    "@(#) $URL: http://dotat.at/prog/unifdef $\n"
  1159. ++;
  1160. ++
  1161. ++/* types of input lines: */
  1162. ++typedef enum {
  1163. ++  LT_TRUEI,       /* a true #if with ignore flag */
  1164. ++  LT_FALSEI,      /* a false #if with ignore flag */
  1165. ++  LT_IF,          /* an unknown #if */
  1166. ++  LT_TRUE,        /* a true #if */
  1167. ++  LT_FALSE,       /* a false #if */
  1168. ++  LT_ELIF,        /* an unknown #elif */
  1169. ++  LT_ELTRUE,      /* a true #elif */
  1170. ++  LT_ELFALSE,     /* a false #elif */
  1171. ++  LT_ELSE,        /* #else */
  1172. ++  LT_ENDIF,       /* #endif */
  1173. ++  LT_DODGY,       /* flag: directive is not on one line */
  1174. ++  LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
  1175. ++  LT_PLAIN,       /* ordinary line */
  1176. ++  LT_EOF,         /* end of file */
  1177. ++  LT_ERROR,       /* unevaluable #if */
  1178. ++  LT_COUNT
  1179. ++} Linetype;
  1180. ++
  1181. ++static char const * const linetype_name[] = {
  1182. ++  "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
  1183. ++  "ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
  1184. ++  "DODGY TRUEI", "DODGY FALSEI",
  1185. ++  "DODGY IF", "DODGY TRUE", "DODGY FALSE",
  1186. ++  "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
  1187. ++  "DODGY ELSE", "DODGY ENDIF",
  1188. ++  "PLAIN", "EOF", "ERROR"
  1189. ++};
  1190. ++
  1191. ++#define linetype_if2elif(lt) ((Linetype)(lt - LT_IF + LT_ELIF))
  1192. ++#define linetype_2dodgy(lt) ((Linetype)(lt + LT_DODGY))
  1193. ++
  1194. ++/* state of #if processing */
  1195. ++typedef enum {
  1196. ++  IS_OUTSIDE,
  1197. ++  IS_FALSE_PREFIX,    /* false #if followed by false #elifs */
  1198. ++  IS_TRUE_PREFIX,     /* first non-false #(el)if is true */
  1199. ++  IS_PASS_MIDDLE,     /* first non-false #(el)if is unknown */
  1200. ++  IS_FALSE_MIDDLE,    /* a false #elif after a pass state */
  1201. ++  IS_TRUE_MIDDLE,     /* a true #elif after a pass state */
  1202. ++  IS_PASS_ELSE,       /* an else after a pass state */
  1203. ++  IS_FALSE_ELSE,      /* an else after a true state */
  1204. ++  IS_TRUE_ELSE,       /* an else after only false states */
  1205. ++  IS_FALSE_TRAILER,   /* #elifs after a true are false */
  1206. ++  IS_COUNT
  1207. ++} Ifstate;
  1208. ++
  1209. ++static char const * const ifstate_name[] = {
  1210. ++  "OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
  1211. ++  "PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
  1212. ++  "PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
  1213. ++  "FALSE_TRAILER"
  1214. ++};
  1215. ++
  1216. ++/* state of comment parser */
  1217. ++typedef enum {
  1218. ++  NO_COMMENT = false, /* outside a comment */
  1219. ++  C_COMMENT,      /* in a comment like this one */
  1220. ++  CXX_COMMENT,        /* between // and end of line */
  1221. ++  STARTING_COMMENT,   /* just after slash-backslash-newline */
  1222. ++  FINISHING_COMMENT,  /* star-backslash-newline in a C comment */
  1223. ++  CHAR_LITERAL,       /* inside '' */
  1224. ++  STRING_LITERAL      /* inside "" */
  1225. ++} Comment_state;
  1226. ++
  1227. ++static char const * const comment_name[] = {
  1228. ++  "NO", "C", "CXX", "STARTING", "FINISHING", "CHAR", "STRING"
  1229. ++};
  1230. ++
  1231. ++/* state of preprocessor line parser */
  1232. ++typedef enum {
  1233. ++  LS_START,       /* only space and comments on this line */
  1234. ++  LS_HASH,        /* only space, comments, and a hash */
  1235. ++  LS_DIRTY        /* this line can't be a preprocessor line */
  1236. ++} Line_state;
  1237. ++
  1238. ++static char const * const linestate_name[] = {
  1239. ++  "START", "HASH", "DIRTY"
  1240. ++};
  1241. ++
  1242. ++/*
  1243. ++ * Minimum translation limits from ISO/IEC 9899:1999 5.2.4.1
  1244. ++ */
  1245. ++#define   MAXDEPTH        64          /* maximum #if nesting */
  1246. ++#define   MAXLINE         4096            /* maximum length of line */
  1247. ++#define   MAXSYMS         16384           /* maximum number of symbols */
  1248. ++
  1249. ++/*
  1250. ++ * Sometimes when editing a keyword the replacement text is longer, so
  1251. ++ * we leave some space at the end of the tline buffer to accommodate this.
  1252. ++ */
  1253. ++#define   EDITSLOP        10
  1254. ++
  1255. ++/*
  1256. ++ * Globals.
  1257. ++ */
  1258. ++
  1259. ++static bool             compblank;        /* -B: compress blank lines */
  1260. ++static bool             lnblank;      /* -b: blank deleted lines */
  1261. ++static bool             complement;       /* -c: do the complement */
  1262. ++static bool             debugging;        /* -d: debugging reports */
  1263. ++static bool             inplace;      /* -m: modify in place */
  1264. ++static bool             iocccok;      /* -e: fewer IOCCC errors */
  1265. ++static bool             strictlogic;      /* -K: keep ambiguous #ifs */
  1266. ++static bool             killconsts;       /* -k: eval constant #ifs */
  1267. ++static bool             lnnum;            /* -n: add #line directives */
  1268. ++static bool             symlist;      /* -s: output symbol list */
  1269. ++static bool             symdepth;     /* -S: output symbol depth */
  1270. ++static bool             text;         /* -t: this is a text file */
  1271. ++
  1272. ++static const char      *symname[MAXSYMS]; /* symbol name */
  1273. ++static const char      *value[MAXSYMS];       /* -Dsym=value */
  1274. ++static bool             ignore[MAXSYMS];  /* -iDsym or -iUsym */
  1275. ++static int              nsyms;            /* number of symbols */
  1276. ++
  1277. ++static FILE            *input;            /* input file pointer */
  1278. ++static const char      *filename;     /* input file name */
  1279. ++static int              linenum;      /* current line number */
  1280. ++static const char      *linefile;     /* file name for #line */
  1281. ++static FILE            *output;           /* output file pointer */
  1282. ++static const char      *ofilename;        /* output file name */
  1283. ++static const char      *backext;      /* backup extension */
  1284. ++static char            *tempname;     /* avoid splatting input */
  1285. ++
  1286. ++static char             tline[MAXLINE+EDITSLOP];/* input buffer plus space */
  1287. ++static char            *keyword;      /* used for editing #elif's */
  1288. ++
  1289. ++/*
  1290. ++ * When processing a file, the output's newline style will match the
  1291. ++ * input's, and unifdef correctly handles CRLF or LF endings whatever
  1292. ++ * the platform's native style. The stdio streams are opened in binary
  1293. ++ * mode to accommodate platforms whose native newline style is CRLF.
  1294. ++ * When the output isn't a processed input file (when it is error /
  1295. ++ * debug / diagnostic messages) then unifdef uses native line endings.
  1296. ++ */
  1297. ++
  1298. ++static const char      *newline;      /* input file format */
  1299. ++static const char       newline_unix[] = "\n";
  1300. ++static const char       newline_crlf[] = "\r\n";
  1301. ++
  1302. ++static Comment_state    incomment;        /* comment parser state */
  1303. ++static Line_state       linestate;        /* #if line parser state */
  1304. ++static Ifstate          ifstate[MAXDEPTH];    /* #if processor state */
  1305. ++static bool             ignoring[MAXDEPTH];   /* ignore comments state */
  1306. ++static int              stifline[MAXDEPTH];   /* start of current #if */
  1307. ++static int              depth;            /* current #if nesting */
  1308. ++static int              delcount;     /* count of deleted lines */
  1309. ++static unsigned         blankcount;       /* count of blank lines */
  1310. ++static unsigned         blankmax;     /* maximum recent blankcount */
  1311. ++static bool             constexpr;        /* constant #if expression */
  1312. ++static bool             zerosyms;     /* to format symdepth output */
  1313. ++static bool             firstsym;     /* ditto */
  1314. ++
  1315. ++static int              exitmode;     /* exit status mode */
  1316. ++static int              exitstat;     /* program exit status */
  1317. ++
  1318. ++static void             addsym1(bool, bool, char *);
  1319. ++static void             addsym2(bool, const char *, const char *);
  1320. ++static char            *astrcat(const char *, const char *);
  1321. ++static void             cleantemp(void);
  1322. ++static void             closeio(void);
  1323. ++static void             debug(const char *, ...);
  1324. ++static void             debugsym(const char *, int);
  1325. ++static bool             defundef(void);
  1326. ++static void             defundefile(const char *);
  1327. ++static void             done(void);
  1328. ++static void             error(const char *);
  1329. ++static int              findsym(const char **);
  1330. ++static void             flushline(bool);
  1331. ++static void             hashline(void);
  1332. ++static void             help(void);
  1333. ++static Linetype         ifeval(const char **);
  1334. ++static void             ignoreoff(void);
  1335. ++static void             ignoreon(void);
  1336. ++static void             indirectsym(void);
  1337. ++static void             keywordedit(const char *);
  1338. ++static const char      *matchsym(const char *, const char *);
  1339. ++static void             nest(void);
  1340. ++static Linetype         parseline(void);
  1341. ++static void             process(void);
  1342. ++static void             processinout(const char *, const char *);
  1343. ++static const char      *skipargs(const char *);
  1344. ++static const char      *skipcomment(const char *);
  1345. ++static const char      *skiphash(void);
  1346. ++static const char      *skipline(const char *);
  1347. ++static const char      *skipsym(const char *);
  1348. ++static void             state(Ifstate);
  1349. ++static void             unnest(void);
  1350. ++static void             usage(void);
  1351. ++static void             version(void);
  1352. ++static const char      *xstrdup(const char *, const char *);
  1353. ++
  1354. ++#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
  1355. ++
  1356. ++/*
  1357. ++ * The main program.
  1358. ++ */
  1359. ++int
  1360. ++main(int argc, char *argv[])
  1361. ++{
  1362. ++  int opt;
  1363. ++
  1364. ++  while ((opt = getopt(argc, argv, "i:D:U:f:I:M:o:x:bBcdehKklmnsStV")) != -1)
  1365. ++      switch (opt) {
  1366. ++      case 'i': /* treat stuff controlled by these symbols as text */
  1367. ++          /*
  1368. ++           * For strict backwards-compatibility the U or D
  1369. ++           * should be immediately after the -i but it doesn't
  1370. ++           * matter much if we relax that requirement.
  1371. ++           */
  1372. ++          opt = *optarg++;
  1373. ++          if (opt == 'D')
  1374. ++              addsym1(true, true, optarg);
  1375. ++          else if (opt == 'U')
  1376. ++              addsym1(true, false, optarg);
  1377. ++          else
  1378. ++              usage();
  1379. ++          break;
  1380. ++      case 'D': /* define a symbol */
  1381. ++          addsym1(false, true, optarg);
  1382. ++          break;
  1383. ++      case 'U': /* undef a symbol */
  1384. ++          addsym1(false, false, optarg);
  1385. ++          break;
  1386. ++      case 'I': /* no-op for compatibility with cpp */
  1387. ++          break;
  1388. ++      case 'b': /* blank deleted lines instead of omitting them */
  1389. ++      case 'l': /* backwards compatibility */
  1390. ++          lnblank = true;
  1391. ++          break;
  1392. ++      case 'B': /* compress blank lines around removed section */
  1393. ++          compblank = true;
  1394. ++          break;
  1395. ++      case 'c': /* treat -D as -U and vice versa */
  1396. ++          complement = true;
  1397. ++          break;
  1398. ++      case 'd':
  1399. ++          debugging = true;
  1400. ++          break;
  1401. ++      case 'e': /* fewer errors from dodgy lines */
  1402. ++          iocccok = true;
  1403. ++          break;
  1404. ++      case 'f': /* definitions file */
  1405. ++          defundefile(optarg);
  1406. ++          break;
  1407. ++      case 'h':
  1408. ++          help();
  1409. ++          break;
  1410. ++      case 'K': /* keep ambiguous #ifs */
  1411. ++          strictlogic = true;
  1412. ++          break;
  1413. ++      case 'k': /* process constant #ifs */
  1414. ++          killconsts = true;
  1415. ++          break;
  1416. ++      case 'm': /* modify in place */
  1417. ++          inplace = true;
  1418. ++          break;
  1419. ++      case 'M': /* modify in place and keep backup */
  1420. ++          inplace = true;
  1421. ++          backext = optarg;
  1422. ++          break;
  1423. ++      case 'n': /* add #line directive after deleted lines */
  1424. ++          lnnum = true;
  1425. ++          break;
  1426. ++      case 'o': /* output to a file */
  1427. ++          ofilename = optarg;
  1428. ++          break;
  1429. ++      case 's': /* only output list of symbols that control #ifs */
  1430. ++          symlist = true;
  1431. ++          break;
  1432. ++      case 'S': /* list symbols with their nesting depth */
  1433. ++          symlist = symdepth = true;
  1434. ++          break;
  1435. ++      case 't': /* don't parse C comments */
  1436. ++          text = true;
  1437. ++          break;
  1438. ++      case 'V':
  1439. ++          version();
  1440. ++          break;
  1441. ++      case 'x':
  1442. ++          exitmode = atoi(optarg);
  1443. ++          if(exitmode < 0 || exitmode > 2)
  1444. ++              usage();
  1445. ++          break;
  1446. ++      default:
  1447. ++          usage();
  1448. ++      }
  1449. ++  argc -= optind;
  1450. ++  argv += optind;
  1451. ++  if (compblank && lnblank)
  1452. ++      errx(2, "-B and -b are mutually exclusive");
  1453. ++  if (symlist && (ofilename != NULL || inplace || argc > 1))
  1454. ++      errx(2, "-s only works with one input file");
  1455. ++  if (argc > 1 && ofilename != NULL)
  1456. ++      errx(2, "-o cannot be used with multiple input files");
  1457. ++  if (argc > 1 && !inplace)
  1458. ++      errx(2, "multiple input files require -m or -M");
  1459. ++  if (argc == 0)
  1460. ++      argc = 1;
  1461. ++  if (argc == 1 && !inplace && ofilename == NULL)
  1462. ++      ofilename = "-";
  1463. ++  indirectsym();
  1464. ++
  1465. ++  atexit(cleantemp);
  1466. ++  if (ofilename != NULL)
  1467. ++      processinout(*argv, ofilename);
  1468. ++  else while (argc-- > 0) {
  1469. ++      processinout(*argv, *argv);
  1470. ++      argv++;
  1471. ++  }
  1472. ++  switch(exitmode) {
  1473. ++  case(0): exit(exitstat);
  1474. ++  case(1): exit(!exitstat);
  1475. ++  case(2): exit(0);
  1476. ++  default: abort(); /* bug */
  1477. ++  }
  1478. ++}
  1479. ++
  1480. ++/*
  1481. ++ * File logistics.
  1482. ++ */
  1483. ++static void
  1484. ++processinout(const char *ifn, const char *ofn)
  1485. ++{
  1486. ++  struct stat st;
  1487. ++
  1488. ++  if (ifn == NULL || strcmp(ifn, "-") == 0) {
  1489. ++      filename = "[stdin]";
  1490. ++      linefile = NULL;
  1491. ++      input = fbinmode(stdin);
  1492. ++  } else {
  1493. ++      filename = ifn;
  1494. ++      linefile = ifn;
  1495. ++      input = fopen(ifn, "rb");
  1496. ++      if (input == NULL)
  1497. ++          err(2, "can't open %s", ifn);
  1498. ++  }
  1499. ++  if (strcmp(ofn, "-") == 0) {
  1500. ++      output = fbinmode(stdout);
  1501. ++      process();
  1502. ++      return;
  1503. ++  }
  1504. ++  if (stat(ofn, &st) < 0) {
  1505. ++      output = fopen(ofn, "wb");
  1506. ++      if (output == NULL)
  1507. ++          err(2, "can't create %s", ofn);
  1508. ++      process();
  1509. ++      return;
  1510. ++  }
  1511. ++
  1512. ++  tempname = astrcat(ofn, ".XXXXXX");
  1513. ++  output = mktempmode(tempname, st.st_mode);
  1514. ++  if (output == NULL)
  1515. ++      err(2, "can't create %s", tempname);
  1516. ++
  1517. ++  process();
  1518. ++
  1519. ++  if (backext != NULL) {
  1520. ++      char *backname = astrcat(ofn, backext);
  1521. ++      if (rename(ofn, backname) < 0)
  1522. ++          err(2, "can't rename \"%s\" to \"%s\"", ofn, backname);
  1523. ++      free(backname);
  1524. ++  }
  1525. ++  if (replace(tempname, ofn) < 0)
  1526. ++      err(2, "can't rename \"%s\" to \"%s\"", tempname, ofn);
  1527. ++  free(tempname);
  1528. ++  tempname = NULL;
  1529. ++}
  1530. ++
  1531. ++/*
  1532. ++ * For cleaning up if there is an error.
  1533. ++ */
  1534. ++static void
  1535. ++cleantemp(void)
  1536. ++{
  1537. ++  if (tempname != NULL)
  1538. ++      remove(tempname);
  1539. ++}
  1540. ++
  1541. ++/*
  1542. ++ * Self-identification functions.
  1543. ++ */
  1544. ++
  1545. ++static void
  1546. ++version(void)
  1547. ++{
  1548. ++  const char *c = copyright;
  1549. ++  for (;;) {
  1550. ++      while (*++c != '$')
  1551. ++          if (*c == '\0')
  1552. ++              exit(0);
  1553. ++      while (*++c != '$')
  1554. ++          putc(*c, stderr);
  1555. ++      putc('\n', stderr);
  1556. ++  }
  1557. ++}
  1558. ++
  1559. ++static void
  1560. ++synopsis(FILE *fp)
  1561. ++{
  1562. ++  fprintf(fp,
  1563. ++      "usage: unifdef [-bBcdehKkmnsStV] [-x{012}] [-Mext] [-opath] \\\n"
  1564. ++      "       [-[i]Dsym[=val]] [-[i]Usym] [-fpath] ... [file] ...\n");
  1565. ++}
  1566. ++
  1567. ++static void
  1568. ++usage(void)
  1569. ++{
  1570. ++  synopsis(stderr);
  1571. ++  exit(2);
  1572. ++}
  1573. ++
  1574. ++static void
  1575. ++help(void)
  1576. ++{
  1577. ++  synopsis(stdout);
  1578. ++  printf(
  1579. ++      "   -Dsym=val  define preprocessor symbol with given value\n"
  1580. ++      "   -Dsym      define preprocessor symbol with value 1\n"
  1581. ++      "   -Usym      preprocessor symbol is undefined\n"
  1582. ++      "   -iDsym=val \\  ignore C strings and comments\n"
  1583. ++      "   -iDsym      ) in sections controlled by these\n"
  1584. ++      "   -iUsym     /  preprocessor symbols\n"
  1585. ++      "   -fpath  file containing #define and #undef directives\n"
  1586. ++      "   -b  blank lines instead of deleting them\n"
  1587. ++      "   -B  compress blank lines around deleted section\n"
  1588. ++      "   -c  complement (invert) keep vs. delete\n"
  1589. ++      "   -d  debugging mode\n"
  1590. ++      "   -e  ignore multiline preprocessor directives\n"
  1591. ++      "   -h  print help\n"
  1592. ++      "   -Ipath  extra include file path (ignored)\n"
  1593. ++      "   -K  disable && and || short-circuiting\n"
  1594. ++      "   -k  process constant #if expressions\n"
  1595. ++      "   -Mext   modify in place and keep backups\n"
  1596. ++      "   -m  modify input files in place\n"
  1597. ++      "   -n  add #line directives to output\n"
  1598. ++      "   -opath  output file name\n"
  1599. ++      "   -S  list #if control symbols with nesting\n"
  1600. ++      "   -s  list #if control symbols\n"
  1601. ++      "   -t  ignore C strings and comments\n"
  1602. ++      "   -V  print version\n"
  1603. ++      "   -x{012} exit status mode\n"
  1604. ++  );
  1605. ++  exit(0);
  1606. ++}
  1607. ++
  1608. ++/*
  1609. ++ * A state transition function alters the global #if processing state
  1610. ++ * in a particular way. The table below is indexed by the current
  1611. ++ * processing state and the type of the current line.
  1612. ++ *
  1613. ++ * Nesting is handled by keeping a stack of states; some transition
  1614. ++ * functions increase or decrease the depth. They also maintain the
  1615. ++ * ignore state on a stack. In some complicated cases they have to
  1616. ++ * alter the preprocessor directive, as follows.
  1617. ++ *
  1618. ++ * When we have processed a group that starts off with a known-false
  1619. ++ * #if/#elif sequence (which has therefore been deleted) followed by a
  1620. ++ * #elif that we don't understand and therefore must keep, we edit the
  1621. ++ * latter into a #if to keep the nesting correct. We use memcpy() to
  1622. ++ * overwrite the 4 byte token "elif" with "if  " without a '\0' byte.
  1623. ++ *
  1624. ++ * When we find a true #elif in a group, the following block will
  1625. ++ * always be kept and the rest of the sequence after the next #elif or
  1626. ++ * #else will be discarded. We edit the #elif into a #else and the
  1627. ++ * following directive to #endif since this has the desired behaviour.
  1628. ++ *
  1629. ++ * "Dodgy" directives are split across multiple lines, the most common
  1630. ++ * example being a multi-line comment hanging off the right of the
  1631. ++ * directive. We can handle them correctly only if there is no change
  1632. ++ * from printing to dropping (or vice versa) caused by that directive.
  1633. ++ * If the directive is the first of a group we have a choice between
  1634. ++ * failing with an error, or passing it through unchanged instead of
  1635. ++ * evaluating it. The latter is not the default to avoid questions from
  1636. ++ * users about unifdef unexpectedly leaving behind preprocessor directives.
  1637. ++ */
  1638. ++typedef void state_fn(void);
  1639. ++
  1640. ++/* report an error */
  1641. ++static void Eelif (void) { error("Inappropriate #elif"); }
  1642. ++static void Eelse (void) { error("Inappropriate #else"); }
  1643. ++static void Eendif(void) { error("Inappropriate #endif"); }
  1644. ++static void Eeof  (void) { error("Premature EOF"); }
  1645. ++static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
  1646. ++/* plain line handling */
  1647. ++static void print (void) { flushline(true); }
  1648. ++static void drop  (void) { flushline(false); }
  1649. ++/* output lacks group's start line */
  1650. ++static void Strue (void) { drop();  ignoreoff(); state(IS_TRUE_PREFIX); }
  1651. ++static void Sfalse(void) { drop();  ignoreoff(); state(IS_FALSE_PREFIX); }
  1652. ++static void Selse (void) { drop();               state(IS_TRUE_ELSE); }
  1653. ++/* print/pass this block */
  1654. ++static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
  1655. ++static void Pelse (void) { print();              state(IS_PASS_ELSE); }
  1656. ++static void Pendif(void) { print(); unnest(); }
  1657. ++/* discard this block */
  1658. ++static void Dfalse(void) { drop();  ignoreoff(); state(IS_FALSE_TRAILER); }
  1659. ++static void Delif (void) { drop();  ignoreoff(); state(IS_FALSE_MIDDLE); }
  1660. ++static void Delse (void) { drop();               state(IS_FALSE_ELSE); }
  1661. ++static void Dendif(void) { drop();  unnest(); }
  1662. ++/* first line of group */
  1663. ++static void Fdrop (void) { nest();  Dfalse(); }
  1664. ++static void Fpass (void) { nest();  Pelif(); }
  1665. ++static void Ftrue (void) { nest();  Strue(); }
  1666. ++static void Ffalse(void) { nest();  Sfalse(); }
  1667. ++/* variable pedantry for obfuscated lines */
  1668. ++static void Oiffy (void) { if (!iocccok) Eioccc(); Fpass(); ignoreon(); }
  1669. ++static void Oif   (void) { if (!iocccok) Eioccc(); Fpass(); }
  1670. ++static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
  1671. ++/* ignore comments in this block */
  1672. ++static void Idrop (void) { Fdrop();  ignoreon(); }
  1673. ++static void Itrue (void) { Ftrue();  ignoreon(); }
  1674. ++static void Ifalse(void) { Ffalse(); ignoreon(); }
  1675. ++/* modify this line */
  1676. ++static void Mpass (void) { memcpy(keyword, "if  ", 4); Pelif(); }
  1677. ++static void Mtrue (void) { keywordedit("else");  state(IS_TRUE_MIDDLE); }
  1678. ++static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
  1679. ++static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
  1680. ++
  1681. ++static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
  1682. ++/* IS_OUTSIDE */
  1683. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
  1684. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eendif,
  1685. ++  print, done,  abort },
  1686. ++/* IS_FALSE_PREFIX */
  1687. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
  1688. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
  1689. ++  drop,  Eeof,  abort },
  1690. ++/* IS_TRUE_PREFIX */
  1691. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
  1692. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
  1693. ++  print, Eeof,  abort },
  1694. ++/* IS_PASS_MIDDLE */
  1695. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
  1696. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Pelif, Oelif, Oelif, Pelse, Pendif,
  1697. ++  print, Eeof,  abort },
  1698. ++/* IS_FALSE_MIDDLE */
  1699. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
  1700. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
  1701. ++  drop,  Eeof,  abort },
  1702. ++/* IS_TRUE_MIDDLE */
  1703. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
  1704. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
  1705. ++  print, Eeof,  abort },
  1706. ++/* IS_PASS_ELSE */
  1707. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
  1708. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Pendif,
  1709. ++  print, Eeof,  abort },
  1710. ++/* IS_FALSE_ELSE */
  1711. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
  1712. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
  1713. ++  drop,  Eeof,  abort },
  1714. ++/* IS_TRUE_ELSE */
  1715. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
  1716. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eioccc,
  1717. ++  print, Eeof,  abort },
  1718. ++/* IS_FALSE_TRAILER */
  1719. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
  1720. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
  1721. ++  drop,  Eeof,  abort }
  1722. ++/*TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF
  1723. ++  TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF (DODGY)
  1724. ++  PLAIN  EOF    ERROR */
  1725. ++};
  1726. ++
  1727. ++/*
  1728. ++ * State machine utility functions
  1729. ++ */
  1730. ++static void
  1731. ++ignoreoff(void)
  1732. ++{
  1733. ++  if (depth == 0)
  1734. ++      abort(); /* bug */
  1735. ++  ignoring[depth] = ignoring[depth-1];
  1736. ++}
  1737. ++static void
  1738. ++ignoreon(void)
  1739. ++{
  1740. ++  ignoring[depth] = true;
  1741. ++}
  1742. ++static void
  1743. ++keywordedit(const char *replacement)
  1744. ++{
  1745. ++  snprintf(keyword, tline + sizeof(tline) - keyword,
  1746. ++      "%s%s", replacement, newline);
  1747. ++  print();
  1748. ++}
  1749. ++static void
  1750. ++nest(void)
  1751. ++{
  1752. ++  if (depth > MAXDEPTH-1)
  1753. ++      abort(); /* bug */
  1754. ++  if (depth == MAXDEPTH-1)
  1755. ++      error("Too many levels of nesting");
  1756. ++  depth += 1;
  1757. ++  stifline[depth] = linenum;
  1758. ++}
  1759. ++static void
  1760. ++unnest(void)
  1761. ++{
  1762. ++  if (depth == 0)
  1763. ++      abort(); /* bug */
  1764. ++  depth -= 1;
  1765. ++}
  1766. ++static void
  1767. ++state(Ifstate is)
  1768. ++{
  1769. ++  ifstate[depth] = is;
  1770. ++}
  1771. ++
  1772. ++/*
  1773. ++ * The last state transition function. When this is called,
  1774. ++ * lineval == LT_EOF, so the process() loop will terminate.
  1775. ++ */
  1776. ++static void
  1777. ++done(void)
  1778. ++{
  1779. ++  if (incomment)
  1780. ++      error("EOF in comment");
  1781. ++  closeio();
  1782. ++}
  1783. ++
  1784. ++/*
  1785. ++ * Write a line to the output or not, according to command line options.
  1786. ++ * If writing fails, closeio() will print the error and exit.
  1787. ++ */
  1788. ++static void
  1789. ++flushline(bool keep)
  1790. ++{
  1791. ++  if (symlist)
  1792. ++      return;
  1793. ++  if (keep ^ complement) {
  1794. ++      bool blankline = tline[strspn(tline, " \t\r\n")] == '\0';
  1795. ++      if (blankline && compblank && blankcount != blankmax) {
  1796. ++          delcount += 1;
  1797. ++          blankcount += 1;
  1798. ++      } else {
  1799. ++          if (lnnum && delcount > 0)
  1800. ++              hashline();
  1801. ++          if (fputs(tline, output) == EOF)
  1802. ++              closeio();
  1803. ++          delcount = 0;
  1804. ++          blankmax = blankcount = blankline ? blankcount + 1 : 0;
  1805. ++      }
  1806. ++  } else {
  1807. ++      if (lnblank && fputs(newline, output) == EOF)
  1808. ++          closeio();
  1809. ++      exitstat = 1;
  1810. ++      delcount += 1;
  1811. ++      blankcount = 0;
  1812. ++  }
  1813. ++  if (debugging && fflush(output) == EOF)
  1814. ++      closeio();
  1815. ++}
  1816. ++
  1817. ++/*
  1818. ++ * Format of #line directives depends on whether we know the input filename.
  1819. ++ */
  1820. ++static void
  1821. ++hashline(void)
  1822. ++{
  1823. ++  int e;
  1824. ++
  1825. ++  if (linefile == NULL)
  1826. ++      e = fprintf(output, "#line %d%s", linenum, newline);
  1827. ++  else
  1828. ++      e = fprintf(output, "#line %d \"%s\"%s",
  1829. ++          linenum, linefile, newline);
  1830. ++  if (e < 0)
  1831. ++      closeio();
  1832. ++}
  1833. ++
  1834. ++/*
  1835. ++ * Flush the output and handle errors.
  1836. ++ */
  1837. ++static void
  1838. ++closeio(void)
  1839. ++{
  1840. ++  /* Tidy up after findsym(). */
  1841. ++  if (symdepth && !zerosyms)
  1842. ++      printf("\n");
  1843. ++  if (output != NULL && (ferror(output) || fclose(output) == EOF))
  1844. ++          err(2, "%s: can't write to output", filename);
  1845. ++  fclose(input);
  1846. ++}
  1847. ++
  1848. ++/*
  1849. ++ * The driver for the state machine.
  1850. ++ */
  1851. ++static void
  1852. ++process(void)
  1853. ++{
  1854. ++  Linetype lineval = LT_PLAIN;
  1855. ++  /* When compressing blank lines, act as if the file
  1856. ++     is preceded by a large number of blank lines. */
  1857. ++  blankmax = blankcount = 1000;
  1858. ++  zerosyms = true;
  1859. ++  newline = NULL;
  1860. ++  linenum = 0;
  1861. ++  while (lineval != LT_EOF) {
  1862. ++      lineval = parseline();
  1863. ++      trans_table[ifstate[depth]][lineval]();
  1864. ++      debug("process line %d %s -> %s depth %d",
  1865. ++          linenum, linetype_name[lineval],
  1866. ++          ifstate_name[ifstate[depth]], depth);
  1867. ++  }
  1868. ++}
  1869. ++
  1870. ++/*
  1871. ++ * Parse a line and determine its type. We keep the preprocessor line
  1872. ++ * parser state between calls in the global variable linestate, with
  1873. ++ * help from skipcomment().
  1874. ++ */
  1875. ++static Linetype
  1876. ++parseline(void)
  1877. ++{
  1878. ++  const char *cp;
  1879. ++  int cursym;
  1880. ++  Linetype retval;
  1881. ++  Comment_state wascomment;
  1882. ++
  1883. ++  wascomment = incomment;
  1884. ++  cp = skiphash();
  1885. ++  if (cp == NULL)
  1886. ++      return (LT_EOF);
  1887. ++  if (newline == NULL) {
  1888. ++      if (strrchr(tline, '\n') == strrchr(tline, '\r') + 1)
  1889. ++          newline = newline_crlf;
  1890. ++      else
  1891. ++          newline = newline_unix;
  1892. ++  }
  1893. ++  if (*cp == '\0') {
  1894. ++      retval = LT_PLAIN;
  1895. ++      goto done;
  1896. ++  }
  1897. ++  keyword = tline + (cp - tline);
  1898. ++  if ((cp = matchsym("ifdef", keyword)) != NULL ||
  1899. ++      (cp = matchsym("ifndef", keyword)) != NULL) {
  1900. ++      cp = skipcomment(cp);
  1901. ++      if ((cursym = findsym(&cp)) < 0)
  1902. ++          retval = LT_IF;
  1903. ++      else {
  1904. ++          retval = (keyword[2] == 'n')
  1905. ++              ? LT_FALSE : LT_TRUE;
  1906. ++          if (value[cursym] == NULL)
  1907. ++              retval = (retval == LT_TRUE)
  1908. ++                  ? LT_FALSE : LT_TRUE;
  1909. ++          if (ignore[cursym])
  1910. ++              retval = (retval == LT_TRUE)
  1911. ++                  ? LT_TRUEI : LT_FALSEI;
  1912. ++      }
  1913. ++  } else if ((cp = matchsym("if", keyword)) != NULL)
  1914. ++      retval = ifeval(&cp);
  1915. ++  else if ((cp = matchsym("elif", keyword)) != NULL)
  1916. ++      retval = linetype_if2elif(ifeval(&cp));
  1917. ++  else if ((cp = matchsym("else", keyword)) != NULL)
  1918. ++      retval = LT_ELSE;
  1919. ++  else if ((cp = matchsym("endif", keyword)) != NULL)
  1920. ++      retval = LT_ENDIF;
  1921. ++  else {
  1922. ++      cp = skipsym(keyword);
  1923. ++      /* no way can we deal with a continuation inside a keyword */
  1924. ++      if (strncmp(cp, "\\\r\n", 3) == 0 ||
  1925. ++          strncmp(cp, "\\\n", 2) == 0)
  1926. ++          Eioccc();
  1927. ++      cp = skipline(cp);
  1928. ++      retval = LT_PLAIN;
  1929. ++      goto done;
  1930. ++  }
  1931. ++  cp = skipcomment(cp);
  1932. ++  if (*cp != '\0') {
  1933. ++      cp = skipline(cp);
  1934. ++      if (retval == LT_TRUE || retval == LT_FALSE ||
  1935. ++          retval == LT_TRUEI || retval == LT_FALSEI)
  1936. ++          retval = LT_IF;
  1937. ++      if (retval == LT_ELTRUE || retval == LT_ELFALSE)
  1938. ++          retval = LT_ELIF;
  1939. ++  }
  1940. ++  /* the following can happen if the last line of the file lacks a
  1941. ++     newline or if there is too much whitespace in a directive */
  1942. ++  if (linestate == LS_HASH) {
  1943. ++      long len = cp - tline;
  1944. ++      if (fgets(tline + len, MAXLINE - len, input) == NULL) {
  1945. ++          if (ferror(input))
  1946. ++              err(2, "can't read %s", filename);
  1947. ++          /* append the missing newline at eof */
  1948. ++          strcpy(tline + len, newline);
  1949. ++          cp += strlen(newline);
  1950. ++          linestate = LS_START;
  1951. ++      } else {
  1952. ++          linestate = LS_DIRTY;
  1953. ++      }
  1954. ++  }
  1955. ++  if (retval != LT_PLAIN && (wascomment || linestate != LS_START)) {
  1956. ++      retval = linetype_2dodgy(retval);
  1957. ++      linestate = LS_DIRTY;
  1958. ++  }
  1959. ++done:
  1960. ++  debug("parser line %d state %s comment %s line", linenum,
  1961. ++      comment_name[incomment], linestate_name[linestate]);
  1962. ++  return (retval);
  1963. ++}
  1964. ++
  1965. ++/*
  1966. ++ * These are the binary operators that are supported by the expression
  1967. ++ * evaluator.
  1968. ++ */
  1969. ++static Linetype op_strict(long *p, long v, Linetype at, Linetype bt) {
  1970. ++  if(at == LT_IF || bt == LT_IF) return (LT_IF);
  1971. ++  return (*p = v, v ? LT_TRUE : LT_FALSE);
  1972. ++}
  1973. ++static Linetype op_lt(long *p, Linetype at, long a, Linetype bt, long b) {
  1974. ++  return op_strict(p, a < b, at, bt);
  1975. ++}
  1976. ++static Linetype op_gt(long *p, Linetype at, long a, Linetype bt, long b) {
  1977. ++  return op_strict(p, a > b, at, bt);
  1978. ++}
  1979. ++static Linetype op_le(long *p, Linetype at, long a, Linetype bt, long b) {
  1980. ++  return op_strict(p, a <= b, at, bt);
  1981. ++}
  1982. ++static Linetype op_ge(long *p, Linetype at, long a, Linetype bt, long b) {
  1983. ++  return op_strict(p, a >= b, at, bt);
  1984. ++}
  1985. ++static Linetype op_eq(long *p, Linetype at, long a, Linetype bt, long b) {
  1986. ++  return op_strict(p, a == b, at, bt);
  1987. ++}
  1988. ++static Linetype op_ne(long *p, Linetype at, long a, Linetype bt, long b) {
  1989. ++  return op_strict(p, a != b, at, bt);
  1990. ++}
  1991. ++static Linetype op_or(long *p, Linetype at, long a, Linetype bt, long b) {
  1992. ++  if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE))
  1993. ++      return (*p = 1, LT_TRUE);
  1994. ++  return op_strict(p, a || b, at, bt);
  1995. ++}
  1996. ++static Linetype op_and(long *p, Linetype at, long a, Linetype bt, long b) {
  1997. ++  if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE))
  1998. ++      return (*p = 0, LT_FALSE);
  1999. ++  return op_strict(p, a && b, at, bt);
  2000. ++}
  2001. ++
  2002. ++/*
  2003. ++ * An evaluation function takes three arguments, as follows: (1) a pointer to
  2004. ++ * an element of the precedence table which lists the operators at the current
  2005. ++ * level of precedence; (2) a pointer to an integer which will receive the
  2006. ++ * value of the expression; and (3) a pointer to a char* that points to the
  2007. ++ * expression to be evaluated and that is updated to the end of the expression
  2008. ++ * when evaluation is complete. The function returns LT_FALSE if the value of
  2009. ++ * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression
  2010. ++ * depends on an unknown symbol, or LT_ERROR if there is a parse failure.
  2011. ++ */
  2012. ++struct ops;
  2013. ++
  2014. ++typedef Linetype eval_fn(const struct ops *, long *, const char **);
  2015. ++
  2016. ++static eval_fn eval_table, eval_unary;
  2017. ++
  2018. ++/*
  2019. ++ * The precedence table. Expressions involving binary operators are evaluated
  2020. ++ * in a table-driven way by eval_table. When it evaluates a subexpression it
  2021. ++ * calls the inner function with its first argument pointing to the next
  2022. ++ * element of the table. Innermost expressions have special non-table-driven
  2023. ++ * handling.
  2024. ++ */
  2025. ++struct op {
  2026. ++  const char *str;
  2027. ++  Linetype (*fn)(long *, Linetype, long, Linetype, long);
  2028. ++};
  2029. ++struct ops {
  2030. ++  eval_fn *inner;
  2031. ++  struct op op[5];
  2032. ++};
  2033. ++static const struct ops eval_ops[] = {
  2034. ++  { eval_table, { { "||", op_or } } },
  2035. ++  { eval_table, { { "&&", op_and } } },
  2036. ++  { eval_table, { { "==", op_eq },
  2037. ++          { "!=", op_ne } } },
  2038. ++  { eval_unary, { { "<=", op_le },
  2039. ++          { ">=", op_ge },
  2040. ++          { "<", op_lt },
  2041. ++          { ">", op_gt } } }
  2042. ++};
  2043. ++
  2044. ++/* Current operator precedence level */
  2045. ++static long prec(const struct ops *ops)
  2046. ++{
  2047. ++  return (ops - eval_ops);
  2048. ++}
  2049. ++
  2050. ++/*
  2051. ++ * Function for evaluating the innermost parts of expressions,
  2052. ++ * viz. !expr (expr) number defined(symbol) symbol
  2053. ++ * We reset the constexpr flag in the last two cases.
  2054. ++ */
  2055. ++static Linetype
  2056. ++eval_unary(const struct ops *ops, long *valp, const char **cpp)
  2057. ++{
  2058. ++  const char *cp;
  2059. ++  char *ep;
  2060. ++  int sym;
  2061. ++  bool defparen;
  2062. ++  Linetype lt;
  2063. ++
  2064. ++  cp = skipcomment(*cpp);
  2065. ++  if (*cp == '!') {
  2066. ++      debug("eval%d !", prec(ops));
  2067. ++      cp++;
  2068. ++      lt = eval_unary(ops, valp, &cp);
  2069. ++      if (lt == LT_ERROR)
  2070. ++          return (LT_ERROR);
  2071. ++      if (lt != LT_IF) {
  2072. ++          *valp = !*valp;
  2073. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  2074. ++      }
  2075. ++  } else if (*cp == '(') {
  2076. ++      cp++;
  2077. ++      debug("eval%d (", prec(ops));
  2078. ++      lt = eval_table(eval_ops, valp, &cp);
  2079. ++      if (lt == LT_ERROR)
  2080. ++          return (LT_ERROR);
  2081. ++      cp = skipcomment(cp);
  2082. ++      if (*cp++ != ')')
  2083. ++          return (LT_ERROR);
  2084. ++  } else if (isdigit((unsigned char)*cp)) {
  2085. ++      debug("eval%d number", prec(ops));
  2086. ++      *valp = strtol(cp, &ep, 0);
  2087. ++      if (ep == cp)
  2088. ++          return (LT_ERROR);
  2089. ++      lt = *valp ? LT_TRUE : LT_FALSE;
  2090. ++      cp = ep;
  2091. ++  } else if (matchsym("defined", cp) != NULL) {
  2092. ++      cp = skipcomment(cp+7);
  2093. ++      if (*cp == '(') {
  2094. ++          cp = skipcomment(cp+1);
  2095. ++          defparen = true;
  2096. ++      } else {
  2097. ++          defparen = false;
  2098. ++      }
  2099. ++      sym = findsym(&cp);
  2100. ++      cp = skipcomment(cp);
  2101. ++      if (defparen && *cp++ != ')') {
  2102. ++          debug("eval%d defined missing ')'", prec(ops));
  2103. ++          return (LT_ERROR);
  2104. ++      }
  2105. ++      if (sym < 0) {
  2106. ++          debug("eval%d defined unknown", prec(ops));
  2107. ++          lt = LT_IF;
  2108. ++      } else {
  2109. ++          debug("eval%d defined %s", prec(ops), symname[sym]);
  2110. ++          *valp = (value[sym] != NULL);
  2111. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  2112. ++      }
  2113. ++      constexpr = false;
  2114. ++  } else if (!endsym(*cp)) {
  2115. ++      debug("eval%d symbol", prec(ops));
  2116. ++      sym = findsym(&cp);
  2117. ++      if (sym < 0) {
  2118. ++          lt = LT_IF;
  2119. ++          cp = skipargs(cp);
  2120. ++      } else if (value[sym] == NULL) {
  2121. ++          *valp = 0;
  2122. ++          lt = LT_FALSE;
  2123. ++      } else {
  2124. ++          *valp = strtol(value[sym], &ep, 0);
  2125. ++          if (*ep != '\0' || ep == value[sym])
  2126. ++              return (LT_ERROR);
  2127. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  2128. ++          cp = skipargs(cp);
  2129. ++      }
  2130. ++      constexpr = false;
  2131. ++  } else {
  2132. ++      debug("eval%d bad expr", prec(ops));
  2133. ++      return (LT_ERROR);
  2134. ++  }
  2135. ++
  2136. ++  *cpp = cp;
  2137. ++  debug("eval%d = %d", prec(ops), *valp);
  2138. ++  return (lt);
  2139. ++}
  2140. ++
  2141. ++/*
  2142. ++ * Table-driven evaluation of binary operators.
  2143. ++ */
  2144. ++static Linetype
  2145. ++eval_table(const struct ops *ops, long *valp, const char **cpp)
  2146. ++{
  2147. ++  const struct op *op;
  2148. ++  const char *cp;
  2149. ++  long val;
  2150. ++  Linetype lt, rt;
  2151. ++
  2152. ++  debug("eval%d", prec(ops));
  2153. ++  cp = *cpp;
  2154. ++  lt = ops->inner(ops+1, valp, &cp);
  2155. ++  if (lt == LT_ERROR)
  2156. ++      return (LT_ERROR);
  2157. ++  for (;;) {
  2158. ++      cp = skipcomment(cp);
  2159. ++      for (op = ops->op; op->str != NULL; op++)
  2160. ++          if (strncmp(cp, op->str, strlen(op->str)) == 0)
  2161. ++              break;
  2162. ++      if (op->str == NULL)
  2163. ++          break;
  2164. ++      cp += strlen(op->str);
  2165. ++      debug("eval%d %s", prec(ops), op->str);
  2166. ++      rt = ops->inner(ops+1, &val, &cp);
  2167. ++      if (rt == LT_ERROR)
  2168. ++          return (LT_ERROR);
  2169. ++      lt = op->fn(valp, lt, *valp, rt, val);
  2170. ++  }
  2171. ++
  2172. ++  *cpp = cp;
  2173. ++  debug("eval%d = %d", prec(ops), *valp);
  2174. ++  debug("eval%d lt = %s", prec(ops), linetype_name[lt]);
  2175. ++  return (lt);
  2176. ++}
  2177. ++
  2178. ++/*
  2179. ++ * Evaluate the expression on a #if or #elif line. If we can work out
  2180. ++ * the result we return LT_TRUE or LT_FALSE accordingly, otherwise we
  2181. ++ * return just a generic LT_IF.
  2182. ++ */
  2183. ++static Linetype
  2184. ++ifeval(const char **cpp)
  2185. ++{
  2186. ++  Linetype ret;
  2187. ++  long val = 0;
  2188. ++
  2189. ++  debug("eval %s", *cpp);
  2190. ++  constexpr = killconsts ? false : true;
  2191. ++  ret = eval_table(eval_ops, &val, cpp);
  2192. ++  debug("eval = %d", val);
  2193. ++  return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
  2194. ++}
  2195. ++
  2196. ++/*
  2197. ++ * Read a line and examine its initial part to determine if it is a
  2198. ++ * preprocessor directive. Returns NULL on EOF, or a pointer to a
  2199. ++ * preprocessor directive name, or a pointer to the zero byte at the
  2200. ++ * end of the line.
  2201. ++ */
  2202. ++static const char *
  2203. ++skiphash(void)
  2204. ++{
  2205. ++  const char *cp;
  2206. ++
  2207. ++  linenum++;
  2208. ++  if (fgets(tline, MAXLINE, input) == NULL) {
  2209. ++      if (ferror(input))
  2210. ++          err(2, "can't read %s", filename);
  2211. ++      else
  2212. ++          return (NULL);
  2213. ++  }
  2214. ++  cp = skipcomment(tline);
  2215. ++  if (linestate == LS_START && *cp == '#') {
  2216. ++      linestate = LS_HASH;
  2217. ++      return (skipcomment(cp + 1));
  2218. ++  } else if (*cp == '\0') {
  2219. ++      return (cp);
  2220. ++  } else {
  2221. ++      return (skipline(cp));
  2222. ++  }
  2223. ++}
  2224. ++
  2225. ++/*
  2226. ++ * Mark a line dirty and consume the rest of it, keeping track of the
  2227. ++ * lexical state.
  2228. ++ */
  2229. ++static const char *
  2230. ++skipline(const char *cp)
  2231. ++{
  2232. ++  linestate = LS_DIRTY;
  2233. ++  while (*cp != '\0')
  2234. ++      cp = skipcomment(cp + 1);
  2235. ++  return (cp);
  2236. ++}
  2237. ++
  2238. ++/*
  2239. ++ * Skip over comments, strings, and character literals and stop at the
  2240. ++ * next character position that is not whitespace. Between calls we keep
  2241. ++ * the comment state in the global variable incomment, and we also adjust
  2242. ++ * the global variable linestate when we see a newline.
  2243. ++ * XXX: doesn't cope with the buffer splitting inside a state transition.
  2244. ++ */
  2245. ++static const char *
  2246. ++skipcomment(const char *cp)
  2247. ++{
  2248. ++  if (text || ignoring[depth]) {
  2249. ++      for (; isspace((unsigned char)*cp); cp++)
  2250. ++          if (*cp == '\n')
  2251. ++              linestate = LS_START;
  2252. ++      return (cp);
  2253. ++  }
  2254. ++  while (*cp != '\0')
  2255. ++      /* don't reset to LS_START after a line continuation */
  2256. ++      if (strncmp(cp, "\\\r\n", 3) == 0)
  2257. ++          cp += 3;
  2258. ++      else if (strncmp(cp, "\\\n", 2) == 0)
  2259. ++          cp += 2;
  2260. ++      else switch (incomment) {
  2261. ++      case NO_COMMENT:
  2262. ++          if (strncmp(cp, "/\\\r\n", 4) == 0) {
  2263. ++              incomment = STARTING_COMMENT;
  2264. ++              cp += 4;
  2265. ++          } else if (strncmp(cp, "/\\\n", 3) == 0) {
  2266. ++              incomment = STARTING_COMMENT;
  2267. ++              cp += 3;
  2268. ++          } else if (strncmp(cp, "/*", 2) == 0) {
  2269. ++              incomment = C_COMMENT;
  2270. ++              cp += 2;
  2271. ++          } else if (strncmp(cp, "//", 2) == 0) {
  2272. ++              incomment = CXX_COMMENT;
  2273. ++              cp += 2;
  2274. ++          } else if (strncmp(cp, "\'", 1) == 0) {
  2275. ++              incomment = CHAR_LITERAL;
  2276. ++              linestate = LS_DIRTY;
  2277. ++              cp += 1;
  2278. ++          } else if (strncmp(cp, "\"", 1) == 0) {
  2279. ++              incomment = STRING_LITERAL;
  2280. ++              linestate = LS_DIRTY;
  2281. ++              cp += 1;
  2282. ++          } else if (strncmp(cp, "\n", 1) == 0) {
  2283. ++              linestate = LS_START;
  2284. ++              cp += 1;
  2285. ++          } else if (strchr(" \r\t", *cp) != NULL) {
  2286. ++              cp += 1;
  2287. ++          } else
  2288. ++              return (cp);
  2289. ++          continue;
  2290. ++      case CXX_COMMENT:
  2291. ++          if (strncmp(cp, "\n", 1) == 0) {
  2292. ++              incomment = NO_COMMENT;
  2293. ++              linestate = LS_START;
  2294. ++          }
  2295. ++          cp += 1;
  2296. ++          continue;
  2297. ++      case CHAR_LITERAL:
  2298. ++      case STRING_LITERAL:
  2299. ++          if ((incomment == CHAR_LITERAL && cp[0] == '\'') ||
  2300. ++              (incomment == STRING_LITERAL && cp[0] == '\"')) {
  2301. ++              incomment = NO_COMMENT;
  2302. ++              cp += 1;
  2303. ++          } else if (cp[0] == '\\') {
  2304. ++              if (cp[1] == '\0')
  2305. ++                  cp += 1;
  2306. ++              else
  2307. ++                  cp += 2;
  2308. ++          } else if (strncmp(cp, "\n", 1) == 0) {
  2309. ++              if (incomment == CHAR_LITERAL)
  2310. ++                  error("unterminated char literal");
  2311. ++              else
  2312. ++                  error("unterminated string literal");
  2313. ++          } else
  2314. ++              cp += 1;
  2315. ++          continue;
  2316. ++      case C_COMMENT:
  2317. ++          if (strncmp(cp, "*\\\r\n", 4) == 0) {
  2318. ++              incomment = FINISHING_COMMENT;
  2319. ++              cp += 4;
  2320. ++          } else if (strncmp(cp, "*\\\n", 3) == 0) {
  2321. ++              incomment = FINISHING_COMMENT;
  2322. ++              cp += 3;
  2323. ++          } else if (strncmp(cp, "*/", 2) == 0) {
  2324. ++              incomment = NO_COMMENT;
  2325. ++              cp += 2;
  2326. ++          } else
  2327. ++              cp += 1;
  2328. ++          continue;
  2329. ++      case STARTING_COMMENT:
  2330. ++          if (*cp == '*') {
  2331. ++              incomment = C_COMMENT;
  2332. ++              cp += 1;
  2333. ++          } else if (*cp == '/') {
  2334. ++              incomment = CXX_COMMENT;
  2335. ++              cp += 1;
  2336. ++          } else {
  2337. ++              incomment = NO_COMMENT;
  2338. ++              linestate = LS_DIRTY;
  2339. ++          }
  2340. ++          continue;
  2341. ++      case FINISHING_COMMENT:
  2342. ++          if (*cp == '/') {
  2343. ++              incomment = NO_COMMENT;
  2344. ++              cp += 1;
  2345. ++          } else
  2346. ++              incomment = C_COMMENT;
  2347. ++          continue;
  2348. ++      default:
  2349. ++          abort(); /* bug */
  2350. ++      }
  2351. ++  return (cp);
  2352. ++}
  2353. ++
  2354. ++/*
  2355. ++ * Skip macro arguments.
  2356. ++ */
  2357. ++static const char *
  2358. ++skipargs(const char *cp)
  2359. ++{
  2360. ++  const char *ocp = cp;
  2361. ++  int level = 0;
  2362. ++  cp = skipcomment(cp);
  2363. ++  if (*cp != '(')
  2364. ++      return (cp);
  2365. ++  do {
  2366. ++      if (*cp == '(')
  2367. ++          level++;
  2368. ++      if (*cp == ')')
  2369. ++          level--;
  2370. ++      cp = skipcomment(cp+1);
  2371. ++  } while (level != 0 && *cp != '\0');
  2372. ++  if (level == 0)
  2373. ++      return (cp);
  2374. ++  else
  2375. ++  /* Rewind and re-detect the syntax error later. */
  2376. ++      return (ocp);
  2377. ++}
  2378. ++
  2379. ++/*
  2380. ++ * Skip over an identifier.
  2381. ++ */
  2382. ++static const char *
  2383. ++skipsym(const char *cp)
  2384. ++{
  2385. ++  while (!endsym(*cp))
  2386. ++      ++cp;
  2387. ++  return (cp);
  2388. ++}
  2389. ++
  2390. ++/*
  2391. ++ * Skip whitespace and take a copy of any following identifier.
  2392. ++ */
  2393. ++static const char *
  2394. ++getsym(const char **cpp)
  2395. ++{
  2396. ++  const char *cp = *cpp, *sym;
  2397. ++
  2398. ++  cp = skipcomment(cp);
  2399. ++  cp = skipsym(sym = cp);
  2400. ++  if (cp == sym)
  2401. ++      return NULL;
  2402. ++  *cpp = cp;
  2403. ++  return (xstrdup(sym, cp));
  2404. ++}
  2405. ++
  2406. ++/*
  2407. ++ * Check that s (a symbol) matches the start of t, and that the
  2408. ++ * following character in t is not a symbol character. Returns a
  2409. ++ * pointer to the following character in t if there is a match,
  2410. ++ * otherwise NULL.
  2411. ++ */
  2412. ++static const char *
  2413. ++matchsym(const char *s, const char *t)
  2414. ++{
  2415. ++  while (*s != '\0' && *t != '\0')
  2416. ++      if (*s != *t)
  2417. ++          return (NULL);
  2418. ++      else
  2419. ++          ++s, ++t;
  2420. ++  if (*s == '\0' && endsym(*t))
  2421. ++      return(t);
  2422. ++  else
  2423. ++      return(NULL);
  2424. ++}
  2425. ++
  2426. ++/*
  2427. ++ * Look for the symbol in the symbol table. If it is found, we return
  2428. ++ * the symbol table index, else we return -1.
  2429. ++ */
  2430. ++static int
  2431. ++findsym(const char **strp)
  2432. ++{
  2433. ++  const char *str;
  2434. ++  int symind;
  2435. ++
  2436. ++  str = *strp;
  2437. ++  *strp = skipsym(str);
  2438. ++  if (symlist) {
  2439. ++      if (*strp == str)
  2440. ++          return (-1);
  2441. ++      if (symdepth && firstsym)
  2442. ++          printf("%s%3d", zerosyms ? "" : "\n", depth);
  2443. ++      firstsym = zerosyms = false;
  2444. ++      printf("%s%.*s%s",
  2445. ++             symdepth ? " " : "",
  2446. ++             (int)(*strp-str), str,
  2447. ++             symdepth ? "" : "\n");
  2448. ++      /* we don't care about the value of the symbol */
  2449. ++      return (0);
  2450. ++  }
  2451. ++  for (symind = 0; symind < nsyms; ++symind) {
  2452. ++      if (matchsym(symname[symind], str) != NULL) {
  2453. ++          debugsym("findsym", symind);
  2454. ++          return (symind);
  2455. ++      }
  2456. ++  }
  2457. ++  return (-1);
  2458. ++}
  2459. ++
  2460. ++/*
  2461. ++ * Resolve indirect symbol values to their final definitions.
  2462. ++ */
  2463. ++static void
  2464. ++indirectsym(void)
  2465. ++{
  2466. ++  const char *cp;
  2467. ++  int changed, sym, ind;
  2468. ++
  2469. ++  do {
  2470. ++      changed = 0;
  2471. ++      for (sym = 0; sym < nsyms; ++sym) {
  2472. ++          if (value[sym] == NULL)
  2473. ++              continue;
  2474. ++          cp = value[sym];
  2475. ++          ind = findsym(&cp);
  2476. ++          if (ind == -1 || ind == sym ||
  2477. ++              *cp != '\0' ||
  2478. ++              value[ind] == NULL ||
  2479. ++              value[ind] == value[sym])
  2480. ++              continue;
  2481. ++          debugsym("indir...", sym);
  2482. ++          value[sym] = value[ind];
  2483. ++          debugsym("...ectsym", sym);
  2484. ++          changed++;
  2485. ++      }
  2486. ++  } while (changed);
  2487. ++}
  2488. ++
  2489. ++/*
  2490. ++ * Add a symbol to the symbol table, specified with the format sym=val
  2491. ++ */
  2492. ++static void
  2493. ++addsym1(bool ignorethis, bool definethis, char *symval)
  2494. ++{
  2495. ++  const char *sym, *val;
  2496. ++
  2497. ++  sym = symval;
  2498. ++  val = skipsym(sym);
  2499. ++  if (definethis && *val == '=') {
  2500. ++      symval[val - sym] = '\0';
  2501. ++      val = val + 1;
  2502. ++  } else if (*val == '\0') {
  2503. ++      val = definethis ? "1" : NULL;
  2504. ++  } else {
  2505. ++      usage();
  2506. ++  }
  2507. ++  addsym2(ignorethis, sym, val);
  2508. ++}
  2509. ++
  2510. ++/*
  2511. ++ * Add a symbol to the symbol table.
  2512. ++ */
  2513. ++static void
  2514. ++addsym2(bool ignorethis, const char *sym, const char *val)
  2515. ++{
  2516. ++  const char *cp = sym;
  2517. ++  int symind;
  2518. ++
  2519. ++  symind = findsym(&cp);
  2520. ++  if (symind < 0) {
  2521. ++      if (nsyms >= MAXSYMS)
  2522. ++          errx(2, "too many symbols");
  2523. ++      symind = nsyms++;
  2524. ++  }
  2525. ++  ignore[symind] = ignorethis;
  2526. ++  symname[symind] = sym;
  2527. ++  value[symind] = val;
  2528. ++  debugsym("addsym", symind);
  2529. ++}
  2530. ++
  2531. ++static void
  2532. ++debugsym(const char *why, int symind)
  2533. ++{
  2534. ++  debug("%s %s%c%s", why, symname[symind],
  2535. ++      value[symind] ? '=' : ' ',
  2536. ++      value[symind] ? value[symind] : "undef");
  2537. ++}
  2538. ++
  2539. ++/*
  2540. ++ * Add symbols to the symbol table from a file containing
  2541. ++ * #define and #undef preprocessor directives.
  2542. ++ */
  2543. ++static void
  2544. ++defundefile(const char *fn)
  2545. ++{
  2546. ++  filename = fn;
  2547. ++  input = fopen(fn, "rb");
  2548. ++  if (input == NULL)
  2549. ++      err(2, "can't open %s", fn);
  2550. ++  linenum = 0;
  2551. ++  while (defundef())
  2552. ++      ;
  2553. ++  if (ferror(input))
  2554. ++      err(2, "can't read %s", filename);
  2555. ++  else
  2556. ++      fclose(input);
  2557. ++  if (incomment)
  2558. ++      error("EOF in comment");
  2559. ++}
  2560. ++
  2561. ++/*
  2562. ++ * Read and process one #define or #undef directive
  2563. ++ */
  2564. ++static bool
  2565. ++defundef(void)
  2566. ++{
  2567. ++  const char *cp, *kw, *sym, *val, *end;
  2568. ++  Comment_state wascomment;
  2569. ++
  2570. ++  wascomment = incomment;
  2571. ++  cp = skiphash();
  2572. ++  if (cp == NULL)
  2573. ++      return (false);
  2574. ++  if (*cp == '\0')
  2575. ++      goto done;
  2576. ++  /* strip trailing whitespace, and do a fairly rough check to
  2577. ++     avoid unsupported multi-line preprocessor directives */
  2578. ++  end = cp + strlen(cp);
  2579. ++  while (end > tline && strchr(" \t\n\r", end[-1]) != NULL)
  2580. ++      --end;
  2581. ++  if (end > tline && end[-1] == '\\')
  2582. ++      Eioccc();
  2583. ++
  2584. ++  kw = cp;
  2585. ++  if ((cp = matchsym("define", kw)) != NULL) {
  2586. ++      sym = getsym(&cp);
  2587. ++      if (sym == NULL)
  2588. ++          error("missing macro name in #define");
  2589. ++      if (*cp == '(') {
  2590. ++          val = "1";
  2591. ++      } else {
  2592. ++          cp = skipcomment(cp);
  2593. ++          val = (cp < end) ? xstrdup(cp, end) : "";
  2594. ++      }
  2595. ++      debug("#define");
  2596. ++      addsym2(false, sym, val);
  2597. ++  } else if ((cp = matchsym("undef", kw)) != NULL) {
  2598. ++      sym = getsym(&cp);
  2599. ++      if (sym == NULL)
  2600. ++          error("missing macro name in #undef");
  2601. ++      cp = skipcomment(cp);
  2602. ++      debug("#undef");
  2603. ++      addsym2(false, sym, NULL);
  2604. ++  } else {
  2605. ++      error("unrecognized preprocessor directive");
  2606. ++  }
  2607. ++  skipline(cp);
  2608. ++done:
  2609. ++  debug("parser line %d state %s comment %s line", linenum,
  2610. ++      comment_name[incomment], linestate_name[linestate]);
  2611. ++  return (true);
  2612. ++}
  2613. ++
  2614. ++/*
  2615. ++ * Concatenate two strings into new memory, checking for failure.
  2616. ++ */
  2617. ++static char *
  2618. ++astrcat(const char *s1, const char *s2)
  2619. ++{
  2620. ++  char *s;
  2621. ++  int len;
  2622. ++  size_t size;
  2623. ++
  2624. ++  len = snprintf(NULL, 0, "%s%s", s1, s2);
  2625. ++  if (len < 0)
  2626. ++      err(2, "snprintf");
  2627. ++  size = (size_t)len + 1;
  2628. ++  s = (char *)malloc(size);
  2629. ++  if (s == NULL)
  2630. ++      err(2, "malloc");
  2631. ++  snprintf(s, size, "%s%s", s1, s2);
  2632. ++  return (s);
  2633. ++}
  2634. ++
  2635. ++/*
  2636. ++ * Duplicate a segment of a string, checking for failure.
  2637. ++ */
  2638. ++static const char *
  2639. ++xstrdup(const char *start, const char *end)
  2640. ++{
  2641. ++  size_t n;
  2642. ++  char *s;
  2643. ++
  2644. ++  if (end < start) abort(); /* bug */
  2645. ++  n = (size_t)(end - start) + 1;
  2646. ++  s = malloc(n);
  2647. ++  if (s == NULL)
  2648. ++      err(2, "malloc");
  2649. ++  snprintf(s, n, "%s", start);
  2650. ++  return (s);
  2651. ++}
  2652. ++
  2653. ++/*
  2654. ++ * Diagnostics.
  2655. ++ */
  2656. ++static void
  2657. ++debug(const char *msg, ...)
  2658. ++{
  2659. ++  va_list ap;
  2660. ++
  2661. ++  if (debugging) {
  2662. ++      va_start(ap, msg);
  2663. ++      vwarnx(msg, ap);
  2664. ++      va_end(ap);
  2665. ++  }
  2666. ++}
  2667. ++
  2668. ++static void
  2669. ++error(const char *msg)
  2670. ++{
  2671. ++  if (depth == 0)
  2672. ++      warnx("%s: %d: %s", filename, linenum, msg);
  2673. ++  else
  2674. ++      warnx("%s: %d: %s (#if line %d depth %d)",
  2675. ++          filename, linenum, msg, stifline[depth], depth);
  2676. ++  closeio();
  2677. ++  errx(2, "output may be truncated");
  2678. ++}
  2679. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.h linux-3.12/scripts/unifdef-upstream/win32/unifdef.h
  2680. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.h   1970-01-01 01:00:00.000000000 +0100
  2681. ++++ linux-3.12/scripts/unifdef-upstream/win32/unifdef.h    2013-12-06 19:36:46.000000000 +0000
  2682. +@@ -0,0 +1,72 @@
  2683. ++/*
  2684. ++ * Copyright (c) 2012 - 2013 Tony Finch <dot@dotat.at>
  2685. ++ *
  2686. ++ * Redistribution and use in source and binary forms, with or without
  2687. ++ * modification, are permitted provided that the following conditions
  2688. ++ * are met:
  2689. ++ * 1. Redistributions of source code must retain the above copyright
  2690. ++ *    notice, this list of conditions and the following disclaimer.
  2691. ++ * 2. Redistributions in binary form must reproduce the above copyright
  2692. ++ *    notice, this list of conditions and the following disclaimer in the
  2693. ++ *    documentation and/or other materials provided with the distribution.
  2694. ++ *
  2695. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  2696. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  2697. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  2698. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  2699. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2700. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  2701. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  2702. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2703. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  2704. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  2705. ++ * SUCH DAMAGE.
  2706. ++ */
  2707. ++
  2708. ++#include <ctype.h>
  2709. ++#include <errno.h>
  2710. ++#include <stdarg.h>
  2711. ++#include <stdio.h>
  2712. ++#include <stdlib.h>
  2713. ++#include <string.h>
  2714. ++
  2715. ++/* Windows POSIX-flavoured headers */
  2716. ++
  2717. ++#include <sys/stat.h>
  2718. ++#include <fcntl.h>
  2719. ++#include <io.h>
  2720. ++
  2721. ++#define stat     _stat
  2722. ++#define snprintf _snprintf
  2723. ++
  2724. ++/* fake stdbool.h */
  2725. ++#define true 1
  2726. ++#define false 0
  2727. ++#define bool int
  2728. ++
  2729. ++/* used by err.c and getopt.c */
  2730. ++#define _getprogname() "unifdef"
  2731. ++
  2732. ++/* win32.c */
  2733. ++int replace(const char *old, const char *new);
  2734. ++FILE *mktempmode(char *tmp, int mode);
  2735. ++FILE *fbinmode(FILE *fp);
  2736. ++
  2737. ++/* err.c */
  2738. ++void err(int, const char *, ...);
  2739. ++void verr(int, const char *, va_list);
  2740. ++void errc(int, int, const char *, ...);
  2741. ++void verrc(int, int, const char *, va_list);
  2742. ++void errx(int, const char *, ...);
  2743. ++void verrx(int, const char *, va_list);
  2744. ++void warn(const char *, ...);
  2745. ++void vwarn(const char *, va_list);
  2746. ++void warnc(int, const char *, ...);
  2747. ++void vwarnc(int, const char *, va_list);
  2748. ++void warnx(const char *, ...);
  2749. ++void vwarnx(const char *, va_list);
  2750. ++
  2751. ++/* getopt.c */
  2752. ++int getopt(int nargc, char *nargv[], const char *ostr);
  2753. ++extern int opterr, optind, optopt, optreset;
  2754. ++extern char *optarg;
  2755. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/version.h linux-3.12/scripts/unifdef-upstream/win32/version.h
  2756. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/version.h   1970-01-01 01:00:00.000000000 +0100
  2757. ++++ linux-3.12/scripts/unifdef-upstream/win32/version.h    2013-12-06 19:36:46.000000000 +0000
  2758. +@@ -0,0 +1,2 @@
  2759. ++"@(#) $Version: unifdef-2.9.5.55501a6 $\n"
  2760. ++"@(#) $Date: 2013-06-12 15:50:39 +0100 $\n"
  2761. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/win32.c linux-3.12/scripts/unifdef-upstream/win32/win32.c
  2762. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/win32.c 1970-01-01 01:00:00.000000000 +0100
  2763. ++++ linux-3.12/scripts/unifdef-upstream/win32/win32.c  2013-12-06 19:36:46.000000000 +0000
  2764. +@@ -0,0 +1,53 @@
  2765. ++/*
  2766. ++ * Copyright (c) 2012 - 2013 Tony Finch <dot@dotat.at>
  2767. ++ *
  2768. ++ * Redistribution and use in source and binary forms, with or without
  2769. ++ * modification, are permitted provided that the following conditions
  2770. ++ * are met:
  2771. ++ * 1. Redistributions of source code must retain the above copyright
  2772. ++ *    notice, this list of conditions and the following disclaimer.
  2773. ++ * 2. Redistributions in binary form must reproduce the above copyright
  2774. ++ *    notice, this list of conditions and the following disclaimer in the
  2775. ++ *    documentation and/or other materials provided with the distribution.
  2776. ++ *
  2777. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  2778. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  2779. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  2780. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  2781. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2782. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  2783. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  2784. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2785. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  2786. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  2787. ++ * SUCH DAMAGE.
  2788. ++ */
  2789. ++
  2790. ++#include "unifdef.h"
  2791. ++
  2792. ++/*
  2793. ++ * The Windows implementation of rename() fails if the new filename
  2794. ++ * already exists. Atomic replacement is not really needed, so just
  2795. ++ * remove anything that might be in the way before renaming.
  2796. ++ */
  2797. ++int
  2798. ++replace(const char *old, const char *new)
  2799. ++{
  2800. ++  if (remove(new) < 0)
  2801. ++      warn("can't remove \"%s\"", new);
  2802. ++  return (rename(old, new));
  2803. ++}
  2804. ++
  2805. ++FILE *
  2806. ++mktempmode(char *tmp, int mode)
  2807. ++{
  2808. ++  mode = mode;
  2809. ++  return (fopen(_mktemp(tmp), "wb"));
  2810. ++}
  2811. ++
  2812. ++FILE *
  2813. ++fbinmode(FILE *fp)
  2814. ++{
  2815. ++  _setmode(_fileno(fp), _O_BINARY);
  2816. ++  return (fp);
  2817. ++}
  2818. Index: patches/linux/3.12.8/140-kernel-disable-archscripts.patch
  2819. ===================================================================
  2820. --- patches/linux/3.12.8/140-kernel-disable-archscripts.patch   (revision 0)
  2821. +++ patches/linux/3.12.8/140-kernel-disable-archscripts.patch   (working copy)
  2822. @@ -0,0 +1,11 @@
  2823. +--- linux-3.12.8/Makefile.orig 2014-01-16 00:31:56.000000000 +0100
  2824. ++++ linux-3.12.8/Makefile  2014-01-20 00:03:25.961403100 +0100
  2825. +@@ -906,7 +906,7 @@
  2826. + archscripts:
  2827. +
  2828. + PHONY += __headers
  2829. +-__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE
  2830. ++__headers: $(version_h) scripts_basic asm-generic archheaders FORCE
  2831. +   $(Q)$(MAKE) $(build)=scripts build_unifdef
  2832. +
  2833. + PHONY += headers_install_all
  2834. Index: patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch
  2835. ===================================================================
  2836. --- patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch (revision 0)
  2837. +++ patches/linux/3.12.8/100-fixdep-fixes-for-Windows.patch (working copy)
  2838. @@ -0,0 +1,154 @@
  2839. +--- linux-3.12.orig/scripts/basic/fixdep.c 2013-11-13 03:05:59.000000000 +0000
  2840. +--- linux-3.12/scripts/basic/fixdep.c  2013-12-04 00:21:00.303303000 +0000
  2841. +@@ -105,7 +105,9 @@
  2842. +
  2843. + #include <sys/types.h>
  2844. + #include <sys/stat.h>
  2845. ++#ifndef __MINGW32__
  2846. + #include <sys/mman.h>
  2847. ++#endif
  2848. + #include <unistd.h>
  2849. + #include <fcntl.h>
  2850. + #include <string.h>
  2851. +@@ -113,13 +115,77 @@
  2852. + #include <stdio.h>
  2853. + #include <limits.h>
  2854. + #include <ctype.h>
  2855. ++#ifndef __MINGW32__
  2856. + #include <arpa/inet.h>
  2857. ++#define O_BINARY 0
  2858. ++#else
  2859. ++inline unsigned int ntohl(unsigned int val);
  2860. ++inline unsigned int ntohl(unsigned int val)
  2861. ++{
  2862. ++  return (((val&0xff      ) << 24) |
  2863. ++          ((val&0xff00    ) << 8 ) |
  2864. ++          ((val&0xff0000  ) >> 8 ) |
  2865. ++          ((val&0xff000000) >> 24) );
  2866. ++}
  2867. ++#endif
  2868. +
  2869. + #define INT_CONF ntohl(0x434f4e46)
  2870. + #define INT_ONFI ntohl(0x4f4e4649)
  2871. + #define INT_NFIG ntohl(0x4e464947)
  2872. + #define INT_FIG_ ntohl(0x4649475f)
  2873. +
  2874. ++#ifdef __MINGW32__
  2875. ++#define UNUSED __attribute__ ((__unused__))
  2876. ++
  2877. ++void *mmap(void *start UNUSED, size_t size, int prot UNUSED,
  2878. ++     int flags UNUSED, int fd, off_t offset UNUSED);
  2879. ++
  2880. ++void munmap(void *p, size_t size UNUSED);
  2881. ++
  2882. ++/* Workaround specifically for fixdep */
  2883. ++#define PROT_READ 0
  2884. ++#define MAP_PRIVATE 0
  2885. ++void *mmap(void *start UNUSED, size_t size, int prot UNUSED,
  2886. ++     int flags UNUSED, int fd, off_t offset UNUSED)
  2887. ++{
  2888. ++  void *p;
  2889. ++  void *curP;
  2890. ++  ssize_t readB;
  2891. ++
  2892. ++  p = malloc(size);
  2893. ++  if (!p)
  2894. ++      return (void*)((long)-1);
  2895. ++
  2896. ++  curP = p;
  2897. ++
  2898. ++  while (size > 0)
  2899. ++  {
  2900. ++      readB = read(fd, curP, size);
  2901. ++
  2902. ++      if (readB == 0)
  2903. ++      {
  2904. ++          /* EOF reached */
  2905. ++          break;
  2906. ++      }
  2907. ++      else if (readB < 0)
  2908. ++      {
  2909. ++          perror("fixdep: read config");
  2910. ++          free(p);
  2911. ++          return (void*)((long)-1);
  2912. ++      }
  2913. ++
  2914. ++      size -= readB;
  2915. ++      curP += readB;
  2916. ++  }
  2917. ++
  2918. ++  return p;
  2919. ++}
  2920. ++void munmap(void *p, size_t size UNUSED)
  2921. ++{
  2922. ++  free(p);
  2923. ++}
  2924. ++#endif
  2925. ++
  2926. + char *target;
  2927. + char *depfile;
  2928. + char *cmdline;
  2929. +@@ -284,7 +350,7 @@
  2930. +   int fd;
  2931. +   void *map;
  2932. +
  2933. +-  fd = open(filename, O_RDONLY);
  2934. ++  fd = open(filename, O_RDONLY|O_BINARY);
  2935. +   if (fd < 0) {
  2936. +       fprintf(stderr, "fixdep: error opening config file: ");
  2937. +       perror(filename);
  2938. +@@ -319,6 +385,7 @@
  2939. +   char *m = map;
  2940. +   char *end = m + len;
  2941. +   char *p;
  2942. ++  char *slash;
  2943. +   char s[PATH_MAX];
  2944. +   int is_target;
  2945. +   int saw_any_target = 0;
  2946. +@@ -328,11 +395,11 @@
  2947. +
  2948. +   while (m < end) {
  2949. +       /* Skip any "white space" */
  2950. +-      while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
  2951. ++      while (m < end && (*m == ' ' || *m == '\\' || *m == '\r' || *m == '\n'))
  2952. +           m++;
  2953. +       /* Find next "white space" */
  2954. +       p = m;
  2955. +-      while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
  2956. ++      while (p < end && *p != ' ' && *p != '\r' && *p != '\n')
  2957. +           p++;
  2958. +       /* Is the token we found a target name? */
  2959. +       is_target = (*(p-1) == ':');
  2960. +@@ -344,6 +411,14 @@
  2961. +           /* Save this token/filename */
  2962. +           memcpy(s, m, p-m);
  2963. +           s[p - m] = 0;
  2964. ++          /* Apply some Windows fixups */
  2965. ++          if (s[0]>='a' && s[0]<='z' && s[1]==':')
  2966. ++              s[0] = s[0]&~32;
  2967. ++          slash = strchr(s, '\\');
  2968. ++          while (slash) {
  2969. ++              *slash = '/';
  2970. ++              slash = strchr(slash, '\\');
  2971. ++          }
  2972. +
  2973. +           /* Ignore certain dependencies */
  2974. +           if (strrcmp(s, "include/generated/autoconf.h") &&
  2975. +@@ -385,6 +460,8 @@
  2976. +        * "whitespace" character that follows this token.
  2977. +        */
  2978. +       m = p + 1;
  2979. ++      while (*m && (*m == '\r' || *m == '\n'))
  2980. ++          ++m;
  2981. +   }
  2982. +
  2983. +   if (!saw_any_target) {
  2984. +@@ -402,7 +479,7 @@
  2985. +   int fd;
  2986. +   void *map;
  2987. +
  2988. +-  fd = open(depfile, O_RDONLY);
  2989. ++  fd = open(depfile, O_RDONLY|O_BINARY);
  2990. +   if (fd < 0) {
  2991. +       fprintf(stderr, "fixdep: error opening depfile: ");
  2992. +       perror(depfile);
  2993. Index: patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch
  2994. ===================================================================
  2995. --- patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch   (revision 0)
  2996. +++ patches/linux/3.12.8/120-Win32-FreeBSD-use-upstream-unifdef.patch   (working copy)
  2997. @@ -0,0 +1,2086 @@
  2998. +diff -urN linux-3.12.orig/scripts/Makefile linux-3.12/scripts/Makefile
  2999. +--- linux-3.12.orig/scripts/Makefile   2013-12-06 19:36:35.000000000 +0000
  3000. ++++ linux-3.12/scripts/Makefile    2013-12-06 19:36:46.000000000 +0000
  3001. +@@ -26,6 +26,15 @@
  3002. + # The following hostprogs-y programs are only build on demand
  3003. + hostprogs-y += unifdef docproc
  3004. +
  3005. ++cc_machine := $(shell $(CC) -dumpmachine)
  3006. ++ifneq (, $(findstring linux, $(cc_machine)))
  3007. ++  unifdef-objs := unifdef.o
  3008. ++else
  3009. ++  ifneq (, $(findstring mingw, $(cc_machine)))
  3010. ++    unifdef-objs := unifdef-upstream/win32/unifdef.o unifdef-upstream/win32/err.o unifdef-upstream/win32/getopt.o unifdef-upstream/win32/win32.o
  3011. ++  endif
  3012. ++endif
  3013. ++
  3014. + # These targets are used internally to avoid "is up to date" messages
  3015. + PHONY += build_unifdef
  3016. + build_unifdef: scripts/unifdef FORCE
  3017. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/COPYING linux-3.12/scripts/unifdef-upstream/COPYING
  3018. +--- linux-3.12.orig/scripts/unifdef-upstream/COPYING   1970-01-01 01:00:00.000000000 +0100
  3019. ++++ linux-3.12/scripts/unifdef-upstream/COPYING    2013-12-06 19:36:46.000000000 +0000
  3020. +@@ -0,0 +1,85 @@
  3021. ++unifdef copyright licence
  3022. ++-------------------------
  3023. ++
  3024. ++All files in this package are distributed under the two-clause BSD
  3025. ++copyright licence, except for the manual page unifdef.1 and the
  3026. ++portability support code in the FreeBSD subdirectory, which all have
  3027. ++a three-clause BSD copyright licence.
  3028. ++
  3029. ++Unifdef was derived from software contributed to Berkeley by Dave
  3030. ++Yost. It was rewritten to support ANSI C by Tony Finch. The original
  3031. ++version of unifdef.c carried the four-clause BSD copyright licence.
  3032. ++None of its code remains in this version (though some of the names
  3033. ++remain) so it now carries the more liberal two-clause licence.
  3034. ++
  3035. ++Unless otherwise stated, the files in this package are:
  3036. ++
  3037. ++  Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  3038. ++
  3039. ++unifdefall.sh is:
  3040. ++
  3041. ++  Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  3042. ++  Copyright (c) 2009 - 2010 Jonathan Nieder <jrnieder@gmail.com>
  3043. ++
  3044. ++Some files in the tests directory are:
  3045. ++
  3046. ++  Copyright 2004, 2008 Bob Proulx <bob@proulx.com>
  3047. ++
  3048. ++The two-clause BSD copyright licence applying to all the above files is:
  3049. ++
  3050. ++  Redistribution and use in source and binary forms, with or without
  3051. ++  modification, are permitted provided that the following conditions
  3052. ++  are met:
  3053. ++  1. Redistributions of source code must retain the above copyright
  3054. ++     notice, this list of conditions and the following disclaimer.
  3055. ++  2. Redistributions in binary form must reproduce the above copyright
  3056. ++     notice, this list of conditions and the following disclaimer in the
  3057. ++     documentation and/or other materials provided with the distribution.
  3058. ++
  3059. ++  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  3060. ++  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3061. ++  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3062. ++  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  3063. ++  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3064. ++  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3065. ++  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3066. ++  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3067. ++  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3068. ++  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3069. ++  SUCH DAMAGE.
  3070. ++
  3071. ++The three-clause BSD copyright licence for the manual page unifdef.1
  3072. ++and the portability support code from FreeBSD is below. The fourth
  3073. ++advertising clause that used to appear between clauses 2 and 3 was
  3074. ++rescinded by the University of California Berkeley in 1999.
  3075. ++ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
  3076. ++
  3077. ++  Copyright (c) 1985 - 1994
  3078. ++  The Regents of the University of California.  All rights reserved.
  3079. ++  Copyright (c) 2002 - 2012 Tony Finch <dot@dotat.at>.  All rights reserved.
  3080. ++
  3081. ++  Redistribution and use in source and binary forms, with or without
  3082. ++  modification, are permitted provided that the following conditions
  3083. ++  are met:
  3084. ++  1. Redistributions of source code must retain the above copyright
  3085. ++     notice, this list of conditions and the following disclaimer.
  3086. ++  2. Redistributions in binary form must reproduce the above copyright
  3087. ++     notice, this list of conditions and the following disclaimer in the
  3088. ++     documentation and/or other materials provided with the distribution.
  3089. ++  3. Neither the name of the University nor the names of its contributors
  3090. ++     may be used to endorse or promote products derived from this software
  3091. ++     without specific prior written permission.
  3092. ++
  3093. ++  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  3094. ++  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3095. ++  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3096. ++  ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  3097. ++  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3098. ++  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3099. ++  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3100. ++  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3101. ++  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3102. ++  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3103. ++  SUCH DAMAGE.
  3104. ++
  3105. ++- end -
  3106. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/err.c linux-3.12/scripts/unifdef-upstream/win32/err.c
  3107. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/err.c   1970-01-01 01:00:00.000000000 +0100
  3108. ++++ linux-3.12/scripts/unifdef-upstream/win32/err.c    2013-12-06 19:36:46.000000000 +0000
  3109. +@@ -0,0 +1,138 @@
  3110. ++/*-
  3111. ++ * Copyright (c) 1993
  3112. ++ *    The Regents of the University of California.  All rights reserved.
  3113. ++ *
  3114. ++ * Redistribution and use in source and binary forms, with or without
  3115. ++ * modification, are permitted provided that the following conditions
  3116. ++ * are met:
  3117. ++ * 1. Redistributions of source code must retain the above copyright
  3118. ++ *    notice, this list of conditions and the following disclaimer.
  3119. ++ * 2. Redistributions in binary form must reproduce the above copyright
  3120. ++ *    notice, this list of conditions and the following disclaimer in the
  3121. ++ *    documentation and/or other materials provided with the distribution.
  3122. ++ * 4. Neither the name of the University nor the names of its contributors
  3123. ++ *    may be used to endorse or promote products derived from this software
  3124. ++ *    without specific prior written permission.
  3125. ++ *
  3126. ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  3127. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3128. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3129. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  3130. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3131. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3132. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3133. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3134. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3135. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3136. ++ * SUCH DAMAGE.
  3137. ++ */
  3138. ++
  3139. ++#include "unifdef.h"
  3140. ++
  3141. ++void
  3142. ++err(int eval, const char *fmt, ...)
  3143. ++{
  3144. ++  va_list ap;
  3145. ++  va_start(ap, fmt);
  3146. ++  verrc(eval, errno, fmt, ap);
  3147. ++  va_end(ap);
  3148. ++}
  3149. ++
  3150. ++void
  3151. ++verr(int eval, const char *fmt, va_list ap)
  3152. ++{
  3153. ++  verrc(eval, errno, fmt, ap);
  3154. ++}
  3155. ++
  3156. ++void
  3157. ++errc(int eval, int code, const char *fmt, ...)
  3158. ++{
  3159. ++  va_list ap;
  3160. ++  va_start(ap, fmt);
  3161. ++  verrc(eval, code, fmt, ap);
  3162. ++  va_end(ap);
  3163. ++}
  3164. ++
  3165. ++void
  3166. ++verrc(int eval, int code, const char *fmt, va_list ap)
  3167. ++{
  3168. ++  fprintf(stderr, "%s: ", _getprogname());
  3169. ++  if (fmt != NULL) {
  3170. ++      vfprintf(stderr, fmt, ap);
  3171. ++      fprintf(stderr, ": ");
  3172. ++  }
  3173. ++  fprintf(stderr, "%s\n", strerror(code));
  3174. ++  exit(eval);
  3175. ++}
  3176. ++
  3177. ++void
  3178. ++errx(int eval, const char *fmt, ...)
  3179. ++{
  3180. ++  va_list ap;
  3181. ++  va_start(ap, fmt);
  3182. ++  verrx(eval, fmt, ap);
  3183. ++  va_end(ap);
  3184. ++}
  3185. ++
  3186. ++void
  3187. ++verrx(int eval, const char *fmt, va_list ap)
  3188. ++{
  3189. ++  fprintf(stderr, "%s: ", _getprogname());
  3190. ++  if (fmt != NULL)
  3191. ++      vfprintf(stderr, fmt, ap);
  3192. ++  fprintf(stderr, "\n");
  3193. ++  exit(eval);
  3194. ++}
  3195. ++
  3196. ++void
  3197. ++warn(const char *fmt, ...)
  3198. ++{
  3199. ++  va_list ap;
  3200. ++  va_start(ap, fmt);
  3201. ++  vwarnc(errno, fmt, ap);
  3202. ++  va_end(ap);
  3203. ++}
  3204. ++
  3205. ++void
  3206. ++vwarn(const char *fmt, va_list ap)
  3207. ++{
  3208. ++  vwarnc(errno, fmt, ap);
  3209. ++}
  3210. ++
  3211. ++void
  3212. ++warnc(int code, const char *fmt, ...)
  3213. ++{
  3214. ++  va_list ap;
  3215. ++  va_start(ap, fmt);
  3216. ++  vwarnc(code, fmt, ap);
  3217. ++  va_end(ap);
  3218. ++}
  3219. ++
  3220. ++void
  3221. ++vwarnc(int code, const char *fmt, va_list ap)
  3222. ++{
  3223. ++  fprintf(stderr, "%s: ", _getprogname());
  3224. ++  if (fmt != NULL) {
  3225. ++      vfprintf(stderr, fmt, ap);
  3226. ++      fprintf(stderr, ": ");
  3227. ++  }
  3228. ++  fprintf(stderr, "%s\n", strerror(code));
  3229. ++}
  3230. ++
  3231. ++void
  3232. ++warnx(const char *fmt, ...)
  3233. ++{
  3234. ++  va_list ap;
  3235. ++  va_start(ap, fmt);
  3236. ++  vwarnx(fmt, ap);
  3237. ++  va_end(ap);
  3238. ++}
  3239. ++
  3240. ++void
  3241. ++vwarnx(const char *fmt, va_list ap)
  3242. ++{
  3243. ++  fprintf(stderr, "%s: ", _getprogname());
  3244. ++  if (fmt != NULL)
  3245. ++      vfprintf(stderr, fmt, ap);
  3246. ++  fprintf(stderr, "\n");
  3247. ++}
  3248. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/getopt.c linux-3.12/scripts/unifdef-upstream/win32/getopt.c
  3249. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/getopt.c    1970-01-01 01:00:00.000000000 +0100
  3250. ++++ linux-3.12/scripts/unifdef-upstream/win32/getopt.c 2013-12-06 19:36:46.000000000 +0000
  3251. +@@ -0,0 +1,118 @@
  3252. ++/*
  3253. ++ * Copyright (c) 1987, 1993, 1994
  3254. ++ *    The Regents of the University of California.  All rights reserved.
  3255. ++ *
  3256. ++ * Redistribution and use in source and binary forms, with or without
  3257. ++ * modification, are permitted provided that the following conditions
  3258. ++ * are met:
  3259. ++ * 1. Redistributions of source code must retain the above copyright
  3260. ++ *    notice, this list of conditions and the following disclaimer.
  3261. ++ * 2. Redistributions in binary form must reproduce the above copyright
  3262. ++ *    notice, this list of conditions and the following disclaimer in the
  3263. ++ *    documentation and/or other materials provided with the distribution.
  3264. ++ * 4. Neither the name of the University nor the names of its contributors
  3265. ++ *    may be used to endorse or promote products derived from this software
  3266. ++ *    without specific prior written permission.
  3267. ++ *
  3268. ++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  3269. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3270. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3271. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  3272. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3273. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3274. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3275. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3276. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3277. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3278. ++ * SUCH DAMAGE.
  3279. ++ */
  3280. ++
  3281. ++#include "unifdef.h"
  3282. ++
  3283. ++int   opterr = 1,     /* if error message should be printed */
  3284. ++  optind = 1,     /* index into parent argv vector */
  3285. ++  optopt,         /* character checked for validity */
  3286. ++  optreset;       /* reset getopt */
  3287. ++char  *optarg;        /* argument associated with option */
  3288. ++
  3289. ++#define   BADCH   (int)'?'
  3290. ++#define   BADARG  (int)':'
  3291. ++
  3292. ++static char EMSG[] = "";
  3293. ++
  3294. ++/*
  3295. ++ * getopt --
  3296. ++ *    Parse argc/argv argument vector.
  3297. ++ */
  3298. ++int
  3299. ++getopt(int nargc, char *nargv[], const char *ostr)
  3300. ++{
  3301. ++  static char *place = EMSG;      /* option letter processing */
  3302. ++  const char *oli;            /* option letter list index */
  3303. ++
  3304. ++  if (optreset || *place == 0) {      /* update scanning pointer */
  3305. ++      optreset = 0;
  3306. ++      place = nargv[optind];
  3307. ++      if (optind >= nargc || *place++ != '-') {
  3308. ++          /* Argument is absent or is not an option */
  3309. ++          place = EMSG;
  3310. ++          return (-1);
  3311. ++      }
  3312. ++      optopt = *place++;
  3313. ++      if (optopt == '-' && *place == 0) {
  3314. ++          /* "--" => end of options */
  3315. ++          ++optind;
  3316. ++          place = EMSG;
  3317. ++          return (-1);
  3318. ++      }
  3319. ++      if (optopt == 0) {
  3320. ++          /* Solitary '-', treat as a '-' option
  3321. ++             if the program (eg su) is looking for it. */
  3322. ++          place = EMSG;
  3323. ++          if (strchr(ostr, '-') == NULL)
  3324. ++              return (-1);
  3325. ++          optopt = '-';
  3326. ++      }
  3327. ++  } else
  3328. ++      optopt = *place++;
  3329. ++
  3330. ++  /* See if option letter is one the caller wanted... */
  3331. ++  if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
  3332. ++      if (*place == 0)
  3333. ++          ++optind;
  3334. ++      if (opterr && *ostr != ':')
  3335. ++          (void)fprintf(stderr,
  3336. ++              "%s: illegal option -- %c\n", _getprogname(),
  3337. ++              optopt);
  3338. ++      return (BADCH);
  3339. ++  }
  3340. ++
  3341. ++  /* Does this option need an argument? */
  3342. ++  if (oli[1] != ':') {
  3343. ++      /* don't need argument */
  3344. ++      optarg = NULL;
  3345. ++      if (*place == 0)
  3346. ++          ++optind;
  3347. ++  } else {
  3348. ++      /* Option-argument is either the rest of this argument or the
  3349. ++         entire next argument. */
  3350. ++      if (*place)
  3351. ++          optarg = place;
  3352. ++      else if (nargc > ++optind)
  3353. ++          optarg = nargv[optind];
  3354. ++      else {
  3355. ++          /* option-argument absent */
  3356. ++          place = EMSG;
  3357. ++          if (*ostr == ':')
  3358. ++              return (BADARG);
  3359. ++          if (opterr)
  3360. ++              (void)fprintf(stderr,
  3361. ++                  "%s: option requires an argument -- %c\n",
  3362. ++                  _getprogname(), optopt);
  3363. ++          return (BADCH);
  3364. ++      }
  3365. ++      place = EMSG;
  3366. ++      ++optind;
  3367. ++  }
  3368. ++  return (optopt);            /* return option letter */
  3369. ++}
  3370. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.c linux-3.12/scripts/unifdef-upstream/win32/unifdef.c
  3371. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.c   1970-01-01 01:00:00.000000000 +0100
  3372. ++++ linux-3.12/scripts/unifdef-upstream/win32/unifdef.c    2013-12-06 19:36:46.000000000 +0000
  3373. +@@ -0,0 +1,1571 @@
  3374. ++/*
  3375. ++ * Copyright (c) 2002 - 2013 Tony Finch <dot@dotat.at>
  3376. ++ *
  3377. ++ * Redistribution and use in source and binary forms, with or without
  3378. ++ * modification, are permitted provided that the following conditions
  3379. ++ * are met:
  3380. ++ * 1. Redistributions of source code must retain the above copyright
  3381. ++ *    notice, this list of conditions and the following disclaimer.
  3382. ++ * 2. Redistributions in binary form must reproduce the above copyright
  3383. ++ *    notice, this list of conditions and the following disclaimer in the
  3384. ++ *    documentation and/or other materials provided with the distribution.
  3385. ++ *
  3386. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  3387. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  3388. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  3389. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  3390. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  3391. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  3392. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  3393. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  3394. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  3395. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  3396. ++ * SUCH DAMAGE.
  3397. ++ */
  3398. ++
  3399. ++/*
  3400. ++ * unifdef - remove ifdef'ed lines
  3401. ++ *
  3402. ++ * This code was derived from software contributed to Berkeley by Dave Yost.
  3403. ++ * It was rewritten to support ANSI C by Tony Finch. The original version
  3404. ++ * of unifdef carried the 4-clause BSD copyright licence. None of its code
  3405. ++ * remains in this version (though some of the names remain) so it now
  3406. ++ * carries a more liberal licence.
  3407. ++ *
  3408. ++ *  Wishlist:
  3409. ++ *      provide an option which will append the name of the
  3410. ++ *        appropriate symbol after #else's and #endif's
  3411. ++ *      provide an option which will check symbols after
  3412. ++ *        #else's and #endif's to see that they match their
  3413. ++ *        corresponding #ifdef or #ifndef
  3414. ++ *
  3415. ++ *   These require better buffer handling, which would also make
  3416. ++ *   it possible to handle all "dodgy" directives correctly.
  3417. ++ */
  3418. ++
  3419. ++#include "unifdef.h"
  3420. ++
  3421. ++static const char copyright[] =
  3422. ++    #include "version.h"
  3423. ++    "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
  3424. ++    "@(#) $URL: http://dotat.at/prog/unifdef $\n"
  3425. ++;
  3426. ++
  3427. ++/* types of input lines: */
  3428. ++typedef enum {
  3429. ++  LT_TRUEI,       /* a true #if with ignore flag */
  3430. ++  LT_FALSEI,      /* a false #if with ignore flag */
  3431. ++  LT_IF,          /* an unknown #if */
  3432. ++  LT_TRUE,        /* a true #if */
  3433. ++  LT_FALSE,       /* a false #if */
  3434. ++  LT_ELIF,        /* an unknown #elif */
  3435. ++  LT_ELTRUE,      /* a true #elif */
  3436. ++  LT_ELFALSE,     /* a false #elif */
  3437. ++  LT_ELSE,        /* #else */
  3438. ++  LT_ENDIF,       /* #endif */
  3439. ++  LT_DODGY,       /* flag: directive is not on one line */
  3440. ++  LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
  3441. ++  LT_PLAIN,       /* ordinary line */
  3442. ++  LT_EOF,         /* end of file */
  3443. ++  LT_ERROR,       /* unevaluable #if */
  3444. ++  LT_COUNT
  3445. ++} Linetype;
  3446. ++
  3447. ++static char const * const linetype_name[] = {
  3448. ++  "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
  3449. ++  "ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
  3450. ++  "DODGY TRUEI", "DODGY FALSEI",
  3451. ++  "DODGY IF", "DODGY TRUE", "DODGY FALSE",
  3452. ++  "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
  3453. ++  "DODGY ELSE", "DODGY ENDIF",
  3454. ++  "PLAIN", "EOF", "ERROR"
  3455. ++};
  3456. ++
  3457. ++#define linetype_if2elif(lt) ((Linetype)(lt - LT_IF + LT_ELIF))
  3458. ++#define linetype_2dodgy(lt) ((Linetype)(lt + LT_DODGY))
  3459. ++
  3460. ++/* state of #if processing */
  3461. ++typedef enum {
  3462. ++  IS_OUTSIDE,
  3463. ++  IS_FALSE_PREFIX,    /* false #if followed by false #elifs */
  3464. ++  IS_TRUE_PREFIX,     /* first non-false #(el)if is true */
  3465. ++  IS_PASS_MIDDLE,     /* first non-false #(el)if is unknown */
  3466. ++  IS_FALSE_MIDDLE,    /* a false #elif after a pass state */
  3467. ++  IS_TRUE_MIDDLE,     /* a true #elif after a pass state */
  3468. ++  IS_PASS_ELSE,       /* an else after a pass state */
  3469. ++  IS_FALSE_ELSE,      /* an else after a true state */
  3470. ++  IS_TRUE_ELSE,       /* an else after only false states */
  3471. ++  IS_FALSE_TRAILER,   /* #elifs after a true are false */
  3472. ++  IS_COUNT
  3473. ++} Ifstate;
  3474. ++
  3475. ++static char const * const ifstate_name[] = {
  3476. ++  "OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
  3477. ++  "PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
  3478. ++  "PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
  3479. ++  "FALSE_TRAILER"
  3480. ++};
  3481. ++
  3482. ++/* state of comment parser */
  3483. ++typedef enum {
  3484. ++  NO_COMMENT = false, /* outside a comment */
  3485. ++  C_COMMENT,      /* in a comment like this one */
  3486. ++  CXX_COMMENT,        /* between // and end of line */
  3487. ++  STARTING_COMMENT,   /* just after slash-backslash-newline */
  3488. ++  FINISHING_COMMENT,  /* star-backslash-newline in a C comment */
  3489. ++  CHAR_LITERAL,       /* inside '' */
  3490. ++  STRING_LITERAL      /* inside "" */
  3491. ++} Comment_state;
  3492. ++
  3493. ++static char const * const comment_name[] = {
  3494. ++  "NO", "C", "CXX", "STARTING", "FINISHING", "CHAR", "STRING"
  3495. ++};
  3496. ++
  3497. ++/* state of preprocessor line parser */
  3498. ++typedef enum {
  3499. ++  LS_START,       /* only space and comments on this line */
  3500. ++  LS_HASH,        /* only space, comments, and a hash */
  3501. ++  LS_DIRTY        /* this line can't be a preprocessor line */
  3502. ++} Line_state;
  3503. ++
  3504. ++static char const * const linestate_name[] = {
  3505. ++  "START", "HASH", "DIRTY"
  3506. ++};
  3507. ++
  3508. ++/*
  3509. ++ * Minimum translation limits from ISO/IEC 9899:1999 5.2.4.1
  3510. ++ */
  3511. ++#define   MAXDEPTH        64          /* maximum #if nesting */
  3512. ++#define   MAXLINE         4096            /* maximum length of line */
  3513. ++#define   MAXSYMS         16384           /* maximum number of symbols */
  3514. ++
  3515. ++/*
  3516. ++ * Sometimes when editing a keyword the replacement text is longer, so
  3517. ++ * we leave some space at the end of the tline buffer to accommodate this.
  3518. ++ */
  3519. ++#define   EDITSLOP        10
  3520. ++
  3521. ++/*
  3522. ++ * Globals.
  3523. ++ */
  3524. ++
  3525. ++static bool             compblank;        /* -B: compress blank lines */
  3526. ++static bool             lnblank;      /* -b: blank deleted lines */
  3527. ++static bool             complement;       /* -c: do the complement */
  3528. ++static bool             debugging;        /* -d: debugging reports */
  3529. ++static bool             inplace;      /* -m: modify in place */
  3530. ++static bool             iocccok;      /* -e: fewer IOCCC errors */
  3531. ++static bool             strictlogic;      /* -K: keep ambiguous #ifs */
  3532. ++static bool             killconsts;       /* -k: eval constant #ifs */
  3533. ++static bool             lnnum;            /* -n: add #line directives */
  3534. ++static bool             symlist;      /* -s: output symbol list */
  3535. ++static bool             symdepth;     /* -S: output symbol depth */
  3536. ++static bool             text;         /* -t: this is a text file */
  3537. ++
  3538. ++static const char      *symname[MAXSYMS]; /* symbol name */
  3539. ++static const char      *value[MAXSYMS];       /* -Dsym=value */
  3540. ++static bool             ignore[MAXSYMS];  /* -iDsym or -iUsym */
  3541. ++static int              nsyms;            /* number of symbols */
  3542. ++
  3543. ++static FILE            *input;            /* input file pointer */
  3544. ++static const char      *filename;     /* input file name */
  3545. ++static int              linenum;      /* current line number */
  3546. ++static const char      *linefile;     /* file name for #line */
  3547. ++static FILE            *output;           /* output file pointer */
  3548. ++static const char      *ofilename;        /* output file name */
  3549. ++static const char      *backext;      /* backup extension */
  3550. ++static char            *tempname;     /* avoid splatting input */
  3551. ++
  3552. ++static char             tline[MAXLINE+EDITSLOP];/* input buffer plus space */
  3553. ++static char            *keyword;      /* used for editing #elif's */
  3554. ++
  3555. ++/*
  3556. ++ * When processing a file, the output's newline style will match the
  3557. ++ * input's, and unifdef correctly handles CRLF or LF endings whatever
  3558. ++ * the platform's native style. The stdio streams are opened in binary
  3559. ++ * mode to accommodate platforms whose native newline style is CRLF.
  3560. ++ * When the output isn't a processed input file (when it is error /
  3561. ++ * debug / diagnostic messages) then unifdef uses native line endings.
  3562. ++ */
  3563. ++
  3564. ++static const char      *newline;      /* input file format */
  3565. ++static const char       newline_unix[] = "\n";
  3566. ++static const char       newline_crlf[] = "\r\n";
  3567. ++
  3568. ++static Comment_state    incomment;        /* comment parser state */
  3569. ++static Line_state       linestate;        /* #if line parser state */
  3570. ++static Ifstate          ifstate[MAXDEPTH];    /* #if processor state */
  3571. ++static bool             ignoring[MAXDEPTH];   /* ignore comments state */
  3572. ++static int              stifline[MAXDEPTH];   /* start of current #if */
  3573. ++static int              depth;            /* current #if nesting */
  3574. ++static int              delcount;     /* count of deleted lines */
  3575. ++static unsigned         blankcount;       /* count of blank lines */
  3576. ++static unsigned         blankmax;     /* maximum recent blankcount */
  3577. ++static bool             constexpr;        /* constant #if expression */
  3578. ++static bool             zerosyms;     /* to format symdepth output */
  3579. ++static bool             firstsym;     /* ditto */
  3580. ++
  3581. ++static int              exitmode;     /* exit status mode */
  3582. ++static int              exitstat;     /* program exit status */
  3583. ++
  3584. ++static void             addsym1(bool, bool, char *);
  3585. ++static void             addsym2(bool, const char *, const char *);
  3586. ++static char            *astrcat(const char *, const char *);
  3587. ++static void             cleantemp(void);
  3588. ++static void             closeio(void);
  3589. ++static void             debug(const char *, ...);
  3590. ++static void             debugsym(const char *, int);
  3591. ++static bool             defundef(void);
  3592. ++static void             defundefile(const char *);
  3593. ++static void             done(void);
  3594. ++static void             error(const char *);
  3595. ++static int              findsym(const char **);
  3596. ++static void             flushline(bool);
  3597. ++static void             hashline(void);
  3598. ++static void             help(void);
  3599. ++static Linetype         ifeval(const char **);
  3600. ++static void             ignoreoff(void);
  3601. ++static void             ignoreon(void);
  3602. ++static void             indirectsym(void);
  3603. ++static void             keywordedit(const char *);
  3604. ++static const char      *matchsym(const char *, const char *);
  3605. ++static void             nest(void);
  3606. ++static Linetype         parseline(void);
  3607. ++static void             process(void);
  3608. ++static void             processinout(const char *, const char *);
  3609. ++static const char      *skipargs(const char *);
  3610. ++static const char      *skipcomment(const char *);
  3611. ++static const char      *skiphash(void);
  3612. ++static const char      *skipline(const char *);
  3613. ++static const char      *skipsym(const char *);
  3614. ++static void             state(Ifstate);
  3615. ++static void             unnest(void);
  3616. ++static void             usage(void);
  3617. ++static void             version(void);
  3618. ++static const char      *xstrdup(const char *, const char *);
  3619. ++
  3620. ++#define endsym(c) (!isalnum((unsigned char)c) && c != '_')
  3621. ++
  3622. ++/*
  3623. ++ * The main program.
  3624. ++ */
  3625. ++int
  3626. ++main(int argc, char *argv[])
  3627. ++{
  3628. ++  int opt;
  3629. ++
  3630. ++  while ((opt = getopt(argc, argv, "i:D:U:f:I:M:o:x:bBcdehKklmnsStV")) != -1)
  3631. ++      switch (opt) {
  3632. ++      case 'i': /* treat stuff controlled by these symbols as text */
  3633. ++          /*
  3634. ++           * For strict backwards-compatibility the U or D
  3635. ++           * should be immediately after the -i but it doesn't
  3636. ++           * matter much if we relax that requirement.
  3637. ++           */
  3638. ++          opt = *optarg++;
  3639. ++          if (opt == 'D')
  3640. ++              addsym1(true, true, optarg);
  3641. ++          else if (opt == 'U')
  3642. ++              addsym1(true, false, optarg);
  3643. ++          else
  3644. ++              usage();
  3645. ++          break;
  3646. ++      case 'D': /* define a symbol */
  3647. ++          addsym1(false, true, optarg);
  3648. ++          break;
  3649. ++      case 'U': /* undef a symbol */
  3650. ++          addsym1(false, false, optarg);
  3651. ++          break;
  3652. ++      case 'I': /* no-op for compatibility with cpp */
  3653. ++          break;
  3654. ++      case 'b': /* blank deleted lines instead of omitting them */
  3655. ++      case 'l': /* backwards compatibility */
  3656. ++          lnblank = true;
  3657. ++          break;
  3658. ++      case 'B': /* compress blank lines around removed section */
  3659. ++          compblank = true;
  3660. ++          break;
  3661. ++      case 'c': /* treat -D as -U and vice versa */
  3662. ++          complement = true;
  3663. ++          break;
  3664. ++      case 'd':
  3665. ++          debugging = true;
  3666. ++          break;
  3667. ++      case 'e': /* fewer errors from dodgy lines */
  3668. ++          iocccok = true;
  3669. ++          break;
  3670. ++      case 'f': /* definitions file */
  3671. ++          defundefile(optarg);
  3672. ++          break;
  3673. ++      case 'h':
  3674. ++          help();
  3675. ++          break;
  3676. ++      case 'K': /* keep ambiguous #ifs */
  3677. ++          strictlogic = true;
  3678. ++          break;
  3679. ++      case 'k': /* process constant #ifs */
  3680. ++          killconsts = true;
  3681. ++          break;
  3682. ++      case 'm': /* modify in place */
  3683. ++          inplace = true;
  3684. ++          break;
  3685. ++      case 'M': /* modify in place and keep backup */
  3686. ++          inplace = true;
  3687. ++          backext = optarg;
  3688. ++          break;
  3689. ++      case 'n': /* add #line directive after deleted lines */
  3690. ++          lnnum = true;
  3691. ++          break;
  3692. ++      case 'o': /* output to a file */
  3693. ++          ofilename = optarg;
  3694. ++          break;
  3695. ++      case 's': /* only output list of symbols that control #ifs */
  3696. ++          symlist = true;
  3697. ++          break;
  3698. ++      case 'S': /* list symbols with their nesting depth */
  3699. ++          symlist = symdepth = true;
  3700. ++          break;
  3701. ++      case 't': /* don't parse C comments */
  3702. ++          text = true;
  3703. ++          break;
  3704. ++      case 'V':
  3705. ++          version();
  3706. ++          break;
  3707. ++      case 'x':
  3708. ++          exitmode = atoi(optarg);
  3709. ++          if(exitmode < 0 || exitmode > 2)
  3710. ++              usage();
  3711. ++          break;
  3712. ++      default:
  3713. ++          usage();
  3714. ++      }
  3715. ++  argc -= optind;
  3716. ++  argv += optind;
  3717. ++  if (compblank && lnblank)
  3718. ++      errx(2, "-B and -b are mutually exclusive");
  3719. ++  if (symlist && (ofilename != NULL || inplace || argc > 1))
  3720. ++      errx(2, "-s only works with one input file");
  3721. ++  if (argc > 1 && ofilename != NULL)
  3722. ++      errx(2, "-o cannot be used with multiple input files");
  3723. ++  if (argc > 1 && !inplace)
  3724. ++      errx(2, "multiple input files require -m or -M");
  3725. ++  if (argc == 0)
  3726. ++      argc = 1;
  3727. ++  if (argc == 1 && !inplace && ofilename == NULL)
  3728. ++      ofilename = "-";
  3729. ++  indirectsym();
  3730. ++
  3731. ++  atexit(cleantemp);
  3732. ++  if (ofilename != NULL)
  3733. ++      processinout(*argv, ofilename);
  3734. ++  else while (argc-- > 0) {
  3735. ++      processinout(*argv, *argv);
  3736. ++      argv++;
  3737. ++  }
  3738. ++  switch(exitmode) {
  3739. ++  case(0): exit(exitstat);
  3740. ++  case(1): exit(!exitstat);
  3741. ++  case(2): exit(0);
  3742. ++  default: abort(); /* bug */
  3743. ++  }
  3744. ++}
  3745. ++
  3746. ++/*
  3747. ++ * File logistics.
  3748. ++ */
  3749. ++static void
  3750. ++processinout(const char *ifn, const char *ofn)
  3751. ++{
  3752. ++  struct stat st;
  3753. ++
  3754. ++  if (ifn == NULL || strcmp(ifn, "-") == 0) {
  3755. ++      filename = "[stdin]";
  3756. ++      linefile = NULL;
  3757. ++      input = fbinmode(stdin);
  3758. ++  } else {
  3759. ++      filename = ifn;
  3760. ++      linefile = ifn;
  3761. ++      input = fopen(ifn, "rb");
  3762. ++      if (input == NULL)
  3763. ++          err(2, "can't open %s", ifn);
  3764. ++  }
  3765. ++  if (strcmp(ofn, "-") == 0) {
  3766. ++      output = fbinmode(stdout);
  3767. ++      process();
  3768. ++      return;
  3769. ++  }
  3770. ++  if (stat(ofn, &st) < 0) {
  3771. ++      output = fopen(ofn, "wb");
  3772. ++      if (output == NULL)
  3773. ++          err(2, "can't create %s", ofn);
  3774. ++      process();
  3775. ++      return;
  3776. ++  }
  3777. ++
  3778. ++  tempname = astrcat(ofn, ".XXXXXX");
  3779. ++  output = mktempmode(tempname, st.st_mode);
  3780. ++  if (output == NULL)
  3781. ++      err(2, "can't create %s", tempname);
  3782. ++
  3783. ++  process();
  3784. ++
  3785. ++  if (backext != NULL) {
  3786. ++      char *backname = astrcat(ofn, backext);
  3787. ++      if (rename(ofn, backname) < 0)
  3788. ++          err(2, "can't rename \"%s\" to \"%s\"", ofn, backname);
  3789. ++      free(backname);
  3790. ++  }
  3791. ++  if (replace(tempname, ofn) < 0)
  3792. ++      err(2, "can't rename \"%s\" to \"%s\"", tempname, ofn);
  3793. ++  free(tempname);
  3794. ++  tempname = NULL;
  3795. ++}
  3796. ++
  3797. ++/*
  3798. ++ * For cleaning up if there is an error.
  3799. ++ */
  3800. ++static void
  3801. ++cleantemp(void)
  3802. ++{
  3803. ++  if (tempname != NULL)
  3804. ++      remove(tempname);
  3805. ++}
  3806. ++
  3807. ++/*
  3808. ++ * Self-identification functions.
  3809. ++ */
  3810. ++
  3811. ++static void
  3812. ++version(void)
  3813. ++{
  3814. ++  const char *c = copyright;
  3815. ++  for (;;) {
  3816. ++      while (*++c != '$')
  3817. ++          if (*c == '\0')
  3818. ++              exit(0);
  3819. ++      while (*++c != '$')
  3820. ++          putc(*c, stderr);
  3821. ++      putc('\n', stderr);
  3822. ++  }
  3823. ++}
  3824. ++
  3825. ++static void
  3826. ++synopsis(FILE *fp)
  3827. ++{
  3828. ++  fprintf(fp,
  3829. ++      "usage: unifdef [-bBcdehKkmnsStV] [-x{012}] [-Mext] [-opath] \\\n"
  3830. ++      "       [-[i]Dsym[=val]] [-[i]Usym] [-fpath] ... [file] ...\n");
  3831. ++}
  3832. ++
  3833. ++static void
  3834. ++usage(void)
  3835. ++{
  3836. ++  synopsis(stderr);
  3837. ++  exit(2);
  3838. ++}
  3839. ++
  3840. ++static void
  3841. ++help(void)
  3842. ++{
  3843. ++  synopsis(stdout);
  3844. ++  printf(
  3845. ++      "   -Dsym=val  define preprocessor symbol with given value\n"
  3846. ++      "   -Dsym      define preprocessor symbol with value 1\n"
  3847. ++      "   -Usym      preprocessor symbol is undefined\n"
  3848. ++      "   -iDsym=val \\  ignore C strings and comments\n"
  3849. ++      "   -iDsym      ) in sections controlled by these\n"
  3850. ++      "   -iUsym     /  preprocessor symbols\n"
  3851. ++      "   -fpath  file containing #define and #undef directives\n"
  3852. ++      "   -b  blank lines instead of deleting them\n"
  3853. ++      "   -B  compress blank lines around deleted section\n"
  3854. ++      "   -c  complement (invert) keep vs. delete\n"
  3855. ++      "   -d  debugging mode\n"
  3856. ++      "   -e  ignore multiline preprocessor directives\n"
  3857. ++      "   -h  print help\n"
  3858. ++      "   -Ipath  extra include file path (ignored)\n"
  3859. ++      "   -K  disable && and || short-circuiting\n"
  3860. ++      "   -k  process constant #if expressions\n"
  3861. ++      "   -Mext   modify in place and keep backups\n"
  3862. ++      "   -m  modify input files in place\n"
  3863. ++      "   -n  add #line directives to output\n"
  3864. ++      "   -opath  output file name\n"
  3865. ++      "   -S  list #if control symbols with nesting\n"
  3866. ++      "   -s  list #if control symbols\n"
  3867. ++      "   -t  ignore C strings and comments\n"
  3868. ++      "   -V  print version\n"
  3869. ++      "   -x{012} exit status mode\n"
  3870. ++  );
  3871. ++  exit(0);
  3872. ++}
  3873. ++
  3874. ++/*
  3875. ++ * A state transition function alters the global #if processing state
  3876. ++ * in a particular way. The table below is indexed by the current
  3877. ++ * processing state and the type of the current line.
  3878. ++ *
  3879. ++ * Nesting is handled by keeping a stack of states; some transition
  3880. ++ * functions increase or decrease the depth. They also maintain the
  3881. ++ * ignore state on a stack. In some complicated cases they have to
  3882. ++ * alter the preprocessor directive, as follows.
  3883. ++ *
  3884. ++ * When we have processed a group that starts off with a known-false
  3885. ++ * #if/#elif sequence (which has therefore been deleted) followed by a
  3886. ++ * #elif that we don't understand and therefore must keep, we edit the
  3887. ++ * latter into a #if to keep the nesting correct. We use memcpy() to
  3888. ++ * overwrite the 4 byte token "elif" with "if  " without a '\0' byte.
  3889. ++ *
  3890. ++ * When we find a true #elif in a group, the following block will
  3891. ++ * always be kept and the rest of the sequence after the next #elif or
  3892. ++ * #else will be discarded. We edit the #elif into a #else and the
  3893. ++ * following directive to #endif since this has the desired behaviour.
  3894. ++ *
  3895. ++ * "Dodgy" directives are split across multiple lines, the most common
  3896. ++ * example being a multi-line comment hanging off the right of the
  3897. ++ * directive. We can handle them correctly only if there is no change
  3898. ++ * from printing to dropping (or vice versa) caused by that directive.
  3899. ++ * If the directive is the first of a group we have a choice between
  3900. ++ * failing with an error, or passing it through unchanged instead of
  3901. ++ * evaluating it. The latter is not the default to avoid questions from
  3902. ++ * users about unifdef unexpectedly leaving behind preprocessor directives.
  3903. ++ */
  3904. ++typedef void state_fn(void);
  3905. ++
  3906. ++/* report an error */
  3907. ++static void Eelif (void) { error("Inappropriate #elif"); }
  3908. ++static void Eelse (void) { error("Inappropriate #else"); }
  3909. ++static void Eendif(void) { error("Inappropriate #endif"); }
  3910. ++static void Eeof  (void) { error("Premature EOF"); }
  3911. ++static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
  3912. ++/* plain line handling */
  3913. ++static void print (void) { flushline(true); }
  3914. ++static void drop  (void) { flushline(false); }
  3915. ++/* output lacks group's start line */
  3916. ++static void Strue (void) { drop();  ignoreoff(); state(IS_TRUE_PREFIX); }
  3917. ++static void Sfalse(void) { drop();  ignoreoff(); state(IS_FALSE_PREFIX); }
  3918. ++static void Selse (void) { drop();               state(IS_TRUE_ELSE); }
  3919. ++/* print/pass this block */
  3920. ++static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
  3921. ++static void Pelse (void) { print();              state(IS_PASS_ELSE); }
  3922. ++static void Pendif(void) { print(); unnest(); }
  3923. ++/* discard this block */
  3924. ++static void Dfalse(void) { drop();  ignoreoff(); state(IS_FALSE_TRAILER); }
  3925. ++static void Delif (void) { drop();  ignoreoff(); state(IS_FALSE_MIDDLE); }
  3926. ++static void Delse (void) { drop();               state(IS_FALSE_ELSE); }
  3927. ++static void Dendif(void) { drop();  unnest(); }
  3928. ++/* first line of group */
  3929. ++static void Fdrop (void) { nest();  Dfalse(); }
  3930. ++static void Fpass (void) { nest();  Pelif(); }
  3931. ++static void Ftrue (void) { nest();  Strue(); }
  3932. ++static void Ffalse(void) { nest();  Sfalse(); }
  3933. ++/* variable pedantry for obfuscated lines */
  3934. ++static void Oiffy (void) { if (!iocccok) Eioccc(); Fpass(); ignoreon(); }
  3935. ++static void Oif   (void) { if (!iocccok) Eioccc(); Fpass(); }
  3936. ++static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
  3937. ++/* ignore comments in this block */
  3938. ++static void Idrop (void) { Fdrop();  ignoreon(); }
  3939. ++static void Itrue (void) { Ftrue();  ignoreon(); }
  3940. ++static void Ifalse(void) { Ffalse(); ignoreon(); }
  3941. ++/* modify this line */
  3942. ++static void Mpass (void) { memcpy(keyword, "if  ", 4); Pelif(); }
  3943. ++static void Mtrue (void) { keywordedit("else");  state(IS_TRUE_MIDDLE); }
  3944. ++static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
  3945. ++static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
  3946. ++
  3947. ++static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
  3948. ++/* IS_OUTSIDE */
  3949. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
  3950. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eendif,
  3951. ++  print, done,  abort },
  3952. ++/* IS_FALSE_PREFIX */
  3953. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
  3954. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
  3955. ++  drop,  Eeof,  abort },
  3956. ++/* IS_TRUE_PREFIX */
  3957. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
  3958. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
  3959. ++  print, Eeof,  abort },
  3960. ++/* IS_PASS_MIDDLE */
  3961. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
  3962. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Pelif, Oelif, Oelif, Pelse, Pendif,
  3963. ++  print, Eeof,  abort },
  3964. ++/* IS_FALSE_MIDDLE */
  3965. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
  3966. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
  3967. ++  drop,  Eeof,  abort },
  3968. ++/* IS_TRUE_MIDDLE */
  3969. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
  3970. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
  3971. ++  print, Eeof,  abort },
  3972. ++/* IS_PASS_ELSE */
  3973. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
  3974. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Pendif,
  3975. ++  print, Eeof,  abort },
  3976. ++/* IS_FALSE_ELSE */
  3977. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
  3978. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
  3979. ++  drop,  Eeof,  abort },
  3980. ++/* IS_TRUE_ELSE */
  3981. ++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
  3982. ++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eioccc,
  3983. ++  print, Eeof,  abort },
  3984. ++/* IS_FALSE_TRAILER */
  3985. ++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
  3986. ++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
  3987. ++  drop,  Eeof,  abort }
  3988. ++/*TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF
  3989. ++  TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF (DODGY)
  3990. ++  PLAIN  EOF    ERROR */
  3991. ++};
  3992. ++
  3993. ++/*
  3994. ++ * State machine utility functions
  3995. ++ */
  3996. ++static void
  3997. ++ignoreoff(void)
  3998. ++{
  3999. ++  if (depth == 0)
  4000. ++      abort(); /* bug */
  4001. ++  ignoring[depth] = ignoring[depth-1];
  4002. ++}
  4003. ++static void
  4004. ++ignoreon(void)
  4005. ++{
  4006. ++  ignoring[depth] = true;
  4007. ++}
  4008. ++static void
  4009. ++keywordedit(const char *replacement)
  4010. ++{
  4011. ++  snprintf(keyword, tline + sizeof(tline) - keyword,
  4012. ++      "%s%s", replacement, newline);
  4013. ++  print();
  4014. ++}
  4015. ++static void
  4016. ++nest(void)
  4017. ++{
  4018. ++  if (depth > MAXDEPTH-1)
  4019. ++      abort(); /* bug */
  4020. ++  if (depth == MAXDEPTH-1)
  4021. ++      error("Too many levels of nesting");
  4022. ++  depth += 1;
  4023. ++  stifline[depth] = linenum;
  4024. ++}
  4025. ++static void
  4026. ++unnest(void)
  4027. ++{
  4028. ++  if (depth == 0)
  4029. ++      abort(); /* bug */
  4030. ++  depth -= 1;
  4031. ++}
  4032. ++static void
  4033. ++state(Ifstate is)
  4034. ++{
  4035. ++  ifstate[depth] = is;
  4036. ++}
  4037. ++
  4038. ++/*
  4039. ++ * The last state transition function. When this is called,
  4040. ++ * lineval == LT_EOF, so the process() loop will terminate.
  4041. ++ */
  4042. ++static void
  4043. ++done(void)
  4044. ++{
  4045. ++  if (incomment)
  4046. ++      error("EOF in comment");
  4047. ++  closeio();
  4048. ++}
  4049. ++
  4050. ++/*
  4051. ++ * Write a line to the output or not, according to command line options.
  4052. ++ * If writing fails, closeio() will print the error and exit.
  4053. ++ */
  4054. ++static void
  4055. ++flushline(bool keep)
  4056. ++{
  4057. ++  if (symlist)
  4058. ++      return;
  4059. ++  if (keep ^ complement) {
  4060. ++      bool blankline = tline[strspn(tline, " \t\r\n")] == '\0';
  4061. ++      if (blankline && compblank && blankcount != blankmax) {
  4062. ++          delcount += 1;
  4063. ++          blankcount += 1;
  4064. ++      } else {
  4065. ++          if (lnnum && delcount > 0)
  4066. ++              hashline();
  4067. ++          if (fputs(tline, output) == EOF)
  4068. ++              closeio();
  4069. ++          delcount = 0;
  4070. ++          blankmax = blankcount = blankline ? blankcount + 1 : 0;
  4071. ++      }
  4072. ++  } else {
  4073. ++      if (lnblank && fputs(newline, output) == EOF)
  4074. ++          closeio();
  4075. ++      exitstat = 1;
  4076. ++      delcount += 1;
  4077. ++      blankcount = 0;
  4078. ++  }
  4079. ++  if (debugging && fflush(output) == EOF)
  4080. ++      closeio();
  4081. ++}
  4082. ++
  4083. ++/*
  4084. ++ * Format of #line directives depends on whether we know the input filename.
  4085. ++ */
  4086. ++static void
  4087. ++hashline(void)
  4088. ++{
  4089. ++  int e;
  4090. ++
  4091. ++  if (linefile == NULL)
  4092. ++      e = fprintf(output, "#line %d%s", linenum, newline);
  4093. ++  else
  4094. ++      e = fprintf(output, "#line %d \"%s\"%s",
  4095. ++          linenum, linefile, newline);
  4096. ++  if (e < 0)
  4097. ++      closeio();
  4098. ++}
  4099. ++
  4100. ++/*
  4101. ++ * Flush the output and handle errors.
  4102. ++ */
  4103. ++static void
  4104. ++closeio(void)
  4105. ++{
  4106. ++  /* Tidy up after findsym(). */
  4107. ++  if (symdepth && !zerosyms)
  4108. ++      printf("\n");
  4109. ++  if (output != NULL && (ferror(output) || fclose(output) == EOF))
  4110. ++          err(2, "%s: can't write to output", filename);
  4111. ++  fclose(input);
  4112. ++}
  4113. ++
  4114. ++/*
  4115. ++ * The driver for the state machine.
  4116. ++ */
  4117. ++static void
  4118. ++process(void)
  4119. ++{
  4120. ++  Linetype lineval = LT_PLAIN;
  4121. ++  /* When compressing blank lines, act as if the file
  4122. ++     is preceded by a large number of blank lines. */
  4123. ++  blankmax = blankcount = 1000;
  4124. ++  zerosyms = true;
  4125. ++  newline = NULL;
  4126. ++  linenum = 0;
  4127. ++  while (lineval != LT_EOF) {
  4128. ++      lineval = parseline();
  4129. ++      trans_table[ifstate[depth]][lineval]();
  4130. ++      debug("process line %d %s -> %s depth %d",
  4131. ++          linenum, linetype_name[lineval],
  4132. ++          ifstate_name[ifstate[depth]], depth);
  4133. ++  }
  4134. ++}
  4135. ++
  4136. ++/*
  4137. ++ * Parse a line and determine its type. We keep the preprocessor line
  4138. ++ * parser state between calls in the global variable linestate, with
  4139. ++ * help from skipcomment().
  4140. ++ */
  4141. ++static Linetype
  4142. ++parseline(void)
  4143. ++{
  4144. ++  const char *cp;
  4145. ++  int cursym;
  4146. ++  Linetype retval;
  4147. ++  Comment_state wascomment;
  4148. ++
  4149. ++  wascomment = incomment;
  4150. ++  cp = skiphash();
  4151. ++  if (cp == NULL)
  4152. ++      return (LT_EOF);
  4153. ++  if (newline == NULL) {
  4154. ++      if (strrchr(tline, '\n') == strrchr(tline, '\r') + 1)
  4155. ++          newline = newline_crlf;
  4156. ++      else
  4157. ++          newline = newline_unix;
  4158. ++  }
  4159. ++  if (*cp == '\0') {
  4160. ++      retval = LT_PLAIN;
  4161. ++      goto done;
  4162. ++  }
  4163. ++  keyword = tline + (cp - tline);
  4164. ++  if ((cp = matchsym("ifdef", keyword)) != NULL ||
  4165. ++      (cp = matchsym("ifndef", keyword)) != NULL) {
  4166. ++      cp = skipcomment(cp);
  4167. ++      if ((cursym = findsym(&cp)) < 0)
  4168. ++          retval = LT_IF;
  4169. ++      else {
  4170. ++          retval = (keyword[2] == 'n')
  4171. ++              ? LT_FALSE : LT_TRUE;
  4172. ++          if (value[cursym] == NULL)
  4173. ++              retval = (retval == LT_TRUE)
  4174. ++                  ? LT_FALSE : LT_TRUE;
  4175. ++          if (ignore[cursym])
  4176. ++              retval = (retval == LT_TRUE)
  4177. ++                  ? LT_TRUEI : LT_FALSEI;
  4178. ++      }
  4179. ++  } else if ((cp = matchsym("if", keyword)) != NULL)
  4180. ++      retval = ifeval(&cp);
  4181. ++  else if ((cp = matchsym("elif", keyword)) != NULL)
  4182. ++      retval = linetype_if2elif(ifeval(&cp));
  4183. ++  else if ((cp = matchsym("else", keyword)) != NULL)
  4184. ++      retval = LT_ELSE;
  4185. ++  else if ((cp = matchsym("endif", keyword)) != NULL)
  4186. ++      retval = LT_ENDIF;
  4187. ++  else {
  4188. ++      cp = skipsym(keyword);
  4189. ++      /* no way can we deal with a continuation inside a keyword */
  4190. ++      if (strncmp(cp, "\\\r\n", 3) == 0 ||
  4191. ++          strncmp(cp, "\\\n", 2) == 0)
  4192. ++          Eioccc();
  4193. ++      cp = skipline(cp);
  4194. ++      retval = LT_PLAIN;
  4195. ++      goto done;
  4196. ++  }
  4197. ++  cp = skipcomment(cp);
  4198. ++  if (*cp != '\0') {
  4199. ++      cp = skipline(cp);
  4200. ++      if (retval == LT_TRUE || retval == LT_FALSE ||
  4201. ++          retval == LT_TRUEI || retval == LT_FALSEI)
  4202. ++          retval = LT_IF;
  4203. ++      if (retval == LT_ELTRUE || retval == LT_ELFALSE)
  4204. ++          retval = LT_ELIF;
  4205. ++  }
  4206. ++  /* the following can happen if the last line of the file lacks a
  4207. ++     newline or if there is too much whitespace in a directive */
  4208. ++  if (linestate == LS_HASH) {
  4209. ++      long len = cp - tline;
  4210. ++      if (fgets(tline + len, MAXLINE - len, input) == NULL) {
  4211. ++          if (ferror(input))
  4212. ++              err(2, "can't read %s", filename);
  4213. ++          /* append the missing newline at eof */
  4214. ++          strcpy(tline + len, newline);
  4215. ++          cp += strlen(newline);
  4216. ++          linestate = LS_START;
  4217. ++      } else {
  4218. ++          linestate = LS_DIRTY;
  4219. ++      }
  4220. ++  }
  4221. ++  if (retval != LT_PLAIN && (wascomment || linestate != LS_START)) {
  4222. ++      retval = linetype_2dodgy(retval);
  4223. ++      linestate = LS_DIRTY;
  4224. ++  }
  4225. ++done:
  4226. ++  debug("parser line %d state %s comment %s line", linenum,
  4227. ++      comment_name[incomment], linestate_name[linestate]);
  4228. ++  return (retval);
  4229. ++}
  4230. ++
  4231. ++/*
  4232. ++ * These are the binary operators that are supported by the expression
  4233. ++ * evaluator.
  4234. ++ */
  4235. ++static Linetype op_strict(long *p, long v, Linetype at, Linetype bt) {
  4236. ++  if(at == LT_IF || bt == LT_IF) return (LT_IF);
  4237. ++  return (*p = v, v ? LT_TRUE : LT_FALSE);
  4238. ++}
  4239. ++static Linetype op_lt(long *p, Linetype at, long a, Linetype bt, long b) {
  4240. ++  return op_strict(p, a < b, at, bt);
  4241. ++}
  4242. ++static Linetype op_gt(long *p, Linetype at, long a, Linetype bt, long b) {
  4243. ++  return op_strict(p, a > b, at, bt);
  4244. ++}
  4245. ++static Linetype op_le(long *p, Linetype at, long a, Linetype bt, long b) {
  4246. ++  return op_strict(p, a <= b, at, bt);
  4247. ++}
  4248. ++static Linetype op_ge(long *p, Linetype at, long a, Linetype bt, long b) {
  4249. ++  return op_strict(p, a >= b, at, bt);
  4250. ++}
  4251. ++static Linetype op_eq(long *p, Linetype at, long a, Linetype bt, long b) {
  4252. ++  return op_strict(p, a == b, at, bt);
  4253. ++}
  4254. ++static Linetype op_ne(long *p, Linetype at, long a, Linetype bt, long b) {
  4255. ++  return op_strict(p, a != b, at, bt);
  4256. ++}
  4257. ++static Linetype op_or(long *p, Linetype at, long a, Linetype bt, long b) {
  4258. ++  if (!strictlogic && (at == LT_TRUE || bt == LT_TRUE))
  4259. ++      return (*p = 1, LT_TRUE);
  4260. ++  return op_strict(p, a || b, at, bt);
  4261. ++}
  4262. ++static Linetype op_and(long *p, Linetype at, long a, Linetype bt, long b) {
  4263. ++  if (!strictlogic && (at == LT_FALSE || bt == LT_FALSE))
  4264. ++      return (*p = 0, LT_FALSE);
  4265. ++  return op_strict(p, a && b, at, bt);
  4266. ++}
  4267. ++
  4268. ++/*
  4269. ++ * An evaluation function takes three arguments, as follows: (1) a pointer to
  4270. ++ * an element of the precedence table which lists the operators at the current
  4271. ++ * level of precedence; (2) a pointer to an integer which will receive the
  4272. ++ * value of the expression; and (3) a pointer to a char* that points to the
  4273. ++ * expression to be evaluated and that is updated to the end of the expression
  4274. ++ * when evaluation is complete. The function returns LT_FALSE if the value of
  4275. ++ * the expression is zero, LT_TRUE if it is non-zero, LT_IF if the expression
  4276. ++ * depends on an unknown symbol, or LT_ERROR if there is a parse failure.
  4277. ++ */
  4278. ++struct ops;
  4279. ++
  4280. ++typedef Linetype eval_fn(const struct ops *, long *, const char **);
  4281. ++
  4282. ++static eval_fn eval_table, eval_unary;
  4283. ++
  4284. ++/*
  4285. ++ * The precedence table. Expressions involving binary operators are evaluated
  4286. ++ * in a table-driven way by eval_table. When it evaluates a subexpression it
  4287. ++ * calls the inner function with its first argument pointing to the next
  4288. ++ * element of the table. Innermost expressions have special non-table-driven
  4289. ++ * handling.
  4290. ++ */
  4291. ++struct op {
  4292. ++  const char *str;
  4293. ++  Linetype (*fn)(long *, Linetype, long, Linetype, long);
  4294. ++};
  4295. ++struct ops {
  4296. ++  eval_fn *inner;
  4297. ++  struct op op[5];
  4298. ++};
  4299. ++static const struct ops eval_ops[] = {
  4300. ++  { eval_table, { { "||", op_or } } },
  4301. ++  { eval_table, { { "&&", op_and } } },
  4302. ++  { eval_table, { { "==", op_eq },
  4303. ++          { "!=", op_ne } } },
  4304. ++  { eval_unary, { { "<=", op_le },
  4305. ++          { ">=", op_ge },
  4306. ++          { "<", op_lt },
  4307. ++          { ">", op_gt } } }
  4308. ++};
  4309. ++
  4310. ++/* Current operator precedence level */
  4311. ++static long prec(const struct ops *ops)
  4312. ++{
  4313. ++  return (ops - eval_ops);
  4314. ++}
  4315. ++
  4316. ++/*
  4317. ++ * Function for evaluating the innermost parts of expressions,
  4318. ++ * viz. !expr (expr) number defined(symbol) symbol
  4319. ++ * We reset the constexpr flag in the last two cases.
  4320. ++ */
  4321. ++static Linetype
  4322. ++eval_unary(const struct ops *ops, long *valp, const char **cpp)
  4323. ++{
  4324. ++  const char *cp;
  4325. ++  char *ep;
  4326. ++  int sym;
  4327. ++  bool defparen;
  4328. ++  Linetype lt;
  4329. ++
  4330. ++  cp = skipcomment(*cpp);
  4331. ++  if (*cp == '!') {
  4332. ++      debug("eval%d !", prec(ops));
  4333. ++      cp++;
  4334. ++      lt = eval_unary(ops, valp, &cp);
  4335. ++      if (lt == LT_ERROR)
  4336. ++          return (LT_ERROR);
  4337. ++      if (lt != LT_IF) {
  4338. ++          *valp = !*valp;
  4339. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  4340. ++      }
  4341. ++  } else if (*cp == '(') {
  4342. ++      cp++;
  4343. ++      debug("eval%d (", prec(ops));
  4344. ++      lt = eval_table(eval_ops, valp, &cp);
  4345. ++      if (lt == LT_ERROR)
  4346. ++          return (LT_ERROR);
  4347. ++      cp = skipcomment(cp);
  4348. ++      if (*cp++ != ')')
  4349. ++          return (LT_ERROR);
  4350. ++  } else if (isdigit((unsigned char)*cp)) {
  4351. ++      debug("eval%d number", prec(ops));
  4352. ++      *valp = strtol(cp, &ep, 0);
  4353. ++      if (ep == cp)
  4354. ++          return (LT_ERROR);
  4355. ++      lt = *valp ? LT_TRUE : LT_FALSE;
  4356. ++      cp = ep;
  4357. ++  } else if (matchsym("defined", cp) != NULL) {
  4358. ++      cp = skipcomment(cp+7);
  4359. ++      if (*cp == '(') {
  4360. ++          cp = skipcomment(cp+1);
  4361. ++          defparen = true;
  4362. ++      } else {
  4363. ++          defparen = false;
  4364. ++      }
  4365. ++      sym = findsym(&cp);
  4366. ++      cp = skipcomment(cp);
  4367. ++      if (defparen && *cp++ != ')') {
  4368. ++          debug("eval%d defined missing ')'", prec(ops));
  4369. ++          return (LT_ERROR);
  4370. ++      }
  4371. ++      if (sym < 0) {
  4372. ++          debug("eval%d defined unknown", prec(ops));
  4373. ++          lt = LT_IF;
  4374. ++      } else {
  4375. ++          debug("eval%d defined %s", prec(ops), symname[sym]);
  4376. ++          *valp = (value[sym] != NULL);
  4377. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  4378. ++      }
  4379. ++      constexpr = false;
  4380. ++  } else if (!endsym(*cp)) {
  4381. ++      debug("eval%d symbol", prec(ops));
  4382. ++      sym = findsym(&cp);
  4383. ++      if (sym < 0) {
  4384. ++          lt = LT_IF;
  4385. ++          cp = skipargs(cp);
  4386. ++      } else if (value[sym] == NULL) {
  4387. ++          *valp = 0;
  4388. ++          lt = LT_FALSE;
  4389. ++      } else {
  4390. ++          *valp = strtol(value[sym], &ep, 0);
  4391. ++          if (*ep != '\0' || ep == value[sym])
  4392. ++              return (LT_ERROR);
  4393. ++          lt = *valp ? LT_TRUE : LT_FALSE;
  4394. ++          cp = skipargs(cp);
  4395. ++      }
  4396. ++      constexpr = false;
  4397. ++  } else {
  4398. ++      debug("eval%d bad expr", prec(ops));
  4399. ++      return (LT_ERROR);
  4400. ++  }
  4401. ++
  4402. ++  *cpp = cp;
  4403. ++  debug("eval%d = %d", prec(ops), *valp);
  4404. ++  return (lt);
  4405. ++}
  4406. ++
  4407. ++/*
  4408. ++ * Table-driven evaluation of binary operators.
  4409. ++ */
  4410. ++static Linetype
  4411. ++eval_table(const struct ops *ops, long *valp, const char **cpp)
  4412. ++{
  4413. ++  const struct op *op;
  4414. ++  const char *cp;
  4415. ++  long val;
  4416. ++  Linetype lt, rt;
  4417. ++
  4418. ++  debug("eval%d", prec(ops));
  4419. ++  cp = *cpp;
  4420. ++  lt = ops->inner(ops+1, valp, &cp);
  4421. ++  if (lt == LT_ERROR)
  4422. ++      return (LT_ERROR);
  4423. ++  for (;;) {
  4424. ++      cp = skipcomment(cp);
  4425. ++      for (op = ops->op; op->str != NULL; op++)
  4426. ++          if (strncmp(cp, op->str, strlen(op->str)) == 0)
  4427. ++              break;
  4428. ++      if (op->str == NULL)
  4429. ++          break;
  4430. ++      cp += strlen(op->str);
  4431. ++      debug("eval%d %s", prec(ops), op->str);
  4432. ++      rt = ops->inner(ops+1, &val, &cp);
  4433. ++      if (rt == LT_ERROR)
  4434. ++          return (LT_ERROR);
  4435. ++      lt = op->fn(valp, lt, *valp, rt, val);
  4436. ++  }
  4437. ++
  4438. ++  *cpp = cp;
  4439. ++  debug("eval%d = %d", prec(ops), *valp);
  4440. ++  debug("eval%d lt = %s", prec(ops), linetype_name[lt]);
  4441. ++  return (lt);
  4442. ++}
  4443. ++
  4444. ++/*
  4445. ++ * Evaluate the expression on a #if or #elif line. If we can work out
  4446. ++ * the result we return LT_TRUE or LT_FALSE accordingly, otherwise we
  4447. ++ * return just a generic LT_IF.
  4448. ++ */
  4449. ++static Linetype
  4450. ++ifeval(const char **cpp)
  4451. ++{
  4452. ++  Linetype ret;
  4453. ++  long val = 0;
  4454. ++
  4455. ++  debug("eval %s", *cpp);
  4456. ++  constexpr = killconsts ? false : true;
  4457. ++  ret = eval_table(eval_ops, &val, cpp);
  4458. ++  debug("eval = %d", val);
  4459. ++  return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret);
  4460. ++}
  4461. ++
  4462. ++/*
  4463. ++ * Read a line and examine its initial part to determine if it is a
  4464. ++ * preprocessor directive. Returns NULL on EOF, or a pointer to a
  4465. ++ * preprocessor directive name, or a pointer to the zero byte at the
  4466. ++ * end of the line.
  4467. ++ */
  4468. ++static const char *
  4469. ++skiphash(void)
  4470. ++{
  4471. ++  const char *cp;
  4472. ++
  4473. ++  linenum++;
  4474. ++  if (fgets(tline, MAXLINE, input) == NULL) {
  4475. ++      if (ferror(input))
  4476. ++          err(2, "can't read %s", filename);
  4477. ++      else
  4478. ++          return (NULL);
  4479. ++  }
  4480. ++  cp = skipcomment(tline);
  4481. ++  if (linestate == LS_START && *cp == '#') {
  4482. ++      linestate = LS_HASH;
  4483. ++      return (skipcomment(cp + 1));
  4484. ++  } else if (*cp == '\0') {
  4485. ++      return (cp);
  4486. ++  } else {
  4487. ++      return (skipline(cp));
  4488. ++  }
  4489. ++}
  4490. ++
  4491. ++/*
  4492. ++ * Mark a line dirty and consume the rest of it, keeping track of the
  4493. ++ * lexical state.
  4494. ++ */
  4495. ++static const char *
  4496. ++skipline(const char *cp)
  4497. ++{
  4498. ++  linestate = LS_DIRTY;
  4499. ++  while (*cp != '\0')
  4500. ++      cp = skipcomment(cp + 1);
  4501. ++  return (cp);
  4502. ++}
  4503. ++
  4504. ++/*
  4505. ++ * Skip over comments, strings, and character literals and stop at the
  4506. ++ * next character position that is not whitespace. Between calls we keep
  4507. ++ * the comment state in the global variable incomment, and we also adjust
  4508. ++ * the global variable linestate when we see a newline.
  4509. ++ * XXX: doesn't cope with the buffer splitting inside a state transition.
  4510. ++ */
  4511. ++static const char *
  4512. ++skipcomment(const char *cp)
  4513. ++{
  4514. ++  if (text || ignoring[depth]) {
  4515. ++      for (; isspace((unsigned char)*cp); cp++)
  4516. ++          if (*cp == '\n')
  4517. ++              linestate = LS_START;
  4518. ++      return (cp);
  4519. ++  }
  4520. ++  while (*cp != '\0')
  4521. ++      /* don't reset to LS_START after a line continuation */
  4522. ++      if (strncmp(cp, "\\\r\n", 3) == 0)
  4523. ++          cp += 3;
  4524. ++      else if (strncmp(cp, "\\\n", 2) == 0)
  4525. ++          cp += 2;
  4526. ++      else switch (incomment) {
  4527. ++      case NO_COMMENT:
  4528. ++          if (strncmp(cp, "/\\\r\n", 4) == 0) {
  4529. ++              incomment = STARTING_COMMENT;
  4530. ++              cp += 4;
  4531. ++          } else if (strncmp(cp, "/\\\n", 3) == 0) {
  4532. ++              incomment = STARTING_COMMENT;
  4533. ++              cp += 3;
  4534. ++          } else if (strncmp(cp, "/*", 2) == 0) {
  4535. ++              incomment = C_COMMENT;
  4536. ++              cp += 2;
  4537. ++          } else if (strncmp(cp, "//", 2) == 0) {
  4538. ++              incomment = CXX_COMMENT;
  4539. ++              cp += 2;
  4540. ++          } else if (strncmp(cp, "\'", 1) == 0) {
  4541. ++              incomment = CHAR_LITERAL;
  4542. ++              linestate = LS_DIRTY;
  4543. ++              cp += 1;
  4544. ++          } else if (strncmp(cp, "\"", 1) == 0) {
  4545. ++              incomment = STRING_LITERAL;
  4546. ++              linestate = LS_DIRTY;
  4547. ++              cp += 1;
  4548. ++          } else if (strncmp(cp, "\n", 1) == 0) {
  4549. ++              linestate = LS_START;
  4550. ++              cp += 1;
  4551. ++          } else if (strchr(" \r\t", *cp) != NULL) {
  4552. ++              cp += 1;
  4553. ++          } else
  4554. ++              return (cp);
  4555. ++          continue;
  4556. ++      case CXX_COMMENT:
  4557. ++          if (strncmp(cp, "\n", 1) == 0) {
  4558. ++              incomment = NO_COMMENT;
  4559. ++              linestate = LS_START;
  4560. ++          }
  4561. ++          cp += 1;
  4562. ++          continue;
  4563. ++      case CHAR_LITERAL:
  4564. ++      case STRING_LITERAL:
  4565. ++          if ((incomment == CHAR_LITERAL && cp[0] == '\'') ||
  4566. ++              (incomment == STRING_LITERAL && cp[0] == '\"')) {
  4567. ++              incomment = NO_COMMENT;
  4568. ++              cp += 1;
  4569. ++          } else if (cp[0] == '\\') {
  4570. ++              if (cp[1] == '\0')
  4571. ++                  cp += 1;
  4572. ++              else
  4573. ++                  cp += 2;
  4574. ++          } else if (strncmp(cp, "\n", 1) == 0) {
  4575. ++              if (incomment == CHAR_LITERAL)
  4576. ++                  error("unterminated char literal");
  4577. ++              else
  4578. ++                  error("unterminated string literal");
  4579. ++          } else
  4580. ++              cp += 1;
  4581. ++          continue;
  4582. ++      case C_COMMENT:
  4583. ++          if (strncmp(cp, "*\\\r\n", 4) == 0) {
  4584. ++              incomment = FINISHING_COMMENT;
  4585. ++              cp += 4;
  4586. ++          } else if (strncmp(cp, "*\\\n", 3) == 0) {
  4587. ++              incomment = FINISHING_COMMENT;
  4588. ++              cp += 3;
  4589. ++          } else if (strncmp(cp, "*/", 2) == 0) {
  4590. ++              incomment = NO_COMMENT;
  4591. ++              cp += 2;
  4592. ++          } else
  4593. ++              cp += 1;
  4594. ++          continue;
  4595. ++      case STARTING_COMMENT:
  4596. ++          if (*cp == '*') {
  4597. ++              incomment = C_COMMENT;
  4598. ++              cp += 1;
  4599. ++          } else if (*cp == '/') {
  4600. ++              incomment = CXX_COMMENT;
  4601. ++              cp += 1;
  4602. ++          } else {
  4603. ++              incomment = NO_COMMENT;
  4604. ++              linestate = LS_DIRTY;
  4605. ++          }
  4606. ++          continue;
  4607. ++      case FINISHING_COMMENT:
  4608. ++          if (*cp == '/') {
  4609. ++              incomment = NO_COMMENT;
  4610. ++              cp += 1;
  4611. ++          } else
  4612. ++              incomment = C_COMMENT;
  4613. ++          continue;
  4614. ++      default:
  4615. ++          abort(); /* bug */
  4616. ++      }
  4617. ++  return (cp);
  4618. ++}
  4619. ++
  4620. ++/*
  4621. ++ * Skip macro arguments.
  4622. ++ */
  4623. ++static const char *
  4624. ++skipargs(const char *cp)
  4625. ++{
  4626. ++  const char *ocp = cp;
  4627. ++  int level = 0;
  4628. ++  cp = skipcomment(cp);
  4629. ++  if (*cp != '(')
  4630. ++      return (cp);
  4631. ++  do {
  4632. ++      if (*cp == '(')
  4633. ++          level++;
  4634. ++      if (*cp == ')')
  4635. ++          level--;
  4636. ++      cp = skipcomment(cp+1);
  4637. ++  } while (level != 0 && *cp != '\0');
  4638. ++  if (level == 0)
  4639. ++      return (cp);
  4640. ++  else
  4641. ++  /* Rewind and re-detect the syntax error later. */
  4642. ++      return (ocp);
  4643. ++}
  4644. ++
  4645. ++/*
  4646. ++ * Skip over an identifier.
  4647. ++ */
  4648. ++static const char *
  4649. ++skipsym(const char *cp)
  4650. ++{
  4651. ++  while (!endsym(*cp))
  4652. ++      ++cp;
  4653. ++  return (cp);
  4654. ++}
  4655. ++
  4656. ++/*
  4657. ++ * Skip whitespace and take a copy of any following identifier.
  4658. ++ */
  4659. ++static const char *
  4660. ++getsym(const char **cpp)
  4661. ++{
  4662. ++  const char *cp = *cpp, *sym;
  4663. ++
  4664. ++  cp = skipcomment(cp);
  4665. ++  cp = skipsym(sym = cp);
  4666. ++  if (cp == sym)
  4667. ++      return NULL;
  4668. ++  *cpp = cp;
  4669. ++  return (xstrdup(sym, cp));
  4670. ++}
  4671. ++
  4672. ++/*
  4673. ++ * Check that s (a symbol) matches the start of t, and that the
  4674. ++ * following character in t is not a symbol character. Returns a
  4675. ++ * pointer to the following character in t if there is a match,
  4676. ++ * otherwise NULL.
  4677. ++ */
  4678. ++static const char *
  4679. ++matchsym(const char *s, const char *t)
  4680. ++{
  4681. ++  while (*s != '\0' && *t != '\0')
  4682. ++      if (*s != *t)
  4683. ++          return (NULL);
  4684. ++      else
  4685. ++          ++s, ++t;
  4686. ++  if (*s == '\0' && endsym(*t))
  4687. ++      return(t);
  4688. ++  else
  4689. ++      return(NULL);
  4690. ++}
  4691. ++
  4692. ++/*
  4693. ++ * Look for the symbol in the symbol table. If it is found, we return
  4694. ++ * the symbol table index, else we return -1.
  4695. ++ */
  4696. ++static int
  4697. ++findsym(const char **strp)
  4698. ++{
  4699. ++  const char *str;
  4700. ++  int symind;
  4701. ++
  4702. ++  str = *strp;
  4703. ++  *strp = skipsym(str);
  4704. ++  if (symlist) {
  4705. ++      if (*strp == str)
  4706. ++          return (-1);
  4707. ++      if (symdepth && firstsym)
  4708. ++          printf("%s%3d", zerosyms ? "" : "\n", depth);
  4709. ++      firstsym = zerosyms = false;
  4710. ++      printf("%s%.*s%s",
  4711. ++             symdepth ? " " : "",
  4712. ++             (int)(*strp-str), str,
  4713. ++             symdepth ? "" : "\n");
  4714. ++      /* we don't care about the value of the symbol */
  4715. ++      return (0);
  4716. ++  }
  4717. ++  for (symind = 0; symind < nsyms; ++symind) {
  4718. ++      if (matchsym(symname[symind], str) != NULL) {
  4719. ++          debugsym("findsym", symind);
  4720. ++          return (symind);
  4721. ++      }
  4722. ++  }
  4723. ++  return (-1);
  4724. ++}
  4725. ++
  4726. ++/*
  4727. ++ * Resolve indirect symbol values to their final definitions.
  4728. ++ */
  4729. ++static void
  4730. ++indirectsym(void)
  4731. ++{
  4732. ++  const char *cp;
  4733. ++  int changed, sym, ind;
  4734. ++
  4735. ++  do {
  4736. ++      changed = 0;
  4737. ++      for (sym = 0; sym < nsyms; ++sym) {
  4738. ++          if (value[sym] == NULL)
  4739. ++              continue;
  4740. ++          cp = value[sym];
  4741. ++          ind = findsym(&cp);
  4742. ++          if (ind == -1 || ind == sym ||
  4743. ++              *cp != '\0' ||
  4744. ++              value[ind] == NULL ||
  4745. ++              value[ind] == value[sym])
  4746. ++              continue;
  4747. ++          debugsym("indir...", sym);
  4748. ++          value[sym] = value[ind];
  4749. ++          debugsym("...ectsym", sym);
  4750. ++          changed++;
  4751. ++      }
  4752. ++  } while (changed);
  4753. ++}
  4754. ++
  4755. ++/*
  4756. ++ * Add a symbol to the symbol table, specified with the format sym=val
  4757. ++ */
  4758. ++static void
  4759. ++addsym1(bool ignorethis, bool definethis, char *symval)
  4760. ++{
  4761. ++  const char *sym, *val;
  4762. ++
  4763. ++  sym = symval;
  4764. ++  val = skipsym(sym);
  4765. ++  if (definethis && *val == '=') {
  4766. ++      symval[val - sym] = '\0';
  4767. ++      val = val + 1;
  4768. ++  } else if (*val == '\0') {
  4769. ++      val = definethis ? "1" : NULL;
  4770. ++  } else {
  4771. ++      usage();
  4772. ++  }
  4773. ++  addsym2(ignorethis, sym, val);
  4774. ++}
  4775. ++
  4776. ++/*
  4777. ++ * Add a symbol to the symbol table.
  4778. ++ */
  4779. ++static void
  4780. ++addsym2(bool ignorethis, const char *sym, const char *val)
  4781. ++{
  4782. ++  const char *cp = sym;
  4783. ++  int symind;
  4784. ++
  4785. ++  symind = findsym(&cp);
  4786. ++  if (symind < 0) {
  4787. ++      if (nsyms >= MAXSYMS)
  4788. ++          errx(2, "too many symbols");
  4789. ++      symind = nsyms++;
  4790. ++  }
  4791. ++  ignore[symind] = ignorethis;
  4792. ++  symname[symind] = sym;
  4793. ++  value[symind] = val;
  4794. ++  debugsym("addsym", symind);
  4795. ++}
  4796. ++
  4797. ++static void
  4798. ++debugsym(const char *why, int symind)
  4799. ++{
  4800. ++  debug("%s %s%c%s", why, symname[symind],
  4801. ++      value[symind] ? '=' : ' ',
  4802. ++      value[symind] ? value[symind] : "undef");
  4803. ++}
  4804. ++
  4805. ++/*
  4806. ++ * Add symbols to the symbol table from a file containing
  4807. ++ * #define and #undef preprocessor directives.
  4808. ++ */
  4809. ++static void
  4810. ++defundefile(const char *fn)
  4811. ++{
  4812. ++  filename = fn;
  4813. ++  input = fopen(fn, "rb");
  4814. ++  if (input == NULL)
  4815. ++      err(2, "can't open %s", fn);
  4816. ++  linenum = 0;
  4817. ++  while (defundef())
  4818. ++      ;
  4819. ++  if (ferror(input))
  4820. ++      err(2, "can't read %s", filename);
  4821. ++  else
  4822. ++      fclose(input);
  4823. ++  if (incomment)
  4824. ++      error("EOF in comment");
  4825. ++}
  4826. ++
  4827. ++/*
  4828. ++ * Read and process one #define or #undef directive
  4829. ++ */
  4830. ++static bool
  4831. ++defundef(void)
  4832. ++{
  4833. ++  const char *cp, *kw, *sym, *val, *end;
  4834. ++  Comment_state wascomment;
  4835. ++
  4836. ++  wascomment = incomment;
  4837. ++  cp = skiphash();
  4838. ++  if (cp == NULL)
  4839. ++      return (false);
  4840. ++  if (*cp == '\0')
  4841. ++      goto done;
  4842. ++  /* strip trailing whitespace, and do a fairly rough check to
  4843. ++     avoid unsupported multi-line preprocessor directives */
  4844. ++  end = cp + strlen(cp);
  4845. ++  while (end > tline && strchr(" \t\n\r", end[-1]) != NULL)
  4846. ++      --end;
  4847. ++  if (end > tline && end[-1] == '\\')
  4848. ++      Eioccc();
  4849. ++
  4850. ++  kw = cp;
  4851. ++  if ((cp = matchsym("define", kw)) != NULL) {
  4852. ++      sym = getsym(&cp);
  4853. ++      if (sym == NULL)
  4854. ++          error("missing macro name in #define");
  4855. ++      if (*cp == '(') {
  4856. ++          val = "1";
  4857. ++      } else {
  4858. ++          cp = skipcomment(cp);
  4859. ++          val = (cp < end) ? xstrdup(cp, end) : "";
  4860. ++      }
  4861. ++      debug("#define");
  4862. ++      addsym2(false, sym, val);
  4863. ++  } else if ((cp = matchsym("undef", kw)) != NULL) {
  4864. ++      sym = getsym(&cp);
  4865. ++      if (sym == NULL)
  4866. ++          error("missing macro name in #undef");
  4867. ++      cp = skipcomment(cp);
  4868. ++      debug("#undef");
  4869. ++      addsym2(false, sym, NULL);
  4870. ++  } else {
  4871. ++      error("unrecognized preprocessor directive");
  4872. ++  }
  4873. ++  skipline(cp);
  4874. ++done:
  4875. ++  debug("parser line %d state %s comment %s line", linenum,
  4876. ++      comment_name[incomment], linestate_name[linestate]);
  4877. ++  return (true);
  4878. ++}
  4879. ++
  4880. ++/*
  4881. ++ * Concatenate two strings into new memory, checking for failure.
  4882. ++ */
  4883. ++static char *
  4884. ++astrcat(const char *s1, const char *s2)
  4885. ++{
  4886. ++  char *s;
  4887. ++  int len;
  4888. ++  size_t size;
  4889. ++
  4890. ++  len = snprintf(NULL, 0, "%s%s", s1, s2);
  4891. ++  if (len < 0)
  4892. ++      err(2, "snprintf");
  4893. ++  size = (size_t)len + 1;
  4894. ++  s = (char *)malloc(size);
  4895. ++  if (s == NULL)
  4896. ++      err(2, "malloc");
  4897. ++  snprintf(s, size, "%s%s", s1, s2);
  4898. ++  return (s);
  4899. ++}
  4900. ++
  4901. ++/*
  4902. ++ * Duplicate a segment of a string, checking for failure.
  4903. ++ */
  4904. ++static const char *
  4905. ++xstrdup(const char *start, const char *end)
  4906. ++{
  4907. ++  size_t n;
  4908. ++  char *s;
  4909. ++
  4910. ++  if (end < start) abort(); /* bug */
  4911. ++  n = (size_t)(end - start) + 1;
  4912. ++  s = malloc(n);
  4913. ++  if (s == NULL)
  4914. ++      err(2, "malloc");
  4915. ++  snprintf(s, n, "%s", start);
  4916. ++  return (s);
  4917. ++}
  4918. ++
  4919. ++/*
  4920. ++ * Diagnostics.
  4921. ++ */
  4922. ++static void
  4923. ++debug(const char *msg, ...)
  4924. ++{
  4925. ++  va_list ap;
  4926. ++
  4927. ++  if (debugging) {
  4928. ++      va_start(ap, msg);
  4929. ++      vwarnx(msg, ap);
  4930. ++      va_end(ap);
  4931. ++  }
  4932. ++}
  4933. ++
  4934. ++static void
  4935. ++error(const char *msg)
  4936. ++{
  4937. ++  if (depth == 0)
  4938. ++      warnx("%s: %d: %s", filename, linenum, msg);
  4939. ++  else
  4940. ++      warnx("%s: %d: %s (#if line %d depth %d)",
  4941. ++          filename, linenum, msg, stifline[depth], depth);
  4942. ++  closeio();
  4943. ++  errx(2, "output may be truncated");
  4944. ++}
  4945. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.h linux-3.12/scripts/unifdef-upstream/win32/unifdef.h
  4946. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/unifdef.h   1970-01-01 01:00:00.000000000 +0100
  4947. ++++ linux-3.12/scripts/unifdef-upstream/win32/unifdef.h    2013-12-06 19:36:46.000000000 +0000
  4948. +@@ -0,0 +1,72 @@
  4949. ++/*
  4950. ++ * Copyright (c) 2012 - 2013 Tony Finch <dot@dotat.at>
  4951. ++ *
  4952. ++ * Redistribution and use in source and binary forms, with or without
  4953. ++ * modification, are permitted provided that the following conditions
  4954. ++ * are met:
  4955. ++ * 1. Redistributions of source code must retain the above copyright
  4956. ++ *    notice, this list of conditions and the following disclaimer.
  4957. ++ * 2. Redistributions in binary form must reproduce the above copyright
  4958. ++ *    notice, this list of conditions and the following disclaimer in the
  4959. ++ *    documentation and/or other materials provided with the distribution.
  4960. ++ *
  4961. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  4962. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  4963. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  4964. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  4965. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  4966. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  4967. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  4968. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  4969. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  4970. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  4971. ++ * SUCH DAMAGE.
  4972. ++ */
  4973. ++
  4974. ++#include <ctype.h>
  4975. ++#include <errno.h>
  4976. ++#include <stdarg.h>
  4977. ++#include <stdio.h>
  4978. ++#include <stdlib.h>
  4979. ++#include <string.h>
  4980. ++
  4981. ++/* Windows POSIX-flavoured headers */
  4982. ++
  4983. ++#include <sys/stat.h>
  4984. ++#include <fcntl.h>
  4985. ++#include <io.h>
  4986. ++
  4987. ++#define stat     _stat
  4988. ++#define snprintf _snprintf
  4989. ++
  4990. ++/* fake stdbool.h */
  4991. ++#define true 1
  4992. ++#define false 0
  4993. ++#define bool int
  4994. ++
  4995. ++/* used by err.c and getopt.c */
  4996. ++#define _getprogname() "unifdef"
  4997. ++
  4998. ++/* win32.c */
  4999. ++int replace(const char *old, const char *new);
  5000. ++FILE *mktempmode(char *tmp, int mode);
  5001. ++FILE *fbinmode(FILE *fp);
  5002. ++
  5003. ++/* err.c */
  5004. ++void err(int, const char *, ...);
  5005. ++void verr(int, const char *, va_list);
  5006. ++void errc(int, int, const char *, ...);
  5007. ++void verrc(int, int, const char *, va_list);
  5008. ++void errx(int, const char *, ...);
  5009. ++void verrx(int, const char *, va_list);
  5010. ++void warn(const char *, ...);
  5011. ++void vwarn(const char *, va_list);
  5012. ++void warnc(int, const char *, ...);
  5013. ++void vwarnc(int, const char *, va_list);
  5014. ++void warnx(const char *, ...);
  5015. ++void vwarnx(const char *, va_list);
  5016. ++
  5017. ++/* getopt.c */
  5018. ++int getopt(int nargc, char *nargv[], const char *ostr);
  5019. ++extern int opterr, optind, optopt, optreset;
  5020. ++extern char *optarg;
  5021. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/version.h linux-3.12/scripts/unifdef-upstream/win32/version.h
  5022. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/version.h   1970-01-01 01:00:00.000000000 +0100
  5023. ++++ linux-3.12/scripts/unifdef-upstream/win32/version.h    2013-12-06 19:36:46.000000000 +0000
  5024. +@@ -0,0 +1,2 @@
  5025. ++"@(#) $Version: unifdef-2.9.5.55501a6 $\n"
  5026. ++"@(#) $Date: 2013-06-12 15:50:39 +0100 $\n"
  5027. +diff -urN linux-3.12.orig/scripts/unifdef-upstream/win32/win32.c linux-3.12/scripts/unifdef-upstream/win32/win32.c
  5028. +--- linux-3.12.orig/scripts/unifdef-upstream/win32/win32.c 1970-01-01 01:00:00.000000000 +0100
  5029. ++++ linux-3.12/scripts/unifdef-upstream/win32/win32.c  2013-12-06 19:36:46.000000000 +0000
  5030. +@@ -0,0 +1,53 @@
  5031. ++/*
  5032. ++ * Copyright (c) 2012 - 2013 Tony Finch <dot@dotat.at>
  5033. ++ *
  5034. ++ * Redistribution and use in source and binary forms, with or without
  5035. ++ * modification, are permitted provided that the following conditions
  5036. ++ * are met:
  5037. ++ * 1. Redistributions of source code must retain the above copyright
  5038. ++ *    notice, this list of conditions and the following disclaimer.
  5039. ++ * 2. Redistributions in binary form must reproduce the above copyright
  5040. ++ *    notice, this list of conditions and the following disclaimer in the
  5041. ++ *    documentation and/or other materials provided with the distribution.
  5042. ++ *
  5043. ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  5044. ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  5045. ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  5046. ++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  5047. ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  5048. ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  5049. ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  5050. ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  5051. ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  5052. ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  5053. ++ * SUCH DAMAGE.
  5054. ++ */
  5055. ++
  5056. ++#include "unifdef.h"
  5057. ++
  5058. ++/*
  5059. ++ * The Windows implementation of rename() fails if the new filename
  5060. ++ * already exists. Atomic replacement is not really needed, so just
  5061. ++ * remove anything that might be in the way before renaming.
  5062. ++ */
  5063. ++int
  5064. ++replace(const char *old, const char *new)
  5065. ++{
  5066. ++  if (remove(new) < 0)
  5067. ++      warn("can't remove \"%s\"", new);
  5068. ++  return (rename(old, new));
  5069. ++}
  5070. ++
  5071. ++FILE *
  5072. ++mktempmode(char *tmp, int mode)
  5073. ++{
  5074. ++  mode = mode;
  5075. ++  return (fopen(_mktemp(tmp), "wb"));
  5076. ++}
  5077. ++
  5078. ++FILE *
  5079. ++fbinmode(FILE *fp)
  5080. ++{
  5081. ++  _setmode(_fileno(fp), _O_BINARY);
  5082. ++  return (fp);
  5083. ++}
  5084. Index: patches/linux/3.12.8/140-kernel-disable-archscripts.patch
  5085. ===================================================================
  5086. --- patches/linux/3.12.8/140-kernel-disable-archscripts.patch   (revision 0)
  5087. +++ patches/linux/3.12.8/140-kernel-disable-archscripts.patch   (working copy)
  5088. @@ -0,0 +1,11 @@
  5089. +--- linux-3.12.8/Makefile.orig 2014-01-16 00:31:56.000000000 +0100
  5090. ++++ linux-3.12.8/Makefile  2014-01-20 00:03:25.961403100 +0100
  5091. +@@ -906,7 +906,7 @@
  5092. + archscripts:
  5093. +
  5094. + PHONY += __headers
  5095. +-__headers: $(version_h) scripts_basic asm-generic archheaders archscripts FORCE
  5096. ++__headers: $(version_h) scripts_basic asm-generic archheaders FORCE
  5097. +   $(Q)$(MAKE) $(build)=scripts build_unifdef
  5098. +
  5099. + PHONY += headers_install_all
  5100. Index: scripts/build/binutils/binutils.sh
  5101. ===================================================================
  5102. --- scripts/build/binutils/binutils.sh  (revision 272)
  5103. +++ scripts/build/binutils/binutils.sh  (working copy)
  5104. @@ -343,6 +343,9 @@
  5105.          [ "${CT_TOOLCHAIN_ENABLE_NLS}" != "y" ] && extra_config+=("--disable-nls")
  5106.  
  5107.          CT_DoExecLog CFG                                            \
  5108. +        CFLAGS="${CT_CFLAGS_FOR_BUILD}"                             \
  5109. +        CXXFLAGS="${CT_CFLAGS_FOR_BUILD}"                           \
  5110. +        LDFLAGS="${CT_LDFLAGS_FOR_BUILD}"                           \
  5111.          "${CT_SRC_DIR}/binutils-${CT_BINUTILS_VERSION}/configure"   \
  5112.              --build=${CT_BUILD}                                     \
  5113.              --host=${CT_TARGET}                                     \
  5114. Index: scripts/build/debug/300-gdb.sh
  5115. ===================================================================
  5116. --- scripts/build/debug/300-gdb.sh  (revision 272)
  5117. +++ scripts/build/debug/300-gdb.sh  (working copy)
  5118. @@ -123,14 +123,14 @@
  5119.          cd "${CT_BUILD_DIR}/build-gdb-cross"
  5120.  
  5121.          cross_extra_config=("${extra_config[@]}")
  5122. -        cross_extra_config+=("--enable-expat")
  5123.          cross_extra_config+=("--with-expat=yes")
  5124. +        cross_extra_config+=("--with-libexpat-prefix=/mingw${CT_ARCH_BITNESS}")
  5125.          case "${CT_THREADS}" in
  5126.              none)   cross_extra_config+=("--disable-threads");;
  5127.              *)      cross_extra_config+=("--enable-threads");;
  5128.          esac
  5129.          if [ "${CT_GDB_CROSS_PYTHON}" = "y" ]; then
  5130. -            cross_extra_config+=( "--with-python=yes" )
  5131. +            cross_extra_config+=( "--with-python=/mingw${CT_ARCH_BITNESS}" )
  5132.          else
  5133.              cross_extra_config+=( "--with-python=no" )
  5134.          fi
  5135. @@ -155,6 +155,9 @@
  5136.          CT_DoExecLog CFG                                \
  5137.          CC="${CC_for_gdb}"                              \
  5138.          LD="${LD_for_gdb}"                              \
  5139. +        CFLAGS="${CT_CFLAGS_FOR_BUILD}"                 \
  5140. +        CXXFLAGS="${CT_CFLAGS_FOR_BUILD}"               \
  5141. +        LDFLAGS="${CT_LDFLAGS_FOR_BUILD}"               \
  5142.          "${gdb_src_dir}/configure"                      \
  5143.              --build=${CT_BUILD}                         \
  5144.              --host=${CT_HOST}                           \
  5145. @@ -326,7 +329,9 @@
  5146.          CC="${CT_TARGET}-gcc"                           \
  5147.          CPP="${CT_TARGET}-cpp"                          \
  5148.          LD="${CT_TARGET}-ld"                            \
  5149. -        LDFLAGS="${gdbserver_LDFLAGS}"                  \
  5150. +        CFLAGS="${CT_CFLAGS_FOR_BUILD}"                 \
  5151. +        CXXFLAGS="${CT_CFLAGS_FOR_BUILD}"               \
  5152. +        LDFLAGS="${CT_LDFLAGS_FOR_BUILD} ${gdbserver_LDFLAGS}"               \
  5153.          "${gdb_src_dir}/gdb/gdbserver/configure"        \
  5154.              --build=${CT_BUILD}                         \
  5155.              --host=${CT_TARGET}                         \
  5156. Index: scripts/crosstool-NG.sh.in
  5157. ===================================================================
  5158. --- scripts/crosstool-NG.sh.in  (revision 272)
  5159. +++ scripts/crosstool-NG.sh.in  (working copy)
  5160. @@ -513,7 +513,7 @@
  5161.      # Help build gcc
  5162.      # Explicitly optimise, else the lines below will overide the
  5163.      # package's default optimisation flags
  5164. -    OPTIM_FLAGS="-O2 -g"
  5165. +    OPTIM_FLAGS="-O2"
  5166.      if [ "${CT_DEBUGGABLE_TOOLCHAIN}" = "y" ]; then
  5167.          # GCC 4.8 provides -Og, but we want as much
  5168.          # debugging as possible.
  5169. Index: scripts/functions
  5170. ===================================================================
  5171. --- scripts/functions   (revision 272)
  5172. +++ scripts/functions   (working copy)
  5173. @@ -466,7 +466,7 @@
  5174.      for dir in "${@}"; do
  5175.          [ -d "${dir}" ] || continue
  5176.          case "$CT_SYS_OS" in
  5177. -            Linux|CYGWIN|MSYS*)
  5178. +            Linux|CYGWIN*|MSYS*)
  5179.                  mode="$(stat -c '%a' "$(dirname "${dir}")")"
  5180.                  ;;
  5181.              Darwin|*BSD)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement