Rizin
unix-like reverse engineering framework and cli tools
spp.c File Reference
#include "spp.h"
#include "rz_api.h"
#include "config.h"
#include "rz_api.c"

Go to the source code of this file.

Functions

S_API int spp_run (char *buf, Output *out)
 
static char * spp_run_str (char *buf, int *rv)
 
void lbuf_strcat (SppBuf *dst, char *src)
 
int do_fputs (Output *out, char *str)
 
S_API void spp_eval (char *buf, Output *out)
 
S_API void spp_proc_eval (SppProc *proc, char *buf, Output *out)
 
S_API void spp_io (FILE *in, Output *out)
 
S_API int spp_file (const char *file, Output *out)
 
S_API void spp_proc_list_kw ()
 
S_API void spp_proc_list ()
 
S_API void spp_proc_set (SppProc *p, const char *arg, int fail)
 
void out_printf (Output *out, char *str,...)
 
static void spp_proc_init (SppProc *p)
 
S_API char * spp_eval_str (SppProc *p, const char *code)
 

Function Documentation

◆ do_fputs()

int do_fputs ( Output out,
char *  str 
)

Definition at line 88 of file spp.c.

88  {
89  int i;
90  int printed = 0;
91  for (i = 0; i <= proc->state.ifl; i++) {
92  if (!proc->state.echo[i]) {
93  return printed;
94  }
95  }
96  if (str[0]) {
97  printed = 1;
98  }
99  if (proc->fputs) {
100  proc->fputs (out, str);
101  } else {
102  if (out->fout) {
103  fprintf (out->fout, "%s", str);
104  }
105  }
106  return printed;
107 }
lzma_index ** i
Definition: index.h:629
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
SppState state
Definition: spp.h:141
int ifl
Definition: spp.h:101
int echo[MAXIFL]
Definition: spp.h:100
struct Proc * proc

References SppState::echo, i, SppState::ifl, out, proc, Proc::state, and cmd_descs_generate::str.

Referenced by spp_io(), and spp_proc_eval().

◆ lbuf_strcat()

void lbuf_strcat ( SppBuf dst,
char *  src 
)

Definition at line 73 of file spp.c.

73  {
74  int len = strlen (src);
75  char *nbuf;
76  if (!dst->lbuf || (len + dst->lbuf_n) > dst->lbuf_s) {
77  nbuf = realloc (dst->lbuf, dst->lbuf_s << 1);
78  if (!nbuf) {
79  fprintf (stderr, "Out of memory.\n");
80  return;
81  }
82  dst->lbuf = nbuf;
83  }
84  memcpy (dst->lbuf + dst->lbuf_n, src, len + 1);
85  dst->lbuf_n += len;
86 }
size_t len
Definition: 6502dis.c:15
lzma_index * src
Definition: index.h:567
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
char * dst
Definition: lz4.h:724

References dst, len, memcpy(), realloc(), and src.

Referenced by spp_proc_eval().

◆ out_printf()

void out_printf ( Output out,
char *  str,
  ... 
)

Definition at line 329 of file spp.c.

329  {
330  va_list ap;
331  va_start (ap, str);
332  if (out->fout) {
333  vfprintf (out->fout, str, ap);
334  } else {
335  char tmp[4096];
336  vsnprintf (tmp, sizeof (tmp), str, ap);
337  tmp[sizeof (tmp) - 1] = 0;
338  rz_strbuf_append (out->cout, tmp);
339  }
340  va_end (ap);
341 }
vsnprintf
Definition: kernel.h:366
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222

References out, rz_strbuf_append(), cmd_descs_generate::str, autogen_x86imm::tmp, and vsnprintf.

◆ spp_eval()

S_API void spp_eval ( char *  buf,
Output out 
)

Definition at line 109 of file spp.c.

109  {
111 }
voidpf void * buf
Definition: ioapi.h:138
S_API void spp_proc_eval(SppProc *proc, char *buf, Output *out)
Definition: spp.c:113

References out, proc, and spp_proc_eval().

Referenced by main(), rz_asm_rasm_assemble(), and spp_io().

◆ spp_eval_str()

S_API char* spp_eval_str ( SppProc p,
const char *  code 
)

Definition at line 352 of file spp.c.

352  {
353  if (p) {
354  spp_proc_init (p);
355  }
356  Output out;
357  out.fout = NULL;
358  out.cout = rz_strbuf_new (NULL);
359  rz_strbuf_init (out.cout);
360  char *c = strdup (code);
361  if (c) {
362  spp_proc_eval (p, c, &out);
363  free (c);
364  }
365  return rz_strbuf_drain (out.cout);
366 }
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void * p
Definition: libc.cpp:67
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define c(i)
Definition: sha256.c:43
static void spp_proc_init(SppProc *p)
Definition: spp.c:343
Definition: spp.h:92
Definition: inftree9.h:24

