home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sd386v50.zip / sd386src.zip / CPYDATA.C < prev    next >
C/C++ Source or Header  |  1995-11-19  |  50KB  |  1,121 lines

  1. /*****************************************************************************/
  2. /* File:                                                                     */
  3. /*   cpydata.c                                                               */
  4. /*                                                                           */
  5. /* Description:                                                              */
  6. /*                                                                           */
  7. /*  Router/formatter for data items for MSH interpreter.                     */
  8. /*                                                                           */
  9. /* History:                                                                  */
  10. /*                                                                           */
  11. /*   03/10/93 Created.                                                       */
  12. /*                                                                           */
  13. /*...Release 1.02 (10/22/92)                                                 */
  14. /*...                                                                        */
  15. /*... 01/26/93  809   Selwyn    HLL Level 2 support.                         */
  16. /*... 03/03/93  813   Joe       Revised types handling for HL03.             */
  17. /*... 03/06/93  814   Joe       Signed 8 bit char not displaying correct     */
  18. /*...                           negative.                                    */
  19. /*****************************************************************************/
  20. #include "all.h"
  21.  
  22. extern MSHPUTOBJECT       MshPutObject;
  23. extern MSHOBJECTSIZE      mshObjectSize;
  24. extern MSHPUTSIMPLEOBJECT MshPutSimpleObject;
  25. extern MSHINITOBJECT      MshInitObject;
  26. extern MSHGET_DIRECT      mshget_direct;
  27. extern MSHPUT_DIRECT      mshput_direct;
  28.  
  29. /*****************************************************************************/
  30. /* CopyDataItem()                                                            */
  31. /*                                                                           */
  32. /* Description:                                                              */
  33. /*                                                                           */
  34. /*   This routine routes the typeno to the correct formatter.                */
  35. /*                                                                           */
  36. /* Parameters:                                                               */
  37. /*                                                                           */
  38. /*   cp         -> to be allocated to a structure                            */
  39. /*              struct { int  len; int dummy; double *data; }                */
  40. /*   data       location in user's address space of data                     */
  41. /*              we want to format.                                           */
  42. /*   mid        module in which the typeno is defined.                       */
  43. /*   typeno     the type number of the record to be formatted.               */
  44. /*   sfx        stack frame index for stack/parameter variables.             */
  45. /*                                                                           */
  46. /* Return:                                                                   */
  47. /*                                                                           */
  48. /*   void                                                                    */
  49. /*                                                                           */
  50. /* Assumptions:                                                              */
  51. /*                                                                           */
  52. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  53. /*  typeno is a valid type number within the mid.                            */
  54. /*                                                                           */
  55. /*****************************************************************************/
  56.  
  57. void CopyDataItem( char *name, COPYDATA **cp, UINT data, UINT mid,
  58.     USHORT typeno, UINT sfx , UINT nitems ,
  59.     MSHOBJECT *mshObject)
  60. {
  61.  MSHOBJECT *mshObjectHold=NULL, mshObjectTemp;
  62.  Trec  *tp;
  63.  
  64.  mshObjectHold=mshObject;
  65.  if(!mshObject) {   /*MSHGET pulldown*/
  66.     mshObject=&mshObjectTemp;
  67.     (*MshInitObject)(mshObject);
  68.     (*MshPutSimpleObject)(mshObject,0,UNDEFINED,1,1);
  69.  }
  70.  if(((int)mshObject)==-1) { /*MSHPUT pulldown*/
  71.     /*First call to get data item size.* */
  72.     int m=1, n=1, t=UNDEFINED;
  73.     char msg[80];
  74.     mshObject=&mshObjectTemp;
  75.     (*MshInitObject)(mshObject);
  76.  
  77.     /*Use t=UNDEFINED to query data size.*/
  78.     (*mshget_direct)(name, &m, &n, &t, (char*)(mshObject->data) );
  79.  
  80.     /*Create dataless item.*/
  81.     (*MshPutSimpleObject)(mshObject,2,t,m,n);
  82.  
  83.     mshObject=(MSHOBJECT *)T2alloc(sizeof(double)*(*mshObjectSize)(mshObject),SD386_MSH_CHAIN);
  84.     if(!mshObject) {
  85.        sprintf("CopyDataItem: cannot allocate memory for MSH object %s.",
  86.            name);
  87.        fmterr(msg);
  88.        beep();
  89.        return;
  90.     }
  91.  
  92.     (*mshget_direct)(name, &m, &n, &t, (char*)(mshObject->data) );
  93.     (*MshPutSimpleObject)(mshObject,2,t,m,n);
  94.  
  95.     /*Set accessfn field to -1 to indicate to Cpy functions that */
  96.     /*data in being put.*/
  97.  
  98.     *((int *)&mshObject->accessfn)=-1;
  99.  
  100.  }
  101.  if( typeno < 512 )
  102.  {
  103. recirculate:
  104.   switch( typeno )
  105.   {
  106.    case TYPE_VOID:
  107.     CpyBytes( cp, data , sfx , 16, mshObject);
  108.     (*cp)->typeno=typeno;
  109.     break;
  110.  
  111.    case TYPE_CHAR:
  112.    case TYPE_UCHAR:
  113.     CpyChar( cp, data , sfx , typeno, nitems, mshObject);
  114.     break;
  115.  
  116.    case TYPE_SHORT:
  117.    case TYPE_USHORT:
  118.     CpyShort( cp, data , sfx , typeno, nitems, mshObject);
  119.     break;
  120.  
  121.    case TYPE_LONG:
  122.    case TYPE_ULONG:
  123.     CpyLong( cp, data , sfx , typeno, nitems, mshObject);
  124.     break;
  125.  
  126.  
  127.    case TYPE_FLOAT:
  128.    case TYPE_DOUBLE:
  129.    case TYPE_LDOUBLE:
  130.     CpyFloat( mid,cp, data , sfx , typeno, nitems, mshObject);
  131.     break;
  132.  
  133.    case TYPE_PCHAR:
  134.    case TYPE_PSHORT:
  135.    case TYPE_PLONG:
  136.    case TYPE_PUCHAR:
  137.    case TYPE_PUSHORT:
  138.    case TYPE_PULONG:
  139.    case TYPE_PFLOAT:
  140.    case TYPE_PDOUBLE:
  141.    case TYPE_PLDOUBLE:
  142.    case TYPE_PVOID:
  143.    case TYPE_FPCHAR:
  144.    case TYPE_FPSHORT:
  145.    case TYPE_FPLONG:
  146.    case TYPE_FPUCHAR:
  147.    case TYPE_FPUSHORT:
  148.    case TYPE_FPULONG:
  149.    case TYPE_FPFLOAT:
  150.    case TYPE_FPDOUBLE:
  151.    case TYPE_FPLDOUBLE:
  152.    case TYPE_FPVOID:
  153.    case TYPE_N16PCHAR:
  154.    case TYPE_N16PSHORT:
  155.    case TYPE_N16PLONG:
  156.    case TYPE_N16PUCHAR:
  157.    case TYPE_N16PUSHORT:
  158.    case TYPE_N16PULONG:
  159.    case TYPE_N16PFLOAT:
  160.    case TYPE_N16PDOUBLE:
  161.    case TYPE_N16PLDOUBLE:
  162.    case TYPE_N16PVOID:
  163.     typeno = CpyPtr(cp,(ULONG*)&data,0/*mid=0*/,typeno,sfx,mshObject);
  164.     /*Return pointer.*/
  165.     typeno=TYPE_ULONG;
  166.     break;
  167.  
  168.   }
  169.   /***************************************************************************/
  170.   /* Remove the \0 inserted by the formatter.                                */
  171.   /***************************************************************************/
  172. #if 0
  173.   *(strchr(cp,'\0')) = ' ';
  174. #endif
  175. msh:
  176.   (*cp)->typeno=typeno;
  177.   mshObject=mshObjectHold;
  178.   if(!(*cp)->rc)
  179.   {
  180.    switch( typeno )
  181.    {
  182.     case TYPE_CHAR:
  183.     case TYPE_UCHAR:
  184.      if(!mshObject) {
  185.          (*mshput_direct)( name, 1, (*cp)->len, 4, (char *) ((*cp)->data) );
  186.      }
  187.      else {
  188.         if(mshObject->mshAttributes.type==UNDEFINED) {
  189.             (*MshPutSimpleObject)(mshObject,0,4, 1, (*cp)->len, (char *) ((*cp)->data) );
  190.         }
  191.         else {
  192.             (*MshPutObject)(mshObject,0,
  193.                 mshObject->mshAttributes.type,
  194.                 mshObject->ndimensions,
  195.                 mshObject->dimensions,
  196.                 (char *) ((*cp)->data) );
  197.         }
  198.      }
  199.      break;
  200.  
  201.     case TYPE_SHORT:
  202.     case TYPE_USHORT:
  203.      if(!mshObject) {
  204.          (*mshput_direct)( name,
  205.              1, ((*cp)->len)/sizeof(SHORT) , 0, (char *) ((*cp)->data) );
  206.      }
  207.      else {
  208.          if(mshObject->mshAttributes.type==UNDEFINED) {
  209.          (*MshPutSimpleObject)(mshObject,0,
  210.              0, 1, ((*cp)->len)/sizeof(SHORT) , (char *) ((*cp)->data) );
  211.         }
  212.         else {
  213.             (*MshPutObject)(mshObject,0,
  214.                 mshObject->mshAttributes.type,
  215.                 mshObject->ndimensions,
  216.                 mshObject->dimensions,
  217.                 (char *) ((*cp)->data) );
  218.         }
  219.      }
  220.      break;
  221.  
  222.     case TYPE_LONG:
  223.     case TYPE_ULONG:
  224.      if(!mshObject) {
  225.          (*mshput_direct)( name,
  226.              1, ((*cp)->len)/sizeof(LONG), 1,(char *) (*cp)->data );
  227.      }
  228.      else {
  229.          if(mshObject->mshAttributes.type==UNDEFINED) {
  230.          (*MshPutSimpleObject)(mshObject,0,
  231.              1, 1, ((*cp)->len)/sizeof(LONG), (char *) (*cp)->data );
  232.         }
  233.         else {
  234.             (*MshPutObject)(mshObject,0,
  235.                 mshObject->mshAttributes.type,
  236.                 mshObject->ndimensions,
  237.                 mshObject->dimensions,
  238.                 (char *) ((*cp)->data) );
  239.         }
  240.      }
  241.      break;
  242.  
  243.     case TYPE_FLOAT:
  244.      if(!mshObject) {
  245.          (*mshput_direct)( name,
  246.              1, ((*cp)->len)/sizeof(float), 3, (char *) (*cp)->data );
  247.      }
  248.      else {
  249.          if(mshObject->mshAttributes.type==UNDEFINED) {
  250.          (*MshPutSimpleObject)(mshObject,0,
  251.              3, 1, ((*cp)->len)/sizeof(float), (char *) (*cp)->data );
  252.         }
  253.         else {
  254.             (*MshPutObject)(mshObject,0,
  255.                 mshObject->mshAttributes.type,
  256.                 mshObject->ndimensions,
  257.                 mshObject->dimensions,
  258.                 (char *) ((*cp)->data) );
  259.         }
  260.      }
  261.      break;
  262.  
  263.     case TYPE_DOUBLE:
  264.     case TYPE_LDOUBLE:
  265.      if(!mshObject) {
  266.          (*mshput_direct)( name,
  267.              1, ((*cp)->len)/sizeof(double), 2, (char *) (*cp)->data );
  268.      }
  269.      else {
  270.          if(mshObject->mshAttributes.type==UNDEFINED) {
  271.          (*MshPutSimpleObject)(mshObject,0,
  272.              2, 1, ((*cp)->len)/sizeof(double), (char *) (*cp)->data );
  273.         }
  274.         else {
  275.             (*MshPutObject)(mshObject,0,
  276.                 mshObject->mshAttributes.type,
  277.                 mshObject->ndimensions,
  278.                 mshObject->dimensions,
  279.                 (char *) ((*cp)->data) );
  280.         }
  281.      }
  282.      break;
  283.  
  284.    }
  285.   }
  286.   FreeChain(SD386_MSH_CHAIN);
  287.   return;
  288.  }
  289.  else
  290.  /****************************************************************************/
  291.  /* - Now, handle typenos > 512.                                             */
  292.  /* - QbasetypeRec may return with tp pointing to a TD_USERDEF record with   */
  293.  /*   a primitive type index. In this case, we grab the primitive typeno     */
  294.  /*   and recirculate.                                                       */
  295.  /****************************************************************************/
  296.  {
  297.   tp = QbasetypeRec(mid,typeno);
  298.   if( tp->RecType == T_TYPDEF )
  299.   {
  300.    typeno = ((TD_USERDEF*)tp)->TypeIndex;
  301.    goto recirculate;
  302.   }
  303.  }
  304.  
  305.  /****************************************************************************/
  306.  /* When we get here, we have a tp pointing to a base type record and it     */
  307.  /* is not a T_USERDEF record.                                               */
  308.  /****************************************************************************/
  309.  switch(tp->RecType)
  310.  {
  311.   default:
  312.    break;
  313.  
  314.   case T_SCALAR:
  315.   case T_PROC:
  316.   case T_ENTRY:
  317.   case T_FUNCTION:
  318.   case T_ARRAY:
  319.   case T_STRUCT:
  320.    {
  321.    struct {
  322.       TD_STRUCT *tp;
  323.       char name[80];
  324.    } findStruct;
  325.    strcpy(findStruct.name,name);
  326.    findStruct.tp=(TD_STRUCT *) tp;
  327.    FindStruct(NULL, (char *) &findStruct, mshObjectHold);
  328.    }
  329.    break;
  330.  
  331.   case T_ENUM:
  332.    typeno = CpyEnums( tp, cp, data, mid, typeno, sfx, mshObject);
  333.    /**************************************************************************/
  334.    /* typeno will be returned as 0 in the event of an error.                 */
  335.    /**************************************************************************/
  336.    if( typeno == 0 )
  337.     break;
  338.    goto recirculate;
  339.  
  340.   case T_BITFLD:
  341.    CpyBitField( tp, cp, data, mid, typeno, sfx, mshObject);
  342.    break;
  343.  
  344. casepointer:
  345.   case T_PTR:
  346.    /**************************************************************************/
  347.    /* See the documentation for Pointer handling. It will make the           */
  348.    /* understanding of this much simpler.                                    */
  349.    /**************************************************************************/
  350.    (void)CpyPtr( cp, (ULONG*)&data , mid , typeno , sfx, mshObject);
  351.    /*Here we force return of the pointer.*/
  352.    typeno=TYPE_ULONG;
  353.    goto msh;
  354.  }
  355. }
  356. /*****************************************************************************/
  357. /* CpyChar()                                                              813*/
  358. /*                                                                           */
  359. /* Description:                                                              */
  360. /*                                                                           */
  361. /*   Format signed/unsigned character data for display.                      */
  362. /*                                                                           */
  363. /* Parameters:                                                               */
  364. /*                                                                           */
  365. /*   cp         input - -> to the buffer we're formatting into.              */
  366. /*   UserAddr   input - location in user's address space of data             */
  367. /*                      we want to format.                                   */
  368. /*   sfx        input - stack frame index for auto data.                     */
  369. /*   typeno     input - primitive type no. Tells signed/unsigned.            */
  370. /*                                                                           */
  371. /* Return:                                                                   */
  372. /*                                                                           */
  373. /*   void                                                                    */
  374. /*                                                                           */
  375. /* Assumptions:                                                              */
  376. /*                                                                           */
  377. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  378. /*                                                                          */
  379. /*****************************************************************************/
  380. #define SIGNED   0x00
  381. #define UNSIGNED 0x04
  382. void CpyChar( COPYDATA  **cp,
  383.               ULONG       UserAddr,
  384.               UINT        sfx,
  385.               USHORT      typeno ,
  386.               UINT        nitems,
  387.               MSHOBJECT  *mshObject)
  388. {
  389.  UINT   read;
  390.  UINT   size;
  391.  signed char *dp;
  392.  
  393.  size = sizeof(char);
  394.  dp = (signed char *) MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  395.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  396.  if( !dp || (size*nitems != read) )
  397.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  398.  
  399.  memcpy((*cp)->data,dp,read);
  400.  (*cp)->len=read;
  401.  (*cp)->rc=0;
  402. }
  403. /*****************************************************************************/
  404. /* CpyShort()                                                             813*/
  405. /*                                                                           */
  406. /* Description:                                                              */
  407. /*                                                                           */
  408. /*   Format signed/unsigned primitive short data types.                      */
  409. /*                                                                           */
  410. /* Parameters:                                                               */
  411. /*                                                                           */
  412. /*   cp         input - -> to the buffer we're formatting into.              */
  413. /*   UserAddr   input - location in user's address space of data             */
  414. /*                      we want to format.                                   */
  415. /*   sfx        input - stack frame index for auto data.                     */
  416. /*   typeno     input - primitive type no. Tells signed/unsigned.            */
  417. /*                                                                           */
  418. /* Return:                                                                   */
  419. /*                                                                           */
  420. /*   void                                                                    */
  421. /*                                                                           */
  422. /* Assumptions:                                                              */
  423. /*                                                                           */
  424. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  425. /*                                                                           */
  426. /*****************************************************************************/
  427. void CpyShort( COPYDATA  **cp,
  428.                ULONG       UserAddr,
  429.                UINT        sfx ,
  430.                USHORT      typeno ,
  431.                UINT        nitems,
  432.                MSHOBJECT  *mshObject)
  433. {
  434.  UINT   read;
  435.  UINT   size;
  436.  signed short *dp;
  437.  
  438.  size = sizeof(short);
  439.  
  440.  dp = (signed short *)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  441.  
  442.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  443.  if( !dp || (size*nitems != read) )
  444.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  445.  
  446.  memcpy((*cp)->data,dp,read);
  447.  (*cp)->len=read;
  448.  (*cp)->rc=0;
  449. }
  450. /*****************************************************************************/
  451. /* CpyLong()                                                              813*/
  452. /*                                                                           */
  453. /* Description:                                                              */
  454. /*                                                                           */
  455. /*   Format signed/unsigned primitive long data types.                       */
  456. /*                                                                           */
  457. /* Parameters:                                                               */
  458. /*                                                                           */
  459. /*   cp         input - -> to the buffer we're formatting into.              */
  460. /*   UserAddr   input - location in user's address space of data             */
  461. /*                      we want to format.                                   */
  462. /*   sfx        input - stack frame index for auto data.                     */
  463. /*   typeno     input - primitive type no. Tells signed/unsigned.            */
  464. /*                                                                           */
  465. /* Return:                                                                   */
  466. /*                                                                           */
  467. /*   void                                                                    */
  468. /*                                                                           */
  469. /* Assumptions:                                                              */
  470. /*                                                                           */
  471. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  472. /*                                                                           */
  473. /*****************************************************************************/
  474. void CpyLong( COPYDATA **cp, ULONG UserAddr, UINT sfx , USHORT typeno , UINT nitems, MSHOBJECT *mshObject)
  475. {
  476.  UINT   read;
  477.  UINT   size;
  478.  signed long *dp;
  479. #if 0
  480.  char   fs[11];
  481. #endif
  482.  size = sizeof(long);
  483.  dp = (signed long *)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  484.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  485.  if( !dp || (size*nitems != read) )
  486.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  487.  memcpy((*cp)->data,dp,read);
  488.  (*cp)->len=read;
  489.  (*cp)->rc=0;
  490. #if 0
  491.  
  492.  if( (typeno & TYP_BITS) == SIGNED )
  493.  {
  494.   strcpy(fs,"%-12ld%#lx");
  495.   sprintf(cp,fs,*dp,(ULONG)*dp);
  496.  }
  497.  else
  498.  {
  499.   strcpy(fs,"%-12lu%#lx");
  500.   sprintf(cp,fs,(ULONG)*dp,(ULONG)*dp);
  501.  }
  502. #endif
  503. }
  504.  
  505. /*****************************************************************************/
  506. /* CpyFloat()                                                             813*/
  507. /*                                                                           */
  508. /* Description:                                                              */
  509. /*                                                                           */
  510. /*   Format primitive floating point types.                                  */
  511. /*                                                                           */
  512. /* Parameters:                                                               */
  513. /*                                                                           */
  514. /*   cp         input - -> to the buffer we're formatting into.              */
  515. /*   UserAddr   input - location in user's address space of data             */
  516. /*                      we want to format.                                   */
  517. /*   sfx        input - stack frame index for auto data.                     */
  518. /*   typeno     input - primitive type no. Tells signed/unsigned.            */
  519. /*                                                                           */
  520. /* Return:                                                                   */
  521. /*                                                                           */
  522. /*   void                                                                    */
  523. /*                                                                           */
  524. /* Assumptions:                                                              */
  525. /*                                                                           */
  526. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  527. /*                                                                           */
  528. /*****************************************************************************/
  529. void CpyFloat( UINT mid,COPYDATA **cp, ULONG UserAddr, UINT sfx , USHORT typeno , UINT nitems, MSHOBJECT *mshObject)
  530. {
  531.  UINT   read;
  532.  UINT   size;
  533.  signed long *dp;
  534.  
  535.  size = QtypeSize(mid,typeno);
  536.  dp = (signed long *)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  537.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  538.  if( !dp || (size*nitems != read) )
  539.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  540.  memcpy((*cp)->data,dp,read);
  541.  (*cp)->len=read;
  542.  (*cp)->rc=0;
  543. #if 0
  544.  
  545.  /****************************************************************************/
  546.  /* Mask all the floating point exceptions while we execute the sprintf.     */
  547.  /* The debugger may trap if we don't do this.                               */
  548.  /*                                                                          */
  549.  /****************************************************************************/
  550.  _control87(0x37f,0xffff);
  551.  switch(typeno)
  552.  {
  553.   case TYPE_FLOAT:
  554.    sprintf(cp,"%.10g",*(float*)dp);
  555.    break;
  556.  
  557.   case TYPE_DOUBLE:
  558.    sprintf(cp,"%.18g",*(double*)dp);
  559.    break;
  560.  
  561.   case TYPE_LDOUBLE:
  562.    sprintf(cp,"%.21Lg",*(long double*)dp);
  563.    break;
  564.  }
  565.  /****************************************************************************/
  566.  /* - Clear any exceptions that may have occurred.                           */
  567.  /* - Reset the control word to the default value.                           */
  568.  /****************************************************************************/
  569.  _clear87();
  570.  _control87(CW_DEFAULT,0xffff);
  571. #endif
  572. }
  573.  
  574. /*****************************************************************************/
  575. /* CpyPtr()                                                               813*/
  576. /*                                                                           */
  577. /* Description:                                                              */
  578. /*                                                                           */
  579. /*   Format pointers to signed/unsigned primitives.                          */
  580. /*                                                                           */
  581. /* Parameters:                                                               */
  582. /*                                                                           */
  583. /*   pcp        input - -> to -> to the buffer we're formatting into.        */
  584. /*   pUserAddr  input - -> to our variable containing the location in        */
  585. /*                         in user's address space of the pointer we         */
  586. /*                         we want to format.                                */
  587. /*   mid        input - module in which the typeno is defined.               */
  588. /*   typeno     input - the type number of the T_BITFLD recoard.             */
  589. /*   sfx        input - stack frame index for auto data.                     */
  590. /*                                                                           */
  591. /* Return:                                                                   */
  592. /*                                                                           */
  593. /*   void                                                                    */
  594. /*                                                                           */
  595. /* Assumptions:                                                              */
  596. /*                                                                           */
  597. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  598. /*                                                                           */
  599. /*****************************************************************************/
  600. USHORT CpyPtr(COPYDATA **pcp,ULONG *pUserAddr,UINT mid, USHORT typeno,UINT sfx, MSHOBJECT *mshObject)
  601. {
  602.  UINT    read;
  603.  UINT    size;
  604.  signed  char  **dp;
  605.  ULONG   UserAddr = *pUserAddr;
  606.  COPYDATA **cp = pcp;
  607.  UINT    type, nitems=1;
  608.  
  609.  type = GetPtrType(mid,typeno);
  610.  size = QtypeSize(mid,typeno);
  611.  
  612.  switch( type )
  613.  {
  614.   case PTR_0_32:
  615.   case PTR_16_16:
  616.    dp = ( signed char**)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  617.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  618.    if( !dp || (size != read) )
  619.     {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return(0);}
  620.  memcpy((*cp)->data,dp,read);
  621.  (*cp)->len=read;
  622.  (*cp)->rc=0;
  623.    if( type == PTR_0_32 )
  624.    {
  625.     *pUserAddr = (ULONG)*dp;
  626.    }
  627.    else /* case PTR_16_16 */
  628.    {
  629.     *pUserAddr = _SelOff2Flat( *((USHORT*)dp+1) , *(USHORT*)dp );
  630.    }
  631. #if 0
  632.  
  633.    if( type == PTR_0_32 )
  634.    {
  635.     sprintf(cp,fs1,*dp);
  636.     *pUserAddr = (ULONG)*dp;
  637.    }
  638.    else /* case PTR_16_16 */
  639.    {
  640.     sprintf(cp,fs2, *((USHORT*)dp+1),*(USHORT*)dp);
  641.     *pUserAddr = _SelOff2Flat( *((USHORT*)dp+1) , *(USHORT*)dp );
  642.    }
  643. #endif
  644.    break;
  645.  
  646.   case PTR_0_16:
  647.    /**************************************************************************/
  648.    /* - Convert a BP Relative location of the near pointer to a flat address */
  649.    /*   if the 0:16 pointer is a stack variable.                             */
  650.    /* - Get 2 bytes of offset from the location.                             */
  651.    /* - Format the 0:16 pointer.                                             */
  652.    /* - Get the selector where the pointer was defined. Since the pointer is */
  653.    /*   near, the target of the pointer has to have the same selector.       */
  654.    /* - Form the flat address value of the pointer.                          */
  655.    /*                                                                        */
  656.    /**************************************************************************/
  657.    if( TestBit(UserAddr,STACKADDRBIT) )
  658.     UserAddr = StackBPRelToAddr( UserAddr , sfx );
  659.    if ( UserAddr == 0 )
  660.     {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return(0);}
  661.  
  662.    dp = ( signed char**)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  663.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  664.    if( !dp || (size != read) )
  665.     {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return(0);}
  666.  memcpy((*cp)->data,dp,read);
  667.  (*cp)->len=read;
  668.  (*cp)->rc=0;
  669. #if 0
  670.    sprintf(cp,fs3, *(USHORT*)dp);
  671. #endif
  672.  
  673.    {
  674.     USHORT Sel;
  675.     USHORT Off;
  676.  
  677.     _Flat2SelOff(UserAddr, &Sel,&Off);
  678.     *pUserAddr = _SelOff2Flat( Sel, *(USHORT*)dp);
  679.    }
  680.  }
  681.  
  682.  /****************************************************************************/
  683.  /* - If the typeno is primitive, then zero the model bits and return        */
  684.  /*   the type of the pointer to the caller.                                 */
  685.  /* - If the typeno is complex, then echo the typeno back to the caller.     */
  686.  /*   What we return is irrelevant;however, we need to return something.     */
  687.  /****************************************************************************/
  688.  if( typeno < 512 )
  689.    typeno &= (~MD_BITS);
  690.  
  691.  /****************************************************************************/
  692.  /* Append strings to type char and type uchar pointers.                     */
  693.  /****************************************************************************/
  694.  if( typeno == TYPE_CHAR || typeno == TYPE_UCHAR )
  695.  {
  696.   char *cpend;
  697.  
  698.   CpyString(cp,cpend,*pUserAddr,sfx,mshObject);
  699.  }
  700.  return(typeno);
  701. }
  702.  
  703. /*****************************************************************************/
  704. /* CpyBytes()                                                             813*/
  705. /*                                                                           */
  706. /* Description:                                                              */
  707. /*                                                                           */
  708. /*   Format bytes in hex.                                                    */
  709. /*                                                                           */
  710. /* Parameters:                                                               */
  711. /*                                                                           */
  712. /*   cp         input - -> to the buffer we're formatting into.              */
  713. /*   UserAddr   input - location in user's address space of data             */
  714. /*                      we want to format.                                   */
  715. /*   sfx        input - stack frame index for auto data.                     */
  716. /*   size       input - number of byte to format.                            */
  717. /*                                                                           */
  718. /* Return:                                                                   */
  719. /*                                                                           */
  720. /*   void                                                                    */
  721. /*                                                                           */
  722. /* Assumptions:                                                              */
  723. /*                                                                           */
  724. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  725. /*                                                                           */
  726. /*****************************************************************************/
  727. void CpyBytes( COPYDATA  **cp,
  728.                ULONG       UserAddr,
  729.                UINT        sfx,
  730.                UINT        size,
  731.                MSHOBJECT  *mshObject)
  732. {
  733.  UINT   read;
  734.  UCHAR *dp;
  735.  UINT   nitems;
  736.  
  737.  nitems = size;
  738.  dp = ( UCHAR *)MshAppData( UserAddr, &nitems, 1, &read, sfx, mshObject);
  739.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  740.  if( !dp || (size != read) )
  741.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  742.  memcpy((*cp)->data,dp,read);
  743.  (*cp)->len=read;
  744.  (*cp)->rc=0;
  745. }
  746.  
  747. /*****************************************************************************/
  748. /* CpyString()                                                            813*/
  749. /*                                                                           */
  750. /* Description:                                                              */
  751. /*                                                                           */
  752. /*   Format a string.                                                        */
  753. /*                                                                           */
  754. /* Parameters:                                                               */
  755. /*                                                                           */
  756. /*   cp         input - -> to the buffer we're formatting into.              */
  757. /*   cpend      input - -> to the end of the buffer.                         */
  758. /*   UserAddr   input - location in user's address space of data             */
  759. /*                      we want to format.                                   */
  760. /*                                                                           */
  761. /* Return:                                                                   */
  762. /*                                                                           */
  763. /*   void                                                                    */
  764. /*                                                                           */
  765. /* Assumptions:                                                              */
  766. /*                                                                           */
  767. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  768. /*                                                                           */
  769. /*****************************************************************************/
  770. void CpyString( COPYDATA **cp,
  771.                 char      *cpend,
  772.                 ULONG      UserAddr,
  773.                 UINT       sfx,
  774.                 MSHOBJECT *mshObject)
  775. {
  776.  UINT   read = 0;
  777.  UINT   size;
  778.  UCHAR *dp;
  779.  UINT   nitems;
  780.  
  781.  /****************************************************************************/
  782.  /*                                                                          */
  783.  /*         read                                                             */
  784.  /*      |<------------------>|                                              */
  785.  /*      |                    |                                              */
  786.  /*         size                                                             */
  787.  /*      |<------------------------------------------------->|               */
  788.  /*      |                                                   |               */
  789.  /*       ---------------------------------------------------                */
  790.  /*      |                                                   |               */
  791.  /*       ---------------------------------------------------                */
  792.  /*       |                   |                             |                */
  793.  /*       |                   |                             |                */
  794.  /*      cp                   cpend( if size<read)          cpend            */
  795.  /*                                                                          */
  796.  /****************************************************************************/
  797.  
  798.  dp = ( UCHAR *)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  799.  *cp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  800.  if( !dp || read==0 )
  801.   {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  802.  memcpy((*cp)->data,dp,read);
  803.  (*cp)->len=read;
  804.  (*cp)->rc=0;
  805. }
  806.  
  807. /*****************************************************************************/
  808. /* CpyEnums()                                                             813*/
  809. /*                                                                           */
  810. /* Description:                                                              */
  811. /*                                                                           */
  812. /*   Format Enums.                                                           */
  813. /*                                                                           */
  814. /* Parameters:                                                               */
  815. /*                                                                           */
  816. /*   tp         input - -> to the enum type record.                          */
  817. /*   pcp        input - ->-> to the buffer we're formatting into.            */
  818. /*   UserAddr   input - location in user's address space of data             */
  819. /*                      we want to format.                                   */
  820. /*   mid        input - module in which the typeno is defined.               */
  821. /*   typeno     input - the type number of the T_BITFLD recoard.             */
  822. /*   sfx        input - stack frame index for auto data.                     */
  823. /*                                                                           */
  824. /* Return:                                                                   */
  825. /*                                                                           */
  826. /*   typeno     the primitive data type for the enum.                        */
  827. /*                                                                           */
  828. /* Assumptions:                                                              */
  829. /*                                                                           */
  830. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  831. /*  tp -> to a valid enum record.                                            */
  832. /*                                                                           */
  833. /*****************************************************************************/
  834. USHORT CpyEnums( Trec       *tp,
  835.                  COPYDATA  **pcp,
  836.                  ULONG       UserAddr,
  837.                  UINT        mid,
  838.                  USHORT      typeno,
  839.                  UINT        sfx,
  840.                  MSHOBJECT  *mshObject)
  841. {
  842.  char   *ename;
  843.  UINT    size;
  844.  USHORT  type;
  845.  long    lvalue;
  846.  long   *dp;
  847.  UINT    read;
  848.  ULONG   index;
  849.  UINT    nitems;
  850.  
  851.  /****************************************************************************/
  852.  /* - Get the type of the enum.                                              */
  853.  /* - Get the size of the enum.                                              */
  854.  /* - Get the value of the enum.                                             */
  855.  /****************************************************************************/
  856.  type = ((TD_ENUM*)tp)->DataType;
  857.  size = QtypeSize(mid,type);
  858.  
  859.  dp = (signed long *)MshAppData( UserAddr, &nitems, size, &read, sfx, mshObject);
  860.  *pcp=(COPYDATA *)T2alloc(sizeof(COPYDATA)+read-sizeof(double),CPY_CHAIN);
  861.  if( !dp || (size != read) )
  862.   {sprintf((*pcp)->buffer,"Invalid Address");return(0);}
  863.  
  864.  memcpy((*pcp)->data,dp,read);
  865.  (*pcp)->len=read;
  866.  (*pcp)->rc=0;
  867.  
  868.  if( size == 1 )
  869.      lvalue = (long)(*(UCHAR *)dp);
  870.  else if( size == 2)
  871.      lvalue = (long)(*(USHORT *)dp);
  872.  else if( size == 4)
  873.      lvalue = *dp;
  874.  
  875.  /***************************************************************************/
  876.  /* - Get the name list index.                                              */
  877.  /* - Find the name associated with the enum value(lvalue) and format it.   */
  878.  /***************************************************************************/
  879.  typeno = ((TD_ENUM*)tp)->NameListIndex;
  880.  
  881.  tp = QbasetypeRec(mid, typeno);
  882.  if( tp && QNameList(tp,VERIFYVALUE,lvalue) )
  883.  {
  884.   index =  QNameList(tp,VALUEINDEX,lvalue);
  885.   ename =  (char*)QNameList(tp,NAME,index);
  886.   memcpy(*pcp, ename+sizeof(USHORT/*2 byte name length*/), *ename );
  887.  
  888.   /***************************************************************************/
  889.   /* bump the buffer pointer for the caller.                                 */
  890.   /***************************************************************************/
  891.   *pcp = *pcp + *ename;
  892.  }
  893.  return(type);
  894. }
  895.  
  896. /*****************************************************************************/
  897. /* CpyBitField()                                                          813*/
  898. /*                                                                           */
  899. /* Description:                                                              */
  900. /*                                                                           */
  901. /*   Format a Bitield.                                                       */
  902. /*                                                                           */
  903. /* Parameters:                                                               */
  904. /*                                                                           */
  905. /*   ptrec      input - -> to the enum type record.                          */
  906. /*   cp         input - -> to the buffer we're formatting into.              */
  907. /*   UserAddr   input - location in user's address space of data             */
  908. /*                      we want to format.                                   */
  909. /*   mid        input - module in which the typeno is defined.               */
  910. /*   typeno     input - the type number of the T_BITFLD recoard.             */
  911. /*   sfx        input - stack frame index for auto data.                     */
  912. /*                                                                           */
  913. /* Return:                                                                   */
  914. /*                                                                           */
  915. /*   void                                                                    */
  916. /*                                                                           */
  917. /* Assumptions:                                                              */
  918. /*                                                                           */
  919. /*  cp -> to a buffer that has been pre-formatted with blanks.               */
  920. /*  tp -> to a valid enum record.                                            */
  921. /*                                                                           */
  922. /*****************************************************************************/
  923. #define MAXPLXBITSTRINGLENGTH 64
  924. #define TYPE_ULONG_8          0
  925. void CpyBitField( Trec       *ptrec,
  926.                   COPYDATA  **cp,
  927.                   ULONG       UserAddr,
  928.                   UINT        mid,
  929.                   USHORT      typeno,
  930.                   UINT        sfx,
  931.                   MSHOBJECT  *mshObject)
  932. {
  933.  TD_BITFLD *tp;                        /* -> to base type record.            */
  934.  UCHAR      type;                      /* type of bitfld storage.            */
  935.  UCHAR      bitfldsize;                /* size of bitfld storage.            */
  936.  UCHAR      bitfldoffs;                /* offset of bitfld within stg.       */
  937.  UCHAR      size;                      /* size of bitfld storage.            */
  938.  UCHAR      offset;                    /* offset of bitfld within stg.       */
  939.  UCHAR      width;                     /* width  of bitfld within stg.       */
  940.  UINT       value;                     /* unsigned value for bitfld.         */
  941.  UCHAR      byteval;                   /* byte value of bit field.           */
  942.  UCHAR      bytemask;                  /* byte mask for bitfield.            */
  943.  int        i;
  944.  int        j;
  945.  UCHAR      fmtmask;                   /* storage mask for bitfld.           */
  946.  UCHAR     *dp;
  947.  UINT       read;
  948.  int        bitsconsumed;
  949.  UINT       nitems;
  950.  
  951.  tp = (TD_BITFLD*)ptrec;
  952.  
  953.  bitfldsize = tp->BitSize;
  954.  bitfldoffs = tp->Offset;
  955.  type       = tp->BaseType;
  956.  if( type == TYPE_ULONG && (tp->Flags & DISPLAY_AS_VALUE ) )
  957.   type = TYPE_ULONG_8;
  958.  
  959.  size = bitfldsize;
  960.  offset = bitfldoffs;
  961.  switch( type )
  962.  {
  963.   case TYPE_UCHAR:
  964.   /*************************************************************************/
  965.   /* PL/X bit fields.                                                      */
  966.   /*************************************************************************/
  967.   {
  968.    width = 8;
  969.  
  970.    bitsconsumed = 0;
  971.    j = 0;
  972.    for(;;)
  973.    {
  974.     if(size+offset>width)
  975.     {
  976.      size = width - offset;
  977.     }
  978.  
  979.     for( i=0; i< (int)width ; i++ )
  980.      if( (i+j)<MAXPLXBITSTRINGLENGTH )
  981.       (*cp)->buffer[j+i] = '.';
  982.     bytemask=(UCHAR)( (bytemask=0x7F)>>(size-1) );
  983.     bytemask=(UCHAR)((UCHAR)(~bytemask)>>offset );
  984.     dp = MshAppData(UserAddr,&nitems, 1,&read,sfx, mshObject);
  985.     if( !dp || (read != 1 ) )
  986.      {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  987.  
  988.     byteval = bytemask & (*dp);
  989.     fmtmask = 0x80;
  990.     for( i=0;
  991.          i< (int)width;
  992.          fmtmask >>=1, i++)
  993.     {
  994.      if( bytemask & fmtmask )
  995.      {
  996.       if( (i+j)<MAXPLXBITSTRINGLENGTH )
  997.        (*cp)->buffer[j+i] = (UCHAR)((fmtmask & byteval)?'1':'0');
  998.      }
  999.     }
  1000.     j += i;
  1001.     bitsconsumed += (int)size;
  1002.     if(bitsconsumed >= (int)bitfldsize)
  1003.      break;
  1004.     size = bitfldsize - (UCHAR)bitsconsumed;   /* ?????????????? */
  1005.     offset = 0;
  1006.     UserAddr++;
  1007.    }
  1008.   }
  1009.   break;
  1010.  
  1011.   case TYPE_USHORT:
  1012.   /**********************************************************************/
  1013.   /* C211/C600 bitfields.                                               */
  1014.   /**********************************************************************/
  1015.   {
  1016.    USHORT mask;
  1017.    USHORT usfmtmask;
  1018.  
  1019.    width = 16;
  1020.    for( i=0; i< (int)width ; i++ )
  1021.     (*cp)->buffer[i] = '.';
  1022.    mask = (~(mask = 1))<<(size-1);
  1023.    mask = (~mask)<<offset;
  1024.  
  1025.    dp = MshAppData(UserAddr,&nitems, 2,&read,sfx, mshObject);
  1026.    if( !dp || (read != 2 ) )
  1027.     {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  1028.  
  1029.    value = mask & (*(USHORT*)dp);
  1030.    usfmtmask = 0x8000;
  1031.    for( i=0; i< (int)width ; usfmtmask >>=1, i++ )
  1032.    {
  1033.     if( mask & usfmtmask )
  1034.      (*cp)->buffer[i] = (UCHAR)((usfmtmask & value)?'1':'0');
  1035.    }
  1036.   }
  1037.   break;
  1038.  
  1039.   case TYPE_ULONG:
  1040.   /**********************************************************************/
  1041.   /* CL386 bitfields.                                                   */
  1042.   /**********************************************************************/
  1043.   {
  1044.    ULONG mask;
  1045.    ULONG ulfmtmask;
  1046.  
  1047.    width = 32;
  1048.    for( i=0; i< (int)width ; i++ )
  1049.     (*cp)->buffer[i] = '.';
  1050.    mask = (~(mask = 1))<<(size-1);
  1051.    mask = (~mask)<<offset;
  1052.  
  1053.    dp = MshAppData(UserAddr,&nitems, 4,&read,sfx, mshObject);
  1054.    if( !dp || (read != 4 ) )
  1055.     {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  1056.  
  1057.    value = mask & (*(ULONG*)dp);
  1058.    ulfmtmask = 0x80000000;
  1059.    for( i=0; i< (int)width ; ulfmtmask >>=1, i++ )
  1060.    {
  1061.       if( mask & ulfmtmask )
  1062.        (*cp)->buffer[i] = (UCHAR)((ulfmtmask & value)?'1':'0');
  1063.    }
  1064.   }
  1065.   break;
  1066.  
  1067.   case TYPE_ULONG_8:
  1068.   /**********************************************************************/
  1069.   /* IBM C SET-2 Bitfields.                                             */
  1070.   /**********************************************************************/
  1071.   {
  1072.    if ( (size > 8) || ((offset+size) > 8) )
  1073.    {
  1074.     /********************************************************************/
  1075.     /* If the bit field spans across bytes then we will not be able     */
  1076.     /* show the exact memory lay out of bits since they are packed      */
  1077.     /* and filled from lower order bits to higher order bits.           */
  1078.     /* In this case we convert the bit string into Hex value and show   */
  1079.     /* it as a bit string.                                              */
  1080.     /********************************************************************/
  1081.     UINT uifmtmask;
  1082.     if (!BytesToValue(UserAddr,offset,size,sfx,&value))
  1083.        return;
  1084.     uifmtmask = 0x1;
  1085.     for( i=0; i< (int)size; uifmtmask <<=1, i++)
  1086.     {
  1087.      if( value & uifmtmask )
  1088.        (*cp)->buffer[size-i-1] = (UCHAR)'1';
  1089.      else
  1090.        (*cp)->buffer[size-i-1] = (UCHAR)'0';
  1091.     }
  1092.    }
  1093.    else
  1094.    {
  1095.     /********************************************************************/
  1096.     /* If the bit field doesn't span across a byte then show the        */
  1097.     /* exact memory lay out of bits.                                    */
  1098.     /********************************************************************/
  1099.     width = 8;
  1100.     for( i=0; i< (int)width ; i++ )
  1101.       (*cp)->buffer[i] = '.';
  1102.     bytemask=(UCHAR)( (~(bytemask = 1))<<(size-1) );
  1103.     bytemask=(UCHAR)((UCHAR)(~bytemask)<<offset );
  1104.     dp = MshAppData(UserAddr,&nitems,1,&read,sfx, mshObject);
  1105.     if( !dp || (read != 1 ) )
  1106.      {sprintf((*cp)->buffer,"Invalid Address");(*cp)->rc=-1;return;}
  1107.  
  1108.     byteval = bytemask & (*dp);
  1109.     fmtmask = 0x80;
  1110.     for( i=0; i< (int)width; fmtmask >>=1, i++)
  1111.     {
  1112.      if( bytemask & fmtmask )
  1113.        (*cp)->buffer[i] = (UCHAR)((fmtmask & byteval)?'1':'0');
  1114.     }
  1115.    }
  1116.   }
  1117.   break;
  1118.  }                                     /* end of switch{}.                  */
  1119.  return;
  1120. }
  1121.