• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC SKILL
  3. XML in SKILL

Stats

  • Locked Locked
  • Replies 11
  • Subscribers 144
  • Views 20557
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

XML in SKILL

ToMWUT
ToMWUT over 16 years ago
Hello All,
In my SKILL++ application I have to store some configuration data on my local hard drive. My question now is how to do this? In standard programming languages I’d use an XML file. Is it possible to use XML in SKILL or maybe I would have to write all parsing of the XML by my own? If the last possibility is valid than only simple text file (values separated by ; for example) is left as a solution, am I right?
Thanks,
ToM
  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 16 years ago

    Hi ToM,

    A while back, I wrote a little package to write HTML, and I recently extended this to support writing of XML. This code is SKILL++ code, and is written in LISP syntax (please use the attachment rather than cutting and pasting the code, as it has been slightly mangled on the forum):

    /* abHtml.ils
    
    vim:syntax=skill
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Jul 26, 2006 
    Modified   Jun 24, 2009 
    By         
    
    Package for easily creating HTML. The API is modelled on the 
    perl CGI package, so anyone used to that package should find
    this easy to use.
    
    Limitations: 
    
    a) Doesn't support any form tags at the moment (no
       particular reason why it couldn't, just didn't implement
       them as this is more likely to be used to create static pages)
    b) Only the most common tags are implemented - although it is
       trivial to add support for a tag
    
    Added better support for XML (can be done with the same API) in
    version 1.3 (can specify whatever tags you like when you call
    abHtml - e.g. abHtml("tag1" "tag2" "tag3")). Also added a ->start_xml
    method. Now also supports tags with no content - e.g. 
    
    ***************************************************
    
    SCCS Info: @(#) abHtml.ils 06/24/09.22:11:08 1.4
    
    */
    
    ;------------------------------------------------------------------------
    ; For efficiency of function lookup, define a structure
    ; with all the "methods" that the closure will return
    ;------------------------------------------------------------------------
    (defstruct abHtmlObj 
      start_html end_html start_xml escapeHTML
      h1 h2 h3 h4 p span 
      blockquote div hr pre br center 
      a img
      ; formatted lists
      dl dd dt ol ul li
      ; table tags
      table tr td th
      ; content-based tags
      cite code 
      )
    
    (defun abHtml (@rest addTags)
      ;----------------------------------------------------------------------
      ; Internal function that is used for most of the tags. This processes all 
      ; the keyword arguments, and builds the tag parameters. Also supports
      ; special boolean arguments ?begin and ?end to indicate that just the
      ; beginning and end tag should be generated. The default is both.
      ;----------------------------------------------------------------------
      (defun htmlTag (tag args)
        (let ((tagParams "") tagBody (completeTag "") param arg beginOnly endOnly )
          (rexCompile "^?")
          (while args
    	     (setq arg (car args))
    	     ;-----------------------------------------------------------
    	     ; If the argument begins with a question mark
    	     ;-----------------------------------------------------------
    	     (if (and (symbolp arg) (rexExecute arg))
    	       (progn  ; then
    		 ;-------------------------------------------------------
    		 ; Find the parameter name, and then move the argument
    		 ; pointer on one
    		 ;-------------------------------------------------------
    		 (setq param (rexReplace (get_string arg) "" 0))
    		 (setq args (cdr args))
    		 (setq arg (car args))
    		 ;-------------------------------------------------------
    		 ; Do any handling of special parameters, such as begin and
    		 ; end
    		 ;-------------------------------------------------------
    		 (case param
    		   ("begin"
    		    (setq beginOnly arg))
    		   ("end"
    		    (setq endOnly arg))
    		   (t
    		     (sprintf tagParams "%s %s=%L" tagParams param arg)
    		     )
    		   ) ; case
    		 )
    	       ; else
    	       (if (listp arg)
    		 ; then - flatten list
    		 (foreach subArg arg
    			  (setq tagBody (tconc tagBody subArg))
    			  )
    		 ; otherwise collect the argument for the body of the tag.
    		 (setq tagBody (tconc tagBody arg))
    		 ) ; if listp
    	       ) ; if
    	     ;-----------------------------------------------------------
    	     ; Move arguments along
    	     ;-----------------------------------------------------------
    	     (setq args (cdr args))
    	     ) ; while
    
          (if (or (car tagBody) endOnly beginOnly)
    	;----------------------------------------------------------------
    	; If the tag has any content, or just begin or end requested
    	;----------------------------------------------------------------
    	(progn
    	  (unless endOnly
    	    (sprintf completeTag "<%s%s>" tag tagParams)
    	    )
    	  (setq completeTag
    		(strcat completeTag (buildString (car tagBody)))
    		)
    	  (unless beginOnly
    	    (sprintf completeTag "%s" completeTag tag)
    	    )
    	  )
    	;----------------------------------------------------------------
    	; Otherwise can do the compact tag which is self-closing
    	;----------------------------------------------------------------
    	(sprintf completeTag "<%s%s/>" tag tagParams)
    	)
          completeTag
          ) ; let
        ) ; defun htmlTag
    
      ;----------------------------------------------------------------------
      ; Function to start the HTML code. Supports passing of a title,
      ; and style sheets - either by a src reference or a code string,
      ; and a class for the main body
      ;----------------------------------------------------------------------
      (defun start_html (@key title styleCode styleSrc class)
        (let (code)
          (setq code "\n")
          (setq code (strcat code "\n"))
          (when title
    	(sprintf code "%s%s\n" code title)
    	)
          (when styleSrc
    	(sprintf code "%s"
    		 code styleSrc)
    	)
          (when styleCode
    	(sprintf code "%s"
    		 code styleCode)
    	)
          (setq code (strcat code ""))
          (setq code (strcat code
    			 (if class 
    			   (sprintf nil "\n" class)
    			   "\n"
    			   )))
          code
          )
        )
    
      ;----------------------------------------------------------------------
      ; Function to start XML code. Currently just convenience, and can
      ; also reference an XSLT stylesheet
      ;----------------------------------------------------------------------
      (defun start_xml (@key xslStylesheet)
        (let (code)
          (setq code "\n")
          (when xslStylesheet
    	(sprintf code "%s\n"
    		 code xslStylesheet
    		 )
    	)
          code
          )
        )
    
      ;----------------------------------------------------------------------
      ; End the HTML
      ;----------------------------------------------------------------------
      (defun end_html ()
        "\n\n"
        )
    
      ;----------------------------------------------------------------------
      ; Function for escaping reserved characters in HTML strings
      ;----------------------------------------------------------------------
      (defun escapeHTML (string)
        (rexCompile "&")
        (setq string (rexReplace string "\\&" 0))
        (rexCompile "<")
        (setq string (rexReplace string "\\<" 0))
        (rexCompile ">")
        (setq string (rexReplace string "\\>" 0))
        string
        )
    
      ;----------------------------------------------------------------------
      ; Create and return the object which provides the "methods" for
      ; the html object. Supports a bunch of builtin methods for HTML
      ; as well as being able to add custom tags for XML, for example.
      ;----------------------------------------------------------------------
      (let (obj)
        (setq obj
    	  (make_abHtmlObj
    	    ?start_html start_html
    	    ?start_xml start_xml
    	    ?end_html end_html
    	    ?escapeHTML escapeHTML
    	    ?h1  (lambda (@rest args) (htmlTag "h1" args))
    	    ?h2  (lambda (@rest args) (htmlTag "h2" args))
    	    ?h3  (lambda (@rest args) (htmlTag "h3" args))
    	    ?h4  (lambda (@rest args) (htmlTag "h4" args))
    	    ?p  (lambda (@rest args) (htmlTag "p" args))
    	    ?span  (lambda (@rest args) (htmlTag "span" args))
    	    ?blockquote  (lambda (@rest args) (htmlTag "blockquote" args))
    	    ?div  (lambda (@rest args) (htmlTag "div" args))
    	    ?hr  (lambda (@rest args) (htmlTag "hr" args))
    	    ?pre  (lambda (@rest args) (htmlTag "pre" args))
    	    ?br  (lambda (@rest args) (htmlTag "br" args))
    	    ?center  (lambda (@rest args) (htmlTag "center" args))
    	    ?a  (lambda (@rest args) (htmlTag "a" args))
    	    ?img (lambda (@rest args) (htmlTag "img" args))
    	    ?dl  (lambda (@rest args) (htmlTag "dl" args))
    	    ?dd  (lambda (@rest args) (htmlTag "dd" args))
    	    ?dt  (lambda (@rest args) (htmlTag "dt" args))
    	    ?ol  (lambda (@rest args) (htmlTag "ol" args))
    	    ?ul  (lambda (@rest args) (htmlTag "ul" args))
    	    ?li (lambda (@rest args) (htmlTag "li" args))
    	    ?table  (lambda (@rest args) (htmlTag "table" args))
    	    ?tr  (lambda (@rest args) (htmlTag "tr" args))
    	    ?td  (lambda (@rest args) (htmlTag "td" args))
    	    ?th (lambda (@rest args) (htmlTag "th" args))
    	    ?cite  (lambda (@rest args) (htmlTag "cite" args))
    	    ?code  (lambda (@rest args) (htmlTag "code" args))
    	    )
    	  )
        (foreach tag addTags
    	     ;-----------------------------------------------------------
    	     ; Need to create a lexically scoped variable - the local
    	     ; variable in foreach is not lexically scoped, it seems
    	     ;-----------------------------------------------------------
    	     (let ((scopeTag tag))
    	       (putprop obj (lambda (@rest args) (htmlTag scopeTag args))
    			(concat tag))
    	       )
    	     )
        obj
        ) ; let
      ) ; defun abHtml
    
    

    The idea is that you'd then use this (example in C-like syntax to simplify things for people not so familiar with LISP syntax):

    xml=abHtml("ROOT" "DATA" "INFO")
    xmlFile=outfile("out.xml")
    fprintf(xmlFile "%s" xml->start_xml())
    fprintf(xmlFile "%s\n"
      xml->ROOT(
         ?hello "world"
         ?attribute "value"
         xml->DATA(
    	xml->INFO(?myAttrib "val1")
         )
      )
    )
    close(xmlFile)
    

    This produces output like this:

     <?xml version="1.0" encoding="UTF-8"?>
    <ROOT hello="world" attribute="value"><DATA><INFO myAttrib="val1"/></DATA></ROOT>

    I've not written anything to read XML in SKILL though. One possibility would be to transform it into something that looks more LISP-like, and then slurp that in using (say) lineread(). One idea that just occurred to me would be to write an XSLT style sheet to transform the XML, using xlstproc, and then parse that using lineread (which uses the SKILL parser). If I have a moment, I'll give that a try...

    The alternative, if you want to write data that is easy to read back in, is to write it as a list, and then use lineread to read it back in. For example, if I write this in a file:

    (nil
      library "mylib"
      cell "mycell"
      view "layout"
      works t
      expensive "very"
      )
    

    I can then read that in very simply:

    in=infile("config")
    data=lineread(in)
    data=car(data)
    close(in)
    

    and then data is a disembodied property list, so I can just do data->view and directly get "layout". 

    Let's hope all the formatting in this email gets preserved in the forum!

    Regards,

    Andrew.

     https://community.cadence.com/cfs-file/__key/communityserver-discussions-components-files/48/abHtml.ils

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 16 years ago

    Hi ToM,

    A while back, I wrote a little package to write HTML, and I recently extended this to support writing of XML. This code is SKILL++ code, and is written in LISP syntax (please use the attachment rather than cutting and pasting the code, as it has been slightly mangled on the forum):

    /* abHtml.ils
    
    vim:syntax=skill
    
    Author     A.D.Beckett
    Group      Custom IC (UK), Cadence Design Systems Ltd.
    Language   SKILL
    Date       Jul 26, 2006 
    Modified   Jun 24, 2009 
    By         
    
    Package for easily creating HTML. The API is modelled on the 
    perl CGI package, so anyone used to that package should find
    this easy to use.
    
    Limitations: 
    
    a) Doesn't support any form tags at the moment (no
       particular reason why it couldn't, just didn't implement
       them as this is more likely to be used to create static pages)
    b) Only the most common tags are implemented - although it is
       trivial to add support for a tag
    
    Added better support for XML (can be done with the same API) in
    version 1.3 (can specify whatever tags you like when you call
    abHtml - e.g. abHtml("tag1" "tag2" "tag3")). Also added a ->start_xml
    method. Now also supports tags with no content - e.g. 
    
    ***************************************************
    
    SCCS Info: @(#) abHtml.ils 06/24/09.22:11:08 1.4
    
    */
    
    ;------------------------------------------------------------------------
    ; For efficiency of function lookup, define a structure
    ; with all the "methods" that the closure will return
    ;------------------------------------------------------------------------
    (defstruct abHtmlObj 
      start_html end_html start_xml escapeHTML
      h1 h2 h3 h4 p span 
      blockquote div hr pre br center 
      a img
      ; formatted lists
      dl dd dt ol ul li
      ; table tags
      table tr td th
      ; content-based tags
      cite code 
      )
    
    (defun abHtml (@rest addTags)
      ;----------------------------------------------------------------------
      ; Internal function that is used for most of the tags. This processes all 
      ; the keyword arguments, and builds the tag parameters. Also supports
      ; special boolean arguments ?begin and ?end to indicate that just the
      ; beginning and end tag should be generated. The default is both.
      ;----------------------------------------------------------------------
      (defun htmlTag (tag args)
        (let ((tagParams "") tagBody (completeTag "") param arg beginOnly endOnly )
          (rexCompile "^?")
          (while args
    	     (setq arg (car args))
    	     ;-----------------------------------------------------------
    	     ; If the argument begins with a question mark
    	     ;-----------------------------------------------------------
    	     (if (and (symbolp arg) (rexExecute arg))
    	       (progn  ; then
    		 ;-------------------------------------------------------
    		 ; Find the parameter name, and then move the argument
    		 ; pointer on one
    		 ;-------------------------------------------------------
    		 (setq param (rexReplace (get_string arg) "" 0))
    		 (setq args (cdr args))
    		 (setq arg (car args))
    		 ;-------------------------------------------------------
    		 ; Do any handling of special parameters, such as begin and
    		 ; end
    		 ;-------------------------------------------------------
    		 (case param
    		   ("begin"
    		    (setq beginOnly arg))
    		   ("end"
    		    (setq endOnly arg))
    		   (t
    		     (sprintf tagParams "%s %s=%L" tagParams param arg)
    		     )
    		   ) ; case
    		 )
    	       ; else
    	       (if (listp arg)
    		 ; then - flatten list
    		 (foreach subArg arg
    			  (setq tagBody (tconc tagBody subArg))
    			  )
    		 ; otherwise collect the argument for the body of the tag.
    		 (setq tagBody (tconc tagBody arg))
    		 ) ; if listp
    	       ) ; if
    	     ;-----------------------------------------------------------
    	     ; Move arguments along
    	     ;-----------------------------------------------------------
    	     (setq args (cdr args))
    	     ) ; while
    
          (if (or (car tagBody) endOnly beginOnly)
    	;----------------------------------------------------------------
    	; If the tag has any content, or just begin or end requested
    	;----------------------------------------------------------------
    	(progn
    	  (unless endOnly
    	    (sprintf completeTag "<%s%s>" tag tagParams)
    	    )
    	  (setq completeTag
    		(strcat completeTag (buildString (car tagBody)))
    		)
    	  (unless beginOnly
    	    (sprintf completeTag "%s" completeTag tag)
    	    )
    	  )
    	;----------------------------------------------------------------
    	; Otherwise can do the compact tag which is self-closing
    	;----------------------------------------------------------------
    	(sprintf completeTag "<%s%s/>" tag tagParams)
    	)
          completeTag
          ) ; let
        ) ; defun htmlTag
    
      ;----------------------------------------------------------------------
      ; Function to start the HTML code. Supports passing of a title,
      ; and style sheets - either by a src reference or a code string,
      ; and a class for the main body
      ;----------------------------------------------------------------------
      (defun start_html (@key title styleCode styleSrc class)
        (let (code)
          (setq code "\n")
          (setq code (strcat code "\n"))
          (when title
    	(sprintf code "%s%s\n" code title)
    	)
          (when styleSrc
    	(sprintf code "%s"
    		 code styleSrc)
    	)
          (when styleCode
    	(sprintf code "%s"
    		 code styleCode)
    	)
          (setq code (strcat code ""))
          (setq code (strcat code
    			 (if class 
    			   (sprintf nil "\n" class)
    			   "\n"
    			   )))
          code
          )
        )
    
      ;----------------------------------------------------------------------
      ; Function to start XML code. Currently just convenience, and can
      ; also reference an XSLT stylesheet
      ;----------------------------------------------------------------------
      (defun start_xml (@key xslStylesheet)
        (let (code)
          (setq code "\n")
          (when xslStylesheet
    	(sprintf code "%s\n"
    		 code xslStylesheet
    		 )
    	)
          code
          )
        )
    
      ;----------------------------------------------------------------------
      ; End the HTML
      ;----------------------------------------------------------------------
      (defun end_html ()
        "\n\n"
        )
    
      ;----------------------------------------------------------------------
      ; Function for escaping reserved characters in HTML strings
      ;----------------------------------------------------------------------
      (defun escapeHTML (string)
        (rexCompile "&")
        (setq string (rexReplace string "\\&" 0))
        (rexCompile "<")
        (setq string (rexReplace string "\\<" 0))
        (rexCompile ">")
        (setq string (rexReplace string "\\>" 0))
        string
        )
    
      ;----------------------------------------------------------------------
      ; Create and return the object which provides the "methods" for
      ; the html object. Supports a bunch of builtin methods for HTML
      ; as well as being able to add custom tags for XML, for example.
      ;----------------------------------------------------------------------
      (let (obj)
        (setq obj
    	  (make_abHtmlObj
    	    ?start_html start_html
    	    ?start_xml start_xml
    	    ?end_html end_html
    	    ?escapeHTML escapeHTML
    	    ?h1  (lambda (@rest args) (htmlTag "h1" args))
    	    ?h2  (lambda (@rest args) (htmlTag "h2" args))
    	    ?h3  (lambda (@rest args) (htmlTag "h3" args))
    	    ?h4  (lambda (@rest args) (htmlTag "h4" args))
    	    ?p  (lambda (@rest args) (htmlTag "p" args))
    	    ?span  (lambda (@rest args) (htmlTag "span" args))
    	    ?blockquote  (lambda (@rest args) (htmlTag "blockquote" args))
    	    ?div  (lambda (@rest args) (htmlTag "div" args))
    	    ?hr  (lambda (@rest args) (htmlTag "hr" args))
    	    ?pre  (lambda (@rest args) (htmlTag "pre" args))
    	    ?br  (lambda (@rest args) (htmlTag "br" args))
    	    ?center  (lambda (@rest args) (htmlTag "center" args))
    	    ?a  (lambda (@rest args) (htmlTag "a" args))
    	    ?img (lambda (@rest args) (htmlTag "img" args))
    	    ?dl  (lambda (@rest args) (htmlTag "dl" args))
    	    ?dd  (lambda (@rest args) (htmlTag "dd" args))
    	    ?dt  (lambda (@rest args) (htmlTag "dt" args))
    	    ?ol  (lambda (@rest args) (htmlTag "ol" args))
    	    ?ul  (lambda (@rest args) (htmlTag "ul" args))
    	    ?li (lambda (@rest args) (htmlTag "li" args))
    	    ?table  (lambda (@rest args) (htmlTag "table" args))
    	    ?tr  (lambda (@rest args) (htmlTag "tr" args))
    	    ?td  (lambda (@rest args) (htmlTag "td" args))
    	    ?th (lambda (@rest args) (htmlTag "th" args))
    	    ?cite  (lambda (@rest args) (htmlTag "cite" args))
    	    ?code  (lambda (@rest args) (htmlTag "code" args))
    	    )
    	  )
        (foreach tag addTags
    	     ;-----------------------------------------------------------
    	     ; Need to create a lexically scoped variable - the local
    	     ; variable in foreach is not lexically scoped, it seems
    	     ;-----------------------------------------------------------
    	     (let ((scopeTag tag))
    	       (putprop obj (lambda (@rest args) (htmlTag scopeTag args))
    			(concat tag))
    	       )
    	     )
        obj
        ) ; let
      ) ; defun abHtml
    
    

    The idea is that you'd then use this (example in C-like syntax to simplify things for people not so familiar with LISP syntax):

    xml=abHtml("ROOT" "DATA" "INFO")
    xmlFile=outfile("out.xml")
    fprintf(xmlFile "%s" xml->start_xml())
    fprintf(xmlFile "%s\n"
      xml->ROOT(
         ?hello "world"
         ?attribute "value"
         xml->DATA(
    	xml->INFO(?myAttrib "val1")
         )
      )
    )
    close(xmlFile)
    

    This produces output like this:

     <?xml version="1.0" encoding="UTF-8"?>
    <ROOT hello="world" attribute="value"><DATA><INFO myAttrib="val1"/></DATA></ROOT>

    I've not written anything to read XML in SKILL though. One possibility would be to transform it into something that looks more LISP-like, and then slurp that in using (say) lineread(). One idea that just occurred to me would be to write an XSLT style sheet to transform the XML, using xlstproc, and then parse that using lineread (which uses the SKILL parser). If I have a moment, I'll give that a try...

    The alternative, if you want to write data that is easy to read back in, is to write it as a list, and then use lineread to read it back in. For example, if I write this in a file:

    (nil
      library "mylib"
      cell "mycell"
      view "layout"
      works t
      expensive "very"
      )
    

    I can then read that in very simply:

    in=infile("config")
    data=lineread(in)
    data=car(data)
    close(in)
    

    and then data is a disembodied property list, so I can just do data->view and directly get "layout". 

    Let's hope all the formatting in this email gets preserved in the forum!

    Regards,

    Andrew.

     https://community.cadence.com/cfs-file/__key/communityserver-discussions-components-files/48/abHtml.ils

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information