Add spp to r2 utils build (#6334)

Integrate SPP into rasm2 to parse asm files
This commit is contained in:
Sven Steinbauer 2016-12-18 08:46:10 +00:00 committed by radare
parent da218c993c
commit 865267fc86
42 changed files with 1983 additions and 5 deletions

View file

@ -1,5 +1,5 @@
BIN=rasm2
BINDEPS=r_asm r_parse r_syscall r_anal r_reg
BINDEPS+=r_flag r_cons r_lang r_util
CFLAGS+=-I../../shlr/spp
include ../rules.mk

View file

@ -8,6 +8,7 @@
#include <r_anal.h>
#include <r_util.h>
#include <r_lib.h>
#include <spp.h>
#include "../blob/version.c"
static RLib *l = NULL;
@ -382,11 +383,11 @@ int main (int argc, char *argv[]) {
&__lib_asm_cb, &__lib_asm_dt, NULL);
r_lib_add_handler (l, R_LIB_TYPE_ANAL, "analysis/emulation plugins",
&__lib_anal_cb, &__lib_anal_dt, NULL);
path = r_sys_getenv (R_LIB_ENV);
if (path && *path)
r_lib_opendir (l, path);
if (1) {
char *homeplugindir = r_str_home (R2_HOMEDIR "/plugins");
// eprintf ("OPENDIR (%s)\n", homeplugindir);
@ -592,6 +593,13 @@ int main (int argc, char *argv[]) {
}
} else {
content = r_file_slurp (file, &length);
Output out;
out.fout = NULL;
out.cout = r_strbuf_new ("");
r_strbuf_init (out.cout);
struct Proc proc;
spp_proc_set (&proc, "asm", 1);
if (content) {
if (len && len > 0 && len < length)
length = len;
@ -608,7 +616,10 @@ int main (int argc, char *argv[]) {
} else if (analinfo) {
ret = show_analinfo ((const char *)buf, offset);
} else {
ret = rasm_asm (content, offset, length, a->bits, bin);
spp_eval (content, &out);
char *spp_out = strdup (r_strbuf_get (out.cout));
ret = rasm_asm (spp_out, offset, length, a->bits, bin);
free (spp_out);
}
ret = !ret;
free (content);

View file

@ -14,6 +14,8 @@ OBJS+=utf8.o strbuf.o lib.o name.o spaces.o
OBJS+=diff.o bdiff.o stack.o queue.o tree.o des.o
OBJS+=punycode.o
include spp.mk
# DO NOT BUILD r_big api (not yet used and its buggy)
ifeq (1,0)
ifeq (${HAVE_LIB_GMP},1)
@ -41,11 +43,11 @@ endif
endif
EXTRA_PRE+=sdb_version
#$(SDBLIB)
include ../rules.mk
include sdb.mk
sync-regex regex-sync:
-rm -rf src/
cvs -qd anoncvs@anoncvs.ca.openbsd.org:/cvs get -P src/lib/libc/regex

6
libr/util/spp.mk Normal file
View file

@ -0,0 +1,6 @@
SPPPATH=../../shlr/spp/
SPP_OBJS=spp.o
SPPOBJS=$(addprefix ${SPPPATH},${SPP_OBJS})
OBJS+=$(SPPOBJS)
$(shell cp ${SPPPATH}/config.def.h ${SPPPATH}/config.h)

View file

@ -45,6 +45,7 @@ MODS+=gdb
MODS+=qnx
SDB_URL=git://github.com/radare/sdb
#SDB_URL=/Users/pancake/prg/sdb
SPP_URL=git://github.com/radare/spp
PWD=$(shell pwd)
SDB_CONFIG=${PWD}/sdb-config.mk
@ -280,3 +281,13 @@ www-sync-t sync-www-t:
sync-www www-sync: www-sync-m www-sync-p www-sync-t
@echo webui sync done
spp-sync:
rm -rf spp
git clone --depth 1 ${SPP_URL} spp
spp: spp-sync
cd spp ; $(MAKE)
.PHONY: spp

3
shlr/spp/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
out.php
test.php
config.h

12
shlr/spp/BUGS Normal file
View file

@ -0,0 +1,12 @@
Known bugs and missfeatures
===========================
* Argument parsing is not correct
* Add includeonce into 'spp'
* set variable names with middle dash doesnt works
<{set foo-bar cow}>
<{ifeq foo-bar}>
<{trace failed}>
<{endif}>

20
shlr/spp/LICENSE Normal file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2009-2016 pancake <pancake@nopcode.org>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

42
shlr/spp/Makefile Normal file
View file

@ -0,0 +1,42 @@
override CFLAGS+=-g -Wall -MD
PREFIX?=/usr
BINDIR=${DESTDIR}${PREFIX}/bin
INSTALL_BIN=install -m 0755
OBJ=spp.o main.o p/strbuf.o
ODF=$(subst .o,.d,$(OBJ))
BIN=spp
all: ${BIN}
config.h:
cp config.def.h config.h
${BIN}: config.h ${OBJ}
${CC} ${LDFLAGS} -o ${BIN} ${OBJ}
symlinks:
ln -s ${BIN} acr
ln -s ${BIN} cpp
ln -s ${BIN} pod
ln -s ${BIN} sh
test:
@for a in t/*spp* ; do \
printf "Testing $$a... " ; \
./spp -tspp -o out.txt $$a ; \
if [ -z "`cat out.txt | grep BUG`" ]; then echo ok ; else echo oops ; fi ; \
cat out.txt | grep BUG ; \
rm -f out.txt ; \
true ; \
done
install:
${INSTALL_BIN} ${BIN} ${BINDIR}
uninstall:
rm -f ${BINDIR}/${BIN}
clean:
-rm -f ${BIN} ${OBJ} ${ODF}
-include ${ODF}

41
shlr/spp/README.md Normal file
View file

@ -0,0 +1,41 @@
spp
===
Author: pancake <pancake<at>nopcode<dot>org>
License: MIT
Description
-----------
SPP stands for Simple Pre-Processor.
The primary use of spp is as a templating language, with
similarities to PHP and CPP. Allowing to embed scripts
in any language in some specific places of the document.
Configuration
-------------
SPP binary can be configured by changing the values in the config.h file, this way you can specify which preprocessors you want to include in the parser.
# Edit the config.h file before typing 'make'
See config.def.h as an example
Build
-----
$ make
Installation
------------
$ make install PREFIX=/usr
Embedding
---------
There are no embedding issues with the MIT license and the
amount if code is pretty low (~400 LOC), and use the apis:
struct Proc p = {0};
spp_proc_set (&p, "sh", 99);
char *res = spp_eval(&p, "hello {{echo orld}}"
printf ("(%s)\n", res);

20
shlr/spp/config.def.h Normal file
View file

@ -0,0 +1,20 @@
#include "p/sh.h"
#include "p/spp.h"
#include "p/acr.h"
#include "p/pod.h"
#include "p/cpp.h"
#include "p/asm.h"
struct Proc *procs[] = {
&spp_proc,
&cpp_proc,
&pod_proc,
&acr_proc,
&sh_proc,
&asm_proc,
NULL
};
DEFAULT_PROC(spp)
#define DEBUG 0

139
shlr/spp/main.c Normal file
View file

@ -0,0 +1,139 @@
/* MIT (C) pancake (at) nopcode (dot) org */
#include "spp.h"
extern struct Proc *procs[];
extern struct Proc *proc;
extern struct Arg *args;
static void spp_help(char *argv0) {
int i;
char supported[128] = "";
for( i = 0; procs[i]; ++i ) {
if (i) strcat (supported, ",");
strcat (supported, procs[i]->name);
}
printf("Usage: %s [-othesv] [file] [...]\n", argv0);
printf( " -o [file] set output file (stdout)\n"
" -t [type] define processor type (%s)\n"
" -e [str] evaluate this string with the selected proc\n"
" -s [str] show this string before anything\n"
" -l list all built-in preprocessors\n"
" -L list keywords registered by the processor\n"
" -n do not read from stdin\n"
" -v show version information\n", supported);
if (proc) {
printf ("%s specific flags:\n", proc->name);
for(i = 0; args[i].flag; i++) {
printf (" %s %s\n", args[i].flag, args[i].desc);
}
}
exit(0);
}
int main(int argc, char **argv) {
int dostdin = 1;
int i, j;
Output out;
out.fout = stdout;
char *arg;
spp_proc_set (proc, argv[0], 0);
if (argc < 2)
spp_io (stdin, &out);
else {
for(i = 1; i < argc; i++) {
/* check preprocessor args */
if (args)
for(j = 0; args[j].flag; j++) {
if (!memcmp (argv[i], args[j].flag, 2)) {
if (args[j].has_arg) {
GET_ARG (arg, argv, i);
args[j].callback (arg);
} else {
args[j].callback (NULL);
}
continue;
}
}
/* TODO: Add these flags in Arg[] */
if (!memcmp (argv[i], "-o", 2)) {
GET_ARG (arg, argv, i);
if (arg != NULL) {
if (!strcmp (arg, "buff")) {
out.fout = NULL;
out.cout = r_strbuf_new ("");
r_strbuf_init (out.cout);
} else {
out.cout = NULL;
out.fout = fopen (arg, "w");
}
}
if (!out.cout && (arg == NULL || out.fout == NULL)) {
fprintf (stderr, "Cannot open output file\n");
exit (1);
}
} else
if (!memcmp (argv[i],"-t", 2)) {
GET_ARG (arg, argv, i);
spp_proc_set (proc, arg, 1);
} else
if (!strcmp (argv[i],"-v")) {
printf ("spp-%s\n", VERSION);
exit (1);
} else
if (!strcmp (argv[i],"-h")) {
/* show help */
spp_help (argv[0]);
} else
if (!strcmp (argv[i],"-n")) {
dostdin = 0;
} else
if (!strcmp (argv[i],"-l")) {
spp_proc_list ();
exit (0);
} else
if (!strcmp (argv[i],"-L")) {
spp_proc_list_kw ();
exit (0);
} else
if (!strcmp (argv[i],"-s")) {
GET_ARG (arg, argv, i);
if (arg == NULL) arg = "";
fprintf (out.fout, "%s\n", arg);
} else
if (!strcmp (argv[i],"-e")) {
GET_ARG (arg, argv, i);
if (arg == NULL) {
arg = "";
}
spp_eval (arg, &out);
} else {
if (i == argc) {
fprintf (stderr, "No file specified.\n");
} else {
spp_file (argv[i], &out);
dostdin = 0;
if (!out.fout) {
D printf ("%s\n", r_strbuf_get (out.cout));
r_strbuf_free (out.cout);
}
}
}
}
if (dostdin) {
spp_io (stdin, &out);
}
}
if (proc->eof)
proc->eof ("", &out);
if (out.fout) {
fclose (out.fout);
}
return 0;
}

60
shlr/spp/p/acr.h Normal file
View file

@ -0,0 +1,60 @@
/* CPP */
static char *pkgname = NULL;
static char *version = NULL;
static char **slurp_ptr = NULL;
static int slurp_args(char *buf)
{
if (slurp_ptr) {
*slurp_ptr = strdup(buf);
slurp_ptr = NULL;
return 1;
}
return 0;
}
TAG_CALLBACK(acr_default)
{
//printf("acr keyword(%s)\n", buf);
if (slurp_args(buf))
return 0;
if (!strcmp(buf, "PKGNAME")) {
slurp_ptr = &pkgname;
} else
if (!strcmp(buf, "VERSION")) {
slurp_ptr = &version;
}
return 0;
}
TAG_CALLBACK(acr_eof)
{
printf("Report:\n pkgname: %s\n version: %s\n", pkgname, version);
return 0;
}
struct Tag acr_tags[] = {
{ NULL, acr_default },
{ NULL }
};
struct Arg acr_args[] = {
{ NULL }
};
struct Proc acr_proc = {
.name = "acr",
.tags = (struct Tag **)acr_tags,
.args = (struct Arg **)acr_args,
.token = " ",
.eof = &acr_eof,
.tag_pre = NULL,
.tag_post = NULL,
.multiline = NULL,
.default_echo = 1,
.chop = 0,
.tag_begin = 0,
};

65
shlr/spp/p/asm.h Normal file
View file

@ -0,0 +1,65 @@
TAG_CALLBACK(asm_default)
{
do_printf (out, "%s", buf);
return 0;
}
TAG_CALLBACK(asm_include)
{
if (echo[ifl]) {
spp_file(buf, out);
}
return 0;
}
TAG_CALLBACK(asm_arch)
{
do_printf (out, ".arch %s\n", buf);
return 0;
}
TAG_CALLBACK(asm_bits)
{
do_printf (out, ".bits %s\n", buf);
return 0;
}
TAG_CALLBACK(asm_string)
{
do_printf (out, ".string %s\n", buf);
return 0;
}
PUT_CALLBACK(asm_fputs)
{
do_printf (out, "%s", buf);
return 0;
}
struct Tag asm_tags[] = {
{ "include", asm_include },
{ "arch", asm_arch },
{ "bits", asm_bits },
{ "string", asm_string },
{ NULL, asm_default },
{ NULL }
};
struct Arg asm_args[] = {
{ NULL }
};
struct Proc asm_proc = {
.name = "asm",
.tags = (struct Tag **)asm_tags,
.args = (struct Arg **)asm_args,
.token = " ",
.eof = NULL,
.tag_pre = ".",
.tag_post = "\n",
.multiline = "\\\n",
.default_echo = 1,
.fputs = asm_fputs,
.chop = 0,
.tag_begin = 0,
};

186
shlr/spp/p/cpp.h Normal file
View file

@ -0,0 +1,186 @@
/* CPP */
TAG_CALLBACK(cpp_default)
{
do_printf (out, "DEFAULT: (%s)\n", buf);
return 0;
}
TAG_CALLBACK(cpp_error)
{
do_printf (out,"\n");
if (echo[ifl] && buf != NULL) {
do_printf (out, "ERROR: %s (line=%d)\n", buf, lineno);
return 1;
}
return 0;
}
TAG_CALLBACK(cpp_warning)
{
do_printf (out,"\n");
if (echo[ifl] && buf != NULL) {
do_printf (out, "WARNING: line %d: %s\n", lineno, buf);
}
return 0;
}
TAG_CALLBACK(cpp_if)
{
char *var = getenv (buf + ((*buf == '!') ? 1 : 0));
if (var && *var=='1')
echo[ifl + 1] = 1;
else echo[ifl + 1] = 0;
if (*buf=='!') echo[ifl+1] = !!!echo[ifl+1];
return 1;
}
TAG_CALLBACK(cpp_ifdef)
{
char *var = getenv (buf);
if (var) {
echo[ifl + 1] = 1;
} else {
echo[ifl + 1] = 0;
}
return 1;
}
TAG_CALLBACK(cpp_else)
{
echo[ifl] = echo[ifl]?0:1;
return 0;
}
TAG_CALLBACK(cpp_ifndef)
{
cpp_ifdef(buf, out);
cpp_else(buf, out);
return 1;
}
static struct cpp_macro_t {
char *name;
char *args;
char *body;
} cpp_macros[10];
static int cpp_macros_n = 0;
static void cpp_macro_add(char *name, char *args, char *body)
{
char *ptr;
cpp_macros[cpp_macros_n].args = strdup(args);
cpp_macros[cpp_macros_n].body = strdup(body);
ptr = strchr(name, '(');
if (ptr)
ptr[1]='\0';
cpp_macros[cpp_macros_n].name = strdup(name);
cpp_macros_n++;
}
PUT_CALLBACK(cpp_fputs)
{
int i;
for (i = 0; i < cpp_macros_n; i++) {
if (strstr(buf, cpp_macros[i].name)) {
fprintf (stderr, "MACRO (%s) HIT\n",
cpp_macros[i].name);
}
}
do_printf (out, "%s", buf);
return 0;
}
TAG_CALLBACK(cpp_define)
{
char *eq = strchr(buf, ' ');
if (eq) {
char *ptr = eq + 1;
char *macro = strchr(buf, '(');
*eq = '\0';
if (macro) {
/*macro[0]='\0'; */
ptr = strchr(macro+1, ')');
if (ptr==NULL) {
fprintf(stderr, "Invalid syntax\n");
return 1;
}
ptr = ptr + 1;
fprintf(stderr, "REGISTER MACRO:\n");
fprintf(stderr, " name: %s\n", buf);
fprintf(stderr, " args: %s\n", macro);
fprintf(stderr, " body: %s\n", ptr+1);
cpp_macro_add(buf,macro,ptr+1);
/* TODO: Name is "BUF(". for funny strstr */
}
r_sys_setenv (buf, ptr);
} else r_sys_setenv (buf, "");
return 0;
}
TAG_CALLBACK(cpp_endif)
{
return -1;
}
TAG_CALLBACK(cpp_include)
{
if (echo[ifl]) {
spp_file (buf, out);
}
return 0;
}
struct Tag cpp_tags[] = {
{ "ifdef", cpp_ifdef },
{ "ifndef", cpp_ifndef },
{ "endif", cpp_endif },
{ "if", cpp_if },
{ "else", cpp_else },
{ "include", cpp_include },
{ "define", cpp_define },
{ "error", cpp_error },
{ "warning", cpp_warning },
{ NULL, cpp_default },
{ NULL }
};
/* arguments */
ARG_CALLBACK(cpp_arg_i)
{
printf("INCLUDEDIR(%s)\n", arg);
return 0;
}
ARG_CALLBACK(cpp_arg_d)
{
// TODO: handle r_sys_setenv==-1
char *eq = strchr(arg, '=');
if (eq) {
*eq = '\0';
r_sys_setenv (arg, eq + 1);
} else r_sys_setenv (arg, "");
return 0;
}
struct Arg cpp_args[] = {
{ "-I", "add include directory", 1, cpp_arg_i },
{ "-D", "define value of variable", 1, cpp_arg_d },
{ NULL }
};
struct Proc cpp_proc = {
.name = "cpp",
.tags = (struct Tag **)cpp_tags,
.args = (struct Arg **)cpp_args,
.token = " ",
.eof = NULL,
.tag_pre = "#",
.tag_post = "\n",
.multiline = "\\\n",
.default_echo = 1,
.fputs = cpp_fputs,
.chop = 0,
.tag_begin = 1,
};

55
shlr/spp/p/pod.h Normal file
View file

@ -0,0 +1,55 @@
/* CPP */
TAG_CALLBACK(pod_default)
{
do_printf (out, "DEFAULT: (%s)\n", buf);
return 0;
}
TAG_CALLBACK(pod_cut)
{
do_printf (out, "\n");
echo[ifl] = 0;
return 0;
}
TAG_CALLBACK(pod_head1)
{
int i, len = strlen (buf);
echo[ifl] = 1;
do_printf (out,"\n");
if (buf==NULL) {
return 0;
}
do_printf (out, "%s\n", buf);
for(i = 0; i < len; i++) {
do_printf (out, "%c", '=');
}
do_printf (out, "\n");
return 0;
}
struct Tag pod_tags[] = {
{ "head1", pod_head1 },
{ "cut", pod_cut },
{ NULL, pod_default },
{ NULL }
};
struct Arg pod_args[] = {
{ NULL }
};
struct Proc pod_proc = {
.name = "pod",
.tags = (struct Tag **)pod_tags,
.args = (struct Arg **)pod_args,
.token = " ",
.eof = NULL,
.tag_pre = "=",
.tag_post = "\n",
.multiline = NULL,
.default_echo = 0,
.chop = 0,
.tag_begin = 1,
};

32
shlr/spp/p/r_strbuf.h Normal file
View file

@ -0,0 +1,32 @@
#if NO_UTIL
#ifndef R_STRBUF_H
#define R_STRBUF_H
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
typedef struct {
int len;
char *ptr;
int ptrlen;
char buf[64];
} RStrBuf;
#define R_FREE(x) { free(x); x = NULL; }
#define R_NEW0(x) (x*)calloc(1,sizeof(x))
#define R_STRBUF_SAFEGET(sb) (r_strbuf_get (sb) ? r_strbuf_get (sb) : "")
RStrBuf *r_strbuf_new(const char *s);
bool r_strbuf_set(RStrBuf *sb, const char *s);
int r_strbuf_append(RStrBuf *sb, const char *s);
char *r_strbuf_get(RStrBuf *sb);
void r_strbuf_free(RStrBuf *sb);
void r_strbuf_fini(RStrBuf *sb);
void r_strbuf_init(RStrBuf *sb);
#endif // R_STRBUF_H
#endif // NO_UTIL

87
shlr/spp/p/sh.h Normal file
View file

@ -0,0 +1,87 @@
/* SH */
// TODO: use popen for {{pipe/endpipe}}
#if 0
static char *eof = NULL;
static char *input = NULL;
#endif
TAG_CALLBACK(sh_default)
{
//if (out != stdout) {
// pipe stdout to out fd
//}
#if 0
ptr = strstr(buf, "<<");
if (ptr) {
*ptr='\0';
for(ptr = ptr+2;*ptr==' ';ptr=ptr+1);
free(eof);
eof = strdup(ptr);
return;
}
// printf("system(%s)\n", buf);
if (eof)
#endif
system(buf);
return 0;
}
static int sh_pipe_enabled = 0;
static char *sh_pipe_cmd = NULL;
TAG_CALLBACK(sh_pipe)
{
sh_pipe_enabled = 1;
free (sh_pipe_cmd);
sh_pipe_cmd = strdup (buf);
return 0;
}
TAG_CALLBACK(sh_endpipe)
{
sh_pipe_enabled = 0;
free (sh_pipe_cmd);
sh_pipe_cmd = NULL;
return 0;
}
PUT_CALLBACK(sh_fputs)
{
if (sh_pipe_enabled) {
char str[1024]; // XXX
sprintf (str, "echo '%s' | %s", buf, sh_pipe_cmd); // XXX
system (str);
} else {
do_printf (out, "%s", buf);
}
return 0;
}
struct Tag sh_tags[] = {
{ "pipe", sh_pipe },
{ "endpipe", sh_endpipe },
{ NULL, sh_default },
{ NULL }
};
struct Arg sh_args[] = {
{ NULL }
};
struct Proc sh_proc = {
.name = "sh",
.tags = (struct Tag **)sh_tags,
.args = (struct Arg **)sh_args,
.eof = NULL,
.token = NULL,
.tag_pre = "{{",
.tag_post = "}}",
.fputs = sh_fputs,
.multiline = "\\\n",
.default_echo = 1,
.chop = 0,
.tag_begin = 0,
};

413
shlr/spp/p/spp.h Normal file
View file

@ -0,0 +1,413 @@
/* Mini MCMS :: renamed to 'spp'? */
static char *spp_var_get(char *var)
{
// fprintf(stderr, "GET(%s)\n", var);
return getenv(var);
}
static int spp_var_set(const char *var, const char *val)
{
// fprintf(stderr, "SET(%s)(%s)\n", var, val);
return r_sys_setenv(var, val);
}
/* Should be dynamic buffer */
static char *cmd_to_str(const char *cmd)
{
char *out = (char *)malloc(4096);
int ret = 0, len = 0, outlen = 4096;
FILE *fd = popen(cmd, "r");
while(fd) {
len += ret;
ret = fread(out+len, 1, 1023, fd);
if (ret<1) {
pclose(fd);
fd = NULL;
}
if (ret+1024>outlen) {
outlen += 4096;
out = realloc (out, outlen);
}
}
out[len]='\0';
return out;
}
TAG_CALLBACK(spp_set)
{
char *eq, *val = "";
if (!echo[ifl]) return 0;
for(eq=buf;eq[0];eq++) {
switch(eq[0]) {
case '-':
case '.':
eq[0]='_';
break;
}
}
eq = strchr(buf, ' ');
if (eq) {
*eq = '\0';
val = eq + 1;
}
if (spp_var_set (buf, val) == -1)
fprintf (stderr, "Invalid variable name '%s' at line %d\n", buf, lineno);
return 0;
}
TAG_CALLBACK(spp_get)
{
char *var;
if (!echo[ifl]) return 0;
var = spp_var_get(buf);
if (var) {
do_printf (out, "%s", var);
}
return 0;
}
TAG_CALLBACK(spp_getrandom)
{
int max;
if (!echo[ifl]) return 0;
srandom(getpid()); // TODO: change this to be portable
max = atoi(buf);
max = (int)(rand()%max);
do_printf(out, "%d", max);
return 0;
}
TAG_CALLBACK(spp_add)
{
char res[32];
char *var, *eq = strchr (buf, ' ');
int ret = 0;
if (!echo[ifl]) return 0;
if (eq) {
*eq = '\0';
var = spp_var_get (buf);
if (var != NULL)
ret = atoi (var);
ret += atoi (eq + 1);
sprintf (res, "%d", ret);
r_sys_setenv (buf, res);
} else { /* syntax error */ }
return 0;
}
TAG_CALLBACK(spp_sub)
{
char *eq = strchr(buf, ' ');
char *var;
int ret = 0;
if (!echo[ifl]) return 0;
if (eq) {
*eq = '\0';
var = spp_var_get(buf);
if (var == NULL) ret = 0;
else ret = atoi(var);
ret -= atoi(eq+1);
r_sys_setenv(buf, eq + 1);
} else { /* syntax error */ }
return 0;
}
// XXX This method needs some love
TAG_CALLBACK(spp_trace)
{
char b[1024];
if (!echo[ifl]) return 0;
snprintf(b, 1023, "echo '%s' > /dev/stderr", buf);
system(b);
return 0;
}
/* TODO: deprecate */
TAG_CALLBACK(spp_echo)
{
if (!echo[ifl]) return 0;
do_printf (out, "%s", buf);
// TODO: add variable replacement here?? not necessary, done by {{get}}
return 0;
}
TAG_CALLBACK(spp_error)
{
if (!echo[ifl]) return 0;
fprintf(stderr, "ERROR: %s (line=%d)\n", buf, lineno);
exit(1);
return 0;
}
TAG_CALLBACK(spp_system)
{
char *str;
if (!echo[ifl]) return 0;
str = cmd_to_str(buf);
do_printf (out, "%s", str);
free(str);
return 0;
}
TAG_CALLBACK(spp_include)
{
char *incdir;
if (!echo[ifl]) return 0;
incdir = getenv("SPP_INCDIR");
if (incdir) {
char *b = strdup(incdir);
b = realloc(b, strlen(b)+strlen(buf)+3);
strcat(b, "/");
strcat(b, buf);
spp_file(b, out);
} else spp_file(buf, out);
return 0;
}
TAG_CALLBACK(spp_if)
{
char *var = spp_var_get(buf);
if (var && *var!='0' && *var != '\0')
echo[ifl+1] = 1;
else echo[ifl+1] = 0;
return 1;
}
/* {{ ifeq $path / }} */
TAG_CALLBACK(spp_ifeq)
{
char *value = buf;
char *eq = strchr(buf, ' ');
if (eq) {
*eq = '\0';
value = spp_var_get(value);
if (value && !strcmp(value, eq+1)) {
echo[ifl+1] = 1;
} else echo[ifl+1] = 0;
//fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, eq+1, echo[ifl]);
} else {
value = spp_var_get(buf);
if (value==NULL || *value=='\0')
echo[ifl+1] = 1;
else echo[ifl+1] = 0;
//fprintf(stderr, "IFEQ(%s)(%s)=%d\n", buf, value, echo[ifl]);
}
return 1;
}
TAG_CALLBACK(spp_hex)
{
int i;
for(i = 0; buf[i]; i++) {
if (buf[i] >= '0' && buf[i] <= '9') {
int b;
unsigned int ch;
b = buf[i + 2];
buf[i + 2] = '\0';
sscanf(buf + i, "%02x", &ch);
do_printf (out, "%c", ch);
buf[i + 2] = b;
buf = buf + 2;
}
}
return 0;
}
TAG_CALLBACK(spp_grepline)
{
FILE *fd;
char b[1024];
char *ptr;
int line;
if (!echo[ifl]) return 1;
ptr = strchr(buf, ' ');
if (ptr) {
*ptr= '\0';
fd = fopen (buf, "r");
line = atoi (ptr+1);
if (fd) {
while (!feof (fd) && line--)
fgets(b, 1023, fd);
fclose (fd);
do_printf (out, "%s", b);
} else {
fprintf(stderr, "Unable to open '%s'\n", buf);
}
}
return 0;
}
TAG_CALLBACK(spp_else)
{
echo[ifl] = echo[ifl] ? 0 : 1;
return 0;
}
TAG_CALLBACK(spp_ifnot)
{
spp_if (buf, out);
spp_else (buf, out);
return 1;
}
TAG_CALLBACK(spp_ifin)
{
char *var, *ptr;
if (!echo[ifl]) return 1;
ptr = strchr (buf, ' ');
echo[ifl + 1] = 0;
if (ptr) {
*ptr='\0';
var = getenv(buf);
if (strstr (ptr + 1, var)) {
echo[ifl + 1] = 1;
}
}
return 1;
}
TAG_CALLBACK(spp_endif)
{
return -1;
}
TAG_CALLBACK(spp_default)
{
if (!echo[ifl]) return 0;
if (buf[-1] != ';') /* commented tag */
fprintf (stderr, "WARNING: invalid command(%s) at line %d\n", buf, lineno);
return 0;
}
static FILE *spp_pipe_fd = NULL;
TAG_CALLBACK(spp_pipe)
{
spp_pipe_fd = popen (buf, "w");
return 0;
}
static char *spp_switch_str = NULL;
TAG_CALLBACK(spp_switch)
{
char *var = spp_var_get (buf);
if (var)
spp_switch_str = strdup (var);
else spp_switch_str = strdup ("");
return 1;
}
TAG_CALLBACK(spp_case)
{
echo[ifl] = strcmp (buf, spp_switch_str)?0:1;
return 0;
}
TAG_CALLBACK(spp_endswitch)
{
free (spp_switch_str);
spp_switch_str = NULL;
return -1;
}
TAG_CALLBACK(spp_endpipe)
{
/* TODO: Get output here */
int ret = 0, len = 0;
int outlen = 4096;
char *str = (char *)malloc (4096);
do {
len += ret;
ret = fread (str + len, 1, 1023, spp_pipe_fd);
if (ret + 1024 > outlen) {
outlen += 4096;
str = realloc (str, outlen);
}
} while (ret > 0);
str[len] = '\0';
do_printf (out, "%s", str);
if (spp_pipe_fd) {
pclose (spp_pipe_fd);
}
spp_pipe_fd = NULL;
return 0;
}
PUT_CALLBACK(spp_fputs)
{
if (spp_pipe_fd) {
fprintf (spp_pipe_fd, "%s", buf);
} else {
do_printf (out, "%s", buf);
}
return 0;
}
struct Tag spp_tags[] = {
{ "get", spp_get },
{ "hex", spp_hex },
{ "getrandom", spp_getrandom },
{ "grepline", spp_grepline },
{ "set", spp_set },
{ "add", spp_add },
{ "sub", spp_sub },
{ "switch", spp_switch },
{ "case", spp_case },
{ "endswitch", spp_endswitch },
{ "echo", spp_echo },
{ "error", spp_error },
{ "trace", spp_trace },
{ "ifin", spp_ifin },
{ "ifnot", spp_ifnot },
{ "ifeq", spp_ifeq },
{ "if", spp_if },
{ "else", spp_else },
{ "endif", spp_endif },
{ "pipe", spp_pipe },
{ "endpipe", spp_endpipe },
{ "include", spp_include },
{ "system", spp_system },
{ NULL, spp_default },
{ NULL }
};
ARG_CALLBACK(spp_arg_i)
{
r_sys_setenv ("SPP_INCDIR", arg);
return 0;
}
ARG_CALLBACK(spp_arg_d)
{
/* TODO: Handle error */
char *eq = strchr (arg, '=');
if (eq) {
*eq = '\0';
spp_var_set (arg, eq+1);
} else spp_var_set (arg, "");
return 0;
}
struct Arg spp_args[] = {
{ "-I", "add include directory", 1, spp_arg_i },
{ "-D", "define value of variable", 1, spp_arg_d },
{ NULL }
};
struct Proc spp_proc = {
.name = "spp",
.tags = (struct Tag **)spp_tags,
.args = (struct Arg **)spp_args,
.token = " ",
.eof = NULL,
.tag_pre = "<{",
.tag_post = "}>",
.chop = 1,
.fputs = spp_fputs,
.multiline = NULL,
.default_echo = 1,
.tag_begin = 0,
};

89
shlr/spp/p/strbuf.c Normal file
View file

@ -0,0 +1,89 @@
/* radare - LGPL - Copyright 2013-2014 - pancake */
#if NO_UTIL
#include "r_strbuf.h"
RStrBuf *r_strbuf_new(const char *str) {
RStrBuf *s = R_NEW0 (RStrBuf);
if (str) r_strbuf_set (s, str);
return s;
}
void r_strbuf_init(RStrBuf *sb) {
memset (sb, 0, sizeof (RStrBuf));
}
bool r_strbuf_set(RStrBuf *sb, const char *s) {
int l;
if (!sb) return false;
if (!s) {
r_strbuf_init (sb);
return true;
}
l = strlen (s);
if (l >= sizeof (sb->buf)) {
char *ptr = sb->ptr;
if (!ptr || l+1 > sb->ptrlen) {
ptr = malloc (l + 1);
if (!ptr) return false;
sb->ptrlen = l + 1;
sb->ptr = ptr;
}
memcpy (ptr, s, l+1);
} else {
sb->ptr = NULL;
memcpy (sb->buf, s, l+1);
}
sb->len = l;
return true;
}
int r_strbuf_append(RStrBuf *sb, const char *s) {
int l = strlen (s);
if (l < 1) {
return false;
}
if ((sb->len + l + 1) < sizeof (sb->buf)) {
memcpy (sb->buf + sb->len, s, l + 1);
R_FREE (sb->ptr);
} else {
int newlen = sb->len + l + 128;
char *p = sb->ptr;
bool allocated = true;
if (!sb->ptr) {
p = malloc (newlen);
if (p && sb->len > 0) {
memcpy (p, sb->buf, sb->len);
}
} else if (sb->len + l + 1 > sb->ptrlen) {
p = realloc (sb->ptr, newlen);
} else {
allocated = false;
}
if (allocated) {
if (!p) return false;
sb->ptr = p;
sb->ptrlen = newlen;
}
memcpy (p + sb->len, s, l + 1);
}
sb->len += l;
return true;
}
char *r_strbuf_get(RStrBuf *sb) {
return sb? (sb->ptr? sb->ptr: sb->buf) : NULL;
}
void r_strbuf_free(RStrBuf *sb) {
r_strbuf_fini (sb);
free (sb);
}
void r_strbuf_fini(RStrBuf *sb) {
if (sb && sb->ptr)
R_FREE (sb->ptr);
}
#endif // NO_UTIL

356
shlr/spp/spp.c Normal file
View file

@ -0,0 +1,356 @@
/* MIT (C) pancake (at) nopcode (dot) org */
#include "spp.h"
#include "config.h"
char *lbuf = NULL;
int lbuf_s = 1024;
int lbuf_n = 0;
int incmd = 0;
int lineno = 1;
int printed = 0;
char *tag_pre, *tag_post, *token;
int tag_begin, echo[MAXIFL];
int ifl = 0; /* conditional nest level */
void spp_run(char *buf, Output *out) {
int i, ret;
char *tok;
D fprintf(stderr, "SPP_RUN(%s)\n", buf);
if (proc->chop) {
for (; IS_SPACE (*buf); buf++);
for (tok = buf + strlen(buf) - 1; IS_SPACE (*tok); tok--) {
*tok='\0';
}
}
if (token) {
tok = strstr (buf, token);
if (tok) {
*tok = '\0';
tok = tok + 1;
} else {
tok = buf;
}
} else {
tok = buf;
}
for (i = 0; tags[i].callback; i++) {
D fprintf (stderr, "NAME=(%s)\n", tok);
if ((tags[i].name == NULL) || (!strcmp (buf, tags[i].name))) {
if (out->fout) {
fflush (out->fout);
}
ret = tags[i].callback (tok, out);
if (ret) {
ifl += ret;
if (ifl < 0 || ifl >= MAXIFL) {
fprintf (stderr, "Nested conditionals parsing error.\n");
return;
}
}
break;
}
}
}
/* XXX : Do not dump to temporally files!! */
char *spp_run_str(char *buf) {
char *b;
Output tmp;
tmp.fout = NULL;
tmp.cout = r_strbuf_new("");
spp_run (buf, &tmp);
b = strdup (r_strbuf_get (tmp.cout));
r_strbuf_free (tmp.cout);
return b;
}
void lbuf_strcat(char *dst, char *src) {
int len = strlen (src);
if ((len + lbuf_n) > lbuf_s)
lbuf = realloc (lbuf, lbuf_s << 1);
memcpy (lbuf + lbuf_n, src, len + 1);
lbuf_n += len;
}
void do_printf(Output *out, char *str, ...) {
va_list ap;
va_start (ap, str);
if (out->fout) {
vfprintf (out->fout, str, ap);
} else {
char tmp[4096];
vsnprintf (tmp, sizeof (tmp), str, ap);
r_strbuf_append (out->cout, tmp);
}
va_end(ap);
}
#if NO_UTIL
int r_sys_setenv(const char *key, const char *value) {
#if __UNIX__ || __CYGWIN__ && !defined(MINGW32)
if (!key) {
return 0;
}
if (!value) {
unsetenv (key);
return 0;
}
return setenv (key, value, 1);
#elif __WINDOWS__
SetEnvironmentVariable (key, (LPSTR)value);
return 0; // TODO. get ret
#else
#warning r_sys_setenv : unimplemented for this platform
return 0;
#endif
}
#endif
void do_fputs(Output *out, char *str) {
int i;
for (i = 0;i <= ifl; i++) {
if (!echo[i]) {
return;
}
}
if (str[0]) {
printed = 1;
}
if (proc->fputs) {
proc->fputs (out, str);
}
else {
if (out->fout) {
fprintf (out->fout, "%s", str);
}
}
}
void spp_eval(char *buf, Output *out) {
char *ptr, *ptr2;
char *ptrr = NULL;
int delta;
printed = 0;
retry:
/* per word */
if (tag_pre == NULL) {
do {
ptr = strstr (buf, token);
if (ptr) {
*ptr = '\0';
}
delta = strlen (buf) - 1;
if (buf[delta] == '\n') {
buf[delta] = '\0';
}
if (*buf) {
spp_run (buf, out);
}
buf = ptr + 1;
} while (ptr);
return;
}
if (tag_post == NULL) {
/* handle per line here ? */
return;
}
// TODO: do it in scope!
delta = strlen (tag_post);
/* (pre) tag */
if (!buf) {
return;
}
ptr = strstr (buf, tag_pre);
if (ptr) {
D printf ("==> 0.0 (%s)\n", ptr);
incmd = 1;
if (!tag_begin || (tag_begin && ptr == buf)) {
*ptr = '\0';
ptr = ptr + strlen (tag_pre);;
do_fputs (out, buf);
D printf ("==> 0 (%s)\n", ptr);
}
ptrr = strstr (ptr + strlen (tag_pre), tag_pre);
}
/* (post) tag */
if (!ptr) {
do_fputs (out, buf);
return;
} else {
ptr2 = strstr (ptr, tag_post);
}
if (ptr2) {
*ptr2 = '\0';
if (ptrr) {
if (ptrr < ptr2) {
char *p = strdup (ptr2 + 2);
char *s = spp_run_str (ptrr + strlen (tag_pre));
D fprintf(stderr, "strcpy(%s)(%s)\n",ptrr, s);
strcpy(ptrr, s);
free(s);
ptr[-2] = tag_pre[0]; // XXX -2 check underflow?
D fprintf(stderr, "strcat(%s)(%s)\n",ptrr, p);
strcat(ptrr, p);
buf = ptr-2;
D fprintf(stderr, "CONTINUE (%s)\n", buf);
ptrr = NULL;
goto retry;
}
}
incmd = 0;
if (lbuf && lbuf[0]) {
D printf("==> 1 (%s)\n", lbuf);
if (ptr) {
lbuf_strcat (lbuf, buf);
do_fputs (out, lbuf);
spp_run (ptr, out);
} else {
lbuf_strcat (lbuf, buf);
D printf ("=(1)=> spp_run(%s)\n", lbuf);
spp_run (lbuf+delta, out);
D printf ("=(1)=> spp_run(%s)\n", lbuf);
}
lbuf[0]='\0';
lbuf_n = 0;
} else {
D printf ("==> 2 (%s)\n", ptr);
if (ptr) {
D printf (" ==> 2.1: run(%s)\n", ptr);
spp_run (ptr, out);
buf = ptr2 + delta;
if (buf[0] == '\n' && printed) {
buf++;
}
D printf (" ==> 2.1: continue(%s)\n", ptr2 + delta);
goto retry;
} else {
do_fputs (out, "\n");
}
}
do_fputs (out, ptr2 + delta);
} else {
D printf ("==> 3\n");
if (ptr) {
lbuf_strcat (lbuf, ptr);
} else {
if (lbuf == NULL) {
// XXX should never happen
fprintf (stderr, "syntax error?\n");
return;
}
if (buf[0]) {
if (incmd) {
lbuf_strcat (lbuf, buf);
}
else {
do_fputs (out, buf);
}
} else {
do_fputs (out, buf);
}
}
}
}
/* TODO: detect nesting */
void spp_io(FILE *in, Output *out) {
char buf[4096];
int lines;
if (lbuf == NULL) {
lbuf = malloc (4096);
}
if (lbuf == NULL) {
fprintf (stderr, "Out of memory.\n");
return;
}
lbuf[0]='\0';
while(!feof(in)) {
buf[0]='\0'; // ???
fgets (buf, 1023, in);
if (feof (in)) break;
lines = 1;
if (!memcmp (buf, "#!", 2)) {
fgets (buf, 1023, in);
if (feof (in)) break;
lines++;
}
if (proc->multiline) {
while (1) {
char *eol = buf + strlen (buf) - strlen (proc->multiline);
if (!strcmp (eol, proc->multiline)) {
D fprintf(stderr, "Multiline detected!\n");
fgets (eol, 1023, in);
if (feof(in)) break;
lines++;
} else break;
}
}
spp_eval (buf, out);
lineno += lines;
}
do_fputs (out, lbuf);
}
int spp_file(const char *file, Output *out) {
FILE *in = fopen (file, "r");
D fprintf(stderr, "SPP-FILE(%s)\n", file);
if (in) {
spp_io (in, out);
fclose (in);
return 1;
} else fprintf (stderr, "Cannot find '%s'\n", file);
return 0;
}
void spp_proc_list_kw() {
int i;
for (i = 0; tags[i].name; i++)
printf ("%s\n", tags[i].name);
}
void spp_proc_list() {
int i;
for (i=0;procs[i];i++) {
printf ("%s\n", procs[i]->name);
}
}
void spp_proc_set(struct Proc *p, char *arg, int fail) {
int i, j;
if (arg)
for (j = 0; procs[j]; j++) {
if (!strcmp (procs[j]->name, arg)) {
proc = procs[j];
D printf ("SET PROC:(%s)(%s)\n", arg, proc->name);
break;
}
}
if (arg && *arg && !procs[j] && fail) {
fprintf (stderr, "Invalid preprocessor name '%s'\n", arg);
return;
}
if (proc == NULL)
proc = p;
if (proc != NULL) {
// TODO: wtf!
tag_pre = proc->tag_pre;
tag_post = proc->tag_post;
for (i = 0; i < MAXIFL; i++)
echo[i] = proc->default_echo;
token = proc->token;
tag_begin = proc->tag_begin;
args = (struct Arg*)proc->args;
tags = (struct Tag*)proc->tags;
}
}

95
shlr/spp/spp.h Normal file
View file

@ -0,0 +1,95 @@
#ifndef _INCLUDE_SPP_H_
#define _INCLUDE_SPP_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#if NO_UTIL
#include "p/r_strbuf.h"
int r_sys_setenv(const char *key, const char *value);
#else
#include <r_util.h>
#endif
#ifdef __WINDOWS__
#include <io.h>
#define popen _popen
#define pclose _pclose
#define srandom srand
#define snprintf _snprintf
#endif
#define VERSION "1.0"
#define MAXIFL 128
extern int ifl;
extern int echo[MAXIFL];
extern int lineno;
#define GET_ARG(x,y,i) if (y[i][2]) x = y[i] + 2; else x = y[++i]
#define DEFAULT_PROC(x) \
struct Tag *tags = (struct Tag *)&x##_tags; \
struct Arg *args = (struct Arg *)&x##_args; \
struct Proc *proc = &x##_proc;
typedef struct {
RStrBuf *cout;
FILE *fout;
int size;
} Output;
#define ARG_CALLBACK(x) int x (char *arg)
/* XXX swap arguments ?? */
#define TAG_CALLBACK(x) int x (char *buf, Output *out)
#define PUT_CALLBACK(x) int x (Output *out, char *buf)
#define IS_SPACE(x) ((x==' ')||(x=='\t')||(x=='\r')||(x=='\n'))
struct Tag {
const char *name;
TAG_CALLBACK((*callback));
};
struct Arg {
const char *flag;
const char *desc;
int has_arg;
ARG_CALLBACK((*callback));
};
struct Proc {
const char *name;
struct Tag **tags;
struct Arg **args;
TAG_CALLBACK ((*eof));
PUT_CALLBACK ((*fputs));
char *tag_pre;
char *tag_post;
char *token;
char *multiline;
int chop;
int tag_begin;
int default_echo;
};
int spp_file(const char *file, Output *out);
void spp_run(char *buf, Output *out);
void spp_eval(char *buf, Output *out);
void spp_io(FILE *in, Output *out);
void do_printf(Output *out, char *str, ...) __attribute__ ((format (printf, 2, 3)));
void spp_proc_list();
void spp_proc_list_kw();
void spp_proc_set(struct Proc *p, char *arg, int fail);
#if DEBUG
#define D if (1)
#else
#define D if (0)
#endif
#endif

1
shlr/spp/t/asminc Normal file
View file

@ -0,0 +1 @@
mov eax, 0x44

5
shlr/spp/t/hello.acr Normal file
View file

@ -0,0 +1,5 @@
PKGNAME spp
VERSION 0.1
CONTACT pancake ; pancake@nopcode.org
LANG_C

2
shlr/spp/t/hello.asm Normal file
View file

@ -0,0 +1,2 @@
.include t/asminc
add eax, 0x1

34
shlr/spp/t/hello.cpp Normal file
View file

@ -0,0 +1,34 @@
This is a hello cpp world
#include t/hello2.cpp
#define visible 1
#if visible
This text is visible
#endif
#if !visible
This text is not visible
#endif
#ifdef SECRET
UG
BUGB B GBUG
UG G BU
BUGBUGBUGBU
BUG BUGBUGBUGBUGBUGBUG
BUGBUGBUGBUGBUGBUGBUGBUG
BUGBUGBUGBUGBUGBUGBUGBUG
BUG BUGBUGBUGBUGBUGBUG
BUGBUGBUGBU
UG G BU
BUGB B GBUG
UG
#endif
#error Oops
this will not be visible

10
shlr/spp/t/hello.pod Normal file
View file

@ -0,0 +1,10 @@
This is a pod file
=head1 Title of the article
this really rocks
OMG this is another line
=cut
fuck :)

9
shlr/spp/t/hello.sh Normal file
View file

@ -0,0 +1,9 @@
hello {{echo world}}
This is a multiline test {{\
\
for a in hello world ; do\
echo $a ;\
done\
\
}}

17
shlr/spp/t/hello.spp Normal file
View file

@ -0,0 +1,17 @@
---
<{ set arch x86-32 }>
hello <{echo world}>
path=<{system echo $PATH}>
arch = <{ get arch }>
<{ ifeq arch x86-32 }>
FOO IS ENABLED
<{ endif }>
<{ pipe perl -ne 's/World/Stupid/g;print;' }>
Hello World
<{ endpipe }>
---
Hello <{echo world <{echo :D}> ==}>-->

1
shlr/spp/t/hello2.cpp Normal file
View file

@ -0,0 +1 @@
This message is from hello2.cpp

3
shlr/spp/t/hex.spp Normal file
View file

@ -0,0 +1,3 @@
Binary: <{hex 41 42 43}>
<{set line 34}>
GrepLine: <{grepline /etc/services <{get line}>}>

7
shlr/spp/t/macro.cpp Normal file
View file

@ -0,0 +1,7 @@
#define FOO 1
#define MAX(x,y) (x>y)?x:y
main()
{
printf("%d\n", MAX(3,10));
}

5
shlr/spp/t/multi.cpp Normal file
View file

@ -0,0 +1,5 @@
#define FOO \
Hello \
World
FOO

2
shlr/spp/t/multi.sh Normal file
View file

@ -0,0 +1,2 @@
{{ for a in hello \
world; do echo $a; done }}

2
shlr/spp/t/multiline.cpp Normal file
View file

@ -0,0 +1,2 @@
#define FOO hello \
world

12
shlr/spp/t/nest.cpp Normal file
View file

@ -0,0 +1,12 @@
#define ONE 1
#define TWO 0
#if ONE
HELLO WORLD
#if TWO
BUG: Nested conditionals
#endif
THIS IS NICE
#endif

46
shlr/spp/t/nest.spp Normal file
View file

@ -0,0 +1,46 @@
Hello <{echo world <{echo :D}> ==}>-->
<{set a secret message}>
<{system echo $a}>
<{ifeq a <{get a}>}> /* always true */
<{set var <{get PATH}>}>
Path is <{get var}>
Path is <{get PATH}>
Path is <{system echo $var}>
<{echo Path is <{get PATH}>}>
<{endif}>
<{set yes 1}>
<{set no 0}>
<{if yes}>
1 INNER VISIBLE TEXT
<{if no}>
2 BUG: INVISIBLE TEXT
<{if no}>
BUG fuck
<{if yes}>
BUG TRAP
<{endif}>
BUG fuck
<{endif}>
BUG: no one loves me
<{endif}>
<{if yes}>
HELLO WORLD
<{endif}>
3 INNER VISIBLE TEXT
<{endif}>
VISIBLE TEXT
<{if yes}>
YES DO IT
<{endif}>
<{if no}>
<{if yes}>
BUG: THIS IS A TRAP
<{endif}>
BUG: NO DONT DO IT
<{endif}>

22
shlr/spp/t/nest2.spp Normal file
View file

@ -0,0 +1,22 @@
<{set foo 2}>
<{set bar 3}>
<{ifeq foo 3}>
BUG 1
<{ifeq bar 4}>
BUG 2
<{else}>
BUG 3
<{endif}>
BUG 4
<{endif}>
<{ifeq foo 2}>
Fine!
<{ifeq bar 3}>
Perfect
<{else}>
BUG 5
<{endif}>
Cool :D
<{endif}>

12
shlr/spp/t/nest3.spp Normal file
View file

@ -0,0 +1,12 @@
<{set foo 2}>
<{set bar 2}>
<{ifeq foo 3}>
BUG 1
<{switch bar}>
<{case 1}>
BUG 2
<{case 3}>
BUG 3
<{endswitch}>
<{endif}>

1
shlr/spp/t/oneliner.spp Normal file
View file

@ -0,0 +1 @@
<{set var 1}><{ifeq var 1}>its true<{else}>BUG: false conditional check in oneliner ifeq<{endif}>

10
shlr/spp/t/random.spp Normal file
View file

@ -0,0 +1,10 @@
<{set var <{getrandom 2}>}>
Value: <{get var}>
<{ifeq var 0}>
Zero value
<{endif}>
<{ifeq var 1}>
One value
<{endif}>

32
shlr/spp/t/spp.cgi Executable file
View file

@ -0,0 +1,32 @@
#!/usr/bin/spp
Content-Type: text/html
Status: 200 OK
<html>
<head>
<title>radare</title>
</head>
<body>
Hello <{system echo beep }>
<br />
hello <{system echo world}>
<{switch QUERY_STRING}>
<{case foo}>
foo
<{case bar}>
bar
<{endswitch}>
<{ifeq QUERY_STRING foo}>
<a href="?">go back</a> <br />
<{else}>
<a href="?foo">click here</a> <br />
<{endif}>
<br />
<{system export | perl -ne 's/\n/<br>/ ;print'}>
</html>