summaryrefslogtreecommitdiff
path: root/src/SDCCmacro.c
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /src/SDCCmacro.c
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'src/SDCCmacro.c')
-rw-r--r--src/SDCCmacro.c186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/SDCCmacro.c b/src/SDCCmacro.c
new file mode 100644
index 0000000..e71a7f7
--- /dev/null
+++ b/src/SDCCmacro.c
@@ -0,0 +1,186 @@
+/*-------------------------------------------------------------------------
+ SDCCmain.c - Macro support code.
+
+ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
+#include "common.h"
+#include "dbuf_string.h"
+
+char *
+eval_macros (hTab * pvals, const char *pfrom)
+{
+ bool fdidsomething = FALSE;
+ char quote = '\0';
+ struct dbuf_s dbuf;
+
+ assert (pvals);
+ assert (pfrom);
+
+ dbuf_init (&dbuf, 256);
+ while (*pfrom)
+ {
+ switch (*pfrom)
+ {
+ case '"':
+ case '\'':
+ if (quote != '\0')
+ {
+ /* write previous quote */
+ dbuf_append_char (&dbuf, quote);
+ }
+ quote = *pfrom++;
+ break;
+
+ case '{':
+ {
+ const char *pend = ++pfrom;
+ const char *pval;
+ char *name;
+
+ /* Find the end of macro */
+ while (*pend && '}' != *pend)
+ {
+ pend++;
+ }
+ if ('}' != *pend)
+ {
+ wassertl (0, "Unterminated macro expansion");
+ }
+
+ name = Safe_strndup (pfrom, pend - pfrom);
+
+ /* Look up the value in the hash table */
+ pval = shash_find (pvals, name);
+ Safe_free (name);
+
+ if (NULL == pval)
+ {
+ /* Empty macro value */
+ if ('\0' != quote)
+ {
+ /* It was a quote */
+ if (pend[1] == quote)
+ {
+ /* Start quote equals end quote: skip both */
+ ++pend;
+ }
+ else
+ {
+ /* Start quote not equals end quote: add both */
+ dbuf_append_char (&dbuf, quote);
+ }
+ }
+ }
+ else
+ {
+ if ('\0' != quote)
+ {
+ dbuf_append_char (&dbuf, quote);
+ }
+ dbuf_append_str (&dbuf, pval);
+ fdidsomething = TRUE;
+ }
+
+ quote = '\0';
+ pfrom = pend + 1;
+ }
+ break;
+
+ default:
+ if ('\0' != quote)
+ {
+ dbuf_append_char (&dbuf, quote);
+ quote = '\0';
+ }
+
+ dbuf_append_char (&dbuf, *pfrom++);
+ }
+ }
+
+ if ('\0' != quote)
+ {
+ dbuf_append_char (&dbuf, quote);
+ }
+
+
+ /* If we did something then recursivly expand any expanded macros */
+ if (fdidsomething)
+ {
+ char *ret = eval_macros (pvals, dbuf_c_str (&dbuf));
+ dbuf_destroy (&dbuf);
+ return ret;
+ }
+
+ return dbuf_detach_c_str (&dbuf);
+}
+
+char *
+mvsprintf (hTab * pvals, const char *pformat, va_list ap)
+{
+ char *p;
+ struct dbuf_s dbuf;
+
+ dbuf_init (&dbuf, 256);
+
+ /* Recursivly evaluate all the macros in the string */
+ p = eval_macros (pvals, pformat);
+
+ /* Evaluate all the arguments */
+ dbuf_vprintf (&dbuf, p, ap);
+ Safe_free (p);
+
+ /* Recursivly evaluate any macros that were used as arguments */
+ p = eval_macros (pvals, dbuf_c_str (&dbuf));
+ dbuf_destroy (&dbuf);
+ return p;
+}
+
+char *
+msprintf (hTab * pvals, const char *pformat, ...)
+{
+ va_list ap;
+ char *pret;
+
+ va_start (ap, pformat);
+
+ pret = mvsprintf (pvals, pformat, ap);
+
+ va_end (ap);
+
+ return pret;
+}
+
+void
+mfprintf (FILE * fp, hTab * pvals, const char *pformat, ...)
+{
+ va_list ap;
+ char *p;
+
+ va_start (ap, pformat);
+
+ p = mvsprintf (pvals, pformat, ap);
+
+ va_end (ap);
+
+ fputs (p, fp);
+ Safe_free (p);
+}