gimp-help-2 r2689 - in trunk: . tools



Author: ulfehlert
Date: Wed Jan 14 18:29:09 2009
New Revision: 2689
URL: http://svn.gnome.org/viewvc/gimp-help-2?rev=2689&view=rev

Log:
2009-01-14  Ulf-D. Ehlert  <ulfehlert svn gnome org>

	* tools/validate_references.py
	* tools/README: make script work with new directory structure

	* configure.ac: added checks for "sed" and "mkdir -p"

	* Makefile.am: use "$(SED)" and "$(MKDIR_P)"; fixed creation of
	  empty directories "C" and "common"; added checks for image references
	* Makefile.GNU: fixed creation of empty directories "C" and "common";
	  added checks for image references


Modified:
   trunk/ChangeLog
   trunk/Makefile.GNU
   trunk/Makefile.am
   trunk/configure.ac
   trunk/tools/README
   trunk/tools/validate_references.py

Modified: trunk/Makefile.GNU
==============================================================================
--- trunk/Makefile.GNU	(original)
+++ trunk/Makefile.GNU	Wed Jan 14 18:29:09 2009
@@ -324,6 +324,7 @@
 	$(cmd) (cd images && find common C $(dir_predicates)) | \
 	while read dir; do \
 		dest=$${dir#*/}; \
+		test "$${dir}" != "$${dest}" || continue; \
 		test -d $@/$${dest} || $(mkdir_p) $@/$${dest}; \
 	done
 	$(cmd) (cd images && find common C $(file_predicates)) | \
@@ -604,7 +605,10 @@
 ####            Source file checks                                  ####
 ########################################################################
 
+check: checks ;
+checks: check-svn-property check-image-references ;
 check-svn: check-svn-property ;
+check-images: check-image-references ;
 
 check-svn-property:
 	$(cmd) if cd $(srcdir) && test -e tools/check_keywords_property.pl && \
@@ -615,7 +619,25 @@
 	    echo >&2 "*** Cannot check svn property (no Perl installed?) ***"; \
 	fi
 
-.PHONY: check-svn check-svn-property
+check-image-references:
+	$(cmd) if cd $(srcdir) && test -e tools/validate_references.py && \
+	type python >/dev/null 2>&1; then \
+	    echo "*** Checking image references ... "; \
+	    python tools/validate_references.py \
+	        --verbose --broken --orphaned \
+		$(VALIDATEREFERENCESFLAGS); \
+	else \
+	    echo >&2 "*** Cannot check image references (no Python installed?) ***"; \
+	fi
+
+check-images-%: FORCE
+	$(cmd) $(MAKE) --no-print-directory check-image-references \
+		VALIDATEREFERENCESFLAGS="--imgdir=images/C,images/$*"
+
+# special case 'en':
+check-images-en check-images-C: check-image-references ;
+
+.PHONY: checks check-svn-property check-image-references
 
 
 ########################################################################

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Wed Jan 14 18:29:09 2009
@@ -67,10 +67,10 @@
 # languages we want to exclude from installing images
 image_lang_exclude = \
 	$(shell echo $(strip $(LANGUAGES)) | \
-	        sed -e '/^$$/d; \
-		        s/ / -o -name /g; \
-			s/^/! \\( -name /; \
-			s/$$/ \\)/ ' \
+	        $(SED) -e '/^$$/d; \
+	                   s/ / -o -name /g; \
+	                   s/^/! \\( -name /; \
+	                   s/$$/ \\)/ ' \
 	)
 
 # find HTML files (used when installing html)
@@ -221,7 +221,7 @@
 xml2pot = ($(XML2PO) --output='-' "$(1)" \
           | $(MSGUNIQ) $(MSGUNIQFLAGS) \
           | $(MSGCAT) $(MSGCATFLAGS) - > "$(2)") 2>&1 \
-          | sed -e '/image file .* not found/d'
+          | $(SED) -e '/image file .* not found/d'
 
 # Merge template (pot) and message catalog (po)
 # or create a new catalog
@@ -255,10 +255,10 @@
 if HAVE_XMLLINT
 po2xml = ($(XML2PO) --po-file=$(2) --language=$(3) --output='-' $(1) \
          | $(XMLLINT) $(XMLLINTFLAGS) --format --output $(4) -) 2>&1 \
-         | sed -e '/Warning: image file .* not found./d'
+         | $(SED) -e '/Warning: image file .* not found./d'
 else
 po2xml = $(XML2PO) --po-file=$(2) --language=$(3) --output=$(4) $(1) 2>&1 \
-         | sed -e '/Warning: image file .* not found./d'
+         | $(SED) -e '/Warning: image file .* not found./d'
 endif
 
 
@@ -266,7 +266,7 @@
 #       Helper functions                                       #
 #--------------------------------------------------------------#
 
-make_target_dir = f=$(1); d=$${f%/*}; test -d $$d || $(mkdir_p) $$d
+make_target_dir = f=$(1); d=$${f%/*}; test -d $$d || $(MKDIR_P) $$d
 
 copy = $(LN_S) $(abs_srcdir)/$(1) $(2)
 
@@ -329,7 +329,7 @@
 # HIDE FROM AUTOMAKE #	fi
 # HIDE FROM AUTOMAKE ## This is indirectly used as HTML prerequisite:
 # HIDE FROM AUTOMAKE #xml/$(1): $$($(1)_XML_FILES)
-# HIDE FROM AUTOMAKE #	$$(cmd) test -d $$@ && touch $$@ || $(mkdir_p) $$@
+# HIDE FROM AUTOMAKE #	$$(cmd) test -d $$@ && touch $$@ || $(MKDIR_P) $$@
 # HIDE FROM AUTOMAKE ## Targets suitable for command line
 # HIDE FROM AUTOMAKE #xml-$(1): xml/$(1) $$($(1)_XML_FILES) xml/$(1)/images ;
 # HIDE FROM AUTOMAKE #endef
@@ -341,12 +341,13 @@
 	$(cmd) if test -L $@; then rm -v $@; fi
 	$(cmd) if test -L xml/$*; then rm -v xml/$*; fi
 	$(cmd) if test -d $@; then rm -rf $@/*; fi
-	$(cmd) test -d $@ || $(mkdir_p) $@
+	$(cmd) test -d $@ || $(MKDIR_P) $@
 	$(msg) "*** Copying images ($*) ..."
 	$(cmd) (cd images && find common C $(dir_predicates)) | \
 	while read dir; do \
 		dest=$${dir#*/}; \
-		test -d $@/$${dest} || $(mkdir_p) $@/$${dest}; \
+		test "$${dir}" != "$${dest}" || continue; \
+		test -d $@/$${dest} || $(MKDIR_P) $@/$${dest}; \
 	done
 	$(cmd) (cd images && find common C $(file_predicates)) | \
 	while read image; do \
@@ -368,7 +369,7 @@
 
 xml/en: $(en_XML_FILES)
 	$(cmd) if test -L $@; then rm -v $@; fi
-	$(cmd) test -d $@ && touch $@ || $(mkdir_p) $@
+	$(cmd) test -d $@ && touch $@ || $(MKDIR_P) $@
 
 # Target suitable for command line
 xml-en: xml/en ;
@@ -393,7 +394,7 @@
 # HIDE FROM AUTOMAKE #	$$(cmd) if type $$(XMLLINT) >/dev/null 2>&1; then \
 # HIDE FROM AUTOMAKE #		echo "*** Validating XML ($(1)) ... "; \
 # HIDE FROM AUTOMAKE #		$$(XMLLINT) $$(XMLLINTFLAGS) --xinclude xml/$(1)/gimp.xml \
-# HIDE FROM AUTOMAKE #		| sed -e 's,xmlns:xi="http://www.w3.org/2001/XInclude";,,' \
+# HIDE FROM AUTOMAKE #		| $(SED) -e 's,xmlns:xi="http://www.w3.org/2001/XInclude";,,' \
 # HIDE FROM AUTOMAKE #		| $$(XMLLINT) $$(XMLLINTFLAGS) --nonet --valid \
 # HIDE FROM AUTOMAKE #			--output log/$(1).xml - 2>$$(@); \
 # HIDE FROM AUTOMAKE #		if test -s $$(@); then \
@@ -450,7 +451,7 @@
 	$(cmd) if test -L $@; then rm -v $@; fi
 
 html/%/images: xml/%/images
-	$(cmd) test -d html/$* || $(mkdir_p) html/$*
+	$(cmd) test -d html/$* || $(MKDIR_P) html/$*
 	$(cmd) $(LN_S) ../../xml/$*/images $@
 
 # The xrefs file is a side effect of the HTML build
@@ -487,7 +488,7 @@
 # TODO: images (--fig-path option?); prerequisites
 pdf/%/gimp.pdf: xml/%/gimp.xml stylesheets/plainprint.xsl xml/%/images
 	$(cmd) if test -f pdf/%.pdf; then rm -f pdf/%.pdf; fi
-	$(cmd) test -d pdf/$* || $(mkdir_p) pdf/$*
+	$(cmd) test -d pdf/$* || $(MKDIR_P) pdf/$*
 	$(msg) "*** Making PDF ($*) ..."
 	$(cmd) $(DBLATEX) $(DBLATEXFLAGS) $(DBLATEXEXTRAFLAGS) \
 	    --xsl-user=$(srcdir)/stylesheets/plainprint.xsl \
@@ -513,7 +514,7 @@
 # TODO: images; prerequisites
 odf/%/gimp.odt: xml/%/gimp-alldocs.xml xml/%/images
 	$(cmd) if test -f odf/%.odt; then rm -f odf/%.odt; fi
-	$(cmd) test -d odf/$* || $(mkdir_p) odf/$*
+	$(cmd) test -d odf/$* || $(MKDIR_P) odf/$*
 	$(msg) "*** Making ODF ($*) ..."
 	$(cmd) $(DOCBOOK2ODF) $(DOCBOOK2ODFFLAGS) \
 	    --debug -v \
@@ -548,15 +549,15 @@
 
 %.draft: %.xml stylesheets/drafthtml.xsl
 	@echo "Making draft page(s), ignore any XSLT complaints:"
-	$(cmd) id=`sed -e 's/.*id=.//; tmatch; d; :match; s/["'"'"'].*//; q' $<`; \
+	$(cmd) id=`$(SED) -e 's/.*id=.//; tmatch; d; :match; s/["'"'"'].*//; q' $<`; \
 	test -n "$$id" || id=noname; \
 	langs="$(shell echo $@ | \
-	               sed -e 's,^src/.*,$(LANGUAGES),; t' \
-	                   -e 's,^xml/\([^/]\+\)/.*,\1,')"; \
+	               $(SED) -e 's,^src/.*,$(LANGUAGES),; t' \
+	                      -e 's,^xml/\([^/]\+\)/.*,\1,')"; \
 	for lang in $${langs}; do \
 		destdir=html/$${lang}; \
 		test -d $${destdir} && continue || \
-		$(mkdir_p) $${destdir}; \
+		$(MKDIR_P) $${destdir}; \
 		cp -fp $(srcdir)/stylesheets/*.css \
 		       $(srcdir)/stylesheets/$$lang/*.css \
 		    $${destdir} 2>/dev/null; \
@@ -590,7 +591,7 @@
 .SECONDARY: $(tarball_prefix)-%.tar
 $(tarball_prefix)-%.tar: html/%/index.html html/%/gimp-help.xml
 	$(cmd) rm -rf $(tarball_prefix)-$*
