Add roll script for expat

Change-Id: I172bcca8493d117d3c04b67580614c8e82107f85
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/609259
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/third_party/expat/0001-Do-not-claim-getrandom.patch b/third_party/expat/0001-Do-not-claim-getrandom.patch
new file mode 100644
index 0000000..df931d2
--- /dev/null
+++ b/third_party/expat/0001-Do-not-claim-getrandom.patch
@@ -0,0 +1,22 @@
+diff --git a/third_party/expat/include/expat_config/expat_config.h b/third_party/expat/include/expat_config/expat_config.h
+index 278d7a8..c693a14a 100644
+--- a/third_party/expat/include/expat_config/expat_config.h
++++ b/third_party/expat/include/expat_config/expat_config.h
+@@ -23,7 +23,7 @@
+ #define HAVE_GETPAGESIZE 1
+ 
+ /* Define to 1 if you have the `getrandom' function. */
+-#define HAVE_GETRANDOM 1
++/* #define HAVE_GETRANDOM 1 */
+ 
+ /* Define to 1 if you have the <inttypes.h> header file. */
+ #define HAVE_INTTYPES_H 1
+@@ -50,7 +50,7 @@
+ #define HAVE_STRING_H 1
+ 
+ /* Define to 1 if you have `syscall' and `SYS_getrandom'. */
+-#define HAVE_SYSCALL_GETRANDOM 1
++/* #define HAVE_SYSCALL_GETRANDOM 1 */
+ 
+ /* Define to 1 if you have the <sys/param.h> header file. */
+ #define HAVE_SYS_PARAM_H 1
diff --git a/third_party/expat/0002-Do-not-claim-arc4random_buf.patch b/third_party/expat/0002-Do-not-claim-arc4random_buf.patch
new file mode 100644
index 0000000..92873c0
--- /dev/null
+++ b/third_party/expat/0002-Do-not-claim-arc4random_buf.patch
@@ -0,0 +1,13 @@
+diff --git a/third_party/expat/include/expat_config/expat_config.h b/third_party/expat/include/expat_config/expat_config.h
+index 795b5aaf0e..4968b01756 100644
+--- a/third_party/expat/include/expat_config/expat_config.h
++++ b/third_party/expat/include/expat_config/expat_config.h
+@@ -11,7 +11,7 @@
+ /* #undef HAVE_ARC4RANDOM */
+ 
+ /* Define to 1 if you have the `arc4random_buf' function. */
+-#define HAVE_ARC4RANDOM_BUF 1
++/* #define HAVE_ARC4RANDOM_BUF 1 */
+ 
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+ #define HAVE_DLFCN_H 1
diff --git a/third_party/expat/BUILD.gn b/third_party/expat/BUILD.gn
index c3dc9b6..df151ef 100644
--- a/third_party/expat/BUILD.gn
+++ b/third_party/expat/BUILD.gn
@@ -15,6 +15,8 @@
   }
 } else {
   third_party("expat") {
+    _src = "../externals/expat"
+
     public_defines = [ "XML_STATIC" ]
 
     public_include_dirs = [
@@ -22,16 +24,31 @@
       "include/expat_config",
     ]
 
-    defines = [
-      "HAVE_MEMMOVE",
-      "XML_DEV_URANDOM",
+    public = [ "$_src/expat/lib/expat.h" ]
+    sources = [
+      "$_src/expat/lib/ascii.h",
+      "$_src/expat/lib/asciitab.h",
+      "$_src/expat/lib/expat_external.h",
+      "$_src/expat/lib/iasciitab.h",
+      "$_src/expat/lib/internal.h",
+      "$_src/expat/lib/latin1tab.h",
+      "$_src/expat/lib/nametab.h",
+      "$_src/expat/lib/siphash.h",
+      "$_src/expat/lib/utf8tab.h",
+      "$_src/expat/lib/winconfig.h",
+      "$_src/expat/lib/xmlparse.c",
+      "$_src/expat/lib/xmlrole.c",
+      "$_src/expat/lib/xmlrole.h",
+      "$_src/expat/lib/xmltok.c",
+      "$_src/expat/lib/xmltok.h",
+      "$_src/expat/lib/xmltok_impl.h",
     ]
 
-    sources = [
-      "../externals/expat/expat/lib/expat.h",
-      "../externals/expat/expat/lib/xmlparse.c",
-      "../externals/expat/expat/lib/xmlrole.c",
-      "../externals/expat/expat/lib/xmltok.c",
+    unused_sources = [
+      # Not independently compiled, but conditionally included in xmltok.c
+      "$_src/expat/lib/xmltok_impl.c",
+      "$_src/expat/lib/xmltok_ns.c",
     ]
+    assert(unused_sources != [])
   }
 }
diff --git a/third_party/expat/include/expat_config/expat_config.h b/third_party/expat/include/expat_config/expat_config.h
index 7c9b986..4968b01 100644
--- a/third_party/expat/include/expat_config/expat_config.h
+++ b/third_party/expat/include/expat_config/expat_config.h
@@ -1,17 +1,135 @@
-/*
- * Copyright 2021 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
+/* expat_config.h.  Generated from expat_config.h.in by configure.  */
+/* expat_config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* 1234 = LILENDIAN, 4321 = BIGENDIAN */
 #define BYTEORDER 1234
+
+/* Define to 1 if you have the `arc4random' function. */
+/* #undef HAVE_ARC4RANDOM */
+
+/* Define to 1 if you have the `arc4random_buf' function. */
+/* #define HAVE_ARC4RANDOM_BUF 1 */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `getpagesize' function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define to 1 if you have the `getrandom' function. */
+/* #define HAVE_GETRANDOM 1 */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
-#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `bsd' library (-lbsd). */
+/* #undef HAVE_LIBBSD */
+
+/* Define to 1 if you have a working `mmap' system call. */
+#define HAVE_MMAP 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
 #define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
 #define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
+
+/* Define to 1 if you have `syscall' and `SYS_getrandom'. */
+/* #define HAVE_SYSCALL_GETRANDOM 1 */
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "expat"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "expat-bugs@libexpat.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "expat"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "expat 2.4.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "expat"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.4.1"
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "2.4.1"
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to allow retrieving the byte offsets for attribute names and values.
+   */
+/* #undef XML_ATTR_INFO */
+
+/* Define to specify how much context to retain around the current parse
+   point. */
 #define XML_CONTEXT_BYTES 1024
+
+/* Define to include code reading entropy from `/dev/urandom'. */
+#define XML_DEV_URANDOM 1
+
+/* Define to make parameter entity parsing functionality available. */
 #define XML_DTD 1
+
+/* Define to make XML Namespaces functionality available. */
 #define XML_NS 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `long int' if <sys/types.h> does not define. */
+/* #undef off_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
diff --git a/third_party/expat/roll-expat.sh b/third_party/expat/roll-expat.sh
new file mode 100755
index 0000000..0d0eeb1
--- /dev/null
+++ b/third_party/expat/roll-expat.sh
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+EXPAT_GIT_REPO=https://chromium.googlesource.com/external/github.com/libexpat/libexpat.git
+EXPAT_GIT_REF=origin/upstream/master
+EXPAT_GIT_DIR=third_party/externals/expat
+EXPAT_BUILD_DIR=$(dirname -- "$0")
+
+previousrev() {
+  STEP="original revision" &&
+  EXPAT_PREVIOUS_REV=$(git grep "${EXPAT_GIT_REPO}" HEAD~1 -- DEPS | sed 's!.*'${EXPAT_GIT_REPO}'@\([[:xdigit:]]\{40\}\).*!\1!')
+}
+
+nextrev() {
+  STEP="next revision" &&
+  git -C "${EXPAT_GIT_DIR}" fetch &&
+  EXPAT_NEXT_REV=$(git -C "${EXPAT_GIT_DIR}" rev-parse ${EXPAT_GIT_REF})
+}
+
+rolldeps() {
+  STEP="roll-deps" &&
+  sed -i'' -e "s!${EXPAT_GIT_REPO}@${EXPAT_PREVIOUS_REV}!${EXPAT_GIT_REPO}@${EXPAT_NEXT_REV}!" DEPS &&
+  tools/git-sync-deps &&
+  git add DEPS
+}
+
+check_all_files_are_categorized() {
+  #for each file name in ${EXPAT_GIT_DIR}/expat/lib/*.{c,h}
+  #  if the file name is not present in BUILD.gn
+  #    should be added to BUILD.gn (in 'unused_sources' if unwanted)
+
+  #for each file name \"expat/lib/.*\" in BUILD.gn
+  #  if the file name does not exist
+  #    should be removed from BUILD.gn
+
+  STEP="Updating BUILD.gn" &&
+  EXPAT_BUILD_DIR_REL=$(realpath --relative-to="${EXPAT_GIT_DIR}" "${EXPAT_BUILD_DIR}")
+  ( # Create subshell for IFS, CDPATH, and cd.
+    # This implementation doesn't handle '"' or '\n' in file names.
+    IFS=$'\n' &&
+    CDPATH= &&
+    cd -- "${EXPAT_GIT_DIR}" &&
+
+    EXPAT_SOURCE_MISSING=false &&
+    find "expat/lib" -type f \( -name "*.c" -o -name "*.h" \) | while read EXPAT_SOURCE
+    do
+      if ! grep -qF "$EXPAT_SOURCE" "${EXPAT_BUILD_DIR_REL}/BUILD.gn"; then
+        if ! ${EXPAT_SOURCE_MISSING}; then
+          echo "Is in expat/lib/*.{c,h} but not in BUILD.gn:"
+          EXPAT_SOURCE_MISSING=true
+        fi
+        echo "      \"\$_src/${EXPAT_SOURCE}\","
+      fi
+    done &&
+
+    GN_SOURCE_MISSING=false &&
+    grep -oE "\"\\\$_src/[^\"]+\"" "${EXPAT_BUILD_DIR_REL}/BUILD.gn" | sed 's@^"._src/\(.*\).$@\1@' | while read GN_SOURCE
+    do
+      if [ ! -f "${GN_SOURCE}" ]; then
+        if ! ${GN_SOURCE_MISSING}; then
+          echo "Is referenced in BUILD.gn but does not exist:" &&
+          GN_SOURCE_MISSING=true
+        fi
+        echo "\"${GN_SOURCE}\""
+      fi
+    done &&
+
+    GN_SOURCE_DUPLICATES=$(sort "${EXPAT_BUILD_DIR_REL}/BUILD.gn" | uniq -d | grep -oE "\"\\\$_src/[^\"]+\"")
+    if [ ! -z ${GN_SOURCE_DUPLICATES} ]; then
+      echo "Is listed more than once in BUILD.gn:" &&
+      echo ${GN_SOURCE_DUPLICATES}
+    fi
+  )
+}
+
+update_expat_config_h() {
+  STEP="update expat config.h" &&
+  ( cd "${EXPAT_GIT_DIR}/expat" &&
+    ./buildconf.sh &&
+    ./configure) &&
+  cp "${EXPAT_GIT_DIR}/expat/expat_config.h" "${EXPAT_BUILD_DIR}/include/expat_config/" &&
+  patch -d "${EXPAT_BUILD_DIR}" -p3 < "${EXPAT_BUILD_DIR}/0001-Do-not-claim-getrandom.patch" &&
+  patch -d "${EXPAT_BUILD_DIR}" -p3 < "${EXPAT_BUILD_DIR}/0002-Do-not-claim-arc4random_buf.patch" &&
+  git add "${EXPAT_BUILD_DIR}/include/expat_config/expat_config.h"
+}
+
+commit() {
+  STEP="commit" &&
+  EXPAT_PREVIOUS_REV_SHORT=$(expr substr "${EXPAT_PREVIOUS_REV}" 1 8) &&
+  EXPAT_NEXT_REV_SHORT=$(expr substr "${EXPAT_NEXT_REV}" 1 8) &&
+  EXPAT_COMMIT_COUNT=$(git -C ${EXPAT_GIT_DIR} rev-list --count ${EXPAT_PREVIOUS_REV}..${EXPAT_NEXT_REV}) &&
+  git commit -m"Roll Expat from ${EXPAT_PREVIOUS_REV_SHORT} to ${EXPAT_NEXT_REV_SHORT} (${EXPAT_COMMIT_COUNT} commits)
+
+${EXPAT_GIT_REPO}/+log/${EXPAT_PREVIOUS_REV}..${EXPAT_NEXT_REV}
+
+Disable: treat-URL-as-trailer"
+}
+
+previousrev &&
+nextrev &&
+rolldeps "$@" &&
+update_expat_config_h &&
+check_all_files_are_categorized &&
+commit &&
+true || { echo "Failed step ${STEP}"; exit 1; }