#
# recursedlls.awk
#
# input:
#   name0 name1 name2 name3 name4 component ...
#
# recursively traverses the component dependency files, putting out dll
# dependencies of the comp<n>
#
# intended for a build using dlls
#
# if in the recursion we find a component that is a dll, we put out its
# name and don't go deeper
#
# if there're any repetitions, all but the last are suppressed
#
#
# we decide if a given component is a dll by the existence of a file
# whose name is the concatenation of
#   name0
#   <component without diversity>
#   name1
#
# the component dependency files are found at the concatenation of
#   name2
#   <component without diversity>
#   name3
#   <component without diversity>
#   name4

BEGIN {
    # phase
    #      0:  looking for name0
    #      1:  looking for name1
    #      2:  looking for name2
    #      3:  looking for name3
    #      4:  looking for name4
    #	   5:  looking for name5
    #	   6:  looking for root array; the end is "SEPARATOR"
    #   else:  looking at component names
    phase = 0
}

function doWord(word, dll, file, n, line, words, i, dllbinaryrel, envword, libdir)# local: dll, file, n, line, words, i, dllbinaryrel, envword, libdir
{
    # if this component is a dll, we add it to the list
    # otherwise we recurse
    #
    # remove trailing diversity stuff

    sub(/_.*/, "", word)

    # if we've looked for this dll before, we don't need to look again

    if (!dllTried[word])
    {
        dllTried[word] = 1
        dll = name0 word name1
        libdir = name3
	libdir1 = name5
        sub ("tmp", "lib", libdir);
	sub ("tmp", "lib", libdir1);
        seendll = 0
	if (name1==".lib"){ 						# nt,ce case
        	dllbinaryrel = root_loc[word] libdir word name1
	}
	else{ 								# tm,linux case
        	dllbinaryrel = root_loc[word] libdir "lib" word name1		
        }
	
	if (name1==".lib"){ 						# nt,ce case
		dllbinaryreldef = root_loc[word] libdir1 word name1
		}
		else{ 								# tm,linux case
		dllbinaryreldef = root_loc[word] libdir1 "lib" word name1
	}
	
#	printf(" spl %s\n", dllbinaryrel)
        dllFound[word] = ((getline line < dll) != -1)
        close(dll)
        if (!dllFound[word]){						# for a binary delivery
        	dllFound[word] = ((getline line < dllbinaryrel) != -1)
	        close(dllbinaryrel)
        }
        if (!dllFound[word]){						# for a binary delivery
        	dllFound[word] = ((getline line < dllbinaryreldef) != -1)
	        close(dllbinaryreldef)
        }
    }
    if (dllFound[word])
    {
        # there was a dll file

        # wordLast[string word] holds the word sequence number of the
        # last occurence of the string word
        #
        # wordSeq[number] holds the word whose sequence number is number

        nWords++
        wordLast[word] = nWords
        wordSeq[nWords] = word
    }
    else
    {
        # recurse into the file

        # fileSeen[string word] is 1 if we've already read this file
        #
        # if we've seen it, then:
        #   fileWords[word, 0] is the number of words from the file
        #   fileWords[word, 1]..file are the words from the file

        if (!fileSeen[word])
        {
            # we've never seen this file; load up fileWords

            fileSeen[word] = 1
            fileWords[word, 0] = 0
            res1 = 0

            file = name2 "comps/" word name3 word name4


            res = (getline line < file)
            if (res == -1){
            	res1 = -1
            }
            while (res > 0)
            {

                n = split(line, words)
                for (i = 1; i <= n; i++)
                {
                    fileWords[word, ++fileWords[word, 0]] = words[i]
                }
                res = (getline line < file)
            }
            close(file)


            file = name2 "intfs/" word name3 word name4

            res = (getline line < file)
            if ((res == -1) && (res1 == -1)){
               printf("ERR_L_%s\n",word);
            }
            while (res > 0)
            {

                n = split(line, words)
                for (i = 1; i <= n; i++)
                {
                    fileWords[word, ++fileWords[word, 0]] = words[i]
                }
                res = (getline line < file)
            }
            close(file)
        }

        # Here we are looking for 'new-created' circular dependencies started from word
        # If they are present ...
        depnumber = 0; #starting from clean circular checks
        deptest=0;
        for (i = 1; i <= fileWords[word, 0]; i++)
        {
            deparray[depnumber] = fileWords[word, i];
            sub(/_.*/, "", deparray[depnumber++]);
        }
        while (deptest<depnumber){
           	if (word==deparray[deptest]){ #circular dependency is detected.
           	  deptest = depnumber+1;
                  printf("ERR_CIRC_COMPS_%s\n",nsfx);
            } 
            else{
              if (deparray[deptest]){
                for (i = 1; i <= fileWords[deparray[deptest], 0]; i++)
                {
                  deparray[depnumber] = fileWords[deparray[deptest], i];
                  sub(/_.*/, "", deparray[depnumber++]);
                }
              }
            }
            deptest++;
        }
    
        # Recursively search for the libraries if there are no circular dependencies.
    
        if (depnumber==deptest){
          for (i = 1; i <= fileWords[word, 0]; i++)
          {
              doWord(fileWords[word, i])
          }
        }
    }
}

{
    n = split($0, words)

    for (i = 1; i <= n; i++)
    {
        if (phase == 0)
        {
            name0 = words[i]
            phase = 1
        }
        else if (phase == 1)
        {
            name1 = words[i]
            phase = 2
        }
        else if (phase == 2)
        {
            name2 = words[i]
	    phase = 3
        }
        else if (phase == 3)
        {
            name3 = words[i]
            phase = 4
        }
        else if (phase == 4)
        {
            name4 = words[i]
            phase = 5
        }
	else if (phase == 5)
        {
            name5 = words[i]
            phase = 6
        }
	else if (phase == 6)
        {
            name6 = words[i]
	    loc_list = (getline loc_list_line < name6)
	    while (loc_list > 0)
            {
		loc=1
                nu = split(loc_list_line, words1)
	        while (loc<nu)
		{
            		root_loc[words1[loc]]=words1[loc+1]
	            	loc+=2
		}	
                loc_list = (getline loc_list_line < name6)
            }
            close(loc_listfile)
            phase = 7
        }
        else
        {
           doWord(words[i])
        }
    }
}

END {
    # walk through the whole sequence, dumping a word if it's the last
    # occurrenc of that word
    for (i = 1; i <= nWords; i++)
    {
        if (wordLast[wordSeq[i]] == i)
        {
           printf("%s\n", wordSeq[i])
        }
    }
}