-	$(cmd) $(mkdir_p) $(tarball_prefix)-$*
+	$(cmd) $(MKDIR_P) $(tarball_prefix)-$*
 	$(cmd) cd $(tarball_prefix)-$* && $(LN_S) ../html/$* .
 	$(cmd) cd $(tarball_prefix)-$* && $(LN_S) ../html/images .
 	$(cmd) tar -chf $@ --exclude .svn $(tarball_prefix)-$*
@@ -614,40 +615,57 @@
 		$(tarball_prefix)-$(lang).zip \
 	)
 
-## TODO ## #### Miscellaneous checks
 
-## TODO ## .PHONY: checks check-lang-attributes check-svn-property check-image-references
+########################################################################
+####            Source file checks                                  ####
+########################################################################
+
+# Note that the default (autoconf) target name is "check".
+checks: check-svn-property check-image-references ;
+check-svn: check-svn-property ;
+check-images: check-image-references ;
+
+check-svn-property:
+	$(cmd) if cd $(srcdir) && test -e tools/check_keywords_property.pl && \
+	type perl >/dev/null 2>&1; then \
+	    echo "*** Checking svn property ... "; \
+	    perl tools/check_keywords_property.pl -v || true; \
+	else \
+	    echo >&2 "*** Cannot check svn property (no Perl installed?) ***"; \
+	fi
+
+check-image-references:
+	$(cmd) if cd $(srcdir) && test -e tools/validate_references.py && \
+	type python >/dev/null 2>&1; then \
+	    echo "*** Checking image references ... "; \
+	    python tools/validate_references.py \
+	        --verbose --broken --orphaned \
+		$(VALIDATEREFERENCESFLAGS); \
+	else \
+	    echo >&2 "*** Cannot check image references (no Python installed?) ***"; \
+	fi
+
+check-images-%: FORCE
+	$(cmd) $(MAKE) --no-print-directory check-image-references \
+		VALIDATEREFERENCESFLAGS="--imgdir=images/C,images/$*"
+
+# special case 'en':
+check-images-en check-images-C: check-image-references ;
+
+.PHONY: checks check-svn-property check-image-references
+
 
