Subversion Repositories pentevo

Rev

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

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