home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / BREAKPNT.C < prev    next >
Text File  |  1996-06-07  |  60KB  |  1,533 lines

  1. /*****************************************************************************/
  2. /* File:                                             IBM INTERNAL USE ONLY   */
  3. /*   breakpnt.c                                                              */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*   Breakpoint file handling.                                               */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   11/30/95 Created.                                                       */
  12. /*                                                                           */
  13. /*****************************************************************************/
  14.  
  15. #include "all.h"
  16. #include "breakpnt.h"
  17.  
  18. static int  BreakpointFileTime;
  19.  
  20. /*****************************************************************************/
  21. /* SaveBreakpoints()                                                         */
  22. /*                                                                           */
  23. /* Description:                                                              */
  24. /*                                                                           */
  25. /*   Save the currently defined breakpoints to a file.                       */
  26. /*                                                                           */
  27. /* Parameters:                                                               */
  28. /*                                                                           */
  29. /* Return:                                                                   */
  30. /*                                                                           */
  31. /* Assumptions:                                                              */
  32. /*                                                                           */
  33. /*****************************************************************************/
  34. void SaveBreakpoints( void )
  35. {
  36.  
  37.  extern PROCESS_NODE *pnode;
  38.  
  39.  char    *pEnvSD386Brk;
  40.  UCHAR   *pHelpMsg;
  41.  FILE    *BkptFile_fp;
  42.  int      irc;
  43.  BRK     *pBrk;
  44.  DEBFILE *pdf;
  45.  char    *cp;
  46.  char    *cpp;
  47.  int      len;
  48.  
  49.  /****************************************************************************/
  50.  /* - Get the breakpoint file environment variable.                          */
  51.  /****************************************************************************/
  52.  pEnvSD386Brk = GetSD386Brk();
  53.  
  54.  /****************************************************************************/
  55.  /* - Get some information about the breakpoint file.  If it can't be        */
  56.  /*   accessed then display a message.                                       */
  57.  /****************************************************************************/
  58.  BkptFile_fp = fopen(pEnvSD386Brk,"wb");
  59.  if( BkptFile_fp == NULL )
  60.    Error( ERR_BKPT_FILE_OPEN, FALSE, 1, pEnvSD386Brk );
  61.  
  62.  /****************************************************************************/
  63.  /* - write syntax info to the file.                                         */
  64.  /****************************************************************************/
  65.  pHelpMsg = GetHelpMsg( HELP_BKPTS_SYNTAX, NULL, 0 );
  66.  irc = fprintf(BkptFile_fp, pHelpMsg);
  67.  if( irc < 0 )
  68.    Error( ERR_BKPT_FILE_WRITE, FALSE, 1, pEnvSD386Brk );
  69.  
  70.  if( pHelpMsg ) Tfree(pHelpMsg);
  71.  
  72.  SayMsgBox5( HELP_BKPTS_SAVE_MSG, 1, pEnvSD386Brk );
  73.  
  74.  /****************************************************************************/
  75.  /* - Reverse linked list so that breakpoints are stored in the same order   */
  76.  /*   they came in. pBrk is left pointing to the tail node.                  */
  77.  /* - Just return if the list is empty.                                      */
  78.  /****************************************************************************/
  79.  pBrk = pnode->allbrks;
  80.  
  81.  if( pBrk == NULL )
  82.   goto fini;
  83.  
  84.  for( pBrk->prev = NULL; pBrk->next; )
  85.  {
  86.   pBrk->next->prev = pBrk;
  87.   pBrk             = pBrk->next;
  88.  }
  89.  
  90.  /****************************************************************************/
  91.  /* - Now, write the breakpoints to a file.                                  */
  92.  /****************************************************************************/
  93.  for( ; pBrk ; pBrk = pBrk->prev )
  94.  {
  95.   if( pBrk->brkat )
  96.   {
  97.    /**************************************************************************/
  98.    /* - Handle converted breakpoints.                                        */
  99.    /**************************************************************************/
  100.    pdf = FindExeOrDllWithAddr(pBrk->brkat);
  101.    if( pdf == NULL )
  102.     continue;  /* bad breakpoint...blow by */
  103.  
  104.    /**************************************************************************/
  105.    /* - check/get a valid dllname.                                           */
  106.    /**************************************************************************/
  107.    if( pBrk->dllname )
  108.    ;
  109.    else
  110.    {
  111.     cp = strrchr( pdf->DebFilePtr->fn, '\\' );
  112.     cp++;
  113.     strlwr(cp);
  114.     pBrk->dllname = Talloc(strlen(cp) + 1);
  115.     strcpy(pBrk->dllname, cp);
  116.    }
  117.  
  118.    /**************************************************************************/
  119.    /* - now, check/build a valid (file name, line number ).                  */
  120.    /**************************************************************************/
  121.    if( pBrk->srcname && pBrk->lno )
  122.    ;
  123.    else if( pBrk->srcname == NULL )
  124.    {
  125.     cp = GetFileName( pBrk->mid, pBrk->sfi );
  126.     if( cp )
  127.     {
  128.      len = *cp;
  129.      cpp = strrchr( cp+1, '\\' );
  130.  
  131.      cpp = ( cpp == NULL )?cp+1:cpp+1;
  132.      len = ( cpp == NULL )?len:len-(cpp-cp)+1;
  133.  
  134.      pBrk->srcname = Talloc(len+1);
  135.  
  136.      strncpy(pBrk->srcname, cpp, len);
  137.     }
  138.    }
  139.    else /* if( pBrk->lno == 0 ) */
  140.    {
  141.     LNOTAB *pLnoTabEntry;
  142.  
  143.     DBMapInstAddr(pBrk->brkat, &pLnoTabEntry, pdf);
  144.     if( pLnoTabEntry != NULL )
  145.      pBrk->lno = pLnoTabEntry->lno;
  146.    }
  147.    /**************************************************************************/
  148.    /* - now, abort if we still don't have a srcname and an lno.              */
  149.    /**************************************************************************/
  150.    if( pBrk->srcname && pBrk->lno )
  151.    ;
  152.    else
  153.     continue;  /* abort this breakpoint. */
  154.  
  155.    fprintf(BkptFile_fp, "\n{");
  156.    fprintf(BkptFile_fp, "%s",  pBrk->dllname );
  157.  
  158.    if( pBrk->flag.DefineType == BP_FUNC_NAME)
  159.     fprintf(BkptFile_fp, ",%s", pBrk->funcname );
  160.    else
  161.    {
  162.     fprintf(BkptFile_fp, ",%s", pBrk->srcname );
  163.     fprintf(BkptFile_fp, ",%d", pBrk->lno );
  164.    }
  165.  
  166.    if( pBrk->flag.DorI == BP_DEFR )
  167.     fprintf( BkptFile_fp, ",D" );
  168.  
  169.    if( pBrk->cond && pBrk->cond->pCondition )
  170.     fprintf(BkptFile_fp, ",%s", pBrk->cond->pCondition );
  171.  
  172.    fprintf(BkptFile_fp, "}");
  173.   }
  174.   else
  175.   {
  176.    /**************************************************************************/
  177.    /* - handle unconverted breakpoints.                                      */
  178.    /**************************************************************************/
  179.    fprintf(BkptFile_fp, "\n{");
  180.    fprintf(BkptFile_fp, "%s",  pBrk->dllname );
  181.    if( pBrk->srcname )
  182.    {
  183.     fprintf(BkptFile_fp, ",%s", pBrk->srcname );
  184.     fprintf(BkptFile_fp, ",%d", pBrk->lno );
  185.    }
  186.    else
  187.     fprintf(BkptFile_fp, ",%s", pBrk->funcname );
  188.  
  189.    if( pBrk->flag.DorI == BP_DEFR )
  190.     fprintf( BkptFile_fp, ",D" );
  191.  
  192.    if( pBrk->cond && pBrk->cond->pCondition )
  193.     fprintf(BkptFile_fp, ",%s", pBrk->cond->pCondition );
  194.  
  195.    fprintf(BkptFile_fp, "}");
  196.   }
  197.  }
  198.  
  199. fini:
  200.  
  201.  if(BkptFile_fp)
  202.  {
  203.   fprintf(BkptFile_fp, "%c", 0x1A );
  204.   /***************************************************************************/
  205.   /* - update the time stamp for the breakpoint file.                        */
  206.   /***************************************************************************/
  207.   {
  208.    struct stat statbuffer;
  209.  
  210.    fstat( fileno(BkptFile_fp), &statbuffer );
  211.  
  212.    BreakpointFileTime = statbuffer.st_mtime;
  213.   }
  214.   fclose(BkptFile_fp);
  215.  }
  216.  
  217.  
  218.  SetUsingBreakpointFileFlag();
  219.  return;
  220. }
  221.  
  222. /*****************************************************************************/
  223. /* InitBreakpoints                                                           */
  224. /*                                                                           */
  225. /* Description:                                                              */
  226. /*                                                                           */
  227. /*   Check for breakpoint file usage and set initial time stamp.             */
  228. /*                                                                           */
  229. /* Parameters:                                                               */
  230. /*                                                                           */
  231. /* Return:                                                                   */
  232. /*                                                                           */
  233. /* Assumptions:                                                              */
  234. /*                                                                           */
  235. /*****************************************************************************/
  236. static BOOL UsingBreakpointFileFlag;
  237.  
  238. void ResetBreakpointFileTime(void){BreakpointFileTime = -1;}
  239.  
  240. void SetUsingBreakpointFileFlag(void)  {UsingBreakpointFileFlag = TRUE; }
  241. void ResetUsingBreakpointFileFlag(void){UsingBreakpointFileFlag = FALSE;}
  242. BOOL IsUsingBreakpointFile(void)       {return(UsingBreakpointFileFlag);}
  243.  
  244. void InitBreakpoints( void )
  245. {
  246.  FILE *BkptFile_fp;
  247.  char *pEnvSD386Brk;
  248.  
  249.  /****************************************************************************/
  250.  /* - Get the breakpoint file environment variable. If it's not defined      */
  251.  /*   then the user doesn't want to use a breakpoint file.                   */
  252.  /****************************************************************************/
  253.  pEnvSD386Brk = GetSD386Brk();
  254.  
  255.  /****************************************************************************/
  256.  /* - Get some information about the breakpoint file.  If it can't be        */
  257.  /*   accessed then display a message.                                       */
  258.  /****************************************************************************/
  259.  BkptFile_fp = fopen(pEnvSD386Brk,"rb");
  260.  if( BkptFile_fp != NULL )
  261.  {
  262.   SetUsingBreakpointFileFlag();
  263.   fclose(BkptFile_fp);
  264.  }
  265.  else
  266.   ResetUsingBreakpointFileFlag();
  267.  
  268.  ResetBreakpointFileTime();
  269.  return;
  270. }
  271.  
  272. /*****************************************************************************/
  273. /* MergeBreakpoints()                                                        */
  274. /*                                                                           */
  275. /* Description:                                                              */
  276. /*                                                                           */
  277. /*   Make a decision aboute whether or not to restore the breakpoints        */
  278. /*   from a file.                                                            */
  279. /*                                                                           */
  280. /* Parameters:                                                               */
  281. /*                                                                           */
  282. /* Return:                                                                   */
  283. /*                                                                           */
  284. /* Assumptions:                                                              */
  285. /*                                                                           */
  286. /*****************************************************************************/
  287. void MergeBreakpoints( void )
  288. {
  289.  if( IsUsingBreakpointFile() == TRUE )
  290.  {
  291.   AFILE *fp;
  292.  
  293.   RestoreBreakpoints();
  294.  
  295.   fp = Getfp_focus();
  296.   if(fp)
  297.    MarkLineBRKs(fp);
  298.  }
  299. }
  300.  
  301. /*****************************************************************************/
  302. /* RestoreBreakpoints                                                        */
  303. /*                                                                           */
  304. /* Description:                                                              */
  305. /*                                                                           */
  306. /*   Read a file of breakpoints and define them.                             */
  307. /*                                                                           */
  308. /* Parameters:                                                               */
  309. /*                                                                           */
  310. /* Return:                                                                   */
  311. /*                                                                           */
  312. /* Assumptions:                                                              */
  313. /*                                                                           */
  314. /*****************************************************************************/
  315. void RestoreBreakpoints( void )
  316. {
  317.  APIRET   rc;
  318.  int      Length;
  319.  char    *pEnvSD386Brk;
  320.  off_t    BkptFileSize;
  321.  FILE    *BkptFile_fp;
  322.  char    *pBkptFileText;
  323.  char    *pBkptFileTextEnd;
  324.  char    *pBkptDefinition;
  325.  char    *pTempCopyBkptDefinition;
  326.  char    *pCopyBkptDefinition;
  327.  char    *pToken;
  328.  int      BkptIndex;
  329.  int      NumBreaks;
  330.  int      errlno;
  331.  char    *pMsg;
  332.  BOOL     SyntaxErr;
  333.  char    *cp;
  334.  int      CommaCount;
  335.  ULONG    addr;
  336.  ULONG    mid;
  337.  ULONG    junk;
  338.  DEBFILE *pdf;
  339.  BRK     *pBrk = NULL;
  340.  ULONG    lno;
  341.  int     *pBkptLinNumInfo;
  342.  int      DefineType;
  343.  int      sfi;
  344.  
  345.  struct stat statbuffer;
  346.  
  347.  struct _syntax
  348.  {
  349.   char *pexe;
  350.   char *pfunc;
  351.   char *pfile;
  352.   char *plno;
  353.   char *pdefr;
  354.   char *pcond;
  355.  }syntax;
  356.  
  357.  pCopyBkptDefinition = NULL;
  358.  pBkptFileText       = NULL;
  359.  
  360.  /****************************************************************************/
  361.  /* - Get the breakpoint file environment variable. If it's not defined      */
  362.  /*   then the user said he didn't want to use a breakpoint file.            */
  363.  /****************************************************************************/
  364.  pEnvSD386Brk = GetSD386Brk();
  365.  
  366.  /****************************************************************************/
  367.  /* Get some information about the breakpoint file. If it can't be accessed  */
  368.  /* then display a message.                                                  */
  369.  /****************************************************************************/
  370.  BkptFile_fp = fopen(pEnvSD386Brk,"rb");
  371.  if( BkptFile_fp == NULL )
  372.  {
  373.    Error( ERR_BKPT_FILE_OPEN, FALSE, 1, pEnvSD386Brk );
  374.    return;
  375.  }
  376.  
  377.  /****************************************************************************/
  378.  /* - Get the file status. We assume this will work since the fopen worked.  */
  379.  /* - If it hasn't changed then don't update it.                             */
  380.  /****************************************************************************/
  381.  fstat( fileno(BkptFile_fp), &statbuffer );
  382.  
  383.  if( BreakpointFileTime == -1 )
  384.  ;
  385.  else
  386.  {
  387.   /***************************************************************************/
  388.   /* - check the time stamp and if it hasn't changed don't do anything.      */
  389.   /***************************************************************************/
  390.   if( statbuffer.st_mtime <= BreakpointFileTime )
  391.    goto fini;
  392.  }
  393.  
  394.  /****************************************************************************/
  395.  /* - update the time stamp.                                                 */
  396.  /****************************************************************************/
  397.  BreakpointFileTime = statbuffer.st_mtime;
  398.  
  399.  /****************************************************************************/
  400.  /* - Allocate/read the breakpoint file.                                     */
  401.  /****************************************************************************/
  402.  BkptFileSize = statbuffer.st_size;
  403.  
  404.  if( BkptFileSize == 0 )
  405.    return;
  406.  
  407.  SayMsgBox5( HELP_BKPTS_RESTORE_MSG, 1, pEnvSD386Brk );
  408.  
  409.  pBkptFileText = Talloc(BkptFileSize + 1);
  410.  
  411.  fread( pBkptFileText, BkptFileSize, 1, BkptFile_fp);
  412.  
  413.  /****************************************************************************/
  414.  /* - Strip out the comments.                                                */
  415.  /* - Remove the crlfs.                                                      */
  416.  /* - Get the number of breakpoints and build a table of breakpoint          */
  417.  /*   line number locations.                                                 */
  418.  /* - Blank out crlfs.                                                       */
  419.  /****************************************************************************/
  420.  pBkptFileTextEnd = pBkptFileText + BkptFileSize - 1;
  421.  
  422.  rc = StripComments( pBkptFileText, pBkptFileTextEnd );
  423.  if( rc != 0 )
  424.   Error( ERR_BKPT_FILE_COMMENT, FALSE, 1, pEnvSD386Brk );
  425.  
  426.  NumBreaks = 0;
  427.  pBkptLinNumInfo = BuildBkptLinNumInfo(  pBkptFileText,
  428.                                          pBkptFileTextEnd,
  429.                                         &NumBreaks
  430.                                       );
  431.  
  432.  BlankOutCRLFs( pBkptFileText, pBkptFileTextEnd );
  433.  
  434.  /****************************************************************************/
  435.  /* - Tokenize/process the breakpoints.                                      */
  436.  /****************************************************************************/
  437.  BkptIndex = 0;
  438.  SyntaxErr = FALSE;
  439.  pBkptDefinition = strtok( pBkptFileText, "}");
  440.  do
  441.  {
  442.   char *cps;
  443.   char *cpd;
  444.  
  445.   /***************************************************************************/
  446.   /* - Allocate space for a copy of the breakpoint.                          */
  447.   /* - Allocate space for a temp copy of the breakpoint.                     */
  448.   /* - Copy the break point to the temp copy.                                */
  449.   /* - Compress the temp copy.                                               */
  450.   /* - Copy the temp copy to the "real" copy adding spaces in front of       */
  451.   /*   any commas.                                                           */
  452.   /*                                                                         */
  453.   /*    This is done to force strtok() to work in the desired manner.        */
  454.   /*    The additional 4 bytes of allocation is for the maximum number       */
  455.   /*    of comma delimiters.                                                 */
  456.   /*                                                                         */
  457.   /* - free the temp copy.                                                   */
  458.   /*                                                                         */
  459.   /***************************************************************************/
  460.   Length = strlen(pBkptDefinition) + 1 + 4;
  461.   cps    = pTempCopyBkptDefinition = Talloc( Length );
  462.   cpd    = pCopyBkptDefinition     = Talloc( Length );
  463.  
  464.   strcpy(pTempCopyBkptDefinition, pBkptDefinition );
  465.   Strip( pTempCopyBkptDefinition, '.', '.', 'c');
  466.   for(; *cpd++ = *cps++ ;) {if(*cps == ',') *cpd++ = ' ';}
  467.   Tfree(pTempCopyBkptDefinition);
  468.  
  469.   /***************************************************************************/
  470.   /* - We will build a structure of pointers to the tokens.                  */
  471.   /***************************************************************************/
  472.   memset( &syntax, 0, sizeof(syntax) );
  473.   pToken = strtok( pCopyBkptDefinition, ",");
  474.  
  475.   /***************************************************************************/
  476.   /* - process dll/exe token                                                 */
  477.   /***************************************************************************/
  478.   if( (pToken == NULL) || (*pToken != '{') )
  479.   {
  480.    Error( ERR_BKPT_FILE_SYNTAX_BRACE, FALSE, 1, pEnvSD386Brk );
  481.    SyntaxErr = TRUE; goto error;
  482.   }
  483.   else if( *(pToken+1) == ' ' )
  484.   {
  485.    pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_DLLEXE, NULL, 0);
  486.    beep(); SayStatusMsg(pMsg);
  487.  
  488.    errlno = pBkptLinNumInfo[BkptIndex];
  489.    browse(pEnvSD386Brk, errlno );
  490.    SyntaxErr = TRUE; goto error;
  491.   }
  492.   else
  493.   {
  494.    syntax.pexe = pToken + 1;
  495.  
  496.    /**************************************************************************/
  497.    /* - process function name/ (filename,line number) token.                 */
  498.    /**************************************************************************/
  499.    pToken = strtok(NULL, ",");
  500.  
  501.    if( (pToken == NULL) || (*pToken == ' ') )
  502.    {
  503.     pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_FUNC, NULL, 0);
  504.     beep(); SayStatusMsg(pMsg);
  505.  
  506.     errlno = pBkptLinNumInfo[BkptIndex];
  507.     browse(pEnvSD386Brk, errlno );
  508.     SyntaxErr = TRUE; goto error;
  509.    }
  510.    else if( strchr(pToken, '.') == NULL )
  511.      syntax.pfunc = pToken;
  512.    else
  513.    {
  514.     syntax.pfile = pToken;
  515.  
  516.     /*************************************************************************/
  517.     /* - process the line number.                                            */
  518.     /*************************************************************************/
  519.     pToken = strtok(NULL, "," );
  520.     if( (pToken == NULL) || (*pToken == ' ') )
  521.     {
  522.      pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_LNO, NULL, 0);
  523.      beep(); SayStatusMsg(pMsg);
  524.  
  525.      errlno = pBkptLinNumInfo[BkptIndex];
  526.      browse(pEnvSD386Brk, errlno );
  527.      SyntaxErr = TRUE; goto error;
  528.     }
  529.     else
  530.     {
  531.      /************************************************************************/
  532.      /* - Verify that the line number is a number.                           */
  533.      /************************************************************************/
  534.      for( cp = pToken ; *cp ; cp++ )
  535.      {
  536.       if( ((*cp < '0') || (*cp > '9')) && (*cp != ' ') )
  537.       {
  538.        pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_LNO, NULL, 0);
  539.        beep(); SayStatusMsg(pMsg);
  540.  
  541.        errlno = pBkptLinNumInfo[BkptIndex];
  542.        browse(pEnvSD386Brk, errlno );
  543.        SyntaxErr = TRUE; goto error;
  544.       }
  545.      }
  546.      syntax.plno = pToken;
  547.     }
  548.    }
  549.  
  550.    /**************************************************************************/
  551.    /* - now look for a type and condition.                                   */
  552.    /**************************************************************************/
  553.    pToken = strtok(NULL, "," );
  554.    if( (pToken == NULL) || (*pToken == ' ') )
  555.    ;/* done parsing */
  556.    else
  557.    {
  558.     if( (stricmp(pToken, "d ") != 0) && (stricmp(pToken, "d") != 0) )
  559.      syntax.pcond = pToken;
  560.     else
  561.     {
  562.      syntax.pdefr = pToken;
  563.  
  564.      pToken = strtok(NULL, "," );
  565.      if( (pToken == NULL) || (*pToken == ' ') )
  566.      ;/* done parsing */
  567.      else
  568.       syntax.pcond = pToken;
  569.     }
  570.    }
  571.   }
  572.  
  573.   /***************************************************************************/
  574.   /*  - At this point, we're done parsing.                                   */
  575.   /*  - The conditional text may have been compressed for the parsing;so now,*/
  576.   /*    if there was a condition, then we have to define a pointer to        */
  577.   /*    the real condition in the original breakpoint definition.            */
  578.   /*                                                                         */
  579.   /***************************************************************************/
  580.   if( syntax.pcond != NULL )
  581.   {
  582.    /**************************************************************************/
  583.    /* - Count the number of commas that were been tokenized.                 */
  584.    /* - Move to the location of the nth comma in the original breakpoint     */
  585.    /*   text and define this as the pointer to the breakpoint condition.     */
  586.    /**************************************************************************/
  587.    CommaCount = 0;
  588.    cp         = pCopyBkptDefinition;
  589.    for( ; cp < syntax.pcond; cp++ ) if( *cp == '\0' ) CommaCount++;
  590.  
  591.    for( cp = pBkptDefinition; CommaCount; cp++ )
  592.     if( *cp == ',' )
  593.      CommaCount--;
  594.  
  595.    syntax.pcond = cp;
  596.   }
  597.  
  598.   /****************************************************************************/
  599.   /* - Now, define the breakpoint.                                            */
  600.   /****************************************************************************/
  601.   Strip( syntax.pexe, '.', '.', 'c');
  602.  
  603.   DefineType = BP_FUNC_NAME;
  604.   if( syntax.pfunc == NULL )
  605.    DefineType = BP_SRC_LNO;
  606.  
  607.   /***************************************************************************/
  608.   /* - kill a .dll extension if there is one.                                */
  609.   /***************************************************************************/
  610.   if( syntax.pexe && ((cp = strchr( syntax.pexe, '.' )) != NULL) )
  611.    *cp = '\0';
  612.  
  613.   pdf = findpdf( syntax.pexe );
  614.   if( pdf == NULL )
  615.   {
  616.    /***************************************************************************/
  617.    /* - force the deferred condition.                                         */
  618.    /***************************************************************************/
  619.    syntax.pdefr = (void*)1UL;
  620.  
  621.    if( DefineType == BP_FUNC_NAME )
  622.    {
  623.     Strip( syntax.pfunc, '.', '.', 'c');
  624.  
  625.     pBrk                  = DefBrk( NULL, FALSE );
  626.     pBrk->flag.DorI       = BP_DEFR;
  627.     pBrk->flag.DefineType = BP_FUNC_NAME;
  628.     pBrk->flag.ActionType = BRK_SIMP;
  629.     pBrk->flag.File       = TRUE;
  630.  
  631.     if( strstr(syntax.pexe , "(null)") )
  632.      pBrk->dllname = NULL;
  633.     else
  634.     {
  635.      pBrk->dllname = Talloc(strlen(syntax.pexe)+1);
  636.      strcpy(pBrk->dllname, syntax.pexe);
  637.     }
  638.  
  639.     if( strstr(syntax.pfunc, "(null)") )
  640.     {
  641.      pBrk->funcname        = NULL;
  642.      pBrk->flag.DefineType = BP_DLL_LOAD;
  643.     }
  644.     else
  645.     {
  646.      pBrk->funcname = Talloc(strlen(syntax.pfunc)+1);
  647.      strcpy(pBrk->funcname, syntax.pfunc);
  648.     }
  649.    }
  650.    else
  651.    {
  652.     Strip( syntax.pfile, '.', '.', 'c');
  653.  
  654.     pBrk                  = DefBrk( NULL, FALSE );
  655.     pBrk->flag.DorI       = BP_DEFR;
  656.     pBrk->flag.DefineType = BP_SRC_LNO;
  657.     pBrk->flag.ActionType = BRK_SIMP;
  658.     pBrk->flag.File       = TRUE;
  659.     pBrk->lno             = atol( syntax.plno );
  660.     pBrk->srcname         = Talloc(strlen(syntax.pfile)+1);
  661.     pBrk->dllname         = Talloc(strlen(syntax.pexe)+1);
  662.  
  663.     strcpy(pBrk->dllname, syntax.pexe);
  664.     strcpy(pBrk->srcname, syntax.pfile);
  665.    }
  666.  
  667.    if( syntax.pcond )
  668.    {
  669.     cp = syntax.pcond;
  670.     while( *cp == ' ') cp++;
  671.     if( *cp == '!' )
  672.      pBrk->cond->relation = COND_MSH;
  673.    }
  674.   }
  675.   else /* pdf != NULL */
  676.   /****************************************************************************/
  677.   /* - define an immediate breakpoint.                                        */
  678.   /****************************************************************************/
  679.   {
  680.    if( DefineType == BP_FUNC_NAME )
  681.    {
  682.     /**************************************************************************/
  683.     /* - function name entry point/immediate.                                 */
  684.     /**************************************************************************/
  685.     Strip( syntax.pfunc, '.', '.', 'c');
  686.  
  687.     addr = DBPub(syntax.pfunc, pdf);
  688.     if( addr == 0 )
  689.     {
  690.      /************************************************************************/
  691.      /* - check for microsoft underscore names.                              */
  692.      /************************************************************************/
  693.      int   len = strlen(syntax.pfunc);
  694.      char *cp  = Talloc(len + 2);
  695.  
  696.      cp[0] = '_';
  697.      strcpy(cp+1, syntax.pfunc);
  698.      addr = DBPub(cp, pdf);
  699.      Tfree(cp);
  700.     }
  701.  
  702.     {
  703.      LNOTAB *pLnoTabEntry;
  704.  
  705.      lno = 0;
  706.      mid = DBMapInstAddr( addr, &pLnoTabEntry, pdf);
  707.      if( pLnoTabEntry != NULL )
  708.      {
  709.       lno = pLnoTabEntry->lno;
  710.       sfi = pLnoTabEntry->sfi;
  711.      }
  712.     }
  713.  
  714.     if( addr == NULL )
  715.     {
  716.      pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_NOFUNC, NULL, 0);
  717.      beep(); SayStatusMsg(pMsg);
  718.  
  719.      errlno = pBkptLinNumInfo[BkptIndex];
  720.      browse(pEnvSD386Brk, errlno );
  721.      SyntaxErr = TRUE; goto error;
  722.     }
  723.    }
  724.    else
  725.    {
  726.     /**************************************************************************/
  727.     /* - (filename, line number) breakpoint/immediate.                        */
  728.     /**************************************************************************/
  729.     Strip( syntax.pfile, '.', '.', 'c');
  730.  
  731.     cp = strrchr( syntax.pfile, '\\' );
  732.     cp = ( cp == NULL )?syntax.pfile:cp+1;
  733.     {
  734.      /************************************************************************/
  735.      /* - need to build an lpz. ( added at linnum re-write.)                 */
  736.      /************************************************************************/
  737.      UCHAR len;
  738.      char  *cpp;
  739.  
  740.      len     = strlen(cp);
  741.      cpp     = Talloc(len + 2);
  742.      cpp[0]  = len;
  743.  
  744.      strcpy(cpp+1, cp );
  745.  
  746.      mid = MapSourceFileToMidSfi( cpp, &sfi, pdf );
  747.      if(cpp) Tfree(cpp);
  748.     }
  749.     lno = atol( syntax.plno );
  750.  
  751.     if( mid == 0 )
  752.     {
  753.      pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_NOFILE, NULL, 0);
  754.      beep(); SayStatusMsg(pMsg);
  755.  
  756.      errlno = pBkptLinNumInfo[BkptIndex];
  757.      browse(pEnvSD386Brk, errlno );
  758.      SyntaxErr = TRUE; goto error;
  759.     }
  760.  
  761.     addr = DBMapLno(mid, lno, sfi, &junk , pdf );
  762.     if( addr == NULL )
  763.     {
  764.      uchar plno[80];
  765.      UCHAR   *SubStringTable[MAX_SUBSTRINGS];
  766.      sprintf(plno,"%d",lno);
  767.      SubStringTable[0]=plno;
  768.      SubStringTable[1]=cp;
  769.      pMsg = GetHelpMsg(ERR_BKPT_DEFN_LINENO, SubStringTable,2);
  770.      beep();
  771.      SayStatusMsg(pMsg);
  772.  
  773.      errlno = pBkptLinNumInfo[BkptIndex];
  774.      browse(pEnvSD386Brk, errlno );
  775.      SyntaxErr = TRUE; goto error;
  776.     }
  777.    }
  778.  
  779.    /**************************************************************************/
  780.    /* - Check for a breakpoint already defined at this address and undefine  */
  781.    /*   it if there is one.                                                  */
  782.    /**************************************************************************/
  783.    pBrk = IfBrkOnAddr( addr );
  784.    if( pBrk )
  785.     UndBrk( addr, TRUE );
  786.  
  787.    pBrk                  = DefBrk( addr, TRUE );
  788.    pBrk->flag.DorI       = BP_IMMEDIATE;
  789.    pBrk->flag.DefineType = DefineType;
  790.    pBrk->flag.ActionType = BRK_SIMP;
  791.    pBrk->flag.File       = TRUE;
  792.    pBrk->lno             = lno;
  793.    pBrk->mid             = mid;
  794.    pBrk->sfi             = sfi;
  795.    pBrk->dllname         = Talloc(strlen(syntax.pexe)+1);
  796.  
  797.    strcpy(pBrk->dllname, syntax.pexe);
  798.  
  799.    if( DefineType == BP_FUNC_NAME )
  800.    {
  801.     pBrk->funcname = Talloc(strlen(syntax.pfunc) + 1);
  802.     strcpy(pBrk->funcname, syntax.pfunc);
  803.    }
  804.    else
  805.    {
  806.     pBrk->srcname = Talloc(strlen(syntax.pfile) + 1);
  807.     strcpy(pBrk->srcname, syntax.pfile);
  808.    }
  809.   }
  810.  
  811.   /***************************************************************************/
  812.   /* - add conditional information to the breakpoint.                        */
  813.   /***************************************************************************/
  814.   if( syntax.pcond )
  815.   {
  816.    pBrk->cond             = (BRKCOND*) Talloc(sizeof(BRKCOND));
  817.    pBrk->cond->pCondition = Talloc(strlen(syntax.pcond)+1);
  818.  
  819.    strcpy(pBrk->cond->pCondition, syntax.pcond);
  820.  
  821.    cp = syntax.pcond;
  822.    while( *cp == ' ') cp++;
  823.  
  824.    if( *cp == '!' )
  825.     pBrk->cond->relation = COND_MSH;
  826.  
  827.    if( syntax.pdefr == NULL )
  828.    {
  829.     /************************************************************************/
  830.     /* - If this is not a deferred break, then we can parse the condition   */
  831.     /*   and report any errors. If the breakpoint is deferred, we have to   */
  832.     /*   wait until convertdefbrks() gets called at module load time.       */
  833.     /************************************************************************/
  834.     cp = ParseCbrk( pBrk->cond, mid, lno, sfi );
  835.     if(cp)
  836.     {
  837.      pMsg = GetHelpMsg(ERR_BKPT_FILE_SYNTAX_COND, &cp, 1 );
  838.      beep(); SayStatusMsg(pMsg);
  839.  
  840.      errlno = pBkptLinNumInfo[BkptIndex];
  841.      browse(pEnvSD386Brk, errlno );
  842.      SyntaxErr = TRUE; goto error;
  843.     }
  844.    }
  845.   }
  846.  
  847.   Tfree(pCopyBkptDefinition);
  848.   pCopyBkptDefinition = NULL;
  849.  
  850.  
  851.   pBkptDefinition += strlen(pBkptDefinition) + 1;
  852.   pBkptDefinition  = strtok(pBkptDefinition, "}" );
  853.   BkptIndex++;
  854.  }
  855.  while( (BkptIndex < NumBreaks) && (pBkptDefinition != NULL) );
  856.  
  857. /*****************************************************************************/
  858. /* - come here after all break have been processed.                          */
  859. /* - come here on syntax errors.                                             */
  860. /*****************************************************************************/
  861. fini:
  862. error:
  863.  if( BkptFile_fp )
  864.   fclose( BkptFile_fp );
  865.  
  866.  if( pBkptFileText )       Tfree(pBkptFileText);
  867.  if( pCopyBkptDefinition ) Tfree(pCopyBkptDefinition);
  868.  
  869.  if( (SyntaxErr == TRUE) && pBrk )
  870.  {
  871.   if( syntax.pdefr )
  872.    UndBrk( pBrk->brkat, FALSE );
  873.   else
  874.    UndBrk( pBrk->brkat, TRUE );
  875.  }
  876.  return;
  877. }
  878.  
  879. /*****************************************************************************/
  880. /* EditBreakpoints                                                           */
  881. /*                                                                           */
  882. /* Description:                                                              */
  883. /*                                                                           */
  884. /*   Edit the breakpoint file.                                               */
  885. /*                                                                           */
  886. /* Parameters:                                                               */
  887. /*                                                                           */
  888. /* Return:                                                                   */
  889. /*                                                                           */
  890. /* Assumptions:                                                              */
  891. /*                                                                           */
  892. /*****************************************************************************/
  893. static ULONG EditorSessionID;
  894. void EditBreakpoints( void )
  895. {
  896.  APIRET  rc;
  897.  char   *pEnvSD386Editor;
  898.  char   *pEnvSD386Brk;
  899.  FILE   *EditFile_fp;
  900.  char    Editor[CCHMAXPATH];
  901.  BOOL    EditAccess;
  902.  FILE    *BkptFile_fp;
  903.  
  904.  struct stat statbuffer;
  905.  
  906.  /****************************************************************************/
  907.  /* - Get the editor environment variable.                                   */
  908.  /****************************************************************************/
  909.  pEnvSD386Editor = GetSD386Editor();
  910.  
  911.  if( pEnvSD386Editor == NULL )
  912.  {
  913.   Error( ERR_BKPT_FILE_ENV_EDITOR, FALSE, NULL, 0 );
  914.   return;
  915.  }
  916.  
  917.  /****************************************************************************/
  918.  /* - now, make sure that we can access the editor.                          */
  919.  /****************************************************************************/
  920.  EditFile_fp = NULL;
  921.  EditAccess  = TRUE;
  922.  if( strrchr(pEnvSD386Editor, '\\' ) )
  923.  {
  924.   /***************************************************************************/
  925.   /* - test with fopen if an explicit path was given.                        */
  926.   /***************************************************************************/
  927.   EditFile_fp = fopen(pEnvSD386Editor,"r");
  928.   if( EditFile_fp == NULL )
  929.    EditAccess = FALSE;
  930.  }
  931.  else
  932.  {
  933.   rc=DosSearchPath(SEARCH_IGNORENETERRS|SEARCH_ENVIRONMENT|SEARCH_CUR_DIRECTORY,
  934.                    "PATH",
  935.                    pEnvSD386Editor,
  936.                    Editor,
  937.                    sizeof(Editor) );
  938.   if( rc )
  939.    EditAccess = FALSE;
  940.  }
  941.  
  942.  /****************************************************************************/
  943.  /* - now, are we able to access the editor?                                 */
  944.  /****************************************************************************/
  945.  if( EditAccess == FALSE )
  946.  {
  947.   Error( ERR_BKPT_FILE_EDITOR_OPEN, FALSE, 1, pEnvSD386Editor );
  948.   if( EditFile_fp ) fclose(EditFile_fp);
  949.   return;
  950.  }
  951.  
  952.  if( EditFile_fp ) fclose(EditFile_fp);
  953.  
  954.  /****************************************************************************/
  955.  /* - Get the breakpoint file environment variable. If it's not defined      */
  956.  /*   then the user said he didn't want to use a breakpoint file.            */
  957.  /****************************************************************************/
  958.  pEnvSD386Brk = GetSD386Brk();
  959.  
  960.  if( pEnvSD386Brk == NULL )
  961.  {
  962.   Error( ERR_BKPT_FILE_ENV_SD386BRK, FALSE, NULL, 0 );
  963.   return;
  964.  }
  965.  
  966.  /****************************************************************************/
  967.  /* Get some information about the breakpoint file. If it can't be accessed  */
  968.  /* then display a message.                                                  */
  969.  /****************************************************************************/
  970.  BkptFile_fp = fopen(pEnvSD386Brk,"rb");
  971.  if( BkptFile_fp == NULL )
  972.  {
  973.    Error( ERR_BKPT_FILE_OPEN, FALSE, 1, pEnvSD386Brk );
  974.    return;
  975.  }
  976.  
  977.  /****************************************************************************/
  978.  /* - If an editor session was previously started, then:                     */
  979.  /*                                                                          */
  980.  /*    1.the user may have edited the file and saved it.                     */
  981.  /*    2.the user may have simply quit without modifying.                    */
  982.  /*    3.the edit session may still be out there.                            */
  983.  /*                                                                          */
  984.  /* - We want to detect cases 1 and 2 and invalidate the session id.         */
  985.  /* - In case 3, we simply want to select the session.                       */
  986.  /*                                                                          */
  987.  /****************************************************************************/
  988.  if( EditorSessionID != 0 )
  989.  {
  990.   fstat( fileno(BkptFile_fp), &statbuffer );
  991.   if( statbuffer.st_mtime <= BreakpointFileTime )
  992.   {
  993.    rc = DosSelectSession( EditorSessionID );
  994.    if( rc )
  995.     EditorSessionID = 0;
  996.   }
  997.   else
  998.    EditorSessionID = 0;
  999.  }
  1000.  
  1001.  if( EditorSessionID == 0 )
  1002.  {
  1003.   extern CmdParms cmd;
  1004.  
  1005.   STARTDATA  sd;
  1006.   char       MsgBuf[CCHMAXPATH];
  1007.   ULONG      pid;
  1008.   ULONG      EditorType;
  1009.   ULONG      SessionType;
  1010.  
  1011.   /***************************************************************************/
  1012.   /* - Define the session type.                                              */
  1013.   /***************************************************************************/
  1014.   SessionType = SSF_TYPE_DEFAULT;
  1015.   if( cmd.ProcessType != SSF_TYPE_PM )
  1016.   ;
  1017.   else
  1018.   {
  1019.    DosQueryAppType( pEnvSD386Editor, &EditorType );
  1020.    EditorType = EditorType & 0x7;
  1021.    if( EditorType == SSF_TYPE_PM )
  1022.    {
  1023.     Error( ERR_BKPT_FILE_EDITOR_PMTYPE, FALSE, NULL, 0 );
  1024.     return;
  1025.    }
  1026.    SessionType = SSF_TYPE_FULLSCREEN;
  1027.   }
  1028.  
  1029.   /***************************************************************************/
  1030.   /* - time stamp the file.                                                  */
  1031.   /***************************************************************************/
  1032.   if(BkptFile_fp)
  1033.   {
  1034.    fstat( fileno(BkptFile_fp), &statbuffer );
  1035.    BreakpointFileTime = statbuffer.st_mtime;
  1036.    fclose(BkptFile_fp);
  1037.   }
  1038.  
  1039.   memset(&sd, 0, sizeof(sd) );
  1040.   memset(MsgBuf, 0, sizeof(MsgBuf) );
  1041.  
  1042.   sd.Length        = sizeof(sd);
  1043.   sd.Related       = SSF_RELATED_CHILD;
  1044.   sd.FgBg          = SSF_FGBG_FORE;
  1045.   sd.TraceOpt      = SSF_TRACEOPT_NONE;
  1046.   sd.InheritOpt    = SSF_INHERTOPT_PARENT;
  1047.   sd.PgmName       = pEnvSD386Editor;
  1048.   sd.PgmInputs     = pEnvSD386Brk;
  1049.   sd.SessionType   = SessionType;
  1050.   sd.PgmTitle      = "SD386 Breakpoint Editor";
  1051.   sd.PgmControl    = SSF_CONTROL_VISIBLE;
  1052.   sd.ObjectBuffLen = sizeof(MsgBuf);
  1053.   sd.ObjectBuffer  = MsgBuf;
  1054.  
  1055.   rc = DosStartSession( (PSTARTDATA)&sd, &EditorSessionID, &pid );
  1056.   if(rc)
  1057.   {
  1058.    char rcstring[20];
  1059.  
  1060.    sprintf(rcstring, "%d", rc);
  1061.    Error( ERR_BKPT_FILE_EDITOR_START, FALSE, 2, rcstring, MsgBuf );
  1062.   }
  1063.  }
  1064. }
  1065.  
  1066.  
  1067. /*****************************************************************************/
  1068. /* Strip()                                                                   */
  1069. /*                                                                           */
  1070. /* Description:                                                              */
  1071. /*                                                                           */
  1072. /*   Strip characters from a string with optional compression.               */
  1073. /*                                                                           */
  1074. /* Parameters:                                                               */
  1075. /*                                                                           */
  1076. /*   cp             -> to the string.                                        */
  1077. /*   c              character to be removed.                                 */
  1078. /*   copt           which ones to remove:                                    */
  1079. /*                   'l' ==>Leading                                          */
  1080. /*                   't' ==>Trailing                                         */
  1081. /*                   'a' ==>All                                              */
  1082. /*                   '.' ==>ignore                                           */
  1083. /*   xopt           compression:                                             */
  1084. /*                   'c' ==>compress(left justify)                           */
  1085. /*                   '.' ==>no compression                                   */
  1086. /*                                                                           */
  1087. /* Return:                                                                   */
  1088. /*                                                                           */
  1089. /* Assumptions:                                                              */
  1090. /*                                                                           */
  1091. /*   The string is a null terminated.                                        */
  1092. /*                                                                           */
  1093. /*   Removed characters are replaced with blanks.                            */
  1094. /*                                                                           */
  1095. /*   Compression means removing the spaces after the characters are          */
  1096. /*   removed and left-justifying the string.                                 */
  1097. /*                                                                           */
  1098. /*****************************************************************************/
  1099. #define BLANK ' '
  1100. void Strip(char *cp, char c, char copt, char xopt)
  1101. {
  1102.  char *cpp;
  1103.  char *cpq;
  1104.  char *cpr;
  1105.  char *cpend;
  1106.  
  1107.  switch( tolower(copt) )
  1108.  {
  1109.   case 't':
  1110.    /**************************************************************************/
  1111.    /* - Scan to the last non-blank character in the string.                  */
  1112.    /* - Replace it with a blank.                                             */
  1113.    /**************************************************************************/
  1114.    for( cpp=cp+strlen(cp)-1; (cpp >= cp) && (*cpp==BLANK); cpp--){;}
  1115.    if( (cpp >= cp) && (*cpp == c) )
  1116.     *cpp = BLANK;
  1117.    break;
  1118.  
  1119.   case 'l':
  1120.    /**************************************************************************/
  1121.    /* - Scan to the first non-blank character in the string.                 */
  1122.    /* - Replace it with a blank.                                             */
  1123.    /**************************************************************************/
  1124.    for( cpp=cp, cpend=cp+strlen(cp); (cpp < cpend) && (*cpp==BLANK); cpp++){;}
  1125.    if( (cpp < cpend) && (*cpp == c) )
  1126.     *cpp = BLANK;
  1127.    break;
  1128.  
  1129.   case 'a':
  1130.    /**************************************************************************/
  1131.    /* - Scan the string replacing all matching chars with blanks.            */
  1132.    /**************************************************************************/
  1133.    for( cpp=cp, cpend=cp+strlen(cp); cpp < cpend ; cpp++)
  1134.    {
  1135.     if( *cpp == c )
  1136.       *cpp = BLANK;
  1137.    }
  1138.    break;
  1139.  
  1140.   case '.':
  1141.    break;
  1142.  }
  1143.  
  1144.  /****************************************************************************/
  1145.  /* Now, do the compression.                                                 */
  1146.  /****************************************************************************/
  1147.  if( tolower(xopt) == 'c' )
  1148.  {
  1149.   for( cpp=cp; ; cpp++)
  1150.   {
  1151.    if( *cpp == BLANK )
  1152.    {
  1153.     for( cpq=cpp; *cpq == BLANK; cpq++ ){;}
  1154.     for( cpr=cpp; *cpr++ = *cpq++; ){;}
  1155.    }
  1156.    if( *cpp == '\0' )
  1157.     break;
  1158.   }
  1159.  }
  1160. }
  1161.  
  1162.  
  1163. /*****************************************************************************/
  1164. /* StripComments()                                                           */
  1165. /*                                                                           */
  1166. /* Description:                                                              */
  1167. /*                                                                           */
  1168. /*   Strip comments from a block of text. Allow for nested comments.         */
  1169. /*                                                                           */
  1170. /* Parameters:                                                               */
  1171. /*                                                                           */
  1172. /*   pTextBlk    ->to the block of text.                                     */
  1173. /*   pEndOfText  ->to the end of the text block.                             */
  1174. /*                                                                           */
  1175. /* Return:                                                                   */
  1176. /*                                                                           */
  1177. /*   rc     0 ==>success                                                     */
  1178. /*          1 ==>failure( unmatched comment at this time )                   */
  1179. /*                                                                           */
  1180. /* Assumptions:                                                              */
  1181. /*                                                                           */
  1182. /*****************************************************************************/
  1183. APIRET StripComments( char *pTextBlk, char *pEndOfText )
  1184. {
  1185.  char *cp;
  1186.  char *cpp;
  1187.  char *cpend;
  1188.  
  1189.  /****************************************************************************/
  1190.  /* - scan for the start of a comment.                                       */
  1191.  /****************************************************************************/
  1192.  cpp   = pTextBlk;
  1193.  cpend = pEndOfText;
  1194.  while( cpp <= pEndOfText )
  1195.  {
  1196.   for( cp = cpp; (cp <= cpend) && (*cp != '/'); cp++ ){;}
  1197.  
  1198.   cpp = FindEndOfComment( cp+1, pEndOfText );
  1199.  
  1200.   /***************************************************************************/
  1201.   /* - check for unmatched comment error.                                    */
  1202.   /***************************************************************************/
  1203.   if( cpp == NULL )
  1204.    return(1);
  1205.  
  1206.   /***************************************************************************/
  1207.   /* - blank out the comment.                                                */
  1208.   /***************************************************************************/
  1209.   if( cpp > (cp+1) )
  1210.    BlankOut(cp, cpp);
  1211.  }
  1212.  return(0);
  1213. }
  1214.  
  1215. /*****************************************************************************/
  1216. /* FindEndOfComment()                                                        */
  1217. /*                                                                           */
  1218. /* Description:                                                              */
  1219. /*                                                                           */
  1220. /*   Find the end of a comment in a block of text. The comment may contain   */
  1221. /*   nested comments.                                                        */
  1222. /*                                                                           */
  1223. /* Parameters:                                                               */
  1224. /*                                                                           */
  1225. /*   pTextBlk    ->to the block of text.                                     */
  1226. /*   pEndOfText  ->to the end of the text block.                             */
  1227. /*                                                                           */
  1228. /* Return:                                                                   */
  1229. /*                                                                           */
  1230. /*   cp  -> to the end of the comment.                                       */
  1231. /*       NULL if unmatched comment.                                          */
  1232. /*                                                                           */
  1233. /* Assumptions:                                                              */
  1234. /*                                                                           */
  1235. /*            ......./...                                                    */
  1236. /*                    |                                                      */
  1237. /*                    |                                                      */
  1238. /*  pStartOfComment-->   points to this position in the text.                */
  1239. /*                                                                           */
  1240. /*****************************************************************************/
  1241. char *FindEndOfComment( char *pStartOfComment, char *pEndOfText )
  1242. {
  1243.  char *cp;
  1244.  int   NestCount = 0;
  1245.  
  1246.  /****************************************************************************/
  1247.  /*                                                                          */
  1248.  /*                       ----------------------------------                 */
  1249.  /*                      |                                  |*               */
  1250.  /*                      |                                 -----------       */
  1251.  /*                      |                                |Start of   |      */
  1252.  /*                      |                          ----->|Comment    |      */
  1253.  /*                      |                   c     |      |           |      */
  1254.  /*                      |                  ----   |       -----------       */
  1255.  /*                      |                 |    |  |/         |!*            */
  1256.  /*         -----------  |   -----------   |    |  |          |              */
  1257.  /* begin  |           |  ->|           |  |   ---------      |              */
  1258.  /* ------>|Start of   |*   |+Transition|   ->|         |     |              */
  1259.  /*        |Comment    |--->|           |     |         |<----               */
  1260.  /*   <----|           |    | Nested++  |---->| Comment |                    */
  1261.  /*     !*  -----------      -----------      |         |   end(nested=0)    */
  1262.  /*                                           |         |-------->           */
  1263.  /*                              ------------>|         |                    */
  1264.  /*                             |              ---------                     */
  1265.  /*                             |               |  |*                        */
  1266.  /*                             |               |  |                         */
  1267.  /*                             |               |  |       -----------       */
  1268.  /*                             |               |   ----->|End of     |      */
  1269.  /*                             |               |         |Comment    |      */
  1270.  /*                             |                <--------|           |      */
  1271.  /*                             |                     !/   -----------       */
  1272.  /*                          -----------                    |                */
  1273.  /*                         |-Transition|                   |/               */
  1274.  /*                         |           |<------------------                 */
  1275.  /*                         | Nested--  |                                    */
  1276.  /*                          -----------                                     */
  1277.  /*                                                                          */
  1278.  /****************************************************************************/
  1279.  cp = pStartOfComment;
  1280.  
  1281.  if( *cp != '*' )
  1282.   return(cp);
  1283.  
  1284.  NestCount++;
  1285.  cp++;
  1286.  
  1287.  for( ; cp < pEndOfText; )
  1288.  {
  1289.   switch( *cp )
  1290.   {
  1291.    case '*':
  1292.     if( *(cp+1) == '/' )
  1293.      {NestCount -= 1; cp++;}
  1294.     break;
  1295.  
  1296.    case '/':
  1297.     if( *(cp+1) == '*' )
  1298.      {NestCount += 1; cp++;}
  1299.     break;
  1300.  
  1301.    default:
  1302.     break;
  1303.   }
  1304.  
  1305.   if( NestCount == 0 )
  1306.    break;
  1307.  
  1308.   cp++;
  1309.  
  1310.  }
  1311.  
  1312.  if( NestCount != 0 )
  1313.   cp = NULL;
  1314.  return(cp);
  1315. }
  1316.  
  1317. /*****************************************************************************/
  1318. /* Fill with blanks. Leave in the newlines.                                  */
  1319. /*****************************************************************************/
  1320. void BlankOut( char *cpstart, char *cpend)
  1321. {
  1322.  char *cp;
  1323.  
  1324.  for( cp = cpstart; cp <= cpend; cp++ )
  1325.   if( *cp != '\n' )
  1326.    *cp = ' ';
  1327. }
  1328.  
  1329. /*****************************************************************************/
  1330. /* Replace crs, lfs, and end-of-file.                                        */
  1331. /*****************************************************************************/
  1332. void BlankOutCRLFs( char *cpstart, char *cpend)
  1333. {
  1334.  char *cp;
  1335.  
  1336.  for( cp = cpstart; cp <= cpend; cp++ )
  1337.  {
  1338.   if( (*cp == '\r') || (*cp == '\n') || (*cp == 0x1A) )
  1339.   {
  1340.    *cp = ' ';
  1341.   }
  1342.  }
  1343. }
  1344.  
  1345. /*****************************************************************************/
  1346. /* - Build a table of line numbers and breakpoint indices.                   */
  1347. /* - The table is allocated here but is freed by the caller.                 */
  1348. /*****************************************************************************/
  1349. int *BuildBkptLinNumInfo( char *cpstart, char *cpend, int *pNumBreaks)
  1350. {
  1351.  char *cp;
  1352.  int   NumBreaks = 0;
  1353.  int   BkptLineNumber;
  1354.  int   BkptIndex;
  1355.  
  1356.  int  *bp;
  1357.  
  1358.  for( cp = cpstart; cp <= cpend; cp++ )
  1359.  {
  1360.   if( *cp == '{' )
  1361.   {
  1362.    NumBreaks++;
  1363.   }
  1364.  }
  1365.  
  1366.  bp = Talloc( NumBreaks * sizeof(int) );
  1367.  
  1368.  BkptLineNumber = 1;
  1369.  BkptIndex      = 0;
  1370.  
  1371.  for( cp = cpstart; cp <= cpend; cp++ )
  1372.  {
  1373.   if( *cp == '\n' )
  1374.   {
  1375.    BkptLineNumber++;
  1376.   }
  1377.   if( *cp == '{' )
  1378.   {
  1379.    bp[BkptIndex] = BkptLineNumber;
  1380.    BkptIndex++;
  1381.   }
  1382.  }
  1383.  *pNumBreaks = NumBreaks;
  1384.  return( bp );
  1385. }
  1386.  
  1387. /*****************************************************************************/
  1388. /* GetSD386Brk()/FreeSD386Brk()                                              */
  1389. /*                                                                           */
  1390. /* Description:                                                              */
  1391. /*                                                                           */
  1392. /*   Define/Retrieve/Free the breakpoint file location.                      */
  1393. /*                                                                           */
  1394. /* Parameters:                                                               */
  1395. /*                                                                           */
  1396. /*   pSD386Brk   -> user specified environment variable.                     */
  1397. /*               NULL ==> user doesn't want to work with breakpoint files.   */
  1398. /*                                                                           */
  1399. /* Return:                                                                   */
  1400. /*                                                                           */
  1401. /* Assumptions:                                                              */
  1402. /*                                                                           */
  1403. /*****************************************************************************/
  1404. static char *pSD386Brk = NULL;
  1405. char *GetSD386Brk( void )
  1406. {
  1407.  char *p;
  1408.  char  exename[13];
  1409.  
  1410.  if( pSD386Brk == NULL )
  1411.  {
  1412.   pSD386Brk = getenv(ENV_SD386BRK_NAME);
  1413.  
  1414.   if( pSD386Brk == NULL )
  1415.   {
  1416.    extern CmdParms cmd;
  1417.    ALLPIDS *p;
  1418.  
  1419.    char *cp;
  1420.    char *cpp;
  1421.    int   len;
  1422.  
  1423.    /**************************************************************************/
  1424.    /* - massage the exe name to build a default breakpoint file name.        */
  1425.    /**************************************************************************/
  1426.    p   = GetPid( cmd.ProcessID);
  1427.    cp  = strrchr( p->pFileSpec, '\\' );
  1428.    cpp = strchr(  cp, '.');
  1429.    len = cpp - cp - 1;
  1430.    memset( exename, 0, sizeof(exename) );
  1431.    strncpy( exename, cp+1, len);
  1432.    strcat(  exename, ".BRK" );
  1433.    strlwr(  exename );
  1434.  
  1435.    pSD386Brk = Talloc(strlen(exename) + 1);
  1436.  
  1437.    strcpy(pSD386Brk, exename );
  1438.   }
  1439.   else
  1440.   {
  1441.    /**************************************************************************/
  1442.    /* - make a local copy and hold on to it.                                 */
  1443.    /**************************************************************************/
  1444.    p         = pSD386Brk;
  1445.    pSD386Brk = Talloc(strlen(p) + 1);
  1446.  
  1447.    strcpy(pSD386Brk, p);
  1448.  
  1449.    Strip(pSD386Brk,';','t','.');
  1450.    Strip(pSD386Brk,'\\','t','c');
  1451.   }
  1452.  }
  1453.  return(pSD386Brk);
  1454. }
  1455.  
  1456. void FreeSD386Brk( void )
  1457. {
  1458.  if(pSD386Brk)
  1459.  {
  1460.   Tfree(pSD386Brk);
  1461.   pSD386Brk = NULL;
  1462.  }
  1463.  FreeSD386Editor();
  1464. }
  1465.  
  1466. /*****************************************************************************/
  1467. /* GetSD386Editor()/FreeSD386Editor()                                        */
  1468. /*                                                                           */
  1469. /* Description:                                                              */
  1470. /*                                                                           */
  1471. /*   Define/Retrieve/Free the editor for the breakpoint file.                */
  1472. /*                                                                           */
  1473. /* Parameters:                                                               */
  1474. /*                                                                           */
  1475. /*   pSD386Editor -> user specified environment variable.                    */
  1476. /*                NULL ==> user doesn't want to work with breakpoint files.  */
  1477. /*                                                                           */
  1478. /* Return:                                                                   */
  1479. /*                                                                           */
  1480. /* Assumptions:                                                              */
  1481. /*                                                                           */
  1482. /*****************************************************************************/
  1483. static char *pSD386Editor = NULL;
  1484. char *GetSD386Editor( void )
  1485. {
  1486.  char *cp;
  1487.  int   len;
  1488.  
  1489.  if( pSD386Editor == NULL )
  1490.  {
  1491.   cp = getenv(ENV_SD386EDITOR_NAME);
  1492.  
  1493.   if( cp == NULL )
  1494.    return( NULL );
  1495.   else
  1496.   {
  1497.    /**************************************************************************/
  1498.    /* - allocate space for the editor environment variable and make an       */
  1499.    /*   allowance for adding a .exe extension if need be.                    */
  1500.    /**************************************************************************/
  1501.    len          = strlen(cp) + 4;
  1502.    pSD386Editor = Talloc(len + 1);
  1503.  
  1504.    strcat(pSD386Editor, cp);
  1505.    Strip (pSD386Editor, ';' , 't', '.' );
  1506.    Strip (pSD386Editor, '\\', 't', 'c' );
  1507.  
  1508.    strlwr(pSD386Editor);
  1509.    if( strstr(pSD386Editor, ".exe") == NULL )
  1510.     strcat(pSD386Editor, ".exe");
  1511.   }
  1512.  }
  1513.  return(pSD386Editor);
  1514. }
  1515.  
  1516. void FreeSD386Editor( void )
  1517. {
  1518.  if(pSD386Editor)
  1519.  {
  1520.   Tfree(pSD386Editor);
  1521.   pSD386Editor = NULL;
  1522.  }
  1523. }
  1524.  
  1525. void KillEditorSession( void )
  1526. {
  1527.  if( EditorSessionID )
  1528.  {
  1529.   DosStopSession(STOP_SESSION_ALL, EditorSessionID);
  1530.  }
  1531. }
  1532.  
  1533.