References c, free(), NULL, out, p, rz_strbuf_drain(), rz_strbuf_init(), rz_strbuf_new(), spp_proc_eval(), spp_proc_init(), and strdup().

◆ spp_file()

S_API int spp_file ( const char *  file,
Output out 
)

Definition at line 272 of file spp.c.

272  {
273  FILE *in = fopen (file, "r");
274  D fprintf (stderr, "SPP-FILE(%s)\n", file);
275  if (in) {
276  spp_io (in, out);
277  fclose (in);
278  return 1;
279  }
280  fprintf (stderr, "Cannot find '%s'\n", file);
281  return 0;
282 }
#define D
Definition: block.c:38
const lzma_allocator const uint8_t * in
Definition: block.h:527
string FILE
Definition: benchmark.py:21
S_API void spp_io(FILE *in, Output *out)
Definition: spp.c:224
Definition: gzappend.c:170

References D, benchmark::FILE, in, out, and spp_io().

Referenced by main(), and TAG_CALLBACK().

◆ spp_io()

S_API void spp_io ( FILE *  in,
Output out 
)

Definition at line 224 of file spp.c.

224  {
225  char buf[4096];
226  int lines;
227  if (!proc->buf.lbuf) {
228  proc->buf.lbuf = calloc (1, 4096);
229  }
230  if (!proc->buf.lbuf) {
231  fprintf (stderr, "Out of memory.\n");
232  return;
233  }
234  proc->buf.lbuf[0] = '\0';
235  proc->buf.lbuf_s = 1024;
236  while (!feof (in)) {
237  buf[0] = '\0'; // ???
238  if (!fgets (buf, sizeof (buf) - 1, in)) {
239  break;
240  }
241  if (feof (in)) break;
242  lines = 1;
243  if (!memcmp (buf, "#!", 2)) {
244  if (!fgets (buf, sizeof (buf) - 1, in) || feof (in)) {
245  break;
246  }
247  lines++;
248  }
249  if (proc->multiline) {
250  while (1) {
251  char *eol = buf + strlen (buf) - strlen (proc->multiline);
252  if (!strcmp (eol, proc->multiline)) {
253  D fprintf (stderr, "Multiline detected!\n");
254  if (!fgets (eol, 1023, in)) {
255  break;
256  }
257  if (feof (in)) {
258  break;
259  }
260  lines++;
261  } else {
262  break;
263  }
264  }
265  }
266  spp_eval (buf, out);
267  proc->state.lineno += lines;
268  }
269  (void)do_fputs (out, proc->buf.lbuf);
270 }
static RzBinSourceLineInfo * lines(RzBinFile *bf)
Definition: bin_symbols.c:427
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
S_API void spp_eval(char *buf, Output *out)
Definition: spp.c:109
int do_fputs(Output *out, char *str)
Definition: spp.c:88
SppBuf buf
Definition: spp.h:142
char * multiline
Definition: spp.h:137
int lbuf_s
Definition: spp.h:106
char * lbuf
Definition: spp.h:105
int lineno
Definition: spp.h:99

References Proc::buf, calloc(), D, do_fputs(), in, SppBuf::lbuf, SppBuf::lbuf_s, SppState::lineno, lines(), Proc::multiline, out, proc, spp_eval(), and Proc::state.

Referenced by main(), and spp_file().

◆ spp_proc_eval()

S_API void spp_proc_eval ( SppProc proc,
char *  buf,
Output out 
)

Definition at line 113 of file spp.c.