-## TODO ## # Note that the default (autoconf) target name is "check".
-## TODO ## checks: check-svn-property check-image-references
 
-## TODO ## check-svn-property:
-## TODO ## 	@if cd $(srcdir) && test -e tools/check_keywords_property.pl && \
-## TODO ## 	type perl >/dev/null 2>&1; then \
-## TODO ## 	    echo "*** Checking svn property ... "; \
-## TODO ## 	    perl tools/check_keywords_property.pl -v || true; \
-## TODO ## 	else \
-## TODO ## 	    echo >&2 "*** Cannot check svn property (no Perl installed?) ***"; \
-## TODO ## 	fi
-
-## TODO ## check-image-references:
-## TODO ## 	@if cd $(srcdir) && test -e tools/validate_references.py && \
-## TODO ## 	type python >/dev/null 2>&1; then \
-## TODO ## 	    echo "*** Checking image references ... "; \
-## TODO ## 	    python tools/validate_references.py --verbose --broken --orphaned || true; \
-## TODO ## 	else \
-## TODO ## 	    echo >&2 "*** Cannot check image references (no Python installed?) ***"; \
-## TODO ## 	fi
 
 ## TODO ## #### Installation
 ## TODO ## 
 ## TODO ## install-data-local:
-## TODO ## 	$(mkdir_p) $(DESTDIR)$(helpdir)
+## TODO ## 	$(MKDIR_P) $(DESTDIR)$(helpdir)
 ## TODO ## 
 ## TODO ## 	@$(echo_n) "** Installing HTML:"
 ## TODO ## 	@cd html && \
 ## TODO ## 	for lang in $(ALL_LINGUAS); do \
