]> granicus.if.org Git - graphviz/commitdiff
port colortbl.h generation script to Python
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Mon, 11 Apr 2022 02:43:04 +0000 (19:43 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Mon, 2 May 2022 14:34:28 +0000 (07:34 -0700)
Note that this does not introduce an extra build dependency in any of the three
build systems:

  1. Autotools: these steps are done during construction of the portable source
     tarball, during which Python 3 is already required (see autogen.sh).

  2. CMake: Python 3 is already required by and used in the top level
     CMakeLists.txt.

  3. MS Build: Python 3 is already used in version generation in
     lib/version/version.vcxproj.

This change is motivated by the goal of removing a dependency on Awk. This
commit removes the last remaining Awk usage in all three build systems, as well
as removing dependencies on `type` and `sort` in the MS Build build system.

This commit removes the generation of the intermediate artifacts color_lib,
color_lib-sort, and color_lib-temp. Instead, we generate only the final
artifact, colortbl.h. This consolidation of logic into Python is part of what
allows the removal of dependencies described above.

Gitlab: #2118

.gitignore
Makefile.am
awk/colortbl.awk [deleted file]
cmake/generate_color_lib.cmake.in [deleted file]
lib/common/CMakeLists.txt
lib/common/Makefile.am
lib/common/make_colortbl.py [new file with mode: 0644]
lib/gvc.vcxproj

index 34e6b259e93f8b89d22fb276a550cf19b0611267..be6e8fb32af87ba1db58b3fbb5baab1648b30118 100644 (file)
@@ -141,9 +141,6 @@ lib/cgraph/grammar.h
 lib/cgraph/grammar.output
 lib/cgraph/scan.c
 lib/common/brewer_lib
-lib/common/color_lib
-lib/common/color_lib-sort
-lib/common/color_lib-temp
 lib/common/colortbl.h
 lib/common/htmlparse.c
 lib/common/htmlparse.h
index 97a34d3a5fb46b34341db9d6b1592936801ee086..e96449f166bd1adf0021cfd1d91edcbbbe152370 100644 (file)
@@ -33,7 +33,7 @@ EXTRA_DIST = $(html) graphviz.spec \
        autogen.sh config/depcomp config/config.rpath \
        builddate.h \
        m4/README m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4 \
-       graphviz.7 Doxyfile.in Doxyfile awk \
+       graphviz.7 Doxyfile.in Doxyfile \
        config/config_perl.pl \
        config/config_ruby.rb config/config_tcl.tcl dot.demo plugin.demo \
        macosx windows debian redhat graphviz.sln
diff --git a/awk/colortbl.awk b/awk/colortbl.awk
deleted file mode 100644 (file)
index ab490f4..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# /*************************************************************************
-# * Copyright (c) 2011 AT&T Intellectual Property 
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors: Details at http://www.graphviz.org/
-# *************************************************************************/
-
-function rgb_to_hsv(r,g,b) {
-       r = r / 255.0; g = g / 255.0; b = b / 255.0;
-       max = r; if (max < g) max = g; if (max < b) max = b;
-       min = r; if (min > g) min = g; if (min > b) min = b;
-       v = max;
-       if (max != 0) s = (max - min) / max;
-       else s = 0;
-       if (s == 0) h = 0;
-       else {
-               delta = max - min;
-               rc = (max - r)/delta;
-               gc = (max - g)/delta;
-               bc = (max - b)/delta;
-               if (r == max) h = bc - gc;
-               else {
-                       if (g == max) h = 2.0 + (rc - bc);
-                       else h = 4.0 + (gc - rc);
-               }
-               h = h * 60.0;
-               if (h < 0.0) h = h + 360.0;
-       }
-       h = h / 360.0 * 255.0;
-       s = s * 255.0;
-       v = v * 255.0;
-}
-
-BEGIN  { gsub("\\.","_",s); printf("static hsvrgbacolor_t color_lib[] = {\n",s); }
-/^$/   { next; }
-/^#/   { next; }
-               {
-                       rgb_to_hsv($2,$3,$4);
-                       printf("{\"%s\",%d,%d,%d,%d,%d,%d,%d},\n",$1,h,s,v,$2,$3,$4,$5);
-               }
-END            { printf("};\n"); }
diff --git a/cmake/generate_color_lib.cmake.in b/cmake/generate_color_lib.cmake.in
deleted file mode 100644 (file)
index f32b80a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-file(READ @CMAKE_CURRENT_BINARY_DIR@/svgcolor_lib svgcolor_lib)
-file(READ @CMAKE_CURRENT_BINARY_DIR@/brewer_lib brewer_lib)
-file(READ @CMAKE_CURRENT_SOURCE_DIR@/color_names color_names)
-
-# Do not ignore empty elements in list
-cmake_policy(SET CMP0007 NEW)
-
-# Make it a list for sorting
-string(REPLACE "\n" ";" color_lib ${svgcolor_lib} ${brewer_lib} ${color_names})
-file(WRITE @CMAKE_CURRENT_BINARY_DIR@/color_lib-temp "${color_lib}")
-list(SORT color_lib)
-file(WRITE @CMAKE_CURRENT_BINARY_DIR@/color_lib-sort "${color_lib}")
-string(REGEX REPLACE ";" "\\n" color_lib "${color_lib}")
-file(WRITE @CMAKE_CURRENT_BINARY_DIR@/color_lib ${color_lib})
index fef1d353f8b94283757e10a19a3fc62fc6faad6d..c9e15e95d6267da9fe36466824775b6b2f3715ce 100644 (file)
@@ -22,29 +22,19 @@ add_custom_command(
           ${CMAKE_CURRENT_BINARY_DIR}/brewer_lib
   COMMENT "generate Brewer color library"
 )
-configure_file(
-  "${CMAKE_SOURCE_DIR}/cmake/generate_color_lib.cmake.in"
-  "${CMAKE_CURRENT_BINARY_DIR}/generate_color_lib.cmake"
-  @ONLY
-)
 add_custom_command(
-  OUTPUT color_lib
+  OUTPUT common/colortbl.h
   DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/svgcolor_lib
           ${CMAKE_CURRENT_BINARY_DIR}/brewer_lib
           ${CMAKE_CURRENT_SOURCE_DIR}/color_names
-  COMMAND ${CMAKE_COMMAND} -P
-          ${CMAKE_CURRENT_BINARY_DIR}/generate_color_lib.cmake
-  COMMENT "generate amalgamated color library"
-)
-add_custom_command(
-  OUTPUT common/colortbl.h
-  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/color_lib
-          ${CMAKE_SOURCE_DIR}/awk/colortbl.awk
+          ${CMAKE_CURRENT_SOURCE_DIR}/make_colortbl.py
   COMMAND ${CMAKE_COMMAND} -E make_directory
           "${CMAKE_CURRENT_BINARY_DIR}/common"
-  COMMAND ${AWK_EXECUTABLE} -f ${CMAKE_SOURCE_DIR}/awk/colortbl.awk
-          ${CMAKE_CURRENT_BINARY_DIR}/color_lib
-          >${CMAKE_CURRENT_BINARY_DIR}/common/colortbl.h
+  COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/make_colortbl.py
+          ${CMAKE_CURRENT_BINARY_DIR}/brewer_lib
+          ${CMAKE_CURRENT_BINARY_DIR}/svgcolor_lib
+          ${CMAKE_CURRENT_SOURCE_DIR}/color_names
+          ${CMAKE_CURRENT_BINARY_DIR}/common/colortbl.h
   COMMENT "generate color table"
 )
 
index 7ea1d7238693ac4063a9a065f7fa59cf24de48d6..6e64b397cdbc28ffe60b2af313688dc64416f8ff 100644 (file)
@@ -36,12 +36,10 @@ libcommon_C_la_LIBADD = \
 
 colxlate.o colxlate.lo : colortbl.h
 
-colortbl.h : color_lib
-       $(AWK) -f $(top_srcdir)/awk/colortbl.awk color_lib > colortbl.h
-
-# ensure color names are properly sorted for bsearch operation
-color_lib : brewer_lib svgcolor_lib $(top_srcdir)/lib/common/color_names
-       cat brewer_lib svgcolor_lib $(top_srcdir)/lib/common/color_names | LC_ALL=C $(SORT) > color_lib
+colortbl.h: brewer_lib svgcolor_lib $(top_srcdir)/lib/common/color_names \
+            $(top_srcdir)/lib/common/make_colortbl.py
+       python3 $(top_srcdir)/lib/common/make_colortbl.py brewer_lib svgcolor_lib \
+         $(top_srcdir)/lib/common/color_names colortbl.h
 
 brewer_lib: $(top_srcdir)/lib/common/brewer_colors \
             $(top_srcdir)/lib/common/make_brewer_lib.py
@@ -57,12 +55,12 @@ htmlparse.o htmlparse.lo: htmlparse.c htmlparse.h
 htmlparse.c htmlparse.h: $(top_srcdir)/lib/common/htmlparse.y
        $(YACC) -Wno-yacc -dv $(top_srcdir)/lib/common/htmlparse.y -o htmlparse.c
 
-DISTCLEANFILES = brewer_lib color_lib colortbl.h \
+DISTCLEANFILES = brewer_lib colortbl.h \
        htmlparse.[ch] svgcolor_lib
 
 EXTRA_DIST = README.imap \
        htmlparse.c htmlparse.h \
        entities.html entities.tcl \
        brewer_colors brewer_lib svgcolor_names svgcolor_lib \
-       color_names color_lib colortbl.h \
-       make_brewer_lib.py make_svgcolor_lib.py
+       color_names colortbl.h \
+       make_brewer_lib.py make_colortbl.py make_svgcolor_lib.py
diff --git a/lib/common/make_colortbl.py b/lib/common/make_colortbl.py
new file mode 100644 (file)
index 0000000..e6a01bf
--- /dev/null
@@ -0,0 +1,103 @@
+#!/usr/bin/python3
+
+"""
+(brewer_lib, svgcolor_lib, color_names) → colortbl.h generator
+"""
+
+import argparse
+import locale
+import re
+import sys
+from typing import List, Tuple
+
+def rgb_to_hsv(r: int, g: int, b: int) -> Tuple[int, int, int]:
+  """transform an RGB color into HSV format"""
+
+  r /= 255.0
+  g /= 255.0
+  b /= 255.0
+
+  max_ = max((r, g, b))
+  min_ = min((r, g, b))
+
+  v = max_
+
+  if max_ != 0:
+    s = (max_ - min_) / max_
+  else:
+    s = 0
+
+  if s == 0:
+    h = 0
+  else:
+    delta = max_ - min_
+    rc = (max_ - r) / delta
+    gc = (max_ - g) / delta
+    bc = (max_ - b) / delta
+    if r == max_:
+      h = bc - gc
+    elif g == max_:
+      h = 2.0 + (rc - bc)
+    else:
+      h = 4.0 + (gc - rc)
+    h *= 60.0
+    if h < 0.0:
+      h += 360.0
+
+  return int(h / 360.0 * 255.0), int(s * 255.0), int(v * 255.0)
+
+def main(args: List[str]) -> int:
+  """entry point"""
+
+  # avoid sorting issues due to locale differences
+  locale.setlocale(locale.LC_ALL, "C")
+
+  # parse command line arguments
+  parser = argparse.ArgumentParser(description=__doc__)
+  parser.add_argument("brewer_lib", type=argparse.FileType("rt"),
+                      help="input Brewer color table entries")
+  parser.add_argument("svgcolor_lib", type=argparse.FileType("rt"),
+                      help="input SVG color table entries")
+  parser.add_argument("color_names", type=argparse.FileType("rt"),
+                      help="input other color table entries")
+  parser.add_argument("output", type=argparse.FileType("wt"),
+                      help="output color table C header")
+  options = parser.parse_args(args[1:])
+
+  options.output.write("static hsvrgbacolor_t color_lib[] = {\n")
+
+  # collect all color entries
+  entries = options.brewer_lib.readlines() + options.svgcolor_lib.readlines() \
+    + options.color_names.readlines()
+
+  # sort these so `bsearch` for a color will work correctly
+  entries = sorted(entries, key=locale.strxfrm)
+
+  for entry in entries:
+
+    # ignore blank lines
+    if entry.strip() == "":
+      continue
+
+    # extract fields of the entry
+    m = re.match(r"(?P<name>\S+) (?P<r>\d+) (?P<g>\d+) (?P<b>\d+) (?P<a>\d+)", entry)
+    assert m is not None, f'unexpected entry format "{entry}"'
+
+    # transform an RGB color into HSV
+    r = int(m.group("r"))
+    g = int(m.group("g"))
+    b = int(m.group("b"))
+    h, s, v = rgb_to_hsv(r, g, b)
+
+    # write this out as a C array entry
+    name = m.group("name")
+    a = int(m.group("a"))
+    options.output.write(f'{{"{name}",{h},{s},{v},{r},{g},{b},{a}}},\n')
+
+  options.output.write("};\n")
+
+  return 0
+
+
+if __name__ == "__main__":
+  sys.exit(main(sys.argv))
index 31100ae4c11d07345215bb0bed8f2653bf276186..bd42ba62bed9aea6399fee5ef665289640a199be 100644 (file)
@@ -74,8 +74,7 @@
       <Command>win_bison -dy -Wno-yacc common\htmlparse.y -o common\htmlparse.c
 python common\make_svgcolor_lib.py common\svgcolor_names common\svgcolor_lib
 python common\make_brewer_lib.py common\brewer_colors common\brewer_lib
-type common\brewer_lib common\svgcolor_lib common\color_names | sort /L C &gt; color_lib
-awk -f $(SolutionDir)awk\colortbl.awk color_lib &gt; common\colortbl.h</Command>
+python common\make_colortbl.py common\brewer_lib common\svgcolor_lib common\color_names common\colortbl.h</Command>
     </PreBuildEvent>
     <PostBuildEvent>
       <Command>copy $(SolutionDir)windows\dependencies\libraries\x86\bin\expat.dll $(OutDir)expat.dll</Command>
@@ -105,8 +104,7 @@ awk -f $(SolutionDir)awk\colortbl.awk color_lib &gt; common\colortbl.h</Command>
       <Command>win_bison -dy -Wno-yacc common\htmlparse.y -o common\htmlparse.c
 python common\make_svgcolor_lib.py common\svgcolor_names common\svgcolor_lib
 python common\make_brewer_lib.py common\brewer_colors common\brewer_lib
-type common\brewer_lib common\svgcolor_lib common\color_names | sort /L C &gt; color_lib
-awk -f $(SolutionDir)awk\colortbl.awk color_lib &gt; common\colortbl.h</Command>
+python common\make_colortbl.py common\brewer_lib common\svgcolor_lib common\color_names common\colortbl.h</Command>
     </PreBuildEvent>
     <PostBuildEvent>
       <Command>copy $(SolutionDir)windows\dependencies\libraries\x86\bin\expat.dll $(OutDir)expat.dll</Command>