Hi all

I'm working lately with cross references in version 9.7 and 10.3. At the beginning I found it useful to know which elements are used by my start-up shell. Then I tried to apply it to the customer's real world (a repository from version 6). Useless. Everything is used by everything. And this statement is not true. 

The problem appears because there are some common components that are re-used everywhere. In theory it should be no problem here because the referer only call a few operations of these common components. So, it is perfectly possible to know which descendants are currently used. 

But then enter in scene Local Proc Modules. As far as I analyze it, there is no possibility to know who is calling local procs.

Let's say component Z have this code:

activate "A".DoB

And let's say A has 2 operations DoB, and DoC; and a local proc (and even a collection operation that activates "E").

operation DoB
	activate "B".exec()
operation DoC
	activate "C".exec()
	call LP_ExtraDoC
entry LP_ExtraDoC
	activate "D".exec()

If I use cross references to know which dependencies have component Z, what I expected to get is: Z, A, and B (blue path in diagram). Of course, A is able to call B, C, D and E... but when doB is the enter point, none of C, D or E are currently needed.

Reading cross-references (in UXCROSS), I find the local procs definition. So, acording with the info in cross references I know that LP_ExtraDoC exists in component A, and also that calls operation exec of component D. But I don't find the way to know who is calling LP_ExtraDoC.

Another example, if I try to know dependecies of A.DoC, I am able to find a call to operation exec of component C. But there is no reference in cross-references to LP_ExtraDoc.

So, to be sure to include all dependencies, I have to add any local proc defined in any component. And this produces a nuclear reaction in real-world projects. In typical repositories with several startup-shells it is very common that subsystems are not really splited. In fact, there are a lot of interdependencies between them. It started someday when somebody wrote an activate to another subsystem and it worked and nobody say nothing.

Am I missing something?

Is there a way to call $ude("getReferenceList") to get a limited list of real referred items?

Note: in symbol table files it does appear who calls local procs. So that info exists in files (although not in UXCROSS).

Note2: if you call a non-existent local proc (call LP_I_DO_NOT_EXISTS) the compilation process includes the reference Operation DoC → LP_I_DO_NOT_EXISTS (as GlobalProc). As soon as mistake is corrected writing an existent local proc, this occurrence disappears. (Uniface


    CommentAdd your comment...

    3 answers


      Hi Luis

      Nope, UnifAce itself will not document calls to component local entries (ENTRY) in UXCROSS
      Only links between components or global procedures are in UXCROSS (plus model&Co)

      But with symbol tavles and $ude, you will got much more info
      Generate all components in question with /lis=1 or /lis=3

      Then do a $1=$ude("load","symboltable;component","<compname>","")

      $2= $item("SYMBOLTAB",$1) gives you all references in this component
      You can loop over them by
      FOR $3 in $2
      putmess $replace($3,1,";"," ",-1)  ; Where ; is GOLD-; and " " ist "<tab>"

      Hope this hints helps you a little bit


        CommentAdd your comment...

        Thank you both

        $ude("load","symboltable;component","<compname>","") does what I was looking for. And it is better than directly reading the files. 

        To me, it is odd that these localProcModules are stored only in symbol table files but not included in UXCROSS.

        At this point, I will forget UXCROSS to focus on $ude("load", ...)

        Gianni, for "real" and "limited" I mean "not imaginary", "non fictitious"

        If you define a LocalProcModules in component CMP1 with

        entry LP_NON_USED
        	activate "CMP2".exec()

        Following info stored in UXCROSS, CMP2 is activated by CMP1. Although no line code is executing LP_NON_USED. This is unreal. UXCROSS skips internal dependencies to LocalProcModules, just include everything inside it as a reference.

        But, in symboltable files, it is said that LP_NON_USED is defined, it calls CMP2 but no one in CMP1 is currently calling LP_NON_USED. In other words, you can track the "real" possible dependencies because symbol table files do include internal dependencies to LocalProcModules. If it is used in trigger read, for example, it will be a reference connecting trigger read with LP_NON_USED.


          CommentAdd your comment...

          Hi Luis,

          I am trying to understand what you asked for with:
          "Is there a way to call $ude("getReferenceList") to get a limited list of real referred items?"

          Any XREF is a TREE.
          After pointing to a specific component|object in the tree, it is possible to navigate it in 3 directions:
          - down: going to sons and nephew (NULL if a leaf)
          - up: going to parents and grandparents (NULL when root)
          - same level: going to sisters|brothers (when available)

          - what do you mean for "real"? Could it be "Only related to context where $ude("getReferenceList") is called"?
          - what do you mean for "limited"? Could it be "Limited only to one level (up or down)"?

          Last but not least: couldn't you read UXCROSS directly?


            CommentAdd your comment...