-## TODO ## 		$(mkdir_p) $(DESTDIR)$(helpdir)/$$lang && $(echo_n) " $$lang"; \
+## TODO ## 		$(MKDIR_P) $(DESTDIR)$(helpdir)/$$lang && $(echo_n) " $$lang"; \
 ## TODO ## 		find $$lang $(html_files_find_predicates) | \
 ## TODO ## 		while read file; do \
 ## TODO ## 		  $(INSTALL_DATA) $$file $(DESTDIR)$(helpdir)/$$file || exit 66; \
@@ -667,7 +685,7 @@
 ## TODO ## 		  *.gif) $(echo_n) G ;; \
 ## TODO ## 		esac; \
 ## TODO ## 		test -d $(DESTDIR)$(helpdir)/$${file%/*} || \
-## TODO ## 		$(mkdir_p) $(DESTDIR)$(helpdir)/$${file%/*}; \
+## TODO ## 		$(MKDIR_P) $(DESTDIR)$(helpdir)/$${file%/*}; \
 ## TODO ## 		$(INSTALL) $(top_srcdir)/$$file $(DESTDIR)$(helpdir)/$$file || exit 66; \
 ## TODO ## 	done
 ## TODO ## 	@echo .

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Wed Jan 14 18:29:09 2009
@@ -19,7 +19,9 @@
 
 AC_PROG_INSTALL
 AC_PROG_LN_S
