Rizin
unix-like reverse engineering framework and cli tools
spp.c
Go to the documentation of this file.
1 /* MIT pancake <pancake@nopcode.org> (C) 2009-2020 */
2 
3 #include "spp.h"
4 #include "rz_api.h"
5 #include "config.h"
6 
7 #if !USE_R2
8 #include "rz_api.c"
9 #endif
10 
11 S_API int spp_run(char *buf, Output *out) {
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 }
58 
59 static char *spp_run_str(char *buf, int *rv) {
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 }
72 
73 void lbuf_strcat(SppBuf *dst, char *src) {
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 }
87 
88 int do_fputs(Output *out, char *str) {
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 }
108 
109 S_API void spp_eval(char *buf, Output *out) {
111 }
112 
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 }
222 
223 /* TODO: detect nesting */
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 }
271 
272 S_API int spp_file(const char *file, Output *out) {
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 }
283 
285  int i;
286  for (i = 0; tags[i].name; i++) {
287  printf ("%s\n", tags[i].name);
288  }
289 }
290 
292  size_t i;
293  for (i = 0; procs[i]; i++) {
294  printf ("%s\n", procs[i]->name);
295  }
296 }
297 
298 S_API void spp_proc_set(SppProc *p, const char *arg, int fail) {
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 }
328 
329 void out_printf(Output *out, char *str, ...) {
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 }
342 
343 static void spp_proc_init(SppProc *p) {
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 }
351 
352 S_API char *spp_eval_str(SppProc *p, const char *code) {
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 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
lzma_index * src
Definition: index.h:567
static RzBinSourceLineInfo * lines(RzBinFile *bf)
Definition: bin_symbols.c:427
#define D
Definition: block.c:38
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
struct Proc * procs[]
Definition: config.h:24
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf void * buf
Definition: ioapi.h:138
vsnprintf
Definition: kernel.h:366
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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")
char * dst
Definition: lz4.h:724
string FILE
Definition: benchmark.py:21
static RzSocket * s
Definition: rtr.c:28
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define b(i)
Definition: sha256.c:42
#define c(i)
Definition: sha256.c:43
S_API void spp_eval(char *buf, Output *out)
Definition: spp.c:109
S_API void spp_proc_list()
Definition: spp.c:291
S_API void spp_proc_list_kw()
Definition: spp.c:284
S_API char * spp_eval_str(SppProc *p, const char *code)
Definition: spp.c:352
S_API int spp_run(char *buf, Output *out)
Definition: spp.c:11
S_API void spp_proc_set(SppProc *p, const char *arg, int fail)
Definition: spp.c:298
static void spp_proc_init(SppProc *p)
Definition: spp.c:343
S_API int spp_file(const char *file, Output *out)
Definition: spp.c:272
void lbuf_strcat(SppBuf *dst, char *src)
Definition: spp.c:73
void out_printf(Output *out, char *str,...)
Definition: spp.c:329
S_API void spp_proc_eval(SppProc *proc, char *buf, Output *out)
Definition: spp.c:113
int do_fputs(Output *out, char *str)
Definition: spp.c:88
S_API void spp_io(FILE *in, Output *out)
Definition: spp.c:224
static char * spp_run_str(char *buf, int *rv)
Definition: spp.c:59
#define S_API
Definition: spp.h:28
#define MAXIFL
Definition: spp.h:63
#define IS_SPACE(x)
Definition: spp.h:114
Definition: spp.h:92
Definition: spp.h:128
SppState state
Definition: spp.h:141
SppBuf buf
Definition: spp.h:142
int default_echo
Definition: spp.h:140
char * tag_pre
Definition: spp.h:134
char * multiline
Definition: spp.h:137
struct Tag ** tags
Definition: spp.h:130
char * token
Definition: spp.h:136
const char * name
Definition: spp.h:129
int chop
Definition: spp.h:138
int tag_begin
Definition: spp.h:139
char * tag_post
Definition: spp.h:135
Definition: spp.h:104
int lbuf_s
Definition: spp.h:106
int lbuf_n
Definition: spp.h:107
char * lbuf
Definition: spp.h:105
int ifl
Definition: spp.h:101
int echo[MAXIFL]
Definition: spp.h:100
int lineno
Definition: spp.h:99
Definition: spp.h:116
Definition: inftree9.h:24
Definition: gzappend.c:170
Definition: z80asm.h:102
ut64 buflen
Definition: core.c:76
struct Proc * proc
#define fail(test)
Definition: tests.h:29
static st64 delta
Definition: vmenus.c:2425