• 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. LibManager Edit Trigger/Callback

Stats

  • Locked Locked
  • Replies 7
  • Subscribers 144
  • Views 6078
  • 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

LibManager Edit Trigger/Callback

dfick
dfick over 11 years ago

 Hi,

 In the Virtuoso Library Manager when a cellview is double-clicked, it automatically opens for edit. However, I would like some things to happen just before a cell view is opened for edit (make a backup copy, change file permissions, etc). Is there a way to set an event trigger or callback that occurs when a cellview is opened for edit? The only commands that I could find with similar functionary are "ccpPostExpandTrigger", which is trigger for copying files, and "cdsLibManager.main dblClickEditCellView", which is a flag enabling/disabling the double-click-to-edit functionality.

 Thanks

 Edit: I am using ic-6.1.5.500.16

  • Cancel
  • tweeks
    tweeks over 11 years ago

    dfick said:

    Is there a way to set an event trigger or callback that occurs when a cellview is opened for edit?

    Yes: In the Virtuoso Design Environment SKILL Reference, Chapter 3:

    * Read the section on Triggering Function Calls, and then look at

    * deGetAppInfo() under Design Editor SKILL Functions.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    Actually deRegUserTriggers is probably more likely to be useful. The other trigger that could be used ddRegTrigger, with a trigger type of:

         ; handle edit access
        ddRegTrigger("PreAutoCheckOut" 'ACLpreAutoCheckOutTrigger 1)

    I wrote an example years ago (1998!) which used this to limit edit access to cellViews using a simple access control list. No idea if this still works (it used to be on Sourcelink years ago, under the "Four Four Forum" which was a set of articles for people migrating from 4.3.X to 4.4.X)

    Regards,

    Andrew.

    /* ACL.il
    
    Author     A.D.Beckett
    Group      Custom IC, Cadence Design Systems Ltd.
    Machine    SUN
    Date       Dec 06, 1998 
    Modified   
    By         
    
    Example code to demonstrate a simple access control list
    mechanism using dd triggers in 4.4.X
    
    Uses PreObjAccess and PreAutoCheckout triggers which are
    available in IC443, but are also available in IC442 QSR3.
    
    The user is determined from the USER environment variable.
    
    The Access Control List file should be placed at the top level of
    a library, and called libACL.att
    
    See separate example of libACL.att.
    
    After loading this file, call ACLinit() to initialize the system
    and register all the triggers.
    
    ***************************************************
    
    SCCS Info: @(#) ACL.il 12/07/98.10:58:01 1.1
    
    */
    
    /*************************************************************************
    *                                                                        *
    *                        ACLreadACLfile(fileName)                        *
    *                                                                        *
    * Read the access control list file from the passed in filename. Doesn't *
    *    do any checking to see if the file exists. Returns the ACL dpl.     *
    *                                                                        *
    *************************************************************************/
    
    procedure(ACLreadACLfile(fileName)
        let((prt acl)
            when(prt=infile(fileName)
                while((acl=lineread(prt)) && acl==t t)
                close(prt)
                car(acl)
                ); when
            ); let
        ); procedure
    
    /***************************************************************************
    *                                                                          *
    *                          ACLreadLibACL(libName)                          *
    *                                                                          *
    * Read the ACL file for the specified library, if it exists. The resulting *
    *                       data is stored in the table.                       *
    *                                                                          *
    ***************************************************************************/
    
    procedure(ACLreadLibACL(libName)
        let((libObj fileName)
            when(libObj=ddGetObj(libName)
                sprintf(fileName "%s/libACL.att" libObj->readPath)
                when( isFile(fileName)
                    ACLdatabase[libName]=ACLreadACLfile(fileName)
                    ); when
                ); when
            ); let
        ); procedure
    
    /**********************************************************************
    *                                                                     *
    *               ACLisUserNameInACL(userName acl groups)               *
    *                                                                     *
    *     Check to see if the username is in the list of entries for      *
    * this access control list, either directly or as the result of being *
    *                        in one of the groups.                        *
    *                                                                     *
    **********************************************************************/
    
    procedure(ACLisUserNameInACL(userName acl groups)
        exists(entry acl
            entry==userName ||
            member(userName cdr(assoc(entry groups)))
            ) && t  ; coerced to be t if true, rather than remainder of acl
        ); procedure
    
    /***************************************************************************
    *                                                                          *
    *                  ACLvalidateUser(libName viewName mode                   *
    *               @optional (userName getShellEnvVar("USER")))               *
    *                                                                          *
    * For a named library and viewName, and access mode one of 'edit or 'read, *
    *    check to see whether the user is allowed that type of access based    *
    *   on the access control list information stored in the libACL.att for    *
    *       that library. This is the main validation function which is        *
    *                        called from the triggers.                         *
    *                                                                          *
    ***************************************************************************/
    
    procedure(ACLvalidateUser(libName viewName mode 
                                @optional (userName getShellEnvVar("USER")))
        let((libACL viewDPL acl)
            libACL=ACLdatabase[libName]
            if(libACL
                then
                    ; find the matching view info
                    viewDPL=car(exists(dpl libACL->views 
                        rexMatchp(sprintf(nil "^%s$" car(dpl)) viewName)
                        ))
                    acl=get(viewDPL mode)
                    ; t is a special value which means everyone
                    acl==t || ACLisUserNameInACL(userName acl libACL->groups)
                else
                    ; if no ACL data for this library, default is wide open
                    t
                ); if
            ); let
        ); procedure
    
    /***************************************************************
    *                                                              *
    *                          ACLinit()                           *
    *                                                              *
    *  Initialise the lookup table for the ACL info, and register  *
    *                      all the triggers.                       *
    *                                                              *
    ***************************************************************/
    
    procedure(ACLinit()
        ; database is going to be indexed by library name
        ACLdatabase=makeTable("ACL data" nil)
        ddRegTrigger("FirstAccessLib" 'ACLfirstAccessLibTrigger 1)
        ddRegTrigger("PostUpdateLibList" 'ACLpostUpdateLibListTrigger 1)
        ; handle read access
        ddRegTrigger("PreObjAccess" 'ACLpreObjAccessTrigger 1)
        ; handle edit access
        ddRegTrigger("PreAutoCheckOut" 'ACLpreAutoCheckOutTrigger 1)
        ); procedure
    
    /**************************************************************************
    *                                                                         *
    *                ACLfirstAccessLibTrigger(@optional libId)                *
    * The FirstAccessLib trigger is used to load the libACL.att file when the *
    *                library is first accessed (if it exists)                 *
    *                                                                         *
    **************************************************************************/
    
    procedure(ACLfirstAccessLibTrigger(@optional libId)
        libId && errset(ACLreadLibACL(libId->name))
        ; make sure we return t - otherwise stops other FirstAccessLib triggers
        ; from running
        t
        ); procedure
    
    /*********************************************************************
    *                                                                    *
    *              ACLpostUpdateLibListTrigger(@rest args)               *
    *                                                                    *
    * The PostUpdateLibList trigger is used to reload all the libACL.att *
    *    files when the library list is updated. This means that when    *
    *   File->Refresh is invoked, the ACLs will be reloaded from disk.   *
    *                                                                    *
    *********************************************************************/
    
    procedure(ACLpostUpdateLibListTrigger(@rest args)
        foreach(libId ddGetLibList()
            libId && errset(ACLreadLibACL(libId->name))
            )
        ; return t for good measure
        t
        ); procedure
    
    /***************************************************************
    *                                                              *
    *  ACLpreObjAccessTrigger(@optional libName cellName viewName  *
    *                   fileName contextId mode)                   *
    *                                                              *
    * The PreObjAccess just checks that it's a cellView or one of  *
    *  the files within the cellView that is being accessed, and   *
    *   then sees whether the user has rights to open it in that   *
    *       mode. Note that edit access implies read access.       *
    *                                                              *
    ***************************************************************/
    
    procedure(ACLpreObjAccessTrigger(@optional libName cellName viewName 
                                    fileName contextId mode)
        if( libName && cellName && viewName
            then
                if( ACLvalidateUser(libName viewName 'edit)||
                    (!mode||(stringp(mode) && substring(mode 1 1)=="r"))&&
                    ACLvalidateUser(libName viewName 'read)
                    then
                        ; access is validated - return t
                        t
                    else
                        printf("ACL: You are not allowed to edit/read %s/%s/%s\n"
                            libName
                            cellName
                            viewName
                            )
                        ; access is disallowed - return nil
                        nil
                    ); if
            else
                ; if not something we're interested in, validate the access
                t
            ); if
        ); procedure
    
    /***********************************************************************
    *                                                                      *
    *         ACLpreAutoCheckOutTrigger(@optional objList isBatch)         *
    *                                                                      *
    *  The PreAutoCheckOut trigger is called prior to something be opened  *
    * for edit to check whether it needs checking out or not. This trigger *
    * checks whether the user is allowed to open it for edit, and returns  *
    * a list of t's and nil's for each of the cellViews passed to indicate *
    *                whether "checkout" is allowed or not.                 *
    *                                                                      *
    ***********************************************************************/
    
    procedure(ACLpreAutoCheckOutTrigger(@optional objList isBatch)
        ; generate a list of t's and nil's corresponding to the objList
        ; passed in
        foreach(mapcar obj objList
            if(obj->type=='ddViewType
                then
                    if(ACLvalidateUser(obj->lib->name obj->name 'edit)
                        then
                            ; "checkout" is validated
                            t
                        else
                            printf("ACL: You are not allowed to edit %s/%s/%s\n"
                                obj->lib->name
                                obj->cell->name
                                obj->name
                                )
                            ; edit access not allowed - invalidate the checkout
                            nil
                        ); if
                else
                    ; if it's an object we're not concerned with, allow access
                    t
                )
            ); foreach
        ); procedure
    
    


     

    Here's an example of a libACL.att file:

    /* libACL.att
    
    Author     A.D.Beckett
    Group      Custom IC, Cadence Design Systems Ltd.
    Machine    SUN
    Date       Dec 06, 1998 
    Modified   
    By         
    
    This contains a disembodied property list representing
    this library's access control list information. There are
    two slots in the DPL, groups and views. The "groups" slot has as its
    value an assoc list of groups, each keyed by the name of
    the group, and the remainder of the list a list of user names.
    The "views" slot has a list of view name entries. Each of these is
    of the form
    
    (pattern
      edit list_of_group_or_user_names
      read list_of_group_or_user_names
    )
    
    The pattern is a regular expression; for example, "layout.*" matches
    all view names beginning with "layout". The list of group or user names
    may also be set to be the value t - which means that anything matches.
    
    ***************************************************
    
    */
    
    (nil
        groups (
    	; three groups of people
    	("Project Leaders" "andrew")
    	("Designers" "louis" "norman")
    	("Layouters" "rob" "lawrence")
        )
        views (
    	; layout views
    	("layout.*"
    	    edit ("Project Leaders" "Layouters")
    	    read ("Designers")
    	)
    	; schematic views - editable by proj leaders, designers and an
    	; extra user, rdm.
    	("schematic"
    	    edit ("Project Leaders" "Designers" "rob")
    	    read ("Layouters")
    	)
    	; any other viewname is only editable by the proj leaders, but
    	; readable by anyone
    	(".*"
    	    edit ("Project Leaders")
    	    ; t is a special value which means accessible by anyone
    	    read t
    	)
        )
    )
    
    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    What do you use to HTML-ify your SKILL?  It always looks so nice!

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 11 years ago

    Tom,

    I have a little CGI script that I use, which is just a wrapper around enscript. enscript supports HTML output and has a SKILL mode (I did find some issues with it a few years ago, and submitted some updates to get them fixed which I think were accepted; I can't remember because it was a long time ago).

    #!/bin/sh
    #
    # Author     A.D.Beckett
    # Group      Custom IC, Cadence Design Systems Ltd
    # Machine    SUN
    # Date       Mar 18, 2010
    # Modified
    # By
    #
    # Simple CGI script to format SKILL code so it is colour coded
    #
    # SCCS Info: @(#) format.cgi 03/18/10.18:21:05 1.2

    if [ -z $QUERY_STRING ]; then
       echo "No file"
    elif [ -r $QUERY_STRING ]; then
       echo "Content-type: text/html"
       echo ""
       /grid/common/pkgs/enscript/v1.6.5.1/bin/enscript --color --language=html -Eskill --output=- $QUERY_STRING
    fi

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • tweeks
    tweeks over 11 years ago

    Hey, that's cool!  Thanks for sharing!

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • dfick
    dfick over 11 years ago

     Thanks, I distilled your example down to a smaller case that does what I need. Before auto-checkout it checks the views to see if they need to be set to editable, so on read it wont do anything, on write-but-already-editable it wont do anything, but on write-but-not-editable it is ready to do something.


    procedure(triggerPing(@optional objList isBatch)

           foreach(mapcar obj objList
                if(obj->type != 'ddViewType
                      then
                            t ; only check for view types
                      else
                            access_modes = ddGetObjAccess(obj "o")
                            rexCompile("w")
                            is_writable = rexExecute(access_modes)

                            if(is_writable
                                then
                                     printf("View is already editable\n")
                                     t ; don't need to do anything
                                else
                                     printf("Need to set edit mode\n")
                                     printf("PING\n");
                                     t
                            )
                 )
           )


    ddRegTrigger("PreAutoCheckOut" `triggerPing)

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • dfick
    dfick over 11 years ago

     Actually, I cannot quite get ddGetObjAccess or ddGetObjAccessEx to properly check the permissions of the view. Sometimes it thinks everything can be written, sometimes it thinks nothing can, but it definitely isn't matching the correct unix permissions.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel

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