+AC_PROG_MKDIR_P
 AC_PROG_MAKE_SET
+AC_PROG_SED
 
 
 #  You can set the ALL_LINGUAS environment variable to

Modified: trunk/tools/README
==============================================================================
--- trunk/tools/README	(original)
+++ trunk/tools/README	Wed Jan 14 18:29:09 2009
@@ -170,8 +170,6 @@
 
     python tools/validate_references.py
 
-Your xml files must have been validated for all languages.
-
 Use the --help option for more information.
 
 

Modified: trunk/tools/validate_references.py
==============================================================================
--- trunk/tools/validate_references.py	(original)
+++ trunk/tools/validate_references.py	Wed Jan 14 18:29:09 2009
@@ -1,23 +1,30 @@
 #!/usr/bin/env python
-# _*_ coding: latin1 -*_
-#
-# gimp-help-2 -- Validate image file references
-# Copyright (C) 2006, 2007, 2008 RÃman Joost
+# -*- coding: latin1 -*-
+"""
+  Validate image file references
+
+  Validates image file references in DocBook XML files and
+  finds orphaned images files.
+"""
+
+# gimp-help-2 -- validate_references.py
 #
-#   This program is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2 of the License, or
-#   (at your option) any later version.
+# Copyright (C) 2006, 2007 RÃman Joost
+#           (C) 2008, 2009 RÃman Joost, Ulf-D. Ehlert
 #
-#   This program is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
 #
-#   You should have received a copy of the GNU General Public License
-#   along with this program; if not, write to the Free Software
-#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
 #
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import sys
 import os
@@ -49,7 +56,7 @@
         self.verbose = verbose
         self.data    = {}
 
-    def contains(self, key):
+    def __contains__(self, key):
         """Is there an entry 'key'?."""
         return self.data.has_key(key)
 
@@ -59,14 +66,26 @@
         """
         self.data[key] = val
 
-    def remove(self, key):
-        """Mark an entry as invalid, i.e. set the info to False,
-           so that this method may be used with an iterator.
+    def __setitem__(self, key, val):
+        """Add a (key, value) pair to the container, e.g.
+           filename and some info corresponding to this filename.
+        """
+        self.data[key] = val
+
+    def erase(self, key):
+        """Mark an entry as invalid.
+        
+        Set the info to False rather than deleting it,
+        so that "removing" while iterating is possible.
         """
         if self.data.has_key(key):
             self.data[key] = False
 
     def size(self):
+        """Return the number of non-empty data entries."""
+        return len([x for x in self.data if self.data[x]])
+
+    def __len__(self):
         """Return the number of data entries."""
         return len(self.data)
 
@@ -80,37 +99,44 @@
     def difference(self, other):
         """Remove entries common to 'self' and 'other'."""
         for key in self.data.iterkeys():
-            if other.contains(key):
-                self.remove(key)
-                other.remove(key)
-        self.data = dict((key, self.data[key])
-                         for key in self.data if self.data.get(key))
+            if key in other:
+                self.erase(key)
+                other.erase(key)
 
 
 class ImageFilesList(FileNameContainer):
     """A container for image file names.
 
     This class is used to collect and save all image files
-    in the gimp-help-2 'images/' directory.
+    in the specified 'images/' directory.
 
     """
     def __init__(self, verbose=0):
         super(ImageFilesList, self).__init__(verbose)
 
-    def find(self, imageroot = "images"):
+    def find(self, imageroot):
         """Search for PNG and JPG files in the image directory."""
-        if self.verbose:
-            sys.stderr.write("searching images ... ")
-            if self.verbose > 1:
-                sys.stderr.write("\n")
 
