Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. /* tempresult.c */
  2. /*****************************************************************************/
  3. /* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only                     */
  4. /*                                                                           */
  5. /* AS-Portierung                                                             */
  6. /*                                                                           */
  7. /* internal holder for int/float/string                                      */
  8. /*                                                                           */
  9. /*****************************************************************************/
  10.  
  11. #include "stdinc.h"
  12. #include <string.h>
  13.  
  14. #include "strutil.h"
  15. #include "asmdef.h"
  16. #include "tempresult.h"
  17.  
  18. /*!------------------------------------------------------------------------
  19.  * \fn     as_tempres_ini(TempResult *p_res)
  20.  * \brief  initialize temp result buffer
  21.  * \param  p_res buffer to initialize
  22.  * ------------------------------------------------------------------------ */
  23.  
  24. void as_tempres_ini(TempResult *p_res)
  25. {
  26.   p_res->Typ = TempNone;
  27.   p_res->Flags = eSymbolFlag_None;
  28.   p_res->AddrSpaceMask = 0;
  29.   p_res->DataSize = eSymbolSizeUnknown;
  30.   p_res->Relocs = NULL;
  31.   memset(&p_res->Contents, 0, sizeof(p_res->Contents));
  32. }
  33.  
  34. /*!------------------------------------------------------------------------
  35.  * \fn     as_tempres_free(TempResult *p_res)
  36.  * \brief  deinit temp result buffer
  37.  * \param  p_res buffer to deinit
  38.  * ------------------------------------------------------------------------ */
  39.  
  40. void as_tempres_free(TempResult *p_res)
  41. {
  42.   if (p_res->Typ == TempString)
  43.     as_nonz_dynstr_free(&p_res->Contents.str);
  44.   p_res->Typ = TempNone;
  45. }
  46.  
  47. /*!------------------------------------------------------------------------
  48.  * \fn     as_tempres_set_none(TempResult *p_res)
  49.  * \brief  set temp result to none
  50.  * \param  p_res result to fill
  51.  * ------------------------------------------------------------------------ */
  52.  
  53. void as_tempres_set_none(TempResult *p_res)
  54. {
  55.   if (p_res->Typ == TempString)
  56.     as_nonz_dynstr_free(&p_res->Contents.str);
  57.   p_res->Typ = TempNone;
  58. }
  59.  
  60. /*!------------------------------------------------------------------------
  61.  * \fn     as_tempres_set_int(TempResult *p_res, LargeInt value)
  62.  * \brief  set temp result to integer value
  63.  * \param  p_res result to fill
  64.  * \param  value integer value to set
  65.  * ------------------------------------------------------------------------ */
  66.  
  67. void as_tempres_set_int(TempResult *p_res, LargeInt value)
  68. {
  69.   if (p_res->Typ == TempString)
  70.     as_nonz_dynstr_free(&p_res->Contents.str);
  71.   p_res->Typ = TempInt;
  72.   p_res->Contents.Int = value;
  73. }
  74.  
  75. /*!------------------------------------------------------------------------
  76.  * \fn     as_tempres_set_float(TempResult *p_res, Double value)
  77.  * \brief  set temp result to float value
  78.  * \param  p_res result to fill
  79.  * \param  value float value to set
  80.  * ------------------------------------------------------------------------ */
  81.  
  82. void as_tempres_set_float(TempResult *p_res, Double value)
  83. {
  84.   if (p_res->Typ == TempString)
  85.     as_nonz_dynstr_free(&p_res->Contents.str);
  86.   p_res->Typ = TempFloat;
  87.   p_res->Contents.Float = value;
  88. }
  89.  
  90. /*!------------------------------------------------------------------------
  91.  * \fn     as_tempres_set_str(TempResult *p_res, const as_nonz_dynstr_t *p_value)
  92.  * \brief  set temp result to string value
  93.  * \param  p_res result to fill
  94.  * \param  p_value string value to set
  95.  * ------------------------------------------------------------------------ */
  96.  
  97. void as_tempres_set_str(TempResult *p_res, const as_nonz_dynstr_t *p_value)
  98. {
  99.   if (p_res->Typ != TempString)
  100.     as_nonz_dynstr_ini(&p_res->Contents.str, p_value->capacity);
  101.   p_res->Typ = TempString;
  102.   as_nonz_dynstr_copy(&p_res->Contents.str, p_value);
  103. }
  104.  
  105. /*!------------------------------------------------------------------------
  106.  * \fn     as_tempres_set_str_raw(TempResult *p_res, const char *p_src, size_t src_len)
  107.  * \brief  set temp result to string value, with raw source
  108.  * \param  p_res result to fill
  109.  * \param  p_src string value to set
  110.  * \param  src_len length of source
  111.  * ------------------------------------------------------------------------ */
  112.  
  113. void as_tempres_set_str_raw(TempResult *p_res, const char *p_src, size_t src_len)
  114. {
  115.   if (p_res->Typ != TempString)
  116.     as_nonz_dynstr_ini(&p_res->Contents.str, as_nonz_dynstr_roundup_len(src_len));
  117.   p_res->Typ = TempString;
  118.   as_nonz_dynstr_append_raw(&p_res->Contents.str, p_src, src_len);
  119. }
  120.  
  121. /*!------------------------------------------------------------------------
  122.  * \fn     as_tempres_set_c_str(TempResult *p_res, const char *p_src)
  123.  * \brief  set temp result to string value, with C string source
  124.  * \param  p_res result to fill
  125.  * \param  p_src string value to set
  126.  * ------------------------------------------------------------------------ */
  127.  
  128. void as_tempres_set_c_str(TempResult *p_res, const char *p_src)
  129. {
  130.   as_tempres_set_str_raw(p_res, p_src, strlen(p_src));
  131. }
  132.  
  133. /*!------------------------------------------------------------------------
  134.  * \fn     as_tempres_set_reg(TempResult *p_res, const tRegDescr *p_value)
  135.  * \brief  set temp result to register value
  136.  * \param  p_res result to fill
  137.  * \param  p_value register value to set
  138.  * ------------------------------------------------------------------------ */
  139.  
  140. void as_tempres_set_reg(TempResult *p_res, const tRegDescr *p_value)
  141. {
  142.   if (p_res->Typ == TempString)
  143.     as_nonz_dynstr_free(&p_res->Contents.str);
  144.   p_res->Typ = TempReg;
  145.   p_res->Contents.RegDescr = *p_value;
  146. }
  147.  
  148. /*!------------------------------------------------------------------------
  149.  * \fn     as_tempres_copy(TempResult *p_dest, const TempResult *p_src)
  150.  * \brief  copy temp result's value
  151.  * \param  p_dest destination
  152.  * \param  p_src source
  153.  * ------------------------------------------------------------------------ */
  154.  
  155. void as_tempres_copy_value(TempResult *p_dest, const TempResult *p_src)
  156. {
  157.   switch (p_src->Typ)
  158.   {
  159.     case TempInt:
  160.       as_tempres_set_int(p_dest, p_src->Contents.Int);
  161.       break;
  162.     case TempFloat:
  163.       as_tempres_set_float(p_dest, p_src->Contents.Float);
  164.       break;
  165.     case TempString:
  166.       as_tempres_set_str(p_dest, &p_src->Contents.str);
  167.       break;
  168.     case TempReg:
  169.       as_tempres_set_reg(p_dest, &p_src->Contents.RegDescr);
  170.       break;
  171.     default:
  172.       as_tempres_set_none(p_dest);
  173.   }
  174. }
  175.  
  176. /*!------------------------------------------------------------------------
  177.  * \fn     as_tempres_copy(TempResult *p_dest, const TempResult *p_src)
  178.  * \brief  copy temp result
  179.  * \param  p_dest destination
  180.  * \param  p_src source
  181.  * ------------------------------------------------------------------------ */
  182.  
  183. void as_tempres_copy(TempResult *p_dest, const TempResult *p_src)
  184. {
  185.   as_tempres_copy_value(p_dest, p_src);
  186.   p_dest->Flags = p_src->Flags;
  187.   p_dest->AddrSpaceMask = p_src->AddrSpaceMask;
  188.   p_dest->DataSize = p_src->DataSize;
  189.   p_dest->Relocs = p_src->Relocs;
  190. }
  191.  
  192. /*!------------------------------------------------------------------------
  193.  * \fn     as_tempres_cmp(const TempResult *p_res1, const TempResult *p_res2)
  194.  * \brief  compare two values
  195.  * \param  p_res1, p_res2 values to compare
  196.  * \return -1/0/+1 for p_res1 </=/> p_res2
  197.  * ------------------------------------------------------------------------ */
  198.  
  199. int as_tempres_cmp(const TempResult *p_res1, const TempResult *p_res2)
  200. {
  201.   if (p_res1->Typ != p_res2->Typ)
  202.     return -1;
  203.   switch (p_res1->Typ)
  204.   {
  205.     case TempString:
  206.       return as_nonz_dynstr_cmp(&p_res1->Contents.str, &p_res2->Contents.str);
  207.     case TempFloat:
  208.       if (p_res1->Contents.Float < p_res2->Contents.Float)
  209.         return -1;
  210.       else if (p_res1->Contents.Float > p_res2->Contents.Float)
  211.         return 1;
  212.       else
  213.         return 0;
  214.     case TempInt:
  215.       if (p_res1->Contents.Int < p_res2->Contents.Int)
  216.         return -1;
  217.       else if (p_res1->Contents.Int > p_res2->Contents.Int)
  218.         return 1;
  219.       else
  220.         return 0;
  221.     case TempReg:
  222.       if (p_res1->Contents.RegDescr.Reg < p_res2->Contents.RegDescr.Reg)
  223.         return -1;
  224.       else if (p_res1->Contents.RegDescr.Reg > p_res2->Contents.RegDescr.Reg)
  225.         return 1;
  226.       else
  227.         return 0;
  228.     default:
  229.       return 0;
  230.   }
  231. }
  232.  
  233. /*!------------------------------------------------------------------------
  234.  * \fn     TempResultToFloat(TempResult *pResult)
  235.  * \brief  convert TempResult to float
  236.  * \param  pResult tempresult to convert
  237.  * \return 0 or error code
  238.  * ------------------------------------------------------------------------ */
  239.  
  240. int TempResultToFloat(TempResult *pResult)
  241. {
  242.   switch (pResult->Typ)
  243.   {
  244.     case TempInt:
  245.       pResult->Contents.Float = pResult->Contents.Int;
  246.       pResult->Typ = TempFloat;
  247.       break;
  248.     case TempFloat:
  249.       break;
  250.     default:
  251.       as_tempres_set_none(pResult);
  252.       return -1;
  253.   }
  254.   return 0;
  255. }
  256.  
  257. /*!------------------------------------------------------------------------
  258.  * \fn     as_tempres_append_dynstr(as_dynstr_t *p_dest, const TempResult *pResult)
  259.  * \brief  convert result to readable form
  260.  * \param  p_dest where to write ASCII representation
  261.  * \param  pResult result to convert
  262.  * \return 0 or error code
  263.  * ------------------------------------------------------------------------ */
  264.  
  265. int as_tempres_append_dynstr(as_dynstr_t *p_dest, const TempResult *pResult)
  266. {
  267.   switch (pResult->Typ)
  268.   {
  269.     case TempInt:
  270.       as_sdprcatf(p_dest, "%llld", pResult->Contents.Int);
  271.       break;
  272.     case TempFloat:
  273.       as_sdprcatf(p_dest, "%0.16e", pResult->Contents.Float);
  274.       KillBlanks(p_dest->p_str);
  275.       break;
  276.     case TempString:
  277.     {
  278.       char quote_chr = (pResult->Flags & eSymbolFlag_StringSingleQuoted) ? '\'' : '"';
  279.       const char *p_run, *p_end;
  280.  
  281.       as_sdprcatf(p_dest, "%c", quote_chr);
  282.       for (p_run = pResult->Contents.str.p_str, p_end = p_run + pResult->Contents.str.len;
  283.            p_run < p_end; p_run++)
  284.         if ((*p_run == '\\') || (*p_run == quote_chr))
  285.           as_sdprcatf(p_dest, "\\%c", *p_run);
  286.         else if (!isprint(*p_run))
  287.           as_sdprcatf(p_dest, "\\%03d", *p_run);
  288.         else
  289.           as_sdprcatf(p_dest, "%c", *p_run);
  290.  
  291.       as_sdprcatf(p_dest, "%c", quote_chr);
  292.       break;
  293.     }
  294.     default:
  295.       return -1;
  296.   }
  297.   return 0;
  298. }
  299.