[PATCH 2/5] libparted: use gperf-generated lookup function

Jim Meyering meyering at redhat.com
Thu Dec 3 10:45:05 UTC 2009


* libparted/labels/pt-tools.c (ptt_partition_max_start_len):
Rewrite to use the gperf-generated look-up function.
(ptt_partition_max_start_sector): New function.
(ptt_partition_max_length): New function.
* libparted/labels/pt-tools.h: Declare them.
* libparted/labels/Makefile.am (GPERF, GPERF_OPTIONS): Define.
(BUILT_SOURCES): Define.
(liblabels_la_SOURCES): Append pt-limit.gperf.
(pt-limit.c): New rule.
(MAINTAINERCLEANFILES): Remove useless definition.
(DISTCLEANFILES): Set to $(BUILT_SOURCES).
* libparted/labels/pt-limit.gperf: New file.
* cfg.mk (bootstrap-tools): Mention gperf.
* bootstrap.conf (buildreq): Require gperf-3.0.3.
---
 .gitignore                      |    1 +
 bootstrap.conf                  |    2 +-
 cfg.mk                          |    3 +
 libparted/.gitignore            |    1 +
 libparted/labels/Makefile.am    |   16 ++++++-
 libparted/labels/pt-limit.gperf |   12 +++++
 libparted/labels/pt-tools.c     |   93 +++++++++++++++++++++++++-------------
 libparted/labels/pt-tools.h     |    3 +
 8 files changed, 97 insertions(+), 34 deletions(-)
 create mode 100644 libparted/labels/pt-limit.gperf

diff --git a/.gitignore b/.gitignore
index 0394d17..6e4c561 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,5 +48,6 @@ partprobe/partprobe
 po/.reference
 stamp-h1
 tests/init.sh
+tests/print-align
 tests/t*.sh.log
 tests/test-suite.log
diff --git a/bootstrap.conf b/bootstrap.conf
index 24f9aad..09870cd 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -123,7 +123,7 @@ automake   1.11
 autopoint  -
 gettext    -
 git        1.4.4
-gperf      -
+gperf      3.0.3
 gzip       -
 makeinfo   -
 perl       5.5
diff --git a/cfg.mk b/cfg.mk
index ce0dfc1..afbdcc0 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -49,3 +49,6 @@ update-copyright-env = UPDATE_COPYRIGHT_USE_INTERVALS=1

 useless_free_options = \
   --name=pth_free
+
+# Tools used to bootstrap this package, used for "announcement".
+bootstrap-tools = autoconf,automake,gnulib,gperf
diff --git a/libparted/.gitignore b/libparted/.gitignore
index 66a3f3f..9f0df15 100644
--- a/libparted/.gitignore
+++ b/libparted/.gitignore
@@ -1,2 +1,3 @@
 *.lo
 *.la
+/labels/pt-limit.c
diff --git a/libparted/labels/Makefile.am b/libparted/labels/Makefile.am
index 05810e5..9e8232c 100644
--- a/libparted/labels/Makefile.am
+++ b/libparted/labels/Makefile.am
@@ -37,4 +37,18 @@ liblabels_la_LIBADD = $(OS_LIBS) $(INTLLIBS)

 INCLUDES = $(partedincludedir) $(INTLINCS)

-MAINTAINERCLEANFILES = Makefile.in
+BUILT_SOURCES = pt-limit.c
+DISTCLEANFILES = $(BUILT_SOURCES)
+liblabels_la_SOURCES += pt-limit.gperf
+
+GPERF = gperf
+GPERF_OPTIONS = \
+  -C -N pt_limit_lookup -n -t -s 6 -k '*' --language=ANSI-C
+
+pt-limit.c: pt-limit.gperf
+	rm -f $@ $@-tmp
+	$(GPERF) $(GPERF_OPTIONS) $< \
+	  | perl -ne '/__GNUC_STDC_INLINE__/ and print "static\n"; print' \
+	  > $@-tmp
+	chmod a-w $@-tmp
+	mv $@-tmp $@
diff --git a/libparted/labels/pt-limit.gperf b/libparted/labels/pt-limit.gperf
new file mode 100644
index 0000000..7e3f8ca
--- /dev/null
+++ b/libparted/labels/pt-limit.gperf
@@ -0,0 +1,12 @@
+struct partition_limit
+{
+  char const *name;
+  uint64_t max_start_sector;
+  uint64_t max_length;
+};
+%%
+dasd,UINT32_MAX,UINT32_MAX
+dvh,UINT32_MAX,UINT32_MAX
+gpt,UINT64_MAX,UINT64_MAX
+mac,UINT32_MAX,UINT32_MAX
+msdos,UINT32_MAX,UINT32_MAX
diff --git a/libparted/labels/pt-tools.c b/libparted/labels/pt-tools.c
index 8b2ea4a..e81bec5 100644
--- a/libparted/labels/pt-tools.c
+++ b/libparted/labels/pt-tools.c
@@ -103,46 +103,75 @@ ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector n)
           ? 1 : ped_device_write (dev, zero, start + n_z_sectors * i, rem));
 }