-        for root, dirs, files in os.walk(imageroot):
+        self.data.clear()
+        self.imageroot = os.path.normpath(imageroot)
+        imageroot = self.imageroot + "/"
+
+        if self.verbose == 1:
+            sys.stderr.write("searching images in %s ... " % imageroot)
+        elif self.verbose > 1:
+            sys.stderr.write("searching images in %s ... \n" % imageroot)
+
+        for root, dirs, files in os.walk(self.imageroot):
+            if self.verbose > 2:
+                sys.stderr.write("    entering " + root + "\n")
             for prune in [ 'callouts', '.svn' ]:
                 if prune in dirs:
                     dirs.remove(prune)
 
             # ignore images in the first level of the images dir
             if root.endswith('images'):
+                if self.verbose > 2:
+                    sys.stderr.write("    skipping " + root + "\n")
                 continue
 
             # don't care about other files than images files
@@ -119,22 +145,24 @@
                 filepath = os.path.join(root, filename)
                 if self.verbose > 1:
                     sys.stderr.write(filepath + '\n')
-                self.add(filepath.replace("images/", ""))
+                self.add(filepath.replace(imageroot, ""))
 
         if self.verbose:
-            sys.stderr.write(str(len(self.data)) + "\n")
+            sys.stderr.write("%d files\n" % len(self.data))
 
     def report(self):
         """Print the list of orphaned image files, i.e. image files
-           which are not referenced in the XML source files.
+           which are not referred to in any XML source file.
         """
+        files = [fname for fname in self.data.keys() if self.data[fname]]
         if self.verbose:
-            sys.stderr.write(str(self.size()) + " orphaned image file")
-            if self.size() != 1: sys.stderr.write("s")
-            if self.size() != 0: sys.stderr.write(":")
-            sys.stderr.write("\n")
-        for imagefile in sorted(self.data.keys()):
-            print "ORPHANED:", "images/" + imagefile
+            colon, plural_s = ":", "s"
+            if len(files) == 0: colon = ""
+            if len(files) == 1: plural_s = ""
+            sys.stderr.write("%d orphaned image file%s%s\n" % \
+                             (len(files), plural_s, colon))
+        for imagefile in sorted(files):
+            print "ORPHANED:", os.path.join(self.imageroot, imagefile)
 
 
 class ImageReferencesList(FileNameContainer):
