home *** CD-ROM | disk | FTP | other *** search
/ gdead.berkeley.edu / gdead.berkeley.edu.tar / gdead.berkeley.edu / pub / cad-tools / ciftomann.tar / CD / actions.c next >
C/C++ Source or Header  |  1988-01-28  |  32KB  |  1,055 lines

  1. /*
  2.  * actions.c
  3.  *
  4.  * Copyright -C- 1981 Giles C. Billingsley
  5.  * sccsid "%W%  %G%"
  6.  *
  7.  *     KIC is a graphics editor that was developed by the integrated
  8.  * circuits group of the Electronics Research Laboratory and the
  9.  * Department of Electrical Engineering and Computer Sciences at
  10.  * the University of California, Berkeley, California.  The program
  11.  * KIC is available free of charge to any interested party.
  12.  * The sale, resale, or use of this program for profit without the
  13.  * express written consent of the Department of Electrical Engineering
  14.  * and Computer Sciences, University of California, Berkeley, California,
  15.  * is forbidden.
  16.  */
  17.  
  18.  
  19. /*
  20.  * Action routines for fast CIF parser.
  21.  * 
  22.  * These routines handle both conversion from and to CIF.
  23.  * AEnd will be the last routine invoked in a successful parse.
  24.  */
  25.  
  26. #include "parser.h"
  27. #include "cd.h"
  28.  
  29. #ifdef vms
  30. #include <types.h>
  31. #include <timeb.h>
  32. #else
  33. #include <sys/types.h>
  34. #endif
  35.  
  36. #define    RADTODEG        57.29577951
  37.  
  38. static int CurrentLayer;
  39. static char TypeOut[200];
  40.  
  41.  
  42. /* Library routines */
  43. char *ctime();
  44. char *strcpy();
  45. double sin(), cos();
  46. #ifndef vms
  47. char *sprintf();
  48. #endif
  49.  
  50.  
  51. AEnd(){
  52.     /*
  53.      * The CIF parsing has ended.
  54.      */
  55. #ifdef TRACEPARSER
  56. GenEnd(stderr);
  57. #endif
  58.     }
  59.  
  60.  
  61. ABeginSymbol(SymbolNum,A,B)
  62.     int SymbolNum,A,B;
  63.     {
  64.     /*
  65.      * This routine begins the parsing action for a symbol definition
  66.      * and performs all necessary initialization for the new symbol.
  67.      *
  68.      * DCONTROLCDTO:
  69.      *    On the first pass, we add the symbol name to the symbol table
  70.      *    which is in CDDesc.dSymTabNames.  To do this we have to switch
  71.      *    according to the value of 'CDDesc.dProgram' which specifies
  72.      *    the style of the CIF.  On the second pass, we open the FILE
  73.      *    descriptor for the KIC cell that coresponds to the respective
  74.      *    CIF symbol and write the header information in the KIC cell.
  75.      *
  76.      * DCONTROLPCIF:
  77.      *    On the first pass, we add the symbol name to the symbol table
  78.      *    which is in CDDesc.dSymTabNames.  To do this we have to switch
  79.      *    according to the value of 'CDDesc.dProgram' which specifies
  80.      *    the style of the CIF.  Also, we open the symbol in the database
  81.      *    via CDOpen() which places the symbol name in the hash table
  82.      *    which is in CDSymbolTable.  We must not invoke CDClose since
  83.      *    that will remove the symbol from memory;  the purpose of
  84.      *    DCONTROLPCIF is to construct the database in memory without
  85.      *    relying on a KIC cell directory in the current search path.
  86.      *    On the second pass, we need only invoke CDSymbol() to obtain
  87.      *    the symbol desc. for the respective symbol.
  88.      *
  89.      * DCONTROLCDOPEN
  90.      *    No action.  It is assumed that the file being parsed is a KIC
  91.      *    cell which will always contain exactly one CIF symbol.
  92.      */
  93.     time_t Long1;
  94.     int Int1 = 0;
  95.  
  96. #ifdef TRACEPARSER
  97. GenBeginSymbol(stderr,SymbolNum,A,B);
  98. #endif
  99.     CurrentLayer = 0;
  100.     if(CDDesc.dControl == DCONTROLCDTO Or CDDesc.dControl == DCONTROLPCIF){
  101.     CDDesc.dRoot = False;
  102.     CDDesc.dDSA = A;
  103.     CDDesc.dDSB = B;
  104.         /*
  105.          * We switch on the following:
  106.          * k KIC:      A KIC symbol name follows a DS command as in 9 PadIn;
  107.          * a Stanford: Stanford symbol name follows a DS command as in (PadIn);
  108.          * b NCA:      An NCA symbol name follows a DS command as in (PadIn);
  109.          * h IGS:      An IGS symbol name follows a DS command as in 9 PadIn;
  110.          * i Icarus:   An Icarus name follows a DS command as in (9 PadIn);
  111.          * s Sif:      A Sif name follows a DS command as in (Name: PadIn);
  112.          * n none of the above
  113.          */
  114.     if(CDDesc.dProgram == 'i'){
  115.         /*
  116.          * Icarus files have the symbol name in a comment of the form
  117.          * (9 SymbolName); after the DS command.
  118.          */
  119.         loop {
  120.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  121.         if(PReturned == PFAILED)
  122.             return(PFAILED); 
  123.         elif(PChar == '9')
  124.             break;
  125.         }
  126.         loop {
  127.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  128.         if(PReturned == PFAILED)
  129.             return(PFAILED); 
  130.         elif(PChar == ')'){
  131.             CDDesc.dSymbolName[Int1] = EOS;
  132.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  133.             strcpy(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  134.                 CDDesc.dSymbolName);
  135.             CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  136.             ++CDDesc.dNumSymbolTable;
  137.             }
  138.             }
  139.         elif(PChar == ';')
  140.             break;
  141.         else {
  142.             if(Int1 < FILENAMESIZE)
  143.             CDDesc.dSymbolName[Int1++] = PChar;
  144.             }
  145.         }
  146.         }
  147.     elif(CDDesc.dProgram == 'a' Or CDDesc.dProgram == 'b'){
  148.         /*
  149.          * Some files have the symbol name in a comment of the form
  150.          * (SymbolName); after the DS command.
  151.          */
  152.         loop {
  153.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  154.         if(PReturned == PFAILED)
  155.             return(PFAILED); 
  156.         elif(PChar == '(')
  157.             break;
  158.         }
  159.         loop {
  160.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  161.         if(PReturned == PFAILED)
  162.             return(PFAILED); 
  163.         elif(PChar == ')'){
  164.             CDDesc.dSymbolName[Int1] = EOS;
  165.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  166.             strcpy(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  167.                 CDDesc.dSymbolName);
  168.             CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  169.             ++CDDesc.dNumSymbolTable;
  170.             }
  171.             }
  172.         elif(PChar == ';')
  173.             break;
  174.         else {
  175.             if(Int1 < FILENAMESIZE)
  176.             CDDesc.dSymbolName[Int1++] = PChar;
  177.             }
  178.         }
  179.         }
  180.     elif(CDDesc.dProgram == 's'){
  181.         /*
  182.          * Sif files have the symbol name in a comment of the form
  183.          * ( Name: SymbolName); after the DS command.
  184.          */
  185.         loop {
  186.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  187.         if(PReturned == PFAILED)
  188.             return(PFAILED); 
  189.         elif(PChar == ':')
  190.             break;
  191.         }
  192.         loop {
  193.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  194.         if(PReturned == PFAILED)
  195.             return(PFAILED); 
  196.         elif(PChar == ')'){
  197.             CDDesc.dSymbolName[Int1] = EOS;
  198.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  199.             strcpy(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  200.                 CDDesc.dSymbolName);
  201.             CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  202.             ++CDDesc.dNumSymbolTable;
  203.             }
  204.             }
  205.         elif(PChar == ';')
  206.             break;
  207.         else {
  208.             if(Int1 < FILENAMESIZE)
  209.             CDDesc.dSymbolName[Int1++] = PChar;
  210.             }
  211.         }
  212.         }
  213.     elif(CDDesc.dProgram == 'q'){
  214.         /*
  215.          * SQUID files have the symbol name in the form 
  216.          * 9 FullName; after the DS command where FullName
  217.          * is the full pathname to the cell or directory.
  218.          *
  219.          * NOTE: This code only works for UNIX file names.
  220.          */
  221.         char PrevName[FILENAMESIZE];
  222.         loop {
  223.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  224.         if(PReturned == PFAILED)
  225.             return(PFAILED); 
  226.         elif(PChar == '9')
  227.             break;
  228.         }
  229.         loop {
  230.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  231.         if(PReturned == PFAILED)
  232.             return(PFAILED); 
  233.         elif(PChar == ';'){
  234.             CDDesc.dSymbolName[Int1] = EOS;
  235.             if(Int1 == 1 And CDDesc.dSymbolName[0] == '.')
  236.             strcpy(CDDesc.dSymbolName,PrevName);
  237.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  238.             strcpy(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  239.                 CDDesc.dSymbolName);
  240.             CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  241.             ++CDDesc.dNumSymbolTable;
  242.             }
  243.             break;
  244.             }
  245.         elif(PChar == '/'){
  246.             /* begin new name; last name was a directory */
  247.             Int1 = 0;
  248.             strcpy(PrevName,CDDesc.dSymbolName);
  249.             }
  250.         else {
  251.             if(Int1 < FILENAMESIZE)
  252.             CDDesc.dSymbolName[Int1++] = PChar;
  253.             }
  254.         }
  255.         }
  256.     elif(CDDesc.dProgram == 'h' Or CDDesc.dProgram == 'k'){
  257.         /*
  258.          * IGS and KIC files have the symbol name in the form 
  259.          * 9 SymbolName; after the DS command.
  260.          */
  261.         loop {
  262.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  263.         if(PReturned == PFAILED)
  264.             return(PFAILED); 
  265.         elif(PChar == '9')
  266.             break;
  267.         }
  268.         loop {
  269.         PCharacter(PReturned,PSTRIPWHITESPACE1,PFAILONEOF);
  270.         if(PReturned == PFAILED)
  271.             return(PFAILED); 
  272.         elif(PChar == ';'){
  273.             CDDesc.dSymbolName[Int1] = EOS;
  274.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  275.             strcpy(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  276.                 CDDesc.dSymbolName);
  277.             CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  278.             ++CDDesc.dNumSymbolTable;
  279.             }
  280.             break;
  281.             }
  282.         else {
  283.             if(Int1 < FILENAMESIZE)
  284.             CDDesc.dSymbolName[Int1++] = PChar;
  285.             }
  286.         }
  287.         }
  288.     if(CDDesc.dControl == DCONTROLPCIF){
  289.         if(CDDesc.dFirstPass){
  290.         /*
  291.          * Open the symbol, but don't search the current directory
  292.          * for a KIC cell.  Also, don't close the symbol since
  293.          * that would remove the symbol from memory.
  294.          */
  295.         for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1){
  296.             if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
  297.             }
  298.             if(Int1 == CDDesc.dNumSymbolTable){
  299.             if(CDDesc.dNumSymbolTable < CDNUMREMEMBER){
  300.                     sprintf(CDDesc.dSymTabNames[CDDesc.dNumSymbolTable],
  301.                 "Symbol%d",SymbolNum);
  302.                     CDDesc.dSymTabNumbers[CDDesc.dNumSymbolTable]=SymbolNum;
  303.             ++CDDesc.dNumSymbolTable;
  304.             }
  305.             else
  306.             return(PFAILED);
  307.             }
  308.                 if(!CDOpen(CDDesc.dSymTabNames[Int1],&CDDesc.dSymbolDesc,'n'))
  309.             return(PFAILED);
  310.                 }
  311.         else{
  312.         /*
  313.          * Symbol is already open.  Just get the desc for it.
  314.          */
  315.         for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1){
  316.             if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
  317.             }
  318.             if(Int1 == CDDesc.dNumSymbolTable){
  319.             return(PFAILED);
  320.             }
  321.             CDSymbol(CDDesc.dSymTabNames[Int1],&CDDesc.dSymbolDesc);
  322.         if(CDDesc.dSymbolDesc == NULL){
  323.             return(PFAILED);
  324.             }
  325.         }
  326.         CDDesc.dControl = DCONTROLPCIF;
  327.         }
  328.     elif(CDDesc.dControl == DCONTROLCDTO){
  329.         if(CDDesc.dFirstPass)
  330.             return(PSUCCEEDED);
  331.         if(CDDesc.dSymbolName[0] == EOS)
  332.             sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
  333.         if((CDDesc.dSymbolFileDesc = POpen(CDDesc.dSymbolName,"w",
  334.         (char *)NULL,(char **)NULL)) == NULL)
  335.             return(PFAILED);
  336.         sprintf(TypeOut," Symbol %s ",CDDesc.dSymbolName);
  337.         GenComment(CDDesc.dSymbolFileDesc,TypeOut);
  338.         Long1 = time((time_t *)NULL);
  339.         sprintf(TypeOut," Creation Date: %.24s ",ctime((time_t *)&Long1));
  340.         GenComment(CDDesc.dSymbolFileDesc,TypeOut);
  341.         GenUserExtension(CDDesc.dSymbolFileDesc,'9',CDDesc.dSymbolName);
  342.         GenBeginSymbol(CDDesc.dSymbolFileDesc,0,1,1);
  343.         CDDesc.dSymbolName[0] = EOS;
  344.         }
  345.     }
  346.     elif(CDDesc.dControl == DCONTROLCDOPEN){
  347.         /* add property list information */
  348.         while(CDDesc.dPrptyList != NULL){
  349.             struct prpty PrptyCopy;
  350.             if(Not CDAddProperty(CDDesc.dSymbolDesc,(struct o *)NULL,
  351.             CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  352.         return(PFAILED);
  353.             /* free storage of CDDesc.dPrptyList */
  354.             PrptyCopy = *CDDesc.dPrptyList;
  355.             free(CDDesc.dPrptyList->prpty_String);
  356.             free((struct prpty *)CDDesc.dPrptyList);
  357.             CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  358.             }
  359.     }
  360.     return(PSUCCEEDED);
  361.     }
  362.  
  363.  
  364. AEndSymbol(){
  365.     /*
  366.      * This routine performs the necessary actions to close a symbol
  367.      * definition.
  368.      *
  369.      * DCONTROLCDTO:
  370.      *     Return on first pass (we are only building the symbol table).
  371.      *     On the second pass, we terminate and close the KIC cell
  372.      *     containing the respective CIF symbol.
  373.      *
  374.      * DCONTROLPCIF:
  375.      *     We set the current cell desc in CDDesc.dSymbolDesc to that of
  376.      *     the root symbol.
  377.      *
  378.      * DCONTROLCDOPEN:
  379.      *     No action.
  380.      */
  381. #ifdef TRACEPARSER
  382. GenEndSymbol(stderr);
  383. #endif
  384.     if(CDDesc.dControl == DCONTROLCDTO){
  385.     if(CDDesc.dFirstPass)
  386.         return;
  387.     GenEndSymbol(CDDesc.dSymbolFileDesc);
  388.     GenEnd(CDDesc.dSymbolFileDesc);
  389.     fclose(CDDesc.dSymbolFileDesc);
  390.     CDDesc.dRoot = True;
  391.     }
  392.     elif(CDDesc.dControl == DCONTROLPCIF){
  393.     CDDesc.dSymbolDesc = CDDesc.dRootCellDesc;
  394.     CDDesc.dRoot = True;
  395.     }
  396.     elif(CDDesc.dControl == DCONTROLCDOPEN){
  397.     if(CDDesc.dSymbolDesc->sLeft == INFINITY)
  398.         CDDesc.dSymbolDesc->sLeft = CDDesc.dSymbolDesc->sBottom
  399.         = CDDesc.dSymbolDesc->sRight = CDDesc.dSymbolDesc->sTop = 0;
  400.     /*
  401.      * Force the dummy call command at the end of the symbol
  402.      * to be ignored by ACall.
  403.      */
  404.     CDDesc.dSymbolName[0] = EOS;
  405.     }
  406.     }
  407.  
  408.  
  409. ADeleteSymbol(SymbolNum)
  410.     int SymbolNum;
  411.     {
  412.     /*
  413.      * We do not deal with definition deletes.
  414.      * It could be handled by using the symbol table to obtain the
  415.      * respective symbol numbers, and invoking CDClose on those cell
  416.      * definitions to be deleted.
  417.      */
  418.  
  419. #ifdef TRACEPARSER
  420. fprintf(stderr,"DD %d;\n",SymbolNum);
  421. #endif
  422.     /*
  423.      *Ignore DD commands.
  424.      */
  425.     fprintf(stderr,"Definition Delete of Symbol %d - ignored\n",SymbolNum);
  426.     }
  427.  
  428.  
  429. AEndCall(){
  430. #ifdef TRACEPARSER
  431. fprintf(stderr,";\n");
  432. #endif
  433.     if(CDDesc.dControl == DCONTROLCDTO){
  434.     if(CDDesc.dFirstPass)
  435.         return(PSUCCEEDED);
  436.     if(CDDesc.dRoot)
  437.         GenEndCall(CDDesc.dRootFileDesc);
  438.     else
  439.         GenEndCall(CDDesc.dSymbolFileDesc);
  440.     }
  441.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  442.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  443.         return(PSUCCEEDED);
  444.     if(Not CDEndMakeCall(CDDesc.dSymbolDesc,CDDesc.dPointer))
  445.         return(PFAILED);
  446.     while(CDDesc.dPrptyList != NULL){
  447.         struct prpty PrptyCopy;
  448.         if(Not CDAddProperty(CDDesc.dSymbolDesc,CDDesc.dPointer,
  449.         CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  450.         return(PFAILED);
  451.         /* free storage of CDDesc.dPrptyList */
  452.         PrptyCopy = *CDDesc.dPrptyList;
  453.         free(CDDesc.dPrptyList->prpty_String);
  454.         free((struct prpty *)CDDesc.dPrptyList);
  455.         CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  456.         }
  457.     }
  458.     return(PSUCCEEDED);
  459.     }
  460.  
  461.  
  462. AT(Type,X,Y)
  463.     char Type;
  464.     int X,Y;
  465.     {
  466. #ifdef TRACEPARSER
  467. fprintf(stderr," T:%c %d %d",Type,X,Y);
  468. #endif
  469.     if(CDDesc.dControl == DCONTROLCDTO){
  470.     if(CDDesc.dFirstPass)
  471.         return(PSUCCEEDED);
  472.     if(Type == CDTRANSLATE)
  473.         if(CDDesc.dRoot)
  474.         GenTranslation(CDDesc.dRootFileDesc,
  475.             X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,
  476.             Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB);
  477.         else GenTranslation(CDDesc.dSymbolFileDesc,
  478.             X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,
  479.             Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB);
  480.     elif(Type == CDROTATE){
  481.         if(abs(X) > 1 Or abs(Y) > 1){
  482.         X = X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;    
  483.         Y = Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;    
  484.         }
  485.         if(CDDesc.dRoot)
  486.         GenRotation(CDDesc.dRootFileDesc,X,Y);
  487.         else
  488.         GenRotation(CDDesc.dSymbolFileDesc,X,Y);
  489.         }
  490.     elif(Type == CDMIRRORX)
  491.         if(CDDesc.dRoot)
  492.         GenMirrorX(CDDesc.dRootFileDesc);
  493.         else
  494.         GenMirrorX(CDDesc.dSymbolFileDesc);
  495.     elif(Type == CDMIRRORY)
  496.         if(CDDesc.dRoot)
  497.         GenMirrorY(CDDesc.dRootFileDesc);
  498.         else
  499.         GenMirrorY(CDDesc.dSymbolFileDesc);
  500.     }
  501.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  502.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  503.         return(PSUCCEEDED);
  504.     return(CDT(CDDesc.dPointer,Type,X,Y));
  505.     }
  506.     return(PSUCCEEDED);
  507.     }
  508.  
  509.  
  510. ABeginCall(SymbolNum)
  511.     int SymbolNum;
  512.     {
  513.     int Int1;
  514. #ifdef TRACEPARSER
  515. fprintf(stderr,"C %d ",SymbolNum);
  516. #endif
  517.     if(CDDesc.dControl == DCONTROLPCIF Or CDDesc.dControl == DCONTROLCDTO){
  518.     if(CDDesc.dFirstPass)
  519.         return(PSUCCEEDED);
  520.     if(CDDesc.dProgram != 'n'){
  521.         for(Int1 = 0; Int1 < CDDesc.dNumSymbolTable; ++Int1){
  522.         if(CDDesc.dSymTabNumbers[Int1] == SymbolNum) break;
  523.         }
  524.         }
  525.     }
  526.     if(CDDesc.dControl == DCONTROLCDTO){
  527.     if(CDDesc.dProgram != 'n' And Int1 < CDDesc.dNumSymbolTable){
  528.         sprintf(TypeOut," %s",CDDesc.dSymTabNames[Int1]);
  529.         if(CDDesc.dRoot)
  530.         GenUserExtension(CDDesc.dRootFileDesc,'9',TypeOut);
  531.         else
  532.         GenUserExtension(CDDesc.dSymbolFileDesc,'9',TypeOut);
  533.         }
  534.     elif(CDDesc.dSymbolName[0] != EOS){
  535.         sprintf(TypeOut," %s",CDDesc.dSymbolName);
  536.         if(CDDesc.dRoot)
  537.         GenUserExtension(CDDesc.dRootFileDesc,'9',TypeOut);
  538.         else
  539.         GenUserExtension(CDDesc.dSymbolFileDesc,'9',TypeOut);
  540.         }
  541.     else {
  542.         sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
  543.         sprintf(TypeOut," Symbol%d",SymbolNum);
  544.         if(CDDesc.dRoot)
  545.         GenUserExtension(CDDesc.dRootFileDesc,'9',TypeOut);
  546.         else
  547.         GenUserExtension(CDDesc.dSymbolFileDesc,'9',TypeOut);
  548.         }
  549.     if(CDDesc.dRoot)
  550.         GenBeginCall(CDDesc.dRootFileDesc,0);
  551.     else 
  552.         GenBeginCall(CDDesc.dSymbolFileDesc,SymbolNum);
  553.     CDDesc.dSymbolName[0] = EOS;
  554.     }
  555.     elif(CDDesc.dControl == DCONTROLPCIF){
  556.     if(CDDesc.dProgram != 'n' And Int1 < CDDesc.dNumSymbolTable){
  557.         strcpy(CDDesc.dSymbolName,CDDesc.dSymTabNames[Int1]);
  558.         }
  559.     else {
  560.         sprintf(CDDesc.dSymbolName,"Symbol%d",SymbolNum);
  561.         }
  562.     if(Not CDBeginMakeCall(CDDesc.dSymbolDesc,CDDesc.dSymbolName,
  563.         CDDesc.dNumX,CDDesc.dDX,CDDesc.dNumY,CDDesc.dDY,&CDDesc.dPointer))
  564.         return(PFAILED);
  565.     CDDesc.dSymbolName[0] = EOS;
  566.     CDDesc.dNumX = CDDesc.dNumY = 1;
  567.     CDDesc.dDX = CDDesc.dDY = 0;
  568.         CDDesc.dControl = DCONTROLPCIF;
  569.     }
  570.     elif(CDDesc.dControl == DCONTROLCDOPEN){
  571.     if(CDDesc.dSymbolName[0] != EOS)
  572.         if(Not CDBeginMakeCall(CDDesc.dSymbolDesc,CDDesc.dSymbolName,
  573.         CDDesc.dNumX,CDDesc.dDX,CDDesc.dNumY,CDDesc.dDY,
  574.         &CDDesc.dPointer))
  575.         return(PFAILED);
  576.     CDDesc.dSymbolName[0] = EOS;
  577.     CDDesc.dNumX = CDDesc.dNumY = 1;
  578.     CDDesc.dDX = CDDesc.dDY = 0;
  579.     }
  580.     return(PSUCCEEDED);
  581.     }
  582.  
  583.  
  584. APolygon(Path)
  585.     struct p *Path;
  586.     {
  587.     struct p *Pair;
  588. #ifdef TRACEPARSER
  589. GenPolygon(stderr,Path);
  590. #endif
  591.     if(CDDesc.dControl == DCONTROLCDTO){
  592.     int NumVertices,Left,Bottom,Right,Top;
  593.     if(CDDesc.dFirstPass)
  594.         return(PSUCCEEDED);
  595.     Pair = Path;
  596.     NumVertices = 0;
  597.     Left = Bottom = INFINITY;
  598.     Right = Top = -INFINITY;
  599.     while(Pair != NULL){
  600.         if(Pair->pX < Left)
  601.         Left = Pair->pX;
  602.         if(Pair->pX > Right)
  603.         Right = Pair->pX;
  604.         if(Pair->pY < Bottom)
  605.         Bottom = Pair->pY;
  606.         if(Pair->pY > Top)
  607.         Top = Pair->pY;
  608.         ++NumVertices;
  609.         Pair = Pair->pSucc;
  610.         }
  611.     if(NumVertices == 4){
  612.         if((Path->pX == Path->pSucc->pX And
  613.         Path->pSucc->pY == Path->pSucc->pSucc->pY And
  614.         Path->pSucc->pSucc->pX == Path->pSucc->pSucc->pSucc->pX And
  615.         Path->pY == Path->pSucc->pSucc->pSucc->pY)
  616.         Or
  617.         (Path->pY == Path->pSucc->pY And
  618.         Path->pSucc->pX == Path->pSucc->pSucc->pX And
  619.         Path->pSucc->pSucc->pY == Path->pSucc->pSucc->pSucc->pY And
  620.         Path->pX == Path->pSucc->pSucc->pSucc->pX))
  621.         {
  622.         return(ABox(Right-Left,Top-Bottom,Left+((Right-Left)/2),
  623.             Bottom+((Top-Bottom)/2),1,0));
  624.         }
  625.         }
  626.     Pair = Path;
  627.     while(Pair != NULL){
  628.         Pair->pX = Pair->pX*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  629.         Pair->pY = Pair->pY*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  630.         Pair = Pair->pSucc;
  631.         }
  632.     if(CDDesc.dRoot)
  633.         GenPolygon(CDDesc.dRootFileDesc,Path);
  634.     else
  635.         GenPolygon(CDDesc.dSymbolFileDesc,Path);
  636.     }
  637.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  638.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  639.         return(PSUCCEEDED);
  640.     if(Not CDMakePolygon(CDDesc.dSymbolDesc,CurrentLayer,Path,
  641.         &CDDesc.dPointer))
  642.         return(PFAILED);
  643.     while(CDDesc.dPrptyList != NULL){
  644.         struct prpty PrptyCopy;
  645.         if(Not CDAddProperty(CDDesc.dSymbolDesc,CDDesc.dPointer,
  646.         CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  647.         return(PFAILED);
  648.         /* free storage of CDDesc.dPrptyList */
  649.         PrptyCopy = *CDDesc.dPrptyList;
  650.         free(CDDesc.dPrptyList->prpty_String);
  651.         free((struct prpty *)CDDesc.dPrptyList);
  652.         CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  653.         }
  654.     }
  655.     return(PSUCCEEDED);
  656.     }
  657.  
  658.  
  659. AWire(Width,Path)
  660.     struct p *Path;
  661.     int Width;
  662.     {
  663.     struct p *Pair;
  664. #ifdef TRACEPARSER
  665. GenWire(stderr,Width,Path);
  666. #endif
  667.     if(CDDesc.dControl == DCONTROLCDTO){
  668.     if(CDDesc.dFirstPass)
  669.         return(PSUCCEEDED);
  670.     Pair = Path;
  671.     while(Pair != NULL){
  672.         Pair->pX = Pair->pX*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  673.         Pair->pY = Pair->pY*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  674.         Pair = Pair->pSucc;
  675.         }
  676.     if(CDDesc.dRoot)
  677.         GenWire(CDDesc.dRootFileDesc,Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,Path);
  678.     else 
  679.         GenWire(CDDesc.dSymbolFileDesc,Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,Path);
  680.     }
  681.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  682.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  683.         return(PSUCCEEDED);
  684.     if(Not CDMakeWire(CDDesc.dSymbolDesc,CurrentLayer,Width,Path,
  685.         &CDDesc.dPointer))
  686.         return(PFAILED);
  687.     while(CDDesc.dPrptyList != NULL){
  688.         struct prpty PrptyCopy;
  689.         if(Not CDAddProperty(CDDesc.dSymbolDesc,CDDesc.dPointer,
  690.         CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  691.         return(PFAILED);
  692.         /* free storage of CDDesc.dPrptyList */
  693.         PrptyCopy = *CDDesc.dPrptyList;
  694.         free(CDDesc.dPrptyList->prpty_String);
  695.         free((struct prpty *)CDDesc.dPrptyList);
  696.         CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  697.         }
  698.     }
  699.     return(PSUCCEEDED);
  700.     }
  701.  
  702.  
  703. ABox(Length,Width,X,Y,XDirection,YDirection)
  704.     int Length,Width,X,Y,XDirection,YDirection;
  705.     {
  706. #ifdef TRACEPARSER
  707. GenBox(stderr,Length,Width,X,Y,XDirection,YDirection);
  708. #endif
  709.     if(CDDesc.dControl == DCONTROLCDTO){
  710.     if(CDDesc.dFirstPass)
  711.         return(PSUCCEEDED);
  712.     Length = Length*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  713.     Width = Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  714.     X = X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  715.     Y = Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  716.     if(XDirection == 1 And YDirection == 0){
  717.         if(CDDesc.dRoot)
  718.         GenBox(CDDesc.dRootFileDesc,Length,Width,X,Y,
  719.             XDirection,YDirection);
  720.         else
  721.         GenBox(CDDesc.dSymbolFileDesc,Length,Width,X,Y,
  722.             XDirection,YDirection);
  723.         }
  724.     else {
  725.         /*
  726.          * Transform non-Manhattan box to polygon.
  727.          */
  728.         float C;
  729.         int Left,Bottom,Right,Top; 
  730.         struct p *Path,*Pair;
  731.  
  732.         Left = X-(Length >> 1);
  733.         Right = X+(Length >> 1);
  734.         Bottom = Y-(Width >> 1);
  735.         Top = Y+(Width >> 1);
  736.         C = sqrt((double)(XDirection*XDirection+YDirection*YDirection));
  737.         if((Pair = Path = (struct p *)malloc(sizeof(struct p))) == NULL)
  738.         return(AMallocFailed());
  739.         Pair->pX = (Left*XDirection-Bottom*YDirection-
  740.         XDirection*X+YDirection*Y)/C+X;
  741.         Pair->pY = (Left*YDirection+Bottom*XDirection-
  742.         YDirection*X-XDirection*Y)/C+Y;
  743.         if((Pair = Pair->pSucc = (struct p *)
  744.         malloc(sizeof(struct p))) == NULL)
  745.         return(AMallocFailed());
  746.         Pair->pX = (Left*XDirection-Top*YDirection-
  747.         XDirection*X+YDirection*Y)/C+X;
  748.         Pair->pY = (Left*YDirection+Top*XDirection-
  749.         YDirection*X-XDirection*Y)/C+Y;
  750.         if((Pair = Pair->pSucc = (struct p *)
  751.         malloc(sizeof(struct p))) == NULL)
  752.         return(AMallocFailed());
  753.         Pair->pX = (Right*XDirection-Top*YDirection-
  754.         XDirection*X+YDirection*Y)/C+X;
  755.         Pair->pY = (Right*YDirection+Top*XDirection-
  756.         YDirection*X-XDirection*Y)/C+Y;
  757.         if((Pair = Pair->pSucc = (struct p *)
  758.         malloc(sizeof(struct p))) == NULL)
  759.         return(AMallocFailed());
  760.         Pair->pX = (Right*XDirection-Bottom*YDirection-
  761.         XDirection*X+YDirection*Y)/C+X;
  762.         Pair->pY = (Right*YDirection+Bottom*XDirection-
  763.         YDirection*X-XDirection*Y)/C+Y;
  764.         Pair->pSucc = NULL;
  765.         if(CDDesc.dRoot)
  766.         GenPolygon(CDDesc.dRootFileDesc,Path);
  767.         else
  768.         GenPolygon(CDDesc.dSymbolFileDesc,Path);
  769.         }
  770.     }
  771.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  772.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  773.         return(PSUCCEEDED);
  774.     if(Not CDMakeBox(CDDesc.dSymbolDesc,CurrentLayer,Length,Width,
  775.         X,Y,&CDDesc.dPointer))
  776.         return(PFAILED);
  777.     while(CDDesc.dPrptyList != NULL){
  778.         struct prpty PrptyCopy;
  779.         if(Not CDAddProperty(CDDesc.dSymbolDesc,CDDesc.dPointer,
  780.         CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  781.         return(PFAILED);
  782.         /* free storage of CDDesc.dPrptyList */
  783.         PrptyCopy = *CDDesc.dPrptyList;
  784.         free(CDDesc.dPrptyList->prpty_String);
  785.         free((struct prpty *)CDDesc.dPrptyList);
  786.         CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  787.         }
  788.     }
  789.     return(PSUCCEEDED);
  790.     }
  791.  
  792.  
  793. ARoundFlash(Width,X,Y)
  794.     int Width,X,Y;
  795.     {
  796.     struct p *Path, *NewPath;
  797.     struct p Pair;
  798.     /*
  799.      *KIC DOES NOT SUPPORT ROUND FLASHES: convert to a wire with one vertex.
  800.      *Therefore, KIC will never try to generate a Roundflash.
  801.      */
  802.     if(CDDesc.dControl == DCONTROLCDTO){
  803.     if(CDDesc.dFirstPass)
  804.         return(PSUCCEEDED);
  805.     Pair.pX = X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  806.     Pair.pY = Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB;
  807.     Pair.pSucc = NULL;
  808.     if(CDDesc.dRoot)
  809.         GenWire(CDDesc.dRootFileDesc,Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,&Pair);
  810.     else 
  811.         GenWire(CDDesc.dSymbolFileDesc,Width*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,&Pair);
  812.     }
  813.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  814.     if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  815.         return(PSUCCEEDED);
  816.     if((NewPath = Path = (struct p *)malloc(sizeof(struct p))) != NULL)
  817.         return(AMallocFailed());
  818.     NewPath->pX = X;
  819.     NewPath->pY = Y;
  820.     NewPath->pSucc = NULL;
  821.     if(Not CDMakeWire(CDDesc.dSymbolDesc,CurrentLayer,Width,Path,
  822.         &CDDesc.dPointer))
  823.         return(PFAILED);
  824.     while(CDDesc.dPrptyList != NULL){
  825.         struct prpty PrptyCopy;
  826.         if(Not CDAddProperty(CDDesc.dSymbolDesc,CDDesc.dPointer,
  827.         CDDesc.dPrptyList->prpty_Value,CDDesc.dPrptyList->prpty_String))
  828.         return(PFAILED);
  829.         /* free storage of CDDesc.dPrptyList */
  830.         PrptyCopy = *CDDesc.dPrptyList;
  831.         free(CDDesc.dPrptyList->prpty_String);
  832.         free((struct prpty *)CDDesc.dPrptyList);
  833.         CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  834.         }
  835.     }
  836.     return(PSUCCEEDED);
  837.     }
  838.  
  839.  
  840. ALayer(Technology,Mask)
  841.     char Technology,Mask[];
  842.     {
  843.     int Layer;
  844. #ifdef TRACEPARSER
  845. GenLayer(stderr,Technology,Mask);
  846. #endif
  847.     if(CDDesc.dControl == DCONTROLCDTO){
  848.     if(CDDesc.dFirstPass)
  849.         return(PSUCCEEDED);
  850.     if(CDDesc.dRoot)
  851.         GenLayer(CDDesc.dRootFileDesc,Technology,Mask);
  852.     else
  853.         GenLayer(CDDesc.dSymbolFileDesc,Technology,Mask);
  854.     return(PSUCCEEDED);
  855.     }
  856.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  857.     for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  858.         if(CDLayer[Layer].lTechnology == Technology And
  859.         CDLayer[Layer].lMask[0] == Mask[0] And
  860.         CDLayer[Layer].lMask[1] == Mask[1] And
  861.         CDLayer[Layer].lMask[2] == Mask[2]){
  862.         CurrentLayer = Layer;
  863.         return(PSUCCEEDED);
  864.         }
  865.         }
  866.     /*
  867.      * Layer is not defined in CD layer table!
  868.      * If parsing CIF and layer is unknown, put it in the layer table.
  869.      * If opening a cell and layer is unknown, complain about it.
  870.      */
  871.     if(CDDesc.dControl == DCONTROLPCIF){
  872.         for(Layer = 1;Layer <= CDNUMLAYERS;++Layer){
  873.             if(CDLayer[Layer].lTechnology == ' ') {
  874.                 CDSetLayer(Layer, Technology, Mask);
  875.                 CurrentLayer = Layer;
  876.                 return(PSUCCEEDED);
  877.             }
  878.         }
  879.         }
  880.     CurrentLayer = 1;
  881.     }
  882.     return(PFAILED);
  883.     }
  884.  
  885.  
  886. AUserExtension(Digit,Text)
  887.     char Digit;
  888.     char *Text;
  889.     {
  890.     char Command[81];
  891.     int X,Y,Layer;
  892.     char Label[81];
  893.  
  894. #ifdef TRACEPARSER
  895. GenUserExtension(stderr,Digit,Text);
  896. #endif
  897.     if(CDDesc.dControl == DCONTROLCDTO){
  898.     if(CDDesc.dFirstPass Or CDDesc.dProgram == 'n')
  899.         return(PSUCCEEDED);
  900.     /*
  901.      * When converting to KIC format, we pass CD user extensions only.
  902.      * If we find an illegal extension, we ignore it.
  903.      */ 
  904.     if(Digit == '9'){
  905.         if(Text[0] == '4'){
  906.         /* CD Label */
  907.         sscanf(&(Text[1]),"%s%d%d",Label,&X,&Y);
  908.         sprintf(TypeOut,"4 %s %d %d",Label,
  909.             X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,
  910.             Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB);
  911.         if(CDDesc.dRoot){
  912.             GenUserExtension(CDDesc.dRootFileDesc,'9',TypeOut);
  913.             }
  914.         else{
  915.             GenUserExtension(CDDesc.dSymbolFileDesc,'9',TypeOut);
  916.             }
  917.         }
  918.         elif(Text[0] == '2'){
  919.         /* NCA Label */
  920.         sscanf(&(Text[1]),"%s%d%d%d",Label,&X,&Y,&Layer);
  921.         sprintf(TypeOut,"%d    ",Layer);
  922.         if(CDDesc.dRoot){
  923.             GenLayer(CDDesc.dRootFileDesc,TypeOut[0],&TypeOut[1]);
  924.             }
  925.         else{
  926.             GenLayer(CDDesc.dSymbolFileDesc,TypeOut[0],&TypeOut[1]);
  927.             }
  928.         sprintf(TypeOut,"4 %s %d %d",Label,
  929.             X*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB,
  930.             Y*CDDesc.dB*CDDesc.dDSA/CDDesc.dA/CDDesc.dDSB);
  931.         if(CDDesc.dRoot){
  932.             GenUserExtension(CDDesc.dRootFileDesc,'9',TypeOut);
  933.             }
  934.         else{
  935.             GenUserExtension(CDDesc.dSymbolFileDesc,'9',TypeOut);
  936.             }
  937.         }
  938.         else {
  939.         /* symbol name */
  940.         if(Text[0] == ' ')
  941.             strcpy(CDDesc.dSymbolName,&(Text[1]));
  942.         else strcpy(CDDesc.dSymbolName,Text);
  943.         if(CDDesc.dRoot)
  944.             GenUserExtension(CDDesc.dRootFileDesc,Digit,Text);
  945.         else
  946.             GenUserExtension(CDDesc.dSymbolFileDesc,Digit,Text);
  947.         }
  948.         }
  949.     elif(Digit == '5' And (Text[0] < '0' Or Text[0] > '9')){
  950.         /* Reserved for CD property list extensions */
  951.         if(CDDesc.dRoot)
  952.         GenUserExtension(CDDesc.dRootFileDesc,Digit,Text);
  953.         else
  954.         GenUserExtension(CDDesc.dSymbolFileDesc,Digit,Text);
  955.         }
  956.     }
  957.     elif(CDDesc.dControl == DCONTROLCDOPEN Or CDDesc.dControl == DCONTROLPCIF){
  958.     /*
  959.      * When parsing CIF, we accept only CD user extensions and
  960.      * ignore any illegal extensions.
  961.      */
  962.     if(Digit == '9'){
  963.         if(Text[0] == '4'){
  964.         /* Label */
  965.         sscanf(&(Text[1]),"%s%d%d",Label,&X,&Y);
  966.             if(CDDesc.dFirstPass And CDDesc.dControl == DCONTROLPCIF)
  967.                 return(PSUCCEEDED);
  968. #ifdef DEBUG
  969. fprintf(stderr,"Making label on layer %d\n",CurrentLayer);
  970. #endif
  971.         if(Not CDMakeLabel(CDDesc.dSymbolDesc,CurrentLayer,Label,
  972.             X,Y,&CDDesc.dPointer))
  973.             return(PFAILED);
  974.         while(CDDesc.dPrptyList != NULL){
  975.             struct prpty PrptyCopy;
  976.             if(Not CDAddProperty(CDDesc.dSymbolDesc,
  977.             CDDesc.dPointer,CDDesc.dPrptyList->prpty_Value,
  978.             CDDesc.dPrptyList->prpty_String)) return(PFAILED);
  979.             /* free storage of CDDesc.dPrptyList */
  980.             PrptyCopy = *CDDesc.dPrptyList;
  981.             free(CDDesc.dPrptyList->prpty_String);
  982.             free((struct prpty *)CDDesc.dPrptyList);
  983.             CDDesc.dPrptyList = PrptyCopy.prpty_Succ;
  984.             }
  985.         }
  986.         elif(Text[0] == '2'){
  987.         /* NCA Label - ignored */
  988.         }
  989.         else {
  990.         /* Symbol name */
  991.         X = 0;
  992.         while(Text[X] == ' ' Or Text[X] == 011) ++X;
  993.         strcpy(CDDesc.dSymbolName,&(Text[X]));
  994.         }
  995.         }
  996.     elif(Digit == '1' And (Text[0] < '0' Or Text[0] > '9')){
  997.         /* Reserved for CD Array extensions */
  998.         sscanf(Text,"%s",Command);
  999.         if(strcmp(Command,"Array") == 0){
  1000.         sscanf(Text,"%s%d%d%d%d",Command,&CDDesc.dNumX,&CDDesc.dDX,
  1001.             &CDDesc.dNumY,&CDDesc.dDY);
  1002.         }
  1003.         }
  1004.     elif(Digit == '5' And (Text[0] < '0' Or Text[0] > '9')){
  1005.         /* Reserved for CD Property List extensions */
  1006.         struct prpty *PDesc;
  1007.         unsigned int size;
  1008.         int i;
  1009.  
  1010.         if((PDesc = (struct prpty *)malloc(sizeof(struct prpty)))==NULL)
  1011.         return(PFAILED);
  1012.         if(sscanf(Text,"%d",&PDesc->prpty_Value) < 1)
  1013.         return(PFAILED);
  1014.         i = 0;
  1015.         /* skip white space before property integer */
  1016.         while((Text[i] < '0' Or Text[i] > '9') And Text[i] != NULL) ++i;
  1017.         /* skip property integer */
  1018.         while(Text[i] >= '0' And Text[i] <= '9') ++i;
  1019.         /* skip white space and control chars after property integer */
  1020.         while(Text[i] <= ' ' And Text[i] != NULL) ++i;
  1021.         size = strlen(&(Text[i])) + 2; 
  1022.         if((PDesc->prpty_String = malloc(size)) == NULL)
  1023.         return(PFAILED);
  1024.         strcpy(PDesc->prpty_String,&(Text[i]));
  1025.         PDesc->prpty_Succ = CDDesc.dPrptyList;
  1026.         CDDesc.dPrptyList = PDesc; 
  1027.         }
  1028.     }
  1029.     return(PSUCCEEDED);
  1030.     }
  1031.  
  1032.  
  1033. AComment(Text)
  1034.     char *Text;
  1035.     {
  1036. #ifdef TRACEPARSER
  1037. GenComment(stderr,Text);
  1038. #endif
  1039.     if(CDDesc.dControl == DCONTROLCDTO){
  1040.     if(Not CDDesc.dFirstPass){
  1041.         if(CDDesc.dRoot)
  1042.             GenComment(CDDesc.dRootFileDesc,Text);
  1043.         else
  1044.             GenComment(CDDesc.dSymbolFileDesc,Text);
  1045.         }
  1046.     }
  1047.     }
  1048.  
  1049.  
  1050. AMallocFailed(){
  1051.     sprintf(CDStatusString,"Out of memory.");
  1052.     CDStatusInt = CDMALLOCFAILED;
  1053.     return(PFAILED);
  1054.     }
  1055.