diff --git a/bitlash.cpp b/bitlash.cpp index a529a3f..92de9d1 100644 --- a/bitlash.cpp +++ b/bitlash.cpp @@ -34,27 +34,16 @@ ***/ -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#ifdef UNIX_BUILD -#include "src/bitlash-unix.c" -//#else -//#include "src/bitlash-arduino.c" -#endif - -#include "src/bitlash-cmdline.c" -#include "src/bitlash-eeprom.c" -#include "src/bitlash-error.c" -#include "src/bitlash-functions.c" -#include "src/bitlash-builtins.c" -#include "src/bitlash-interpreter.c" -#include "src/bitlash-instream.c" -#include "src/bitlash-parser.c" -#include "src/bitlash-serial.c" -#include "src/bitlash-taskmgr.c" -#include "src/bitlash-api.c" -#include "src/eeprom.c" + +#include "src/bitlash-cmdline.cpp" +#include "src/bitlash-eeprom.cpp" +#include "src/bitlash-error.cpp" +#include "src/bitlash-functions.cpp" +#include "src/bitlash-builtins.cpp" +#include "src/bitlash-interpreter.cpp" +#include "src/bitlash-instream.cpp" +#include "src/bitlash-parser.cpp" +#include "src/bitlash-serial.cpp" +#include "src/bitlash-taskmgr.cpp" +#include "src/bitlash-api.cpp" +#include "src/eeprom.cpp" diff --git a/src/Makefile b/src/Makefile index a9f182a..5fe2485 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,12 @@ -all: - gcc -pthread *.c -o bin/bitlash +CFLAGS := -DUNIX_BUILD -pthread +LDFLAGS := -lstdc++ -pthread +SOURCES := $(wildcard *.cpp) +BINARY := bin/bitlash +PREFIX := /usr/local +BINPATH := $(PREFIX)/bin + +all: + gcc -DUNIX_BUILD $(LDFLAGS) $(CFLAGS) $(SOURCES) -o $(BINARY) install: - sudo cp bin/bitlash /usr/local/bin/ + sudo cp $(BINARY) $(BINPATH) diff --git a/src/bitlash-api.c b/src/bitlash-api.cpp similarity index 95% rename from src/bitlash-api.c rename to src/bitlash-api.cpp index da829e0..0d4be6f 100644 --- a/src/bitlash-api.c +++ b/src/bitlash-api.cpp @@ -45,7 +45,7 @@ jmp_buf env; // // doCommand: main entry point to execute a bitlash command // -numvar doCommand(char *cmd) { +numvar doCommand(const char *cmd) { return execscript(SCRIPT_RAM, (numvar) cmd, 0); } diff --git a/src/bitlash-builtins.c b/src/bitlash-builtins.cpp similarity index 99% rename from src/bitlash-builtins.c rename to src/bitlash-builtins.cpp index 5c9c911..dc80669 100644 --- a/src/bitlash-builtins.c +++ b/src/bitlash-builtins.cpp @@ -87,7 +87,7 @@ const prog_char builtin_table[] PROGMEM = { -byte findbuiltin(char *name) { +byte findbuiltin(const char *name) { const prog_char *wordlist = builtin_table; while (pgm_read_byte(wordlist)) { diff --git a/src/bitlash-cmdline.c b/src/bitlash-cmdline.cpp similarity index 99% rename from src/bitlash-cmdline.c rename to src/bitlash-cmdline.cpp index 45ac712..6c5a8fc 100644 --- a/src/bitlash-cmdline.c +++ b/src/bitlash-cmdline.cpp @@ -125,7 +125,7 @@ byte putlbuf(char c) { void pointToError(void) { if (fetchtype == SCRIPT_RAM) { - int i = (char *) fetchptr - lbuf; + int i = (const char *) fetchptr - lbuf; if ((i < 0) || (i >= LBUFLEN)) return; speol(); while (i-- >= 0) spb('-'); diff --git a/src/bitlash-eeprom.c b/src/bitlash-eeprom.cpp similarity index 94% rename from src/bitlash-eeprom.c rename to src/bitlash-eeprom.cpp index 0283f41..7bb6598 100644 --- a/src/bitlash-eeprom.c +++ b/src/bitlash-eeprom.cpp @@ -73,7 +73,7 @@ int findend(int addr) { // return true if string in EEPROM at addr matches string at str -char eestrmatch(int addr, char *str) { +char eestrmatch(int addr, const char *str) { while (*str) if (eeread(addr++) != *str++) return 0; if (eeread(addr) == 0) return 1; // ended at the same place? return 0; @@ -81,7 +81,7 @@ char eestrmatch(int addr, char *str) { // find an entry in the db; return offset of id or FAIL -int findKey(char *id) { +int findKey(const char *id) { int start = STARTDB; while (start < ENDDB-4) { // find the next entry @@ -100,7 +100,7 @@ int start = STARTDB; // Look up an entry by key. Returns -1 on fail else addr of value. -int getValue(char *key) { +int getValue(const char *key) { int kaddr = findKey(key); return (kaddr < 0) ? kaddr : findend(kaddr); } @@ -134,7 +134,7 @@ int starthole = STARTDB, endhole; // // Save string at str to EEPROM at addr -void saveString(int addr, char *str) { +void saveString(int addr, const char *str) { while (*str) eewrite(addr++, *str++); eewrite(addr, 0); } @@ -150,7 +150,7 @@ int erasestr(int addr) { } // erase entry by id -void eraseentry(char *id) { +void eraseentry(const char *id) { int entry = findKey(id); if (entry >= 0) erasestr(erasestr(entry)); } @@ -180,10 +180,10 @@ char id[IDLEN+1]; // buffer for id // fetchptr is on the character after '{' // // BUG: This is broken for file scripts - char *startmark = (char *) fetchptr; // mark first char of macro text + const char *startmark = (const char *) fetchptr; // mark first char of macro text void skipstatement(void); skipstatement(); // gobble it up without executing it - char *endmark = (char *) fetchptr; // and note the char past '}' + const char *endmark = (const char *) fetchptr; // and note the char past '}' // endmark is past the closing '}' - back up and find it do { diff --git a/src/bitlash-error.c b/src/bitlash-error.cpp similarity index 100% rename from src/bitlash-error.c rename to src/bitlash-error.cpp diff --git a/src/bitlash-functions.c b/src/bitlash-functions.cpp similarity index 97% rename from src/bitlash-functions.c rename to src/bitlash-functions.cpp index 6c2074f..df0f57e 100644 --- a/src/bitlash-functions.c +++ b/src/bitlash-functions.cpp @@ -176,7 +176,7 @@ numvar func_pulsein(void) { reqargs(3); return pulseIn(arg1, arg2, arg3); } numvar func_snooze(void) { reqargs(1); snooze(arg1); return 0; } numvar func_delay(void) { reqargs(1); delay(arg1); return 0; } -#if !defined(TINY_BUILD) +#if defined(SOFTWARE_SERIAL_TX) numvar func_setBaud(void) { reqargs(2); setBaud(arg1, arg2); return 0; } #endif @@ -189,14 +189,14 @@ numvar func_bitread(void) { reqargs(2); return (arg1 & ((numvar)1 << arg2)) != 0 numvar func_bitwrite(void) { reqargs(3); return arg3 ? func_bitset() : func_bitclear(); } numvar func_getkey(void) { - if (getarg(0) > 0) sp((char *) getarg(1)); + if (getarg(0) > 0) sp((const char *) getarg(1)); while (!serialAvailable()) {;} // blocking! return (numvar) serialRead(); } numvar func_getnum(void) { numvar num = 0; - if (getarg(0) > 0) sp((char *) getarg(1)); + if (getarg(0) > 0) sp((const char *) getarg(1)); for (;;) { while (!serialAvailable()) {;} // blocking! int k = serialRead(); @@ -274,7 +274,9 @@ const prog_char functiondict[] PROGMEM = { "abs\0" "ar\0" "aw\0" +#if defined(SOFTWARE_SERIAL_TX) "baud\0" +#endif "bc\0" "beep\0" "br\0" @@ -351,7 +353,9 @@ const bitlash_function function_table[] PROGMEM = { func_abs, func_ar, func_aw, +#if defined(SOFTWARE_SERIAL_TX) func_setBaud, +#endif func_bitclear, func_beep, func_bitread, @@ -383,13 +387,6 @@ const bitlash_function function_table[] PROGMEM = { }; #endif -// Enable USER_FUNCTIONS to include the add_bitlash_function() extension mechanism -// This costs about 256 bytes -// -#if !defined(TINY_BUILD) -#define USER_FUNCTIONS -#endif - #ifdef USER_FUNCTIONS #define MAX_USER_FUNCTIONS 20 // increase this if needed, but keep free() > 200 ish #define USER_FUNCTION_FLAG 0x80 @@ -441,7 +438,7 @@ void addBitlashFunction(const char *name, bitlash_function func_ptr) { // find_user_function: find id in the user function table. // return true if found, with the user function token in symval (with USER_FUNCTION_FLAG set) // -char find_user_function(char *id) { +char find_user_function(const char *id) { symval = 0; while (symval < bf_install_count) { if (!strcmp(id, user_functions[symval].name)) { diff --git a/src/bitlash-instream.c b/src/bitlash-instream.cpp similarity index 88% rename from src/bitlash-instream.c rename to src/bitlash-instream.cpp index dad38f0..0d69a55 100644 --- a/src/bitlash-instream.c +++ b/src/bitlash-instream.cpp @@ -35,19 +35,19 @@ ***/ #include "bitlash.h" -#if defined(SDFILE) +#if defined(SDFILE) || defined(UNIX_BUILD) #define O_READ 0x01 // from SdFile.h // Trampolines for the SD library -byte scriptfileexists(char *scriptname); -byte scriptopen(char *scriptname, numvar position, byte flags); +byte scriptfileexists(const char *scriptname); +byte scriptopen(const char *scriptname, numvar position, byte flags); numvar scriptgetpos(void); byte scriptread(void); -byte scriptwrite(char *filename, char *contents, byte append); +byte scriptwrite(const char *filename, const char *contents, byte append); void scriptwritebyte(byte b); -#elif !defined(UNIX_BUILD) -byte scriptfileexists(char *scriptname) { return 0; } +#else +byte scriptfileexists(const char *scriptname) { return 0; } #endif // masks for stashing the pointer type in the high nibble @@ -60,7 +60,7 @@ byte scriptfileexists(char *scriptname) { return 0; } #endif // forward declaration -void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname); +void initparsepoint(byte scripttype, numvar scriptaddress, const char *scriptname); ///////// @@ -72,7 +72,7 @@ void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname); // and in runBackgroundTasks to kick off the background run. // // -numvar execscript(byte scripttype, numvar scriptaddress, char *scriptname) { +numvar execscript(byte scripttype, numvar scriptaddress, const char *scriptname) { // save parse context parsepoint fetchmark; @@ -137,8 +137,8 @@ numvar execscript(byte scripttype, numvar scriptaddress, char *scriptname) { // how to access the calling and called function names // //#define callername ((char *) ((numvar *) arg[2]) [1]) -#define callername (arg[2] ? (char* ) (((numvar *) arg[2]) [1]) : NULL ) -#define calleename ((char *) arg[1]) +#define callername (arg[2] ? (const char* ) (((numvar *) arg[2]) [1]) : NULL ) +#define calleename ((const char *) arg[1]) ///////// @@ -195,7 +195,7 @@ void markparsepoint(parsepoint *p) { } -void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname) { +void initparsepoint(byte scripttype, numvar scriptaddress, const char *scriptname) { #ifdef PARSER_TRACE if (trace) { @@ -234,12 +234,12 @@ void initparsepoint(byte scripttype, numvar scriptaddress, char *scriptname) { #ifdef UNIX_BUILD -char *topname = ".top."; +const char *topname = ".top."; void returntoparsepoint(parsepoint *p, byte returntoparent) { // restore parse type and location; for script files, pass name from string pool byte ftype = p->fetchtype; - char *scriptname = calleename; + const char *scriptname = calleename; if (returntoparent) { if ((ftype == SCRIPT_NONE) || (ftype == SCRIPT_RAM)) scriptname = topname; @@ -297,7 +297,7 @@ void fetchc(void) { // void primec(void) { switch (fetchtype) { - case SCRIPT_RAM: inchar = *(char *) fetchptr; break; + case SCRIPT_RAM: inchar = *(const char *) fetchptr; break; case SCRIPT_PROGMEM: inchar = pgm_read_byte(fetchptr); break; case SCRIPT_EEPROM: inchar = eeread((int) fetchptr); break; @@ -327,7 +327,7 @@ void primec(void) { void traceback(void) { numvar *a = arg; while (a) { - sp((char *) (a[1])); speol(); + sp((const char *) (a[1])); speol(); a = (numvar *) (a[2]); } } @@ -340,10 +340,10 @@ numvar *a = arg; // "cat": copy file to serial out // numvar sdcat(void) { - if (!scriptfileexists((char *) getarg(1))) return 0; + if (!scriptfileexists((const char *) getarg(1))) return 0; parsepoint fetchmark; markparsepoint(&fetchmark); - initparsepoint(SCRIPT_FILE, 0L, (char *) getarg(1)); + initparsepoint(SCRIPT_FILE, 0L, (const char *) getarg(1)); while (inchar) { if (inchar == '\n') spb('\r'); spb(inchar); @@ -358,7 +358,7 @@ numvar sdcat(void) { // // sdwrite: write or append a line to a file // -numvar sdwrite(char *filename, char *contents, byte append) { +numvar sdwrite(const char *filename, const char *contents, byte append) { #if !defined(UNIX_BUILD) parsepoint fetchmark; markparsepoint(&fetchmark); @@ -373,6 +373,8 @@ numvar sdwrite(char *filename, char *contents, byte append) { return 1; } +// fprintf needs SERIAL_OVERRIDE to work +#ifdef SERIAL_OVERRIDE ////////// // // func_fprintf(): implementation of fprintf() function @@ -382,7 +384,7 @@ numvar func_fprintf(void) { parsepoint fetchmark; markparsepoint(&fetchmark); - scriptwrite((char *) getarg(1), "", 1); // open the file for append (but append nothing) + scriptwrite((const char *) getarg(1), "", 1); // open the file for append (but append nothing) //serialOutputFunc saved_handler = serial_override_handler; // save previous output handler void scriptwritebyte(byte); @@ -397,5 +399,6 @@ numvar func_fprintf(void) { #endif returntoparsepoint(&fetchmark, 1); } +#endif #endif // SDFILE diff --git a/src/bitlash-interpreter.c b/src/bitlash-interpreter.cpp similarity index 100% rename from src/bitlash-interpreter.c rename to src/bitlash-interpreter.cpp diff --git a/src/bitlash-parser.c b/src/bitlash-parser.cpp similarity index 99% rename from src/bitlash-parser.c rename to src/bitlash-parser.cpp index 30d20a5..df3a9bf 100644 --- a/src/bitlash-parser.c +++ b/src/bitlash-parser.cpp @@ -44,7 +44,7 @@ byte fetchtype; // current script type numvar fetchptr; // pointer to current char in script numvar symval; // value of current numeric expression -#if !USE_GPIORS +#if !defined(USE_GPIORS) byte sym; // current input symbol byte inchar; // Current parser character #endif @@ -222,7 +222,7 @@ void spush(char c) { } // push a string into the string pool -void strpush(char *ptr) { +void strpush(const char *ptr) { while (*ptr) spush(*ptr++); spush(0); } @@ -383,7 +383,7 @@ const prog_uchar reservedwordtypes[] PROGMEM = { s_arg, s_boot, s_else, s_functi #endif // find id in PROGMEM wordlist. result in symval, return true if found. -byte findindex(char *id, const prog_char *wordlist, byte sorted) { +byte findindex(const char *id, const prog_char *wordlist, byte sorted) { symval = 0; while (pgm_read_byte(wordlist)) { int result = strcmp_P(id, wordlist); @@ -436,7 +436,7 @@ const prog_uchar pinvalues[] PROGMEM = { 0, 1, 13, (PV_ANALOG | 1), (PV_VAR | 25) }; -byte findpinname(char *alias) { +byte findpinname(const char *alias) { if (!findindex(alias, (const prog_char *) pinnames, 0)) return 0; // sets symval byte pin = pgm_read_byte(pinvalues + symval); //sym = (pin & PV_ANALOG) ? s_apin : s_dpin; @@ -612,7 +612,9 @@ void parseid(void) { else if (findpinname(idbuf)) {;} // sym and symval are set in findpinname #endif +#ifdef USER_FUNCTIONS else if (find_user_function(idbuf)) sym = s_nfunct; +#endif else findscript(idbuf); } @@ -622,7 +624,7 @@ void parseid(void) { // // findscript: look up a script, with side effects // -byte findscript(char *idbuf) { +byte findscript(const char *idbuf) { // script function in eeprom? if ((symval=findKey(idbuf)) >= 0) sym = s_script_eeprom; diff --git a/src/bitlash-serial.c b/src/bitlash-serial.cpp similarity index 98% rename from src/bitlash-serial.c rename to src/bitlash-serial.cpp index e003335..a77ca09 100644 --- a/src/bitlash-serial.c +++ b/src/bitlash-serial.cpp @@ -386,7 +386,7 @@ void cmd_print(void) { else if (symval == 'b'-'a') printBinary((unumvar) expval); // :b print binary #endif else if (symval == 'y'-'a') spb(expval); // :y print byte - else if (symval == 's'-'a') sp((char *)expval); // :s print string + else if (symval == 's'-'a') sp((const char *)expval); // :s print string } else if (sym > ' ') while (expval-- > 0) spb(sym); // any litsym else expected(M_pfmts); @@ -422,7 +422,7 @@ numvar func_printf_handler(byte formatarg, byte optionalargs) { // todo: get rid of s_pound if (getarg(0) < formatarg) { speol(); return 0; } - char *fptr = (char *) getarg(formatarg); // format string pointer + const char *fptr = (const char *) getarg(formatarg); // format string pointer while (*fptr) { if (*fptr == '%') { @@ -447,7 +447,7 @@ numvar func_printf_handler(byte formatarg, byte optionalargs) { case 'b': printIntegerInBase(getarg(optionalargs), 2, width, pad); break; // binary case 's': { // string - char *sptr = (char *) getarg(optionalargs); + const char *sptr = (const char *) getarg(optionalargs); // BUG: width is the max not the prepad width -= strlen(sptr); while (width-- > 0) spb(' '); // pre-pad with blanks diff --git a/src/bitlash-taskmgr.c b/src/bitlash-taskmgr.cpp similarity index 100% rename from src/bitlash-taskmgr.c rename to src/bitlash-taskmgr.cpp diff --git a/src/bitlash-unix-file.c b/src/bitlash-unix-file.cpp similarity index 89% rename from src/bitlash-unix-file.c rename to src/bitlash-unix-file.cpp index 035fd5d..bd19aaf 100644 --- a/src/bitlash-unix-file.c +++ b/src/bitlash-unix-file.cpp @@ -77,6 +77,11 @@ ***/ #include "bitlash.h" +#include +#include +#include +#include +#include #if defined(UNIX_BUILD) @@ -90,7 +95,7 @@ char cachedname[FNAMELEN]; byte cachedflags; // return true iff script exists -byte scriptfileexists(char *scriptname) { +byte scriptfileexists(const char *scriptname) { FILE *file; if ((file = fopen(scriptname, "r")) == NULL) return 0; fclose(file); @@ -106,7 +111,7 @@ byte scriptclose(void) { } // open and set parse location on input file -byte scriptopen(char *scriptname, numvar position, byte flags) { +byte scriptopen(const char *scriptname, numvar position, byte flags) { // open the input file if there is no file open, // or the open file does not match what we want @@ -140,14 +145,14 @@ byte scriptread(void) { return input; } -byte scriptwrite(char *filename, char *contents, byte append) { +byte scriptwrite(const char *filename, const char *contents, byte append) { /// if (scriptfile_is_open) { /// if (!scriptfile.close()) return 0; /// } FILE *outfile; - char *flags; + const char *flags; if (append) flags = "a"; else flags = "w"; @@ -179,28 +184,28 @@ numvar sdls(void) { return 0; } numvar sdexists(void) { - return scriptfileexists((char *) getarg(1)); + return scriptfileexists((const char *) getarg(1)); } numvar sdrm(void) { - return unlink((char *) getarg(1)); + return unlink((const char *) getarg(1)); } numvar sdcreate(void) { - return sdwrite((char *) getarg(1), (char *) getarg(2), 0); + return sdwrite((const char *) getarg(1), (const char *) getarg(2), 0); } numvar sdappend(void) { - return sdwrite((char *) getarg(1), (char *) getarg(2), 1); + return sdwrite((const char *) getarg(1), (const char *) getarg(2), 1); } numvar sdcd(void) { // close any cached open file handle if (scriptfile_is_open) scriptclose(); - return chdir((char *) getarg(1)); + return chdir((const char *) getarg(1)); } numvar sdmd(void) { - return mkdir((char *) getarg(1)); + return mkdir((const char *) getarg(1), 0777); } numvar exec(void) { - return doCommand((char *) getarg(1)); + return doCommand((const char *) getarg(1)); } numvar func_pwd(void) { @@ -234,4 +239,4 @@ void setup(void) { #endif -#endif // defined(UNIX_BUILD) \ No newline at end of file +#endif // defined(UNIX_BUILD) diff --git a/src/bitlash-unix.c b/src/bitlash-unix.cpp similarity index 95% rename from src/bitlash-unix.c rename to src/bitlash-unix.cpp index 4262e39..1489793 100644 --- a/src/bitlash-unix.c +++ b/src/bitlash-unix.cpp @@ -27,13 +27,16 @@ OTHER DEALINGS IN THE SOFTWARE. */ #include "bitlash.h" +#include +#include +#include +#include /* Build: - cd bitlash/src - mac: gcc *.c -o bitlash - linux: gcc -pthread *.c -o bitlash + cd bitlash/src + make Issues @@ -232,9 +235,10 @@ void fputbyte(byte b) { fwrite(&b, 1, 1, savefd); } +#ifdef SERIAL_OVERRIDE numvar func_save(void) { - char *fname = "eeprom"; - if (getarg(0) > 0) fname = (char *) getarg(1); + const char *fname = "eeprom"; + if (getarg(0) > 0) fname = (const char *) getarg(1); savefd = fopen(fname, "w"); if (!savefd) return 0; setOutputHandler(&fputbyte); @@ -243,6 +247,7 @@ numvar func_save(void) { fclose(savefd); return 1; }; +#endif @@ -272,7 +277,7 @@ void *BackgroundMacroThread(void *threadid) { numvar func_system(void) { - return system((char *) getarg(1)); + return system((const char *) getarg(1)); } numvar func_exit(void) { @@ -310,10 +315,11 @@ int main () { init_fake_eeprom(); addBitlashFunction("system", (bitlash_function) &func_system); addBitlashFunction("exit", (bitlash_function) &func_exit); + #ifdef SERIAL_OVERRIDE addBitlashFunction("save", (bitlash_function) &func_save); + #endif // from bitlash-unix-file.c - extern bitlash_function exec, sdls, sdexists, sdrm, sdcreate, sdappend, sdcat, sdcd, sdmd, func_pwd; addBitlashFunction("exec", (bitlash_function) &exec); addBitlashFunction("dir", (bitlash_function) &sdls); addBitlashFunction("exists", (bitlash_function) &sdexists); @@ -324,7 +330,9 @@ int main () { addBitlashFunction("cd", (bitlash_function) &sdcd); addBitlashFunction("md", (bitlash_function) &sdmd); addBitlashFunction("pwd", (bitlash_function) &func_pwd); + #ifdef SERIAL_OVERRIDE addBitlashFunction("fprintf", (bitlash_function) &func_fprintf); + #endif init_millis(); @@ -338,7 +346,7 @@ int main () { // run the main stdin command loop for (;;) { - char * ret = fgets(lbuf, STRVALLEN, stdin); + const char * ret = fgets(lbuf, STRVALLEN, stdin); if (ret == NULL) break; doCommand(lbuf); initlbuf(); diff --git a/src/bitlash.h b/src/bitlash.h index 51895af..205c279 100644 --- a/src/bitlash.h +++ b/src/bitlash.h @@ -36,9 +36,19 @@ #ifndef _BITLASH_H #define _BITLASH_H -#if defined(__x86_64__) || defined(__i386__) -#define UNIX_BUILD 1 -#elif defined(__SAM3X8E__) +#if defined(HIGH) || defined(ARDUINO) // this detects the Arduino build environment +#if defined(ARDUINO) && ARDUINO >= 100 + #include "Arduino.h" + #define prog_char char PROGMEM + #define prog_uchar char PROGMEM +#else + #include "WProgram.h" + #include "WConstants.h" +#endif +#endif // HIGH || ARDUINO + +#if !defined(UNIX_BUILD) +#if defined(__SAM3X8E__) #define ARM_BUILD 1 #elif (defined(__MK20DX128__) || defined(__MK20DX256__)) && defined (CORE_TEENSY) // Teensy 3 @@ -46,6 +56,7 @@ #else #define AVR_BUILD 1 #endif +#endif // !defined(UNIX_BUILD) #if defined(AVR_BUILD) @@ -54,30 +65,9 @@ #include "avr/interrupt.h" #endif -#if defined(AVR_BUILD) || defined(ARM_BUILD) -#include "string.h" -#include "ctype.h" -#include "setjmp.h" -#endif - -// Unix includes -#if defined(UNIX_BUILD) -#include -#include -#include #include -#include "ctype.h" -#include "setjmp.h" -#include -#include -#include -//#include -#endif - -#ifndef byte -#define byte uint8_t -#endif - +#include +#include //////////////////////////////////////////////////// // GLOBAL BUILD OPTIONS @@ -125,17 +115,6 @@ // Arduino version: 11 - enable by hand if needed; see bitlash-serial.h //#define ARDUINO_VERSION 11 - -#if defined(ARDUINO) && ARDUINO >= 100 - #include "Arduino.h" - #define prog_char char PROGMEM - #define prog_uchar char PROGMEM -#else - #include "WProgram.h" - #include "WConstants.h" -#endif - - // Enable Software Serial tx support for Arduino // this enables "setbaud(4, 4800); print #4:..." // at a cost of about 400 bytes (for tx only) @@ -314,6 +293,12 @@ void beginEthernet(unsigned long baud) { #endif // TINY_BUILD +// Enable USER_FUNCTIONS to include the add_bitlash_function() extension mechanism +// This costs about 256 bytes +// +#if !defined(TINY_BUILD) +#define USER_FUNCTIONS +#endif /////////////////////////////////////////////////////// // @@ -379,7 +364,7 @@ void beginSerial(unsigned long baud) { ; } // Unix build options // (not working) // -// > gcc bitlash.cpp -D UNIX_BUILD +// See README-UNIX.md for info about how to compile // #ifdef UNIX_BUILD #define MINIMUM_FREE_RAM 200 @@ -390,6 +375,7 @@ void beginSerial(unsigned long baud) { ; } #define E2END 2047 +#define byte uint8_t #define uint8_t unsigned char #define uint32_t unsigned long int #define prog_char char @@ -460,11 +446,16 @@ void connectBitlash(void); // void initBitlash(unsigned long baud); // start up and set baud rate void runBitlash(void); // call this in loop(), frequently -numvar doCommand(char *); // execute a command from your sketch +numvar doCommand(const char *); // execute a command from your sketch void doCharacter(char); // pass an input character to the line editor //void flash(unsigned int, int); +///////////////////////////////////////////// +// bitlash-builtins.c +// +void displayBanner(void); +byte findbuiltin(const char *name); ///////////////////////////////////////////// // bitlash-arduino.c @@ -488,10 +479,9 @@ void delayMicroseconds(unsigned int); ///////////////////////////////////////////// // bitlash-cmdline.c // -#ifdef TINY_BUILD -byte putlbuf(char); void initlbuf(void); -#endif +void pointToError(void); +void cmd_help(void); // String value buffer size #ifdef AVR_BUILD @@ -509,8 +499,8 @@ extern char lbuf[LBUFLEN]; ///////////////////////////////////////////// // bitlash-eeprom.c // -int findKey(char *key); // return location of macro keyname in EEPROM or -1 -int getValue(char *key); // return location of macro value in EEPROM or -1 +int findKey(const char *key); // return location of macro keyname in EEPROM or -1 +int getValue(const char *key); // return location of macro value in EEPROM or -1 int findoccupied(int); int findend(int); @@ -557,7 +547,7 @@ void expected(byte); void expectedchar(byte); void unexpected(byte); void missing(byte); -//void oops(int); // fatal exit +void oops(int); // fatal exit ///////////////////////////////////////////// @@ -565,6 +555,8 @@ void missing(byte); // typedef numvar (*bitlash_function)(void); void show_user_functions(void); +char find_user_function(const char *id); +void addBitlashFunction(const char *name, bitlash_function func_ptr); void dofunctioncall(byte); numvar func_free(void); @@ -594,6 +586,7 @@ void speol(void); numvar func_printf(void); numvar func_printf_handler(byte,byte); +void cmd_print(void); #ifdef SOFTWARE_SERIAL_TX numvar setBaud(numvar, unumvar); @@ -626,6 +619,7 @@ void stopTask(byte); void startTask(int, numvar); void snooze(unumvar); void showTaskList(void); +unsigned long millisUntilNextTask(void); extern byte background; extern byte curtask; extern byte suspendBackground; @@ -633,15 +627,21 @@ extern byte suspendBackground; ///////////////////////////////////////////// // eeprom.c -// they must live off piste due to aggressive compiler inlining. // +void eewrite(int, byte); +byte eeread(int); +void eraseentry(const char *id); +void cmd_function(void); +void cmd_ls(void); +void cmd_peep(void); + #if defined(AVR_BUILD) +// they must live off piste due to aggressive compiler inlining. void eewrite(int, byte) __attribute__((noinline)); byte eeread(int) __attribute__((noinline)); +#endif -#elif defined(ARM_BUILD) -void eewrite(int, byte); -byte eeread(int); +#if defined(ARM_BUILD) extern char virtual_eeprom[]; void eeinit(void); #endif @@ -674,9 +674,9 @@ numvar incVar(uint8_t id); // increment variable. id is [0..25] for [a..z] #define SCRIPT_EEPROM 3 #define SCRIPT_FILE 4 -byte findscript(char *); -byte scriptfileexists(char *); -numvar execscript(byte, numvar, char *); +byte findscript(const char *); +byte scriptfileexists(const char *); +numvar execscript(byte, numvar, const char *); void callscriptfunction(byte, numvar); typedef struct { @@ -716,12 +716,8 @@ extern byte fetchtype; // current script type extern numvar fetchptr; // pointer to current char in input buffer extern numvar symval; // value of current numeric expression -#define USE_GPIORS defined(AVR_BUILD) - -#ifndef GPIOR0 || GPIOR1 - #undef USE_GPIORS -#endif -#if (defined USE_GPIORS) +#if defined(AVR_BUILD) && defined(GPIOR0) && defined(GPIOR1) +#define USE_GPIORS #define sym GPIOR0 #define inchar GPIOR1 #else @@ -743,6 +739,47 @@ extern numvar expval; // value of numeric expr or length of string #define IDLEN 12 extern char idbuf[IDLEN+1]; +///////////////////////////////////////////// +// bitlash-instream.c +// + +#if defined(SDFILE) || defined(UNIX_BUILD) +numvar sdwrite(const char *filename, const char *contents, byte append); +#endif + +///////////////////////////////////////////// +// bitlash-unix-file.c +// +#if defined(UNIX_BUILD) +numvar exec(void); +numvar sdls(void); +numvar sdexists(void); +numvar sdrm(void); +numvar sdcreate(void); +numvar sdappend(void); +numvar sdcat(void); +numvar sdcd(void); +numvar sdmd(void); +numvar func_pwd(void); +#endif + +///////////////////////////////////////////// +// bitlash-unix.c +// +#if defined(UNIX_BUILD) +int serialAvailable(void); +int serialRead(void); +void digitalWrite(uint8_t, uint8_t); +int digitalRead(uint8_t); +int analogRead(uint8_t); +void analogWrite(byte, int); +void pinMode(uint8_t, uint8_t); +int pulseIn(int, int, int); +unsigned long millis(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int); +#endif + // Strings live in PROGMEM to save ram // diff --git a/src/conio.h b/src/conio.h deleted file mode 100644 index 6b2e2ea..0000000 --- a/src/conio.h +++ /dev/null @@ -1,30 +0,0 @@ -// from http://www.daniweb.com/software-development/c/threads/410155/gcc-equivalent-for-getch -#include -#include -#include -/* reads from keypress, doesn't echo */ -int getch(void) -{ - struct termios oldattr, newattr; - int ch; - tcgetattr( STDIN_FILENO, &oldattr ); - newattr = oldattr; - newattr.c_lflag &= ~( ICANON | ECHO ); - tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); - ch = getchar(); - tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); - return ch; -} -/* reads from keypress, echoes */ -int getche(void) -{ - struct termios oldattr, newattr; - int ch; - tcgetattr( STDIN_FILENO, &oldattr ); - newattr = oldattr; - newattr.c_lflag &= ~( ICANON ); - tcsetattr( STDIN_FILENO, TCSANOW, &newattr ); - ch = getchar(); - tcsetattr( STDIN_FILENO, TCSANOW, &oldattr ); - return ch; -} \ No newline at end of file diff --git a/src/eeprom.c b/src/eeprom.cpp similarity index 100% rename from src/eeprom.c rename to src/eeprom.cpp diff --git a/src/mygetch.c b/src/mygetch.c deleted file mode 100644 index 7e7b25e..0000000 --- a/src/mygetch.c +++ /dev/null @@ -1,59 +0,0 @@ -// fromm http://pastebin.com/r6BRYDxV -#include -#include -#include -#include "ctype.h" -#include "setjmp.h" -#include -#include -#include - -int mygetch() { - char ch; - int error; - static struct termios Otty, Ntty; - - fflush(stdout); - tcgetattr(0, &Otty); - Ntty = Otty; - - Ntty.c_iflag = 0; /* input mode */ - Ntty.c_oflag = 0; /* output mode */ - Ntty.c_lflag &= ~ICANON; /* line settings */ - -#if 1 - /* disable echoing the char as it is typed */ - Ntty.c_lflag &= ~ECHO; /* disable echo */ -#else - /* enable echoing the char as it is typed */ - Ntty.c_lflag |= ECHO; /* enable echo */ -#endif - -// Ntty.c_cc[VMIN] = CMIN; /* minimum chars to wait for */ -// Ntty.c_cc[VTIME] = CTIME; /* minimum wait time */ - Ntty.c_cc[VMIN] = 0; /* minimum chars to wait for */ - Ntty.c_cc[VTIME] = 0; /* minimum wait time */ - -//printf("MYGETCH: %d %d", CMIN, CTIME); // 1 0 -//fflush(stdout); - -#if 0 - /* - * use this to flush the input buffer before blocking for new input - */ - #define FLAG TCSAFLUSH -#else - /* - * use this to return a char from the current input buffer, or block if - * no input is waiting. - */ - #define FLAG TCSANOW -#endif - - if ((error = tcsetattr(0, FLAG, &Ntty)) == 0) { - error = read(0, &ch, 1); /* get char from stdin */ - error += tcsetattr(0, FLAG, &Otty); /* restore old settings */ - } - - return (error == 1 ? (int) ch : -1 ); -}