@@ -145,9 +173,8 @@
     ('image-file', 'source-file') pairs.
 
     """
-    def __init__(self, source, verbose=0):
+    def __init__(self, verbose=0):
         super(ImageReferencesList, self).__init__(verbose)
-        self.source    = source
         self.cur_files = []	# stack for files in progress
         self.all_files = 0	# visited files
         self.handler   = XMLHandler(self)
@@ -165,34 +192,43 @@
         parser.setFeature(xml.sax.handler.feature_external_pes, 0)
         return parser
         
-    def find(self):
+    def find(self, source_file):
         """Parse XML files and extract image references."""
 
-        if self.verbose:
+        if self.verbose > 1:
+            sys.stderr.write("parsing XML files ... \n")
+        elif self.verbose:
             sys.stderr.write("parsing XML files ... ")
-            if self.verbose > 1: sys.stderr.write("\n")
-
-        self.push_file(self.source)
-        self.parser.parse(self.source)
 
+        self.push_file(source_file)
+        try:
+            self.parser.parse(source_file)
+        except xml.sax.SAXException, err:
+            sys.stderr.write("ERROR parsing %s\n" % err)
+        except:
+            sys.stderr.write("ERROR reading %s\n" % source_file)
         assert(len(self.cur_files) == 1)
 
-        if self.verbose:
-            if self.verbose > 1: sys.stderr.write("parsed ")
-            sys.stderr.write(str(self.all_files) + " files, " +
-                             str(self.size()) + " references\n")
+        if self.verbose > 1:
+            sys.stderr.write("parsed %d files, %d references\n" % \
+                             (self.all_files, self.size()))
+        elif self.verbose:
+            sys.stderr.write("%d files, %d references\n" % \
+                             (self.all_files, self.size()))
 
     def report(self):
         """Print the list of broken image referencess
            in the XML source file(s).
         """
+        files = [fname for fname in self.data.keys() if self.data[fname]]
         if self.verbose:
-            sys.stderr.write(str(self.size()) + " broken image reference")
-            if self.size() != 1: sys.stderr.write("s")
-            if self.size() != 0: sys.stderr.write(":")
-            sys.stderr.write("\n")
-        for imagefile in sorted(self.data.keys()):
-            print "BROKEN:", "images/" + imagefile, "IN", self.data[imagefile]
+            colon, plural_s = ":", "s"
+            if len(files) == 0: colon = ""
+            if len(files) == 1: plural_s = ""
+            sys.stderr.write("%d broken image reference%s%s\n" % \
+                                  (len(files), plural_s, colon))
+        for imagefile in sorted(files):
+            print "BROKEN: images/%s IN %s" % (imagefile, self.data[imagefile])
 
     # Internal stack methods to keep track of the opened files
 
@@ -218,7 +254,7 @@
     def startElement(self, name, attrs):
         """Handle image nodes."""
         if name in IMAGE_NODES:
-            fileref = attrs.getValue('fileref').replace("../images/", "")
+            fileref = attrs.getValue('fileref').replace("images/", "")
             if not IGNORE_IMAGE_REGEX.match(fileref):
                 self.owner.add(fileref, self.owner.current_file())
         if name == "xi:include" and attrs.has_key('href'):
@@ -231,8 +267,10 @@
                 parser = self.owner.make_parser()
                 try:
                     parser.parse(filename)
+                except xml.sax.SAXException, err:
+                    sys.stderr.write("ERROR parsing %s\n" % err)
                 except:
-                    sys.stderr.write("ERROR reading " + str(filename) + "\n")
+                    sys.stderr.write("ERROR reading %s\n" % filename)
                 self.owner.pop_file()
             else:
                 if self.owner.verbose > 1:
@@ -258,32 +296,43 @@
     """
     verbose                = 0
     gimp_help_root_dir     = "."
-    xml_root_file          = "src/gimp.xml"
+    xml_dir                = "src"
+    img_dirs               = "images/C"
+    xml_root_file          = "gimp.xml"
     find_orphaned_images   = False
     find_broken_references = False
 
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "hvr:bliof:",
-                                   ["help", "verbose", "root", "broken",
-                                   "links", "orphaned", "images", "file"])
-    except getopt.GetoptError:
-        usage(64)
+        opts, args = getopt.getopt(sys.argv[1:], "hvr:x:s:i:blio",
+                         ["help", "verbose",
+                          "root=", "xmldir=", "srcdir=", "imgdir=",
+                          "broken", "links", "orphaned", "images"])
+    except getopt.GetoptError, err:
+        usage(64, str(err))
 
     for opt, arg in opts:
         if opt == "-h" or opt == "--help":
             usage()
         elif opt == "-v" or opt == "--verbose":
-            verbose = verbose + 1
+            verbose += 1
         elif opt in ["-r", "--root"]:
             gimp_help_root_dir = arg
-        elif opt in ["-b", "-l", "--broken", "--links"]:
+        elif opt in ["-x", "--xmldir", "-s", "--srcdir"]:
+            xml_dir = arg
+            xml_root_file = os.path.join(xml_dir, xml_root_file)
+        elif opt in ["-i", "--imgdir"]:
+            img_dirs = re.split('[, ]+', arg)
+        elif opt in ["-b", "--broken", "-l", "--links"]:
             find_broken_references = True
-        elif opt in ["-i", "-o", "--orphaned", "--images"]:
+        elif opt in ["-o", "--orphaned"]:
             find_orphaned_images = True
         elif opt == "-f" or opt == "--file":
             find_broken_references = True
             xml_root_file = arg
 
+    if args:
+        usage(64, "Too many arguments.")
+
     # Change to user specified root dir.
     if gimp_help_root_dir != ".":
         try:
@@ -300,60 +349,66 @@
 
     # We need an existing xml source file to parse.
     if not os.path.isfile(xml_root_file):