+#include "pt-limit.c"
+
 /* Throw an exception and return 0 if PART's starting sector number or
    its length is greater than the maximum allowed value for LABEL_TYPE.
    Otherwise, return 1.  */
 int
-ptt_partition_max_start_len (char const *label_type, const PedPartition *part)
+ptt_partition_max_start_len (char const *pt_type, const PedPartition *part)
 {
-  static char const *const max_32[] = {"msdos", "dvh", "dasd", "mac"};
-  unsigned int i;
+  struct partition_limit const *pt_lim
+    = pt_limit_lookup (pt_type, strlen (pt_type));
+
+  /* If we don't have info on the type, return "true".  */
+  if (pt_lim == NULL)
+    return 1;

-  for (i = 0; i < sizeof max_32 / sizeof *max_32; i++)
+  /* If the length in sectors exceeds the limit, you lose.  */
+  if (part->geom.length > pt_lim->max_length)
     {
-      if (strcmp (label_type, max_32[i]) == 0)
-        {
-          /* The length (in sectors) must fit in 32 bytes.  */
-          if (part->geom.length > UINT32_MAX)
-            {
-              ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
-                                   _("partition length of %jd sectors exceeds"
-                                     " the %s-partition-table-imposed maximum"
-                                     " of %jd"),
-                                   part->geom.length,
-                                   label_type,
-                                   UINT32_MAX);
-              return 0;
-            }
-
-          /* The starting sector number must fit in 32 bytes.  */
-          if (part->geom.start > UINT32_MAX) {
-            ped_exception_throw (
-                                 PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
-                                 _("starting sector number, %jd exceeds"
-                                   " the %s-partition-table-imposed maximum"
-                                   " of %jd"),
-                                 part->geom.start,
-                                 label_type,
-                                 UINT32_MAX);
-            return 0;
-          }
-        }
+      ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+			   _("partition length of %jd sectors exceeds"
+			     " the %s-partition-table-imposed maximum"
+			     " of %jd"),
+			   part->geom.length,
+			   pt_type,
+			   UINT32_MAX);
+      return 0;
     }

+  /* If the starting sector exceeds the limit, you lose.  */
+  if (part->geom.start > pt_lim->max_start_sector) {
+    ped_exception_throw (
+			 PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
+			 _("starting sector number, %jd exceeds"
+			   " the %s-partition-table-imposed maximum"
+			   " of %jd"),
+			 part->geom.start,
+			 pt_type,
+			 UINT32_MAX);
+    return 0;
+  }
+
   return 1;
 }
+
+/* Set *MAX to the largest representation-imposed starting sector number
+   of a partition of type PT_TYPE and return 0.  If PT_TYPE is not
+   recognized, return -1.  */
+int
+ptt_partition_max_start_sector (char const *pt_type, PedSector *max)
+{
+  struct partition_limit const *pt_lim
+    = pt_limit_lookup (pt_type, strlen (pt_type));
+  if (pt_lim == NULL)
+    return -1;
+
+  *max = pt_lim->max_start_sector;
+  return 0;
+}
+
+/* Set *MAX to the maximum representable length of a partition of type
+   PT_TYPE and return 0.  If PT_TYPE is not recognized, return -1.  */
+int
+ptt_partition_max_length (char const *pt_type, PedSector *max)
+{
+  struct partition_limit const *pt_lim
+    = pt_limit_lookup (pt_type, strlen (pt_type));
+  if (pt_lim == NULL)
+    return -1;
+
+  *max = pt_lim->max_length;
+  return 0;
+}
diff --git a/libparted/labels/pt-tools.h b/libparted/labels/pt-tools.h
index 3f275d0..8131501 100644
--- a/libparted/labels/pt-tools.h
+++ b/libparted/labels/pt-tools.h
@@ -24,3 +24,6 @@ int ptt_read_sectors (PedDevice const *dev, PedSector start_sector,
 int ptt_clear_sectors (PedDevice *dev, PedSector start, PedSector count);
 int ptt_partition_max_start_len (char const *label_type,
                 const PedPartition *part);
+
+int ptt_partition_max_start_sector (char const *pt_type, PedSector *max);
+int ptt_partition_max_length (char const *pt_type, PedSector *max);
--
1.6.6.rc0.285.g73651




More information about the parted-devel mailing list