/[papo]/gnue/common/scripts/gnuedtd
ViewVC logotype

Diff of /gnue/common/scripts/gnuedtd

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.3 by charlie, Tue Aug 27 18:15:51 2002 UTC revision 1.4 by styxman, Fri Nov 15 15:32:54 2002 UTC
# Line 1  Line 1 
1  #!python  #!/bin/env python
2  #  #
3  # This file is part of GNU Enterprise.  # This file is part of GNU Enterprise.
4  #  #
5  # GNU Enterprise is free software; you can redistribute it  # GNU Enterprise is free software; you can redistribute it
6  # and/or modify it under the terms of the GNU General Public  # and/or modify it under the terms of the GNU General Public
7  # License as published by the Free Software Foundation; either  # License as published by the Free Software Foundation; either
8  # version 2, or (at your option) any later version.  # version 2, or (at your option) any later version.
9  #  #
10  # GNU Enterprise is distributed in the hope that it will be  # GNU Enterprise is distributed in the hope that it will be
11  # useful, but WITHOUT ANY WARRANTY; without even the implied  # useful, but WITHOUT ANY WARRANTY; without even the implied
12  # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13  # PURPOSE. See the GNU General Public License for more details.  # PURPOSE. See the GNU General Public License for more details.
14  #  #
15  # You should have received a copy of the GNU General Public  # You should have received a copy of the GNU General Public
16  # License along with program; see the file COPYING. If not,  # License along with program; see the file COPYING. If not,
17  # write to the Free Software Foundation, Inc., 59 Temple Place  # write to the Free Software Foundation, Inc., 59 Temple Place
18  # - Suite 330, Boston, MA 02111-1307, USA.  # - Suite 330, Boston, MA 02111-1307, USA.
19  #  #
20  # Copyright 2001 Free Software Foundation  # Copyright 2001-2002 Free Software Foundation
21  #  #
22  #  #
23  # FILE:  # FILE:
24  # gnuedtd  # gnuedtd
25  #  #
26  # DESCRIPTION:  # DESCRIPTION:
27  # This script generates a DTD for the client apps based on  # This script generates a DTD for the client apps based on
28  # their GParser markup  # their GParser markup
29  #  #
30  # NOTES:  # NOTES:
# Line 33  Line 33 
33  import sys, string, time  import sys, string, time
34  from gnue.common import GParser, GTypecast  from gnue.common import GParser, GTypecast
35    
36    # This is simply to initialize gettext support :(
37    from gnue.common import GBaseApp
38    
39  class GenerateDTD:  class GenerateDTD:
40    def __init__ (self, tool, dest=sys.__stdout__):    def __init__ (self, tool, dest=sys.__stdout__):
41    
42      if tool == 'reports':      if tool == 'reports':
43        from gnue.reports import GRParser, VERSION, PACKAGE        from gnue.reports import GRParser, VERSION, PACKAGE
44        xmlElements = GRParser.getXMLelements()        xmlElements = GRParser.getXMLelements()
45        topLevelElement = 'report'        topLevelElement = 'report'
46        name = PACKAGE        name = PACKAGE
47        version = VERSION        version = VERSION
48    
49      elif tool == 'forms':      elif tool == 'forms':
50        from gnue.forms import GFParser, VERSION, PACKAGE        from gnue.forms import GFParser, VERSION, PACKAGE
51        xmlElements = GFParser.getXMLelements()        xmlElements = GFParser.getXMLelements()
52        topLevelElement = 'form'        topLevelElement = 'form'
53        name = PACKAGE        name = PACKAGE
54        version = VERSION        version = VERSION
55    
56      elif tool == 'gnurpc':      elif tool == 'navigator':
57          from gnue.navigator import GNParser, VERSION, PACKAGE
58          xmlElements = GNParser.getXMLelements()
59          topLevelElement = 'processes'
60          name = PACKAGE
61          version = VERSION
62    
63        elif tool == 'schema':
64          from gnue.common.schema import GSParser
65          from gnue.common import VERSION, PACKAGE
66          xmlElements = GSParser.getXMLelements()
67          topLevelElement = 'schema'
68          name = 'GNUe Schema'
69          version = VERSION
70    
71        elif tool == 'gnurpc':
72        from gnue.common.commdrivers._parser import Parser        from gnue.common.commdrivers._parser import Parser
73        xmlElements = Parser.getXMLelements()        xmlElements = Parser.getXMLelements()
74        topLevelElement = 'gnurpc'        topLevelElement = 'gnurpc'
75        name = 'GNURPC'        name = 'GNURPC'
76        version = '0.0001'        from gnue.common import VERSION as version
77    
78      else:      else:
79        print "\nSyntax: gnuedtd <forms|reports|gnurpc>\n"        print "\nSyntax: gnuedtd <forms|reports|schema|navigator|gnurpc> [outfile.dtd]\n"
80        sys.exit()        sys.exit()
81    
82      self.parentMappings = {}      self.parentMappings = {}
# Line 70  class GenerateDTD: Line 88  class GenerateDTD:
88      for element in xmlElements.keys():      for element in xmlElements.keys():
89        # Get a mapping of all parent tags        # Get a mapping of all parent tags
90        if xmlElements[element].has_key('ParentTags') and \        if xmlElements[element].has_key('ParentTags') and \
91           xmlElements[element]['ParentTags'] != None:           xmlElements[element]['ParentTags'] != None:
92          for parent in xmlElements[element]['ParentTags']:          for parent in xmlElements[element]['ParentTags']:
93            if not self.parentMappings.has_key(parent):            if not self.parentMappings.has_key(parent):
94              self.parentMappings[parent] = {}              self.parentMappings[parent] = {}
# Line 79  class GenerateDTD: Line 97  class GenerateDTD:
97               xmlElements[element]['UsableBySiblings']               xmlElements[element]['UsableBySiblings']
98    
99        # Find out what Typecasts are being used        # Find out what Typecasts are being used
100        if xmlElements[element].has_key('Attributes'):        if xmlElements[element].has_key('Attributes'):
101          for att in xmlElements[element]['Attributes'].keys():          for att in xmlElements[element]['Attributes'].keys():
102            self.typecasts[xmlElements[element]['Attributes'][att]['Typecast']] \            self.typecasts[xmlElements[element]['Attributes'][att]['Typecast']] \
103                        = 'CDATA'                        = 'CDATA'
# Line 88  class GenerateDTD: Line 106  class GenerateDTD:
106    
107      dest.write ("""      dest.write ("""
108  <!--  <!--
109       Copyright 2001 Free Software Foundation       Copyright 2001-2002 Free Software Foundation
110        
111       This file is part of GNU Enterprise.       This file is part of GNU Enterprise.
112        
113       GNU Enterprise is free software; you can redistribute it       GNU Enterprise is free software; you can redistribute it
114       and/or modify it under the terms of the GNU General Public       and/or modify it under the terms of the GNU General Public
115       License as published by the Free Software Foundation; either       License as published by the Free Software Foundation; either
116       version 2, or (at your option) any later version.       version 2, or (at your option) any later version.
117        
118       GNU Enterprise is distributed in the hope that it will be       GNU Enterprise is distributed in the hope that it will be
119       useful, but WITHOUT ANY WARRANTY; without even the implied       useful, but WITHOUT ANY WARRANTY; without even the implied
120       warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
121       PURPOSE. See the GNU General Public License for more details.       PURPOSE. See the GNU General Public License for more details.
122        
123       You should have received a copy of the GNU General Public       You should have received a copy of the GNU General Public
124       License along with program; see the file COPYING. If not,       License along with program; see the file COPYING. If not,
125       write to the Free Software Foundation, Inc., 59 Temple Place       write to the Free Software Foundation, Inc., 59 Temple Place
126       - Suite 330, Boston, MA 02111-1307, USA.       - Suite 330, Boston, MA 02111-1307, USA.
127  -->  -->
128    
129  <!-- Entities for characters/symbols -->  <!-- Entities for characters/symbols -->
130  <!ENTITY lt "&#38;#60;">  <!ENTITY % lt "&#38;#60;">
131  <!ENTITY gt "&#62;">  <!ENTITY % gt "&#62;">
132  <!ENTITY amp "&#38;#38;">  <!ENTITY % amp "&#38;#38;">
133    
134  <!-- +---------------------------------------------------+ -->  <!--  =================================================  -->
135  <!-- | Datatype entities to make DTD more human readable | -->  <!--  Datatype entities to make DTD more human readable  -->
136  <!-- +---------------------------------------------------+ -->  <!--  =================================================  -->
137    
138  """)  """)
139      if self.typecasts.has_key (GTypecast.text):        if self.typecasts.has_key (GTypecast.text):
140        self.typecasts[GTypecast.text] = '%text;'        self.typecasts[GTypecast.text] = '%text;'
141        dest.write('<!ENTITY % text "CDATA">\n\n')        dest.write('<!ENTITY % text "CDATA">\n\n')
142    
143      if self.typecasts.has_key (GTypecast.boolean):      if self.typecasts.has_key (GTypecast.boolean):
144        self.typecasts[GTypecast.boolean] = '%boolean;'        self.typecasts[GTypecast.boolean] = '%boolean;'
145        dest.write('<!ENTITY % boolean "(%true;) #IMPLIED">\n'        dest.write('<!ENTITY % true "Y">\n'
146                   '<!ENTITY % true "">\n\n')                   '<!ENTITY % false "N">\n'
147                     '<!ENTITY % boolean "(%true;|%false;) #IMPLIED">\n\n')
148    
149      if self.typecasts.has_key (GTypecast.number):      if self.typecasts.has_key (GTypecast.number):
150        self.typecasts[GTypecast.number] = '%number;'        self.typecasts[GTypecast.number] = '%number;'
151        dest.write('<!ENTITY % number "NMTOKEN">\n'        dest.write('<!ENTITY % number "NMTOKEN">\n'
152                   '<!-- [-]?[0-9]+([.][0-9]+)? -->\n\n')                   '<!-- [-]?[0-9]+([.][0-9]+)? -->\n\n')
153    
154      if self.typecasts.has_key (GTypecast.whole):      if self.typecasts.has_key (GTypecast.whole):
# Line 149  class GenerateDTD: Line 168  class GenerateDTD:
168    
169      if self.typecasts.has_key (GTypecast.names):      if self.typecasts.has_key (GTypecast.names):
170        self.typecasts[GTypecast.names] = '%names;'        self.typecasts[GTypecast.names] = '%names;'
171        dest.write('<!ENTITY & names "CDATA">\n'        dest.write('<!ENTITY % names "CDATA">\n'
172                   '<!-- (%name;)(,[ ]*(%name;))* -->\n\n')                   '<!-- (%name;)(,[ ]*(%name;))* -->\n\n')
173    
174      dest.write('\n')      dest.write('\n')
175    
176      self.elementStack = [['Top level element',topLevelElement]]      self.elementStack = [['Top level element',topLevelElement]]
177    
178      while len(self.elementStack) and \      while len(self.elementStack) and \
179                (self.elementStack!=[['Child elements of service']]):                (self.elementStack!=[['Child elements of service']]):
180        i = 1        i = 1
181        #print "first loop: %s, %s " % \        ##print "first loop: %s, %s " % \
182        #      (len(self.elementStack),self.elementStack)        ##      (len(self.elementStack),self.elementStack)
183    
184        ## remove allready processed tags        ## remove allready processed tags
185        while i < len(self.elementStack[0]):                while i < len(self.elementStack[0]):
186          if self.processedTags.has_key(self.elementStack[0][i]):          if self.processedTags.has_key(self.elementStack[0][i]):
187              ## print "Popping already used tag %s" % self.elementStack[0][i]
188            self.elementStack[0].pop(i)            self.elementStack[0].pop(i)
189          else:          else:
190            i = i + 1            i += 1
191    
192        if len (self.elementStack[0]) > 1:        if len (self.elementStack[0]) > 1:
193          elements = self.elementStack[0][1:]          elements = self.elementStack[0][1:]
194          elements.sort()          elements.sort()
195          dest.write('\n<!-- +-' + '-' * (len(self.elementStack[0][0])) + '-+ -->\n')          dest.write('\n<!-- ' + '=' * (len(self.elementStack[0][0])) + ' -->\n')
196          dest.write('<!-- | %s | -->\n' % self.elementStack[0][0])          dest.write('<!-- %s -->\n' % self.elementStack[0][0])
197          dest.write('<!-- +-' + '-' * (len(self.elementStack[0][0])) + '-+ -->\n')          dest.write('<!-- ' + '=' * (len(self.elementStack[0][0])) + ' -->\n')
198          for element in elements:          for element in elements:
199            self.handleElement(element)            self.handleElement(element)
200          self.elementStack.pop(0)          self.elementStack.pop(0)
201  #      else:        else:
202  #        self.elementStack.pop(0)          self.elementStack.pop(0)
203    
204    
205      dest.write ("\n<!-- This DTD was created by gnuedtd\n"      dest.write ("\n<!-- This DTD was created by gnuedtd\n"
# Line 191  class GenerateDTD: Line 211  class GenerateDTD:
211    # If a dictionary has a key, return value    # If a dictionary has a key, return value
212    # associated w/that key. Otherwise return dflt.    # associated w/that key. Otherwise return dflt.
213    #    #
214    def default(self, dict, key, dflt):    def default(self, dict, key, dflt):
215      if dict.has_key(key):      if dict.has_key(key):
216        return dict[key]        return dict[key]
217      else:      else:
# Line 202  class GenerateDTD: Line 222  class GenerateDTD:
222    # Line wrap a string.  Note, this eliminates redundant spacing    # Line wrap a string.  Note, this eliminates redundant spacing
223    #    #
224    def wrap(self, indent, text, firstindent=None):    def wrap(self, indent, text, firstindent=None):
225        if firstindent == None:        if firstindent == None:
226          firstindent = indent          firstindent = indent
227    
228        pos = 0        pos = 0
# Line 236  class GenerateDTD: Line 256  class GenerateDTD:
256     # for i in self.xmlElements.keys():     # for i in self.xmlElements.keys():
257      #  print "element: %s" % i      #  print "element: %s" % i
258    
259      if self.default(self.xmlElements[element],'Deprecated',0):      deprecated = self.default(self.xmlElements[element],'Deprecated',0)
260        self.dest.write(self.wrap(17,      if deprecated:
261           '<!-- DEPRECATED: Use of the %s element has been deprecated -->' % \        if type(deprecated) != type(""):
262               (element),0))          deprecated = ""
263          else:
264            deprecated = "[%s] " % deprecated
265    
266          self.dest.write(self.wrap(17,
267             '<!-- DEPRECATED: Use of the <%s> element has been deprecated %s -->' % \
268                 (element, deprecated),0))
269    
270      if self.parentMappings.has_key(element):      if self.parentMappings.has_key(element):
271        es = self.parentMappings[element].keys()        es = self.parentMappings[element].keys()
272      else:      else:
273        es = []        es = []
274      if len(es):      if len(es):
275        es.insert(0,'Child elements of %s' % element)        es.insert(0,'Child elements of %s' % element)
276        self.elementStack.append(es)        self.elementStack.append(es)
277    
278    
279      descr = self.default(self.xmlElements[element],'Description','')      descr = self.default(self.xmlElements[element],'Description','')
280      if len(descr):      if len(descr):
281        self.dest.write(self.wrap(5,        self.dest.write(self.wrap(5,
282          '<!-- %s -->' % (description), 0))          '<!-- %s -->' % (descr), 0))
283    
284      elemdef = "<!ELEMENT %s" % element      elemdef = "<!ELEMENT %s" % element
285      indent = len(elemdef) + 2      indent = len(elemdef) + 2
# Line 265  class GenerateDTD: Line 291  class GenerateDTD:
291        for child in m:        for child in m:
292          required = self.default(self.xmlElements[child], 'Required', 0)          required = self.default(self.xmlElements[child], 'Required', 0)
293          single = self.default(self.xmlElements[child],'SingleInstance',0)          single = self.default(self.xmlElements[child],'SingleInstance',0)
294          if single and required:          if single and required:
295            children.append("%s" % child)            children.append("%s" % child)
296          elif single:          elif single:
297            children.append("%s?" % child)            children.append("%s?" % child)
298          elif required:          elif required:
299            children.append("%s+" % child)            children.append("%s+" % child)
300          else:          else:
301            children.append("%s*" % child)            children.append("%s*" % child)
# Line 278  class GenerateDTD: Line 304  class GenerateDTD:
304          children.append ('#PCDATA')          children.append ('#PCDATA')
305    
306        elemdef = elemdef + (" (%s)" % string.join(children,', '))        elemdef = elemdef + (" (%s)" % string.join(children,', '))
307            
308      else:      else:
309        elemdef = elemdef + " EMPTY"        elemdef = elemdef + " EMPTY"
310    
311      elemdef = elemdef + ">\n"      elemdef = elemdef + ">\n"
# Line 293  class GenerateDTD: Line 319  class GenerateDTD:
319      otherAtts = []      otherAtts = []
320      atts = self.default(self.xmlElements[element], 'Attributes',{}).keys()      atts = self.default(self.xmlElements[element], 'Attributes',{}).keys()
321      atts.sort()      atts.sort()
322      for att in atts:      for att in atts:
323    
324        req = self.default(self.xmlElements[element]['Attributes'][att],        req = self.default(self.xmlElements[element]['Attributes'][att],
325                           'Required',0)                           'Required',0)
# Line 321  class GenerateDTD: Line 347  class GenerateDTD:
347    
348          attdef = "<!ATTLIST %s %s " % (element, att)          attdef = "<!ATTLIST %s %s " % (element, att)
349    
350          if self.default(self.xmlElements[element]['Attributes'][att],          deprecated = self.default(self.xmlElements[element]['Attributes'][att],
351                             'Deprecated',0):                             'Deprecated',0)
352            self.dest.write(self.wrap(17,          if deprecated:
353              '  <!-- DEPRECATED: The %s attribute of %s '            if type(deprecated) != type(""):
354              'has been deprecated -->' % (att, element),0))              deprecated = ""
355              else:
356                deprecated = "\n[%s] " % deprecated
357    
358              self.dest.write(self.wrap(17,
359                '  <!-- DEPRECATED: The "%s" attribute of "%s" '
360                'has been deprecated %s -->' % (att, element, deprecated),0))
361    
362    
363          descr = self.default(self.xmlElements[element]['Attributes'][att],          descr = self.default(self.xmlElements[element]['Attributes'][att],
364                           'Description','')                           'Description','')
365          if len(descr):          if len(descr):
366            self.dest.write(self.wrap(7,            self.dest.write(self.wrap(7,
367              '  <!-- %s -->' % (description), 0))              '  <!-- %s: %s -->' % (att, descr), 0))
368    
369          datatype = self.default(          datatype = self.default(
370               self.xmlElements[element]['Attributes'][att],               self.xmlElements[element]['Attributes'][att],
371               'Typecast',GParser.char)               'Typecast',GTypecast.text)
372    
373          if datatype == int:          if datatype == int:
374            tokentype = "%number;"            tokentype = "%number;"
375          else:          else:
376            tokentype = "NMTOKEN"            tokentype = "NMTOKEN"
377    
378          # handle bool attributes specially          # handle bool attributes specially
379          if datatype == GParser.bool:          if datatype == GTypecast.boolean:
380            self.dest.write(self.wrap(len(attdef),attdef +'%boolean;>',0))            self.dest.write(self.wrap(len(attdef),attdef +'%boolean;>',0))
381    
382          elif set != None:          elif set != None:
383            set = set.keys()            set = set.keys()
384            set.sort()            set.sort()
385            if len(set) == 1:            if len(set) == 1:
386              indent = len(attdef)              indent = len(attdef)
387              attdef = attdef + '%s #FIXED "%s">' \              attdef = attdef + '%s #FIXED "%s">' \
388                  % (self.typecasts[datatype], set[0])                  % (self.typecasts[datatype], set[0])
389            else:            else:
390              attdef = attdef + "("              attdef = attdef + "("
391              indent = len(attdef)              indent = len(attdef)
392              attdef = attdef + "%s)" % string.join(set, ' | ')              attdef = attdef + "%s)" % string.join(set, ' | ')
393              if dflt != None and len(dflt):              if dflt != None and len(dflt):
394                attdef = attdef + ' "%s">' % dflt                attdef = attdef + ' "%s">' % dflt
395              else:              else:
396                attdef = attdef + ' #IMPLIED>'                attdef = attdef + ' #IMPLIED>'
397            self.dest.write(self.wrap(indent, attdef, 0))            self.dest.write(self.wrap(indent, attdef, 0))
398    
399          elif refs != None:          elif refs != None:
400            indent = len(attdef)            indent = len(attdef)
401            if req:            if req:
402              attdef = attdef + ' IDREF #REQUIRED>'              attdef = attdef + ' IDREF #REQUIRED>'
403            else:            else:
404              attdef = attdef + ' IDREF #IMPLIED>'              attdef = attdef + ' IDREF #IMPLIED>'
405            self.dest.write(self.wrap(indent, attdef, 0))                      self.dest.write(self.wrap(indent, attdef, 0))
406    
407          elif unq:          elif unq:
408            indent = len(attdef)            indent = len(attdef)
409            if req:            if req:
410              attdef = attdef + ' ID #REQUIRED>'              attdef = attdef + ' ID #REQUIRED>'
411            else:            else:
412              attdef = attdef + ' ID #IMPLIED>'              attdef = attdef + ' ID #IMPLIED>'
413            self.dest.write(self.wrap(indent, attdef, 0))            self.dest.write(self.wrap(indent, attdef, 0))
414    
415          elif dflt != None:          elif dflt != None:
416            indent = len(attdef)            indent = len(attdef)
417            attdef = attdef + ' %s #DEFAULT "%s">' \            attdef = attdef + ' %s "%s">' \
418                % (self.typecasts[datatype], dflt)                % (self.typecasts[datatype], dflt)
419            self.dest.write(self.wrap(indent, attdef, 0))            self.dest.write(self.wrap(indent, attdef, 0))
420    
421          else:          else:
# Line 399  class GenerateDTD: Line 431  class GenerateDTD:
431            
432      self.dest.write ("\n")      self.dest.write ("\n")
433    
434  if len(sys.argv) > 1:  if len(sys.argv) > 1:
435    GenerateDTD(sys.argv[1])    try:
436  else:      dest = open(sys.argv[2],'w')
437      except IndexError:
438        dest = sys.stdout
439      GenerateDTD(sys.argv[1], dest)
440      dest.close()
441    else:
442    GenerateDTD(None)    GenerateDTD(None)

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26