-        usage(66, "Cannot find " + xml_root_file + ".")
+        if os.path.isfile(os.path.join(xml_dir, xml_root_file)):
+            xml_root_file = os.path.join(xml_dir, xml_root_file)
+        else:
+            usage(66, "Cannot find " + xml_root_file + ".")
 
     # When finding orphaned images, we must parse all xml files.
-    if find_orphaned_images and (xml_root_file != "src/gimp.xml"):
-        usage(64, "'--file <file>' and '--orphaned' are mutually exclusive.")
+    #if find_orphaned_images and (xml_root_file != "src/gimp.xml"):
+    #    usage(64, "'--file <file>' and '--orphaned' are mutually exclusive.")
 
     # If no action specified: search for broken image references.
     if not (find_orphaned_images or find_broken_references):
         find_broken_references = True
 
-    # Step 1: find all image files. 
-    image_files = ImageFilesList(verbose) 
-    image_files.find()
+    # Step 1: find all image references.
+    image_refs = ImageReferencesList(verbose)
+    image_refs.find(xml_root_file)
 
-    # Step 2: find all image references.
-    image_refs = ImageReferencesList(xml_root_file, verbose)
-    image_refs.find()
-
-    # Step 3: remove intersection of image references and images files,
-    # the result is the list of invalid (broken) references.
-    if find_broken_references:
-        image_refs.sort_out_valid(image_files)
-        image_refs.report()
-
-    # Step 4: remove intersection of image references and images files,
-    # the result is the list of orphaned image files.
-    if find_orphaned_images:
-        image_files.sort_out_valid(image_refs)
-        image_files.report()
+    # Step 2: find all image files. 
+    image_files = ImageFilesList(verbose) 
+    if isinstance(img_dirs, str): img_dirs = [img_dirs]
+    for imgdir in img_dirs:
+        image_files.find(imgdir)
+
+        # Step 3: remove intersection of image references and images files,
+        # the result is the list of invalid (broken) references.
+        if find_broken_references:
+            image_refs.sort_out_valid(image_files)
+            image_refs.report()
+            find_broken_references = False
+
+        # Step 4: remove intersection of image references and images files,
+        # the result is the list of orphaned image files.
+        if find_orphaned_images:
+            image_files.sort_out_valid(image_refs)
+            image_files.report()
 
 
 def usage(exitcode=0, msg=""):
     """Help the user."""
-    if msg:
+    if exitcode > 0 or msg:
         sys.stderr.write("Error: " + msg + "\n")
+        sys.stderr.write("(try \"%s --help\")\n" % sys.argv[0])
     else:
-        sys.stderr.write ( """\
-validate_references - Copyright (C) 2006-2008 RÃman Joost (gimp-help-2)
-validates file references in docbook xml files.\n""")
-    sys.stderr.write ( """\
+        sys.stdout.write ( """\
+validate_references - validates image file references in DocBook xml files
+
+Copyright (C) 2006-2008 RÃman Joost,
+          (C) 2008-2009 RÃman Joost, Ulf-D. Ehlert
 
-usage: validate_references.py [options]
+Usage: validate_references.py [options]
 
     options:
-        -h | --help      this help
-        -v | --verbose   verbose; doubling (-v -v) is possible
-        -r <dir>         specify the gimp-help-2 root directory
-        --root <dir>     same as '-r'
-        -o | --orphaned  check for orphaned image files
-        -i | --images    same as '-o'
-        -b | --broken    check for broken links
-                         (this is the default action)
-        -f  <file>       check only <file>
-                         (implies '-b', conflicts with '-o')\n""")
+        -h | --help          this help
+        -v | --verbose       verbose; doubling (-v -v) is possible
+        -r | --root <dir>    specify the gimp-help-2 root directory
+        -x | --xmldir <dir>  specify the XML files directory
+        -i | --imgdir <dir>  comma-separated list of images directories
+        -o | --orphaned      check for orphaned image files
+        -b | --broken        check for broken links (default action)
+\n""")    
     sys.exit(exitcode)
 
 if __name__ == "__main__":



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]