113  {
114  char *ptr, *ptr2;
115  char *ptrr = NULL;
116  int delta;
117  int printed = 0;
118 retry:
119  /* per word */
120  if (!proc->tag_pre && proc->token) {
121  do {
122  ptr = strstr (buf, proc->token);
123  if (ptr) {
124  *ptr = '\0';
125  }
126  delta = strlen (buf) - 1;
127  if (buf[delta] == '\n') {
128  buf[delta] = '\0';
129  }
130  if (*buf) {
131  spp_run (buf, out);
132  }
133  buf = ptr + 1;
134  } while (ptr);
135  return;
136  }
137 
138  if (!proc->tag_post) {
139  /* handle per line here ? */
140  return;
141  }
142 
143  // TODO: do it in scope!
144  delta = strlen (proc->tag_post);
145 
146  /* (pre) tag */
147  ptr = proc->tag_pre? strstr (buf, proc->tag_pre): NULL;
148  if (ptr) {
149  D printf ("==> 0.0 (%s)\n", ptr);
150  if (!proc->tag_begin || (proc->tag_begin && ptr == buf)) {
151  *ptr = '\0';
152  ptr = ptr + strlen (proc->tag_pre);
153  if (do_fputs (out, buf)) {
154  printed = 1;
155  }
156  D printf ("==> 0 (%s)\n", ptr);
157  }
158  ptrr = strstr (ptr + strlen (proc->tag_pre), proc->tag_pre);
159  }
160 
161  /* (post) tag */
162  if (!ptr) {
163  do_fputs (out, buf);
164  return;
165  }
166  ptr2 = strstr (ptr, proc->tag_post);
167  if (ptr2) {
168  *ptr2 = '\0';
169  if (ptrr) {
170  if (ptrr < ptr2) {
171  char *p = strdup (ptr2 + 2);
172  char *s = spp_run_str (ptrr + strlen (proc->tag_pre), NULL);
173  D fprintf (stderr, "strcpy(%s)(%s)\n", ptrr, s);
174  strcpy (ptrr, s);
175  free (s);
176  ptr[-2] = proc->tag_pre[0]; // XXX -2 check underflow?
177 
178  D fprintf (stderr, "strcat(%s)(%s)\n", ptrr, p);
179  strcat (ptrr, p);
180  buf = ptr - 2;
181  D fprintf (stderr, "CONTINUE (%s)\n", buf);
182  free (p);
183  ptrr = NULL;
184  goto retry;
185  }
186  }
187  if (proc->buf.lbuf && proc->buf.lbuf[0]) {
188  D printf("==> 1 (%s)\n", proc->buf.lbuf);
189  if (ptr) {
190  lbuf_strcat (&proc->buf, buf);
191  do_fputs (out, buf);
192  spp_run (ptr, out);
193  } else {
194  lbuf_strcat (&proc->buf, buf);
195  D printf ("=(1)=> spp_run(%s)\n", proc->buf.lbuf);
196  spp_run (proc->buf.lbuf + delta, out);
197  D printf ("=(1)=> spp_run(%s)\n", proc->buf.lbuf);
198  }
199  proc->buf.lbuf[0]='\0';
200  proc->buf.lbuf_n = 0;
201  } else {
202  D printf ("==> 2 (%s)\n", ptr);
203  if (ptr) {
204  D printf (" ==> 2.1: run(%s)\n", ptr);
205  spp_run (ptr, out);
206  buf = ptr2 + delta;
207  if (buf[0] == '\n' && printed) {
208  buf++;
209  }
210  D printf (" ==> 2.1: continue(%s)\n", buf);
211  goto retry;
212  } else {
213  do_fputs (out, buf);
214  }
215  }
216  do_fputs (out, buf);
217  } else {
218  D printf ("==> 3\n");
219  lbuf_strcat (&proc->buf, ptr);
220  }
221 }
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
static RzSocket * s
Definition: rtr.c:28
S_API int spp_run(char *buf, Output *out)
Definition: spp.c:11
void lbuf_strcat(SppBuf *dst, char *src)
Definition: spp.c:73
static char * spp_run_str(char *buf, int *rv)
Definition: spp.c:59
char * tag_pre
Definition: spp.h:134
char * token
Definition: spp.h:136
int tag_begin
Definition: spp.h:139
char * tag_post
Definition: spp.h:135
int lbuf_n
Definition: spp.h:107
static st64 delta
Definition: vmenus.c:2425

References Proc::buf, D, delta, do_fputs(), free(), SppBuf::lbuf, SppBuf::lbuf_n, lbuf_strcat(), NULL, out, p, printf(), proc, s, spp_run(), spp_run_str(), strdup(), Proc::tag_begin, Proc::tag_post, Proc::tag_pre, and Proc::token.

Referenced by spp_eval(), and spp_eval_str().

◆ spp_proc_init()

static void spp_proc_init ( SppProc p)
static

Definition at line 343 of file spp.c.

343  {
344  p->state.lineno = 1;
345  p->state.ifl = 0;
346  size_t i;
347  for (i = 0; i < MAXIFL; i++) {
348  p->state.echo[i] = p->default_echo;
349  }
350 }
#define MAXIFL
Definition: spp.h:63

References i, MAXIFL, and p.

Referenced by spp_eval_str().

◆ spp_proc_list()

S_API void spp_proc_list ( void  )

Definition at line 291 of file spp.c.

291  {
292  size_t i;
293  for (i = 0; procs[i]; i++) {
294  printf ("%s\n", procs[i]->name);
295  }
296 }
struct Proc * procs[]
Definition: config.h:24
Definition: z80asm.h:102

References i, printf(), and procs.

Referenced by main().

◆ spp_proc_list_kw()

S_API void spp_proc_list_kw ( void  )

Definition at line 284 of file spp.c.

284  {
285  int i;
286  for (i = 0; tags[i].name; i++) {
287  printf ("%s\n", tags[i].name);
288  }
289 }

References i, printf(), and make_dist_html::tags.

Referenced by main().

◆ spp_proc_set()

S_API void spp_proc_set ( SppProc p,
const char *  arg,
int  fail 
)

Definition at line 298 of file spp.c.

298  {
299  size_t i;
300  bool found = false;
301  if (arg) {
302  for (i = 0; procs[i]; i++) {
303  if (!strcmp (procs[i]->name, arg)) {
304  proc = procs[i];
305  found = true;
306  D printf ("SET PROC:(%s)(%s)\n", arg, proc->name);
307  break;
308  }
309  }
310  }
311  if (arg && *arg && !procs[i] && fail) {
312  fprintf (stderr, "Invalid preprocessor name '%s'\n", arg);
313  return;
314  }
315  if (!found || !proc) {
316  proc = p;
317  }
318  if (proc) {
319  proc->state.lineno = 1;
320  proc->state.ifl = 0;
321  for (i = 0; i < MAXIFL; i++) {
323  }
324  //args = (struct Arg*)proc->args;
325  tags = (SppTag*)proc->tags;
326  }
327 }
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
int default_echo
Definition: spp.h:140
struct Tag ** tags
Definition: spp.h:130
const char * name
Definition: spp.h:129
Definition: spp.h:116
#define fail(test)
Definition: tests.h:29

References D, Proc::default_echo, SppState::echo, fail, found, i, SppState::ifl, SppState::lineno, MAXIFL, Proc::name, p, printf(), proc, procs, Proc::state, make_dist_html::tags, and Proc::tags.

Referenced by main(), and rz_asm_rasm_assemble().

◆ spp_run()

S_API int spp_run ( char *  buf,
Output out 
)

Definition at line 11 of file spp.c.

11  {
12  size_t i;
13  int ret = 0;
14  char *tok;
15 
16  D fprintf (stderr, "SPP_RUN(%s)\n", buf);
17  if (proc->chop) {
18  for (; IS_SPACE (*buf); buf++);
19  int buflen = strlen (buf);
20  for (tok = buf + (buflen? buflen - 1: 0); IS_SPACE (*tok); tok--) {
21  *tok = '\0';
22  }
23  }
24 
25  if (proc->token) {
26  tok = strstr (buf, proc->token);
27  if (tok) {
28  *tok = '\0';
29  tok = tok + 1;
30  } else {
31  tok = buf;
32  }
33  } else {
34  tok = buf;
35  }
36  for (i = 0; tags[i].callback; i++) {
37  D fprintf (stderr, "NAME=(%s)\n", tok);
38  if ((!tags[i].name) || (!strcmp (buf, tags[i].name))) {
39  if (out->fout) {
40  fflush (out->fout);
41  }
42  ret = tags[i].callback (&proc->state, out, tok);
43  proc->state.ifl += ret;
44  if (ret == -1) {
45  break;
46  }
47  if (ret) {
48  if (proc->state.ifl < 0 || proc->state.ifl >= MAXIFL) {
49  fprintf (stderr, "Nested conditionals parsing error.\n");
50  break;
51  }
52  }
53  break;
54  }
55  }
56  return ret;
57 }
#define IS_SPACE(x)
Definition: spp.h:114
int chop
Definition: spp.h:138
ut64 buflen
Definition: core.c:76

References buflen, Proc::chop, D, i, SppState::ifl, IS_SPACE, MAXIFL, out, proc, Proc::state, make_dist_html::tags, and Proc::token.

Referenced by spp_proc_eval(), and spp_run_str().

◆ spp_run_str()

static char* spp_run_str ( char *  buf,
int rv 
)
static

Definition at line 59 of file spp.c.

59  {
60  char *b;
61  Output tmp;
62  tmp.fout = NULL;
63  tmp.cout = rz_strbuf_new ("");
64  int rc = spp_run (buf, &tmp);
65  b = strdup (rz_strbuf_get (tmp.cout));
66  rz_strbuf_free (tmp.cout);
67  if (rv) {
68  *rv = rc;
69  }
70  return b;
71 }
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
#define b(i)
Definition: sha256.c:42

References b, NULL, rz_strbuf_free(), rz_strbuf_get(), rz_strbuf_new(), spp_run(), strdup(), and autogen_x86imm::tmp.

Referenced by spp_proc_eval().