diff --git a/.gitignore b/.gitignore index 8df7ccb2e55..ce45cabadd5 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,8 @@ hardware/arduino/bootloaders/caterina_LUFA/Caterina.elf hardware/arduino/bootloaders/caterina_LUFA/Caterina.eep hardware/arduino/bootloaders/caterina_LUFA/.dep/ build/libastylej-*.zip +build/ctags-*.zip +build/coan-*.zip build/windows/work/ build/windows/*.zip build/windows/*.tgz @@ -25,6 +27,8 @@ build/windows/launch4j-*.tgz build/windows/launch4j-*.zip build/windows/launcher/launch4j build/windows/WinAVR-*.zip +build/windows/ctags* +build/windows/coan* build/macosx/arduino-*.zip build/macosx/dist/*.tar.gz build/macosx/dist/*.tar.bz2 @@ -35,14 +39,19 @@ build/macosx/appbundler*.zip build/macosx/appbundler build/macosx/appbundler-1.0ea-arduino2 build/macosx/appbundler-1.0ea-upstream1 +build/macosx/ctags* +build/macosx/coan* build/linux/work/ build/linux/dist/*.tar.gz build/linux/dist/*.tar.bz2 build/linux/*.tgz build/linux/*.tar.bz2 +build/linux/*.tar.xz build/linux/*.zip build/linux/libastylej* build/shared/reference*.zip +build/linux/ctags* +build/linux/coan* test-bin *.iml .idea diff --git a/app/build.xml b/app/build.xml index cbab1355226..d196ffd5ee6 100644 --- a/app/build.xml +++ b/app/build.xml @@ -99,6 +99,7 @@ + diff --git a/app/test/processing/app/AbstractWithPreferencesTest.java b/app/test/processing/app/AbstractWithPreferencesTest.java index ca07ec385ff..e86a4b5db52 100644 --- a/app/test/processing/app/AbstractWithPreferencesTest.java +++ b/app/test/processing/app/AbstractWithPreferencesTest.java @@ -2,11 +2,17 @@ import org.junit.Before; +import java.io.File; +import java.util.LinkedList; + public abstract class AbstractWithPreferencesTest { @Before public void init() throws Exception { Base.initPlatform(); + BaseNoGui.initPackages(); + BaseNoGui.scanAndUpdateLibraries(new LinkedList()); + BaseNoGui.populateImportToLibraryTable(); Preferences.init(null); Theme.init(); diff --git a/app/test/processing/app/LoadHardwareTest.java b/app/test/processing/app/LoadHardwareTest.java new file mode 100644 index 00000000000..a1fce1b6a7d --- /dev/null +++ b/app/test/processing/app/LoadHardwareTest.java @@ -0,0 +1,39 @@ +package processing.app; + +import org.junit.Test; +import processing.app.debug.TargetPlatform; +import processing.app.helpers.PreferencesMap; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class LoadHardwareTest extends AbstractWithPreferencesTest { + + @Test + public void shouldHaveLoadedTheParentPlatformTxtFiles() { + TargetPlatform targetPlatform = BaseNoGui.getTargetPlatform("arduino", "avr"); + + PreferencesMap ctags = targetPlatform.getTool("ctags"); + assertNotNull(ctags); + assertEquals("{runtime.ide.path}/hardware/tools/ctags", ctags.get("cmd.path")); + assertEquals("\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzn \"{source_file}\"", ctags.get("pattern")); + + PreferencesMap coan = targetPlatform.getTool("coan"); + assertNotNull(coan); + assertEquals("{runtime.ide.path}/hardware/tools/coan", coan.get("cmd.path")); + assertEquals("\"{cmd.path}\" source -m -E -P -kb {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} \"{source_file}\"", coan.get("pattern")); + + targetPlatform = BaseNoGui.getTargetPlatform("arduino", "sam"); + + ctags = targetPlatform.getTool("ctags"); + assertNotNull(ctags); + assertEquals("{runtime.ide.path}/hardware/tools/ctags", ctags.get("cmd.path")); + assertEquals("\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzn \"{source_file}\"", ctags.get("pattern")); + + coan = targetPlatform.getTool("coan"); + assertNotNull(coan); + assertEquals("{runtime.ide.path}/hardware/tools/coan", coan.get("cmd.path")); + assertEquals("\"{cmd.path}\" source -m -E -P -kb {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.libsam.c.flags} \"{source_file}\"", coan.get("pattern")); + } + +} diff --git a/app/test/processing/app/debug/UploaderFactoryTest.java b/app/test/processing/app/debug/UploaderFactoryTest.java index 5365f97bc95..20861f1917b 100644 --- a/app/test/processing/app/debug/UploaderFactoryTest.java +++ b/app/test/processing/app/debug/UploaderFactoryTest.java @@ -8,6 +8,7 @@ import org.junit.Before; import org.junit.Test; import processing.app.AbstractWithPreferencesTest; +import processing.app.helpers.PreferencesMap; import java.io.File; @@ -19,7 +20,7 @@ public class UploaderFactoryTest extends AbstractWithPreferencesTest { @Before public void setUp() throws Exception { - targetPackage = new TargetPackage("arduino", new File(".", "hardware/arduino/")); + targetPackage = new TargetPackage("arduino", new File(".", "hardware/arduino/"), new PreferencesMap()); } @Test diff --git a/app/test/processing/app/preproc/Baladuino.nocomments.ino b/app/test/processing/app/preproc/Baladuino.nocomments.ino deleted file mode 100644 index 81324031cf3..00000000000 --- a/app/test/processing/app/preproc/Baladuino.nocomments.ino +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - - - - - - - -#define ENABLE_TOOLS -#define ENABLE_SPP -#define ENABLE_PS3 -#define ENABLE_WII -#define ENABLE_XBOX -#define ENABLE_ADK - -#include "Balanduino.h" -#include -#include - -#ifdef ENABLE_ADK -#include -#endif - - - -#include - -#ifdef ENABLE_XBOX -#include -#endif -#ifdef ENABLE_SPP -#include -#endif -#ifdef ENABLE_PS3 -#include -#endif -#ifdef ENABLE_WII -#include -#endif - - -Kalman kalman; - -#if defined(ENABLE_SPP) || defined(ENABLE_PS3) || defined(ENABLE_WII) || defined(ENABLE_XBOX) || defined(ENABLE_ADK) -#define ENABLE_USB -USB Usb; -#endif - -#ifdef ENABLE_ADK - -ADK adk(&Usb, "TKJ Electronics", - "Balanduino", - "Android App for Balanduino", - "0.5.0", - "https://play.google.com/store/apps/details?id=com.tkjelectronics.balanduino", - "1234"); -#endif - -#ifdef ENABLE_XBOX -XBOXRECV Xbox(&Usb); -#endif - -#if defined(ENABLE_SPP) || defined(ENABLE_PS3) || defined(ENABLE_WII) -USBHub Hub(&Usb); -BTD Btd(&Usb); -#endif - -#ifdef ENABLE_SPP -SPP SerialBT(&Btd, "Balanduino", "0000"); -#endif - -#ifdef ENABLE_PS3 -PS3BT PS3(&Btd); -#endif - -#ifdef ENABLE_WII -WII Wii(&Btd); - - - - -#endif - -void setup() { - - Serial.begin(115200); - - - if (!checkInitializationFlags()) - readEEPROMValues(); - - - pinMode(leftEncoder1, INPUT); - pinMode(leftEncoder2, INPUT); - pinMode(rightEncoder1, INPUT); - pinMode(rightEncoder2, INPUT); - attachInterrupt(0, leftEncoder, CHANGE); - attachInterrupt(1, rightEncoder, CHANGE); - - - pinMode(leftEnable, OUTPUT); - pinMode(rightEnable, OUTPUT); - digitalWrite(leftEnable, HIGH); - digitalWrite(rightEnable, HIGH); - - - sbi(pwmPortDirection, leftPWM); - sbi(leftPortDirection, leftA); - sbi(leftPortDirection, leftB); - sbi(pwmPortDirection, rightPWM); - sbi(rightPortDirection, rightA); - sbi(rightPortDirection, rightB); - - - - TCCR1B = _BV(WGM13) | _BV(CS10); - ICR1 = PWMVALUE; - - - - - TCCR1A = _BV(COM1A1) | _BV(COM1B1); - setPWM(leftPWM, 0); - setPWM(rightPWM, 0); - - - pinMode(buzzer, OUTPUT); - -#ifdef ENABLE_USB - if (Usb.Init() == -1) { - Serial.print(F("OSC did not start")); - digitalWrite(buzzer, HIGH); - while (1); - } -#endif - - - -#ifdef ENABLE_PS3 - PS3.attachOnInit(onInit); -#endif -#ifdef ENABLE_WII - Wii.attachOnInit(onInit); -#endif -#ifdef ENABLE_XBOX - Xbox.attachOnInit(onInit); -#endif - - - Wire.begin(); - - while (i2cRead(0x75, i2cBuffer, 1)); - if (i2cBuffer[0] != 0x68) { - Serial.print(F("Error reading sensor")); - digitalWrite(buzzer, HIGH); - while (1); - } - - i2cBuffer[0] = 19; - i2cBuffer[1] = 0x00; - i2cBuffer[2] = 0x00; - i2cBuffer[3] = 0x00; - while (i2cWrite(0x19, i2cBuffer, 4, false)); - while (i2cWrite(0x6B, 0x09, true)); - - delay(100); - - - while (i2cRead(0x3D, i2cBuffer, 4)); - accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); - accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); - - - accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; - - kalman.setAngle(accAngle); - pitch = accAngle; - gyroAngle = accAngle; - - - calibrateGyro(); - - pinMode(LED_BUILTIN, OUTPUT); - - - digitalWrite(buzzer, HIGH); - delay(100); - digitalWrite(buzzer, LOW); - - - kalmanTimer = micros(); - pidTimer = kalmanTimer; - encoderTimer = kalmanTimer; - imuTimer = millis(); - reportTimer = imuTimer; - ledTimer = imuTimer; - blinkTimer = imuTimer; -} - -void loop() { -#ifdef ENABLE_WII - if (Wii.wiimoteConnected) - Usb.Task(); -#endif - - - while (i2cRead(0x3D, i2cBuffer, 8)); - accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); - accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); - gyroX = ((i2cBuffer[6] << 8) | i2cBuffer[7]); - - - - accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; - - uint32_t timer = micros(); - - if ((accAngle < 90 && pitch > 270) || (accAngle > 270 && pitch < 90)) { - kalman.setAngle(accAngle); - pitch = accAngle; - gyroAngle = accAngle; - } else { - gyroRate = ((double)gyroX - gyroXzero) / 131.0; - double dt = (double)(timer - kalmanTimer) / 1000000.0; - gyroAngle += gyroRate * dt; - if (gyroAngle < 0 || gyroAngle > 360) - gyroAngle = pitch; - pitch = kalman.getAngle(accAngle, gyroRate, dt); - } - kalmanTimer = timer; - - -#ifdef ENABLE_WII - if (Wii.wiimoteConnected) - Usb.Task(); -#endif - - - timer = micros(); - - - if ((layingDown && (pitch < cfg.targetAngle - 10 || pitch > cfg.targetAngle + 10)) || (!layingDown && (pitch < cfg.targetAngle - 45 || pitch > cfg.targetAngle + 45))) { - layingDown = true; - stopAndReset(); - } else { - layingDown = false; - updatePID(cfg.targetAngle, targetOffset, turningOffset, (double)(timer - pidTimer) / 1000000.0); - } - pidTimer = timer; - - - timer = micros(); - if (timer - encoderTimer >= 100000) { - encoderTimer = timer; - int32_t wheelPosition = getWheelsPosition(); - wheelVelocity = wheelPosition - lastWheelPosition; - lastWheelPosition = wheelPosition; - - if (abs(wheelVelocity) <= 40 && !stopped) { - targetPosition = wheelPosition; - stopped = true; - } - - batteryCounter++; - if (batteryCounter > 10) { - batteryCounter = 0; - batteryVoltage = (double)analogRead(VBAT) / 63.050847458; - if (batteryVoltage < 10.2 && batteryVoltage > 5) - digitalWrite(buzzer, HIGH); - else - digitalWrite(buzzer, LOW); - } - } - - -#ifdef ENABLE_USB - readUsb(); -#endif -#ifdef ENABLE_TOOLS - checkSerialData(); -#endif -#if defined(ENABLE_TOOLS) || defined(ENABLE_SPP) - printValues(); -#endif - -#if defined(ENABLE_SPP) || defined(ENABLE_PS3) || defined(ENABLE_WII) - if (Btd.isReady()) { - timer = millis(); - if ((Btd.watingForConnection && timer - blinkTimer > 1000) || (!Btd.watingForConnection && timer - blinkTimer > 100)) { - blinkTimer = timer; - ledState = !ledState; - digitalWrite(LED_BUILTIN, ledState); - } - } else if (ledState) { - ledState = !ledState; - digitalWrite(LED_BUILTIN, ledState); - } -#endif -} - diff --git a/app/test/processing/app/preproc/Baladuino.preprocessed.ino b/app/test/processing/app/preproc/Baladuino.preprocessed.ino new file mode 100644 index 00000000000..675a6d7f726 --- /dev/null +++ b/app/test/processing/app/preproc/Baladuino.preprocessed.ino @@ -0,0 +1,309 @@ +/* + * The code is released under the GNU General Public License. + * Developed by Kristian Lauszus, TKJ Electronics 2013 + * This is the algorithm for the Balanduino balancing robot. + * It can be controlled by either an Android app or a Processing application via Bluetooth. + * The Android app can be found at the following link: https://github.com/TKJElectronics/BalanduinoAndroidApp + * The Processing application can be found here: https://github.com/TKJElectronics/BalanduinoProcessingApp + * It can also be controlled by a PS3, Wii or a Xbox controller + * For details, see: http://balanduino.net/ + */ + +/* Use this to enable and disable the different options */ +#define ENABLE_TOOLS +#define ENABLE_SPP +#define ENABLE_PS3 +#define ENABLE_WII +#define ENABLE_XBOX +#define ENABLE_ADK + +#include "Balanduino.h" +#include // Official Arduino Wire library +#include // Some dongles can have a hub inside + + +#include + + +// These are all open source libraries written by Kristian Lauszus, TKJ Electronics +// The USB libraries are located at the following link: https://github.com/felis/USB_Host_Shield_2.0 +#include // Kalman filter library - see: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it/ + + +#include + + +#include + + +#include + + +#include + + +// Create the Kalman library instance +#include +#line 46 +Kalman kalman; // See https://github.com/TKJElectronics/KalmanFilter for source code + + +#define ENABLE_USB +USB Usb; // This will take care of all USB communication + + + +// Implementation for the Android Open Accessory Protocol. Simply connect your phone to get redirected to the Play Store +ADK adk(&Usb, "TKJ Electronics", // Manufacturer Name + "Balanduino", // Model Name + "Android App for Balanduino", // Description - user visible string + "0.5.0", // Version of the Android app + "https://play.google.com/store/apps/details?id=com.tkjelectronics.balanduino", // URL - web page to visit if no installed apps support the accessory + "1234"); // Serial Number - this is not used + + + +XBOXRECV Xbox(&Usb); // You have to connect a Xbox wireless receiver to the Arduino to control it with a wireless Xbox controller + + + +USBHub Hub(&Usb); // Some dongles have a hub inside +BTD Btd(&Usb); // This is the main Bluetooth library, it will take care of all the USB and HCI communication with the Bluetooth dongle + + + +SPP SerialBT(&Btd, "Balanduino", "0000"); // The SPP (Serial Port Protocol) emulates a virtual Serial port, which is supported by most computers and mobile phones + + + +PS3BT PS3(&Btd); // The PS3 library supports all three official controllers: the Dualshock 3, Navigation and Move controller + + + +WII Wii(&Btd); // The Wii library can communicate with Wiimotes and the Nunchuck and Motion Plus extension and finally the Wii U Pro Controller +//WII Wii(&Btd,PAIR); // You will have to pair with your Wiimote first by creating the instance like this and the press 1+2 on the Wiimote +// or press sync if you are using a Wii U Pro Controller +// Or you can simply send "CW;" to the robot to start the pairing sequence +// This can also be done using the Android or Processing application + + +void setup(); +void loop(); +#line 88 +void setup() { + /* Initialize UART */ + Serial.begin(115200); + + /* Read the PID values, target angle and other saved values in the EEPROM */ + if (!checkInitializationFlags()) + readEEPROMValues(); // Only read the EEPROM values if they have not been restored + + /* Setup encoders */ + pinMode(leftEncoder1, INPUT); + pinMode(leftEncoder2, INPUT); + pinMode(rightEncoder1, INPUT); + pinMode(rightEncoder2, INPUT); + attachInterrupt(0, leftEncoder, CHANGE); + attachInterrupt(1, rightEncoder, CHANGE); + + /* Enable the motor drivers */ + pinMode(leftEnable, OUTPUT); + pinMode(rightEnable, OUTPUT); + digitalWrite(leftEnable, HIGH); + digitalWrite(rightEnable, HIGH); + + /* Setup motor pins to output */ + sbi(pwmPortDirection, leftPWM); + sbi(leftPortDirection, leftA); + sbi(leftPortDirection, leftB); + sbi(pwmPortDirection, rightPWM); + sbi(rightPortDirection, rightA); + sbi(rightPortDirection, rightB); + + /* Set PWM frequency to 20kHz - see the datasheet http://www.atmel.com/Images/doc8272.pdf page 128-135 */ + // Set up PWM, Phase and Frequency Correct on pin 18 (OC1A) & pin 17 (OC1B) with ICR1 as TOP using Timer1 + TCCR1B = _BV(WGM13) | _BV(CS10); // Set PWM Phase and Frequency Correct with ICR1 as TOP and no prescaling + ICR1 = PWMVALUE; // ICR1 is the TOP value - this is set so the frequency is equal to 20kHz + + /* Enable PWM on pin 18 (OC1A) & pin 17 (OC1B) */ + // Clear OC1A/OC1B on compare match when up-counting + // Set OC1A/OC1B on compare match when downcounting + TCCR1A = _BV(COM1A1) | _BV(COM1B1); + setPWM(leftPWM, 0); // Turn off PWM on both pins + setPWM(rightPWM, 0); + + /* Setup buzzer pin */ + pinMode(buzzer, OUTPUT); + + + if (Usb.Init() == -1) { // Check if USB Host is working + Serial.print(F("OSC did not start")); + digitalWrite(buzzer, HIGH); + while (1); // Halt + } + + + /* Attach onInit function */ + // This is used to set the LEDs according to the voltage level and vibrate the controller to indicate the new connection + + PS3.attachOnInit(onInit); + + + Wii.attachOnInit(onInit); + + + Xbox.attachOnInit(onInit); + + + /* Setup IMU */ + Wire.begin(); + + while (i2cRead(0x75, i2cBuffer, 1)); + if (i2cBuffer[0] != 0x68) { // Read "WHO_AM_I" register + Serial.print(F("Error reading sensor")); + digitalWrite(buzzer, HIGH); + while (1); // Halt + } + + i2cBuffer[0] = 19; // Set the sample rate to 400Hz - 8kHz/(19+1) = 400Hz + i2cBuffer[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling + i2cBuffer[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s + i2cBuffer[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g + while (i2cWrite(0x19, i2cBuffer, 4, false)); // Write to all four registers at once + while (i2cWrite(0x6B, 0x09, true)); // PLL with X axis gyroscope reference, disable temperature sensor and disable sleep mode + + delay(100); // Wait for the sensor to get ready + + /* Set Kalman and gyro starting angle */ + while (i2cRead(0x3D, i2cBuffer, 4)); + accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); + accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); + // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2 + // We then convert it to 0 to 2π and then from radians to degrees + accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; + + kalman.setAngle(accAngle); // Set starting angle + pitch = accAngle; + gyroAngle = accAngle; + + /* Find gyro zero value */ + calibrateGyro(); + + pinMode(LED_BUILTIN, OUTPUT); // LED_BUILTIN is defined in pins_arduino.h in the hardware add-on + + /* Beep to indicate that it is now ready */ + digitalWrite(buzzer, HIGH); + delay(100); + digitalWrite(buzzer, LOW); + + /* Setup timing */ + kalmanTimer = micros(); + pidTimer = kalmanTimer; + encoderTimer = kalmanTimer; + imuTimer = millis(); + reportTimer = imuTimer; + ledTimer = imuTimer; + blinkTimer = imuTimer; +} + +void loop() { + + if (Wii.wiimoteConnected) // We have to read much more often from the Wiimote to decrease latency + Usb.Task(); + + + /* Calculate pitch */ + while (i2cRead(0x3D, i2cBuffer, 8)); + accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); + accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); + gyroX = ((i2cBuffer[6] << 8) | i2cBuffer[7]); + + // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2 + // We then convert it to 0 to 2π and then from radians to degrees + accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; + + uint32_t timer = micros(); + // This fixes the 0-360 transition problem when the accelerometer angle jumps between 0 and 360 degrees + if ((accAngle < 90 && pitch > 270) || (accAngle > 270 && pitch < 90)) { + kalman.setAngle(accAngle); + pitch = accAngle; + gyroAngle = accAngle; + } else { + gyroRate = ((double)gyroX - gyroXzero) / 131.0; // Convert to deg/s + double dt = (double)(timer - kalmanTimer) / 1000000.0; + gyroAngle += gyroRate * dt; // Gyro angle is only used for debugging + if (gyroAngle < 0 || gyroAngle > 360) + gyroAngle = pitch; // Reset the gyro angle when it has drifted too much + pitch = kalman.getAngle(accAngle, gyroRate, dt); // Calculate the angle using a Kalman filter + } + kalmanTimer = timer; + //Serial.print(accAngle);Serial.print('\t');Serial.print(gyroAngle);Serial.print('\t');Serial.println(pitch); + + + if (Wii.wiimoteConnected) // We have to read much more often from the Wiimote to decrease latency + Usb.Task(); + + + /* Drive motors */ + timer = micros(); + // If the robot is laying down, it has to be put in a vertical position before it starts balancing + // If it's already balancing it has to be ±45 degrees before it stops trying to balance + if ((layingDown && (pitch < cfg.targetAngle - 10 || pitch > cfg.targetAngle + 10)) || (!layingDown && (pitch < cfg.targetAngle - 45 || pitch > cfg.targetAngle + 45))) { + layingDown = true; // The robot is in a unsolvable position, so turn off both motors and wait until it's vertical again + stopAndReset(); + } else { + layingDown = false; // It's no longer laying down + updatePID(cfg.targetAngle, targetOffset, turningOffset, (double)(timer - pidTimer) / 1000000.0); + } + pidTimer = timer; + + /* Update encoders */ + timer = micros(); + if (timer - encoderTimer >= 100000) { // Update encoder values every 100ms + encoderTimer = timer; + int32_t wheelPosition = getWheelsPosition(); + wheelVelocity = wheelPosition - lastWheelPosition; + lastWheelPosition = wheelPosition; + //Serial.print(wheelPosition);Serial.print('\t');Serial.print(targetPosition);Serial.print('\t');Serial.println(wheelVelocity); + if (abs(wheelVelocity) <= 40 && !stopped) { // Set new targetPosition if braking + targetPosition = wheelPosition; + stopped = true; + } + + batteryCounter++; + if (batteryCounter > 10) { // Measure battery every 1s + batteryCounter = 0; + batteryVoltage = (double)analogRead(VBAT) / 63.050847458; // VBAT is connected to analog input 5 which is not broken out. This is then connected to a 47k-12k voltage divider - 1023.0/(3.3/(12.0/(12.0+47.0))) = 63.050847458 + if (batteryVoltage < 10.2 && batteryVoltage > 5) // Equal to 3.4V per cell - don't turn on if it's below 5V, this means that no battery is connected + digitalWrite(buzzer, HIGH); + else + digitalWrite(buzzer, LOW); + } + } + + /* Read the Bluetooth dongle and send PID and IMU values */ + + readUsb(); + + + checkSerialData(); + + + printValues(); + + + + if (Btd.isReady()) { + timer = millis(); + if ((Btd.watingForConnection && timer - blinkTimer > 1000) || (!Btd.watingForConnection && timer - blinkTimer > 100)) { + blinkTimer = timer; + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); // Used to blink the built in LED, starts blinking faster upon an incoming Bluetooth request + } + } else if (ledState) { // The LED is on + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); // This will turn it off + } + +} + diff --git a/app/test/processing/app/preproc/Baladuino.stripped.ino b/app/test/processing/app/preproc/Baladuino.stripped.ino deleted file mode 100644 index 168eedd375c..00000000000 --- a/app/test/processing/app/preproc/Baladuino.stripped.ino +++ /dev/null @@ -1,303 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Kalman kalman; - - - -USB Usb; - - - - -ADK adk(&Usb, , - , - , - , - , - ); - - - -XBOXRECV Xbox(&Usb); - - - -USBHub Hub(&Usb); -BTD Btd(&Usb); - - - -SPP SerialBT(&Btd, , ); - - - -PS3BT PS3(&Btd); - - - -WII Wii(&Btd); - - - - - - -void setup() { - - Serial.begin(115200); - - - if (!checkInitializationFlags()) - readEEPROMValues(); - - - pinMode(leftEncoder1, INPUT); - pinMode(leftEncoder2, INPUT); - pinMode(rightEncoder1, INPUT); - pinMode(rightEncoder2, INPUT); - attachInterrupt(0, leftEncoder, CHANGE); - attachInterrupt(1, rightEncoder, CHANGE); - - - pinMode(leftEnable, OUTPUT); - pinMode(rightEnable, OUTPUT); - digitalWrite(leftEnable, HIGH); - digitalWrite(rightEnable, HIGH); - - - sbi(pwmPortDirection, leftPWM); - sbi(leftPortDirection, leftA); - sbi(leftPortDirection, leftB); - sbi(pwmPortDirection, rightPWM); - sbi(rightPortDirection, rightA); - sbi(rightPortDirection, rightB); - - - - TCCR1B = _BV(WGM13) | _BV(CS10); - ICR1 = PWMVALUE; - - - - - TCCR1A = _BV(COM1A1) | _BV(COM1B1); - setPWM(leftPWM, 0); - setPWM(rightPWM, 0); - - - pinMode(buzzer, OUTPUT); - - - if (Usb.Init() == -1) { - Serial.print(F( )); - digitalWrite(buzzer, HIGH); - while (1); - } - - - - - - PS3.attachOnInit(onInit); - - - Wii.attachOnInit(onInit); - - - Xbox.attachOnInit(onInit); - - - - Wire.begin(); - - while (i2cRead(0x75, i2cBuffer, 1)); - if (i2cBuffer[0] != 0x68) { - Serial.print(F( )); - digitalWrite(buzzer, HIGH); - while (1); - } - - i2cBuffer[0] = 19; - i2cBuffer[1] = 0x00; - i2cBuffer[2] = 0x00; - i2cBuffer[3] = 0x00; - while (i2cWrite(0x19, i2cBuffer, 4, false)); - while (i2cWrite(0x6B, 0x09, true)); - - delay(100); - - - while (i2cRead(0x3D, i2cBuffer, 4)); - accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); - accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); - - - accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; - - kalman.setAngle(accAngle); - pitch = accAngle; - gyroAngle = accAngle; - - - calibrateGyro(); - - pinMode(LED_BUILTIN, OUTPUT); - - - digitalWrite(buzzer, HIGH); - delay(100); - digitalWrite(buzzer, LOW); - - - kalmanTimer = micros(); - pidTimer = kalmanTimer; - encoderTimer = kalmanTimer; - imuTimer = millis(); - reportTimer = imuTimer; - ledTimer = imuTimer; - blinkTimer = imuTimer; -} - -void loop() { - - if (Wii.wiimoteConnected) - Usb.Task(); - - - - while (i2cRead(0x3D, i2cBuffer, 8)); - accY = ((i2cBuffer[0] << 8) | i2cBuffer[1]); - accZ = ((i2cBuffer[2] << 8) | i2cBuffer[3]); - gyroX = ((i2cBuffer[6] << 8) | i2cBuffer[7]); - - - - accAngle = (atan2((double)accY - cfg.accYzero, (double)accZ - cfg.accZzero) + PI) * RAD_TO_DEG; - - uint32_t timer = micros(); - - if ((accAngle < 90 && pitch > 270) || (accAngle > 270 && pitch < 90)) { - kalman.setAngle(accAngle); - pitch = accAngle; - gyroAngle = accAngle; - } else { - gyroRate = ((double)gyroX - gyroXzero) / 131.0; - double dt = (double)(timer - kalmanTimer) / 1000000.0; - gyroAngle += gyroRate * dt; - if (gyroAngle < 0 || gyroAngle > 360) - gyroAngle = pitch; - pitch = kalman.getAngle(accAngle, gyroRate, dt); - } - kalmanTimer = timer; - - - - if (Wii.wiimoteConnected) - Usb.Task(); - - - - timer = micros(); - - - if ((layingDown && (pitch < cfg.targetAngle - 10 || pitch > cfg.targetAngle + 10)) || (!layingDown && (pitch < cfg.targetAngle - 45 || pitch > cfg.targetAngle + 45))) { - layingDown = true; - stopAndReset(); - } else { - layingDown = false; - updatePID(cfg.targetAngle, targetOffset, turningOffset, (double)(timer - pidTimer) / 1000000.0); - } - pidTimer = timer; - - - timer = micros(); - if (timer - encoderTimer >= 100000) { - encoderTimer = timer; - int32_t wheelPosition = getWheelsPosition(); - wheelVelocity = wheelPosition - lastWheelPosition; - lastWheelPosition = wheelPosition; - - if (abs(wheelVelocity) <= 40 && !stopped) { - targetPosition = wheelPosition; - stopped = true; - } - - batteryCounter++; - if (batteryCounter > 10) { - batteryCounter = 0; - batteryVoltage = (double)analogRead(VBAT) / 63.050847458; - if (batteryVoltage < 10.2 && batteryVoltage > 5) - digitalWrite(buzzer, HIGH); - else - digitalWrite(buzzer, LOW); - } - } - - - - readUsb(); - - - checkSerialData(); - - - printValues(); - - - - if (Btd.isReady()) { - timer = millis(); - if ((Btd.watingForConnection && timer - blinkTimer > 1000) || (!Btd.watingForConnection && timer - blinkTimer > 100)) { - blinkTimer = timer; - ledState = !ledState; - digitalWrite(LED_BUILTIN, ledState); - } - } else if (ledState) { - ledState = !ledState; - digitalWrite(LED_BUILTIN, ledState); - } - -} diff --git a/app/test/processing/app/preproc/CTagsBakedPreprocessorTest.java b/app/test/processing/app/preproc/CTagsBakedPreprocessorTest.java new file mode 100644 index 00000000000..5a25765729b --- /dev/null +++ b/app/test/processing/app/preproc/CTagsBakedPreprocessorTest.java @@ -0,0 +1,175 @@ +package processing.app.preproc; + +import org.junit.Before; +import org.junit.Test; +import processing.app.AbstractWithPreferencesTest; +import processing.app.BaseNoGui; +import processing.app.PreferencesData; +import processing.app.helpers.FileUtils; +import processing.app.helpers.PreferencesMap; + +import java.io.File; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class CTagsBakedPreprocessorTest extends AbstractWithPreferencesTest { + + private PreferencesMap prefs; + + @Before + public void preparePreferences() { + PreferencesData.set("target_package", "arduino"); + PreferencesData.set("target_platform", "avr"); + + prefs = new PreferencesMap(); + prefs.putAll(PreferencesData.getMap()); + prefs.putAll(BaseNoGui.getTargetPlatform().getTool("ctags")); + prefs.putAll(BaseNoGui.getTargetBoard().getPreferences()); + prefs.putAll(BaseNoGui.getTargetBoard().getContainerPlatform().getPreferences()); + prefs.put("build.arch", "AVR"); + } + + @Test + public void shouldPreprocessSketchWithIfDef() throws Exception { + Map context = preprocessTestSketch("SketchWithIfDef.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(5, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("void debug();", prototypes.get(2)); + assertEquals("void disabledIsDefined();", prototypes.get(3)); + assertEquals("int useMyType(MyType type);", prototypes.get(4)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("SketchWithIfDef.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessBaladuino() throws Exception { + Map context = preprocessTestSketch("Baladuino.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(2, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("Baladuino.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessCharWithEscapedDoubleQuote() throws Exception { + Map context = preprocessTestSketch("CharWithEscapedDoubleQuote.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(21, prototypes.size()); + assertTrue(prototypes.contains("void setup();")); + assertTrue(prototypes.contains("byte decToBcd( byte b );")); + assertTrue(prototypes.contains("void sendTextMessage( char number[], char messg[] );")); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("CharWithEscapedDoubleQuote.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessIncludeBetweenMultilineComment() throws Exception { + Map context = preprocessTestSketch("IncludeBetweenMultilineComment.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(2, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("IncludeBetweenMultilineComment.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessLineContinuations() throws Exception { + Map context = preprocessTestSketch("LineContinuations.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(2, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("LineContinuations.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessStringWithComment() throws Exception { + Map context = preprocessTestSketch("StringWithComment.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(2, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("StringWithComment.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + @Test + public void shouldPreprocessSketchWithStruct() throws Exception { + Map context = preprocessTestSketch("SketchWithStruct.ino"); + + String preprocessedCode = (String) context.get("source"); + List prototypes = (List) context.get("prototypes"); + + assertEquals(3, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("void dostuff(A_NEW_TYPE * bar);", prototypes.get(2)); + + File expectedPreprocessedSketch = new File(CTagsBakedPreprocessorTest.class.getResource("SketchWithStruct.preprocessed.ino").getFile()); + String expectedOutput = FileUtils.readFileToString(expectedPreprocessedSketch); + + assertEquals(expectedOutput, preprocessedCode); + } + + private Map preprocessTestSketch(String sketchName) throws Exception { + File sketch = new File(CTagsBakedPreprocessorTest.class.getResource(sketchName).getFile()); + + String input = FileUtils.readFileToString(sketch); + + Map context = new HashMap(); + context.put("source", input); + context.put("lineOffset", 0); + + new IncludesFinder(prefs, true).preprocess(context); + + new CTagsBakedPreprocessor(prefs, true).preprocess(context, prefs); + return context; + } + +} diff --git a/app/test/processing/app/preproc/CTagsParserTest.java b/app/test/processing/app/preproc/CTagsParserTest.java new file mode 100644 index 00000000000..5f71bcfb634 --- /dev/null +++ b/app/test/processing/app/preproc/CTagsParserTest.java @@ -0,0 +1,149 @@ +package processing.app.preproc; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class CTagsParserTest { + + @Test + public void shouldListPrototypes() throws Exception { + String ctagsOutput = "server\t/tmp/sketch7210316334309249705.cpp\t/^YunServer server;$/;\"\tkind:variable\tline:31\n" + + "setup\t/tmp/sketch7210316334309249705.cpp\t/^void setup() {$/;\"\tkind:function\tline:33\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch7210316334309249705.cpp\t/^void loop() {$/;\"\tkind:function\tline:46\tsignature:()\treturntype:void\n" + + "process\t/tmp/sketch7210316334309249705.cpp\t/^void process(YunClient client);$/;\"\tkind:prototype\tline:61\tsignature:(YunClient client)\treturntype:void\n" + + "process\t/tmp/sketch7210316334309249705.cpp\t/^void process(YunClient client) {$/;\"\tkind:function\tline:62\tsignature:(YunClient client)\treturntype:void\n" + + "digitalCommand\t/tmp/sketch7210316334309249705.cpp\t/^void digitalCommand(YunClient client) {$/;\"\tkind:function\tline:82\tsignature:(YunClient client)\treturntype:void\n" + + "analogCommand\t/tmp/sketch7210316334309249705.cpp\t/^void analogCommand(YunClient client) {$/;\"\tkind:function\tline:110\tsignature:(YunClient client)\treturntype:void\n" + + "modeCommand\t/tmp/sketch7210316334309249705.cpp\t/^void modeCommand(YunClient client) {$/;\"\tkind:function\tline:151\tsignature:(YunClient client)\treturntype:void\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(5, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("void digitalCommand(YunClient client);", prototypes.get(2)); + assertEquals("void analogCommand(YunClient client);", prototypes.get(3)); + assertEquals("void modeCommand(YunClient client);", prototypes.get(4)); + } + + @Test + public void shouldListTemplates() throws Exception { + String ctagsOutput = "minimum\t/tmp/sketch8398023134925534708.cpp\t/^template T minimum (T a, T b) $/;\"\tkind:function\tline:2\tsignature:(T a, T b)\treturntype:templateT\n" + + "setup\t/tmp/sketch8398023134925534708.cpp\t/^void setup () $/;\"\tkind:function\tline:9\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch8398023134925534708.cpp\t/^void loop () { }$/;\"\tkind:function\tline:13\tsignature:()\treturntype:void\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(3, prototypes.size()); + assertEquals("template T minimum (T a, T b);", prototypes.get(0)); + assertEquals("void setup();", prototypes.get(1)); + assertEquals("void loop();", prototypes.get(2)); + } + + @Test + public void shouldListTemplates2() throws Exception { + String ctagsOutput = "setup\t/tmp/sketch463160524247569568.cpp\t/^void setup() {$/;\"\tkind:function\tline:1\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch463160524247569568.cpp\t/^void loop() {$/;\"\tkind:function\tline:6\tsignature:()\treturntype:void\n" + + "SRAM_writeAnything\t/tmp/sketch463160524247569568.cpp\t/^template int SRAM_writeAnything(int ee, const T& value)$/;\"\tkind:function\tline:11\tsignature:(int ee, const T& value)\treturntype:template int\n" + + "SRAM_readAnything\t/tmp/sketch463160524247569568.cpp\t/^template int SRAM_readAnything(int ee, T& value)$/;\"\tkind:function\tline:21\tsignature:(int ee, T& value)\treturntype:template int\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(4, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("template int SRAM_writeAnything(int ee, const T& value);", prototypes.get(2)); + assertEquals("template int SRAM_readAnything(int ee, T& value);", prototypes.get(3)); + } + + @Test + public void shouldDealWithClasses() throws Exception { + String ctagsOutput = "SleepCycle\t/tmp/sketch9043227824785312266.cpp\t/^ SleepCycle( const char* name );$/;\"\tkind:prototype\tline:4\tsignature:( const char* name )\n" + + "SleepCycle\t/tmp/sketch9043227824785312266.cpp\t/^ SleepCycle::SleepCycle( const char* name )$/;\"\tkind:function\tline:8\tsignature:( const char* name )\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(0, prototypes.size()); + } + + @Test + public void shouldDealWithStructs() throws Exception { + String ctagsOutput = "A_NEW_TYPE\t/tmp/sketch8930345717354294915.cpp\t/^struct A_NEW_TYPE {$/;\"\tkind:struct\tline:3\n" + + "foo\t/tmp/sketch8930345717354294915.cpp\t/^} foo;$/;\"\tkind:variable\tline:7\ttyperef:struct:A_NEW_TYPE\n" + + "setup\t/tmp/sketch8930345717354294915.cpp\t/^void setup() {$/;\"\tkind:function\tline:9\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch8930345717354294915.cpp\t/^void loop() {$/;\"\tkind:function\tline:13\tsignature:()\treturntype:void\n" + + "dostuff\t/tmp/sketch8930345717354294915.cpp\t/^void dostuff (A_NEW_TYPE * bar)$/;\"\tkind:function\tline:17\tsignature:(A_NEW_TYPE * bar)\treturntype:void\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(3, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("void dostuff(A_NEW_TYPE * bar);", prototypes.get(2)); + } + + @Test + public void shouldDealWithMacros() throws Exception { + String ctagsOutput = "DEBUG\t/tmp/sketch5976699731718729500.cpp\t1;\"\tkind:macro\tline:1\n" + + "DISABLED\t/tmp/sketch5976699731718729500.cpp\t2;\"\tkind:macro\tline:2\n" + + "hello\t/tmp/sketch5976699731718729500.cpp\t/^String hello = \"world!\";$/;\"\tkind:variable\tline:16\n" + + "setup\t/tmp/sketch5976699731718729500.cpp\t/^void setup() {$/;\"\tkind:function\tline:18\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch5976699731718729500.cpp\t/^void loop() {$/;\"\tkind:function\tline:23\tsignature:()\treturntype:void\n" + + "debug\t/tmp/sketch5976699731718729500.cpp\t/^void debug() {$/;\"\tkind:function\tline:35\tsignature:()\treturntype:void\n" + + "disabledIsDefined\t/tmp/sketch5976699731718729500.cpp\t/^void disabledIsDefined() {$/;\"\tkind:function\tline:46\tsignature:()\treturntype:void\n" + + "useMyType\t/tmp/sketch5976699731718729500.cpp\t/^int useMyType(MyType type) {$/;\"\tkind:function\tline:50\tsignature:(MyType type)\treturntype:int\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(5, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("void debug();", prototypes.get(2)); + assertEquals("void disabledIsDefined();", prototypes.get(3)); + assertEquals("int useMyType(MyType type);", prototypes.get(4)); + + assertEquals(18, context.get("firstFunctionAtLine")); + } + + + @Test + public void shouldRemoveDefaultArgsValues() throws Exception { + String ctagsOutput = "setup\t/tmp/sketch3020016532877959639.cpp\t/^void setup() {$/;\"\tkind:function\tline:2\tsignature:()\treturntype:void\n" + + "loop\t/tmp/sketch3020016532877959639.cpp\t/^void loop() {$/;\"\tkind:function\tline:7\tsignature:()\treturntype:void\n" + + "program\t/tmp/sketch3020016532877959639.cpp\t/^byte program (const byte b1, const byte b2 = 0, const byte b3 = 0, const byte b4 = 0)$/;\"\tkind:function\tline:12\tsignature:(const byte b1, const byte b2 = 0, const byte b3 = 0, const byte b4 = 0)\treturntype:byte\n"; + + Map context = new HashMap(); + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + List prototypes = (List) context.get("prototypes"); + + assertEquals(3, prototypes.size()); + assertEquals("void setup();", prototypes.get(0)); + assertEquals("void loop();", prototypes.get(1)); + assertEquals("byte program(const byte b1, const byte b2, const byte b3, const byte b4);", prototypes.get(2)); + } + +} diff --git a/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.nocomments.ino b/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.nocomments.ino deleted file mode 100644 index 0b2af8b5f10..00000000000 --- a/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.nocomments.ino +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include - - -#define DS3231_I2C_ADDRESS 104 -#define DS3231_TIME_CAL_ADDR 0 -#define DS3231_ALARM1_ADDR 7 -#define DS3231_ALARM2_ADDR 11 -#define DS3231_CONTROL_ADDR 14 -#define DS3231_STATUS_ADDR 15 - -#define DS3231_TEMPERATURE_ADDR 17 - - -SoftwareSerial GPRS( 7, 8 ); -byte buffer[ 64 ]; -int count = 0, e = 0, count2 = 0, t = 0, q; -char temp, lastCaller[13] = "blank"; -boolean callIncoming = false, done; - - -byte time[ 7 ]; -byte time_A1[ 5 ]; -byte time_A2[ 4 ]; -byte received[1]; -float temperature; - - -char telescopeNames[6][4]; - - - - - - - - - -void setPowerStateTo( int newState ) -{ - if( newState != 1 && newState != 0 ) { - Serial.print( "Error: Invalid powerstate. Current powerstate = " ); - Serial.print( getPowerState() ); - Serial.print( "\n" ); - } - else { - if( newState == getPowerState() ) { - Serial.print( "Powerstate = " ); - Serial.print( newState ); - Serial.print( " remains unchanged.\n" ); - } - else { - powerUpOrDown(); - Serial.print( "Powerstate changed from " ); - Serial.print( 1 - newState ); - Serial.print( " to " ); - Serial.print( newState ); - Serial.print( "\n" ); - } - } - delay( 5000 ); -} - -int getPowerState() -{ - int ret; - if ( digitalRead(18) == 0 && digitalRead(19) == 0 ) - ret = 1; - else - ret = 0; - - return ret; -} - -void powerUpOrDown() -{ - pinMode( 9, OUTPUT ); - digitalWrite( 9, LOW ); - delay( 1000 ); - digitalWrite( 9, HIGH ); - delay( 2000 ); - digitalWrite( 9, LOW ); - delay( 3000 ); -} - - - - - -void clearBufferArray() -{ - for( int i = 0; i < count; i++ ) - buffer[ i ] = NULL; -} - -void makeMissedCall( char num[] ) -{ - int i; - char in[ 18 ] = "ATD"; - for( i = 3; i <= 14; i++ ) - in[ i ] = num[ i - 3] ; - in[ 15 ] = ';'; - in[ 16 ] = '\r'; - in[ 17 ] = '\0'; - GPRS.write( in ); - delay( 10000 ); - GPRS.write( "ATH\r\0" ); - delay( 1000 ); -} - -void sendTextMessage( char number[], char messg[] ) -{ - char temp[ 27 ] = "AT + CMGS = \""; - for( q = 0; q < 12; q++ ) - temp[ q + 13 ] = number[ q ]; - temp[ 25 ] = '\"'; - temp[ 26 ] = '\0'; - - GPRS.println( "AT+CMGF=1\r" ); - delay( 1000 ); - GPRS.println( temp ); - delay( 1000 ); - GPRS.println( messg ); - delay( 1000 ); - GPRS.println( (char) 26 ); - delay( 1000 ); -} - -void analise(byte incoming[], int length) -{ - e = 0; - done = false; - while( e < length && !done){ - temp = char( incoming[e] ); - switch( temp ){ - case 'R': - { - if( length > e + 3 && !callIncoming ) { - if(char( incoming[e + 1] ) == 'I' - && char( incoming[e + 2] ) == 'N' - && char( incoming[e + 3] ) == 'G'){ - GPRS.write("AT+CLCC\r"); - delay(500); - GPRS.write("ATH\r"); - callIncoming = true; - done = true; - } - } - } - break; - case '+': - { - if(char( buffer[ e + 1]) == '2' && length > e + 11 && callIncoming){ - for(t = 0; t < 12; t++) - lastCaller[t] = char( buffer[ e + t ]); - lastCaller[12] = '\0'; - callIncoming = false; - done = true; - } - } - break; - case 'l': - Serial.println(lastCaller); - break; - } - e++; - } -} - - - - - - - - - - -byte decToBcd( byte b ) -{ - return ( b / 10 << 4 ) + b % 10; -} - -boolean getBit( byte addr, int pos ) -{ - byte temp = getByte( addr ); - return boolean( (temp >> pos) & B00000001 ); -} - -void setBit( byte addr, int pos, boolean newBit ) -{ - boolean oldBit = getBit( addr, pos ); - byte temp = received[ 0 ]; - if ( oldBit != newBit ) - { - if( newBit ) - temp += (B00000001 << pos); - else - temp -= (B00000001 << pos); - } - setByte( addr, temp ); -} - -byte getByte( byte addr ) -{ - byte temp; - if( getBytes( addr, 1) ) - temp = received[ 0 ]; - else temp = -1; - return temp; -} - -boolean getBytes( byte addr, int amount ) -{ - boolean wireWorked = false; - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - Wire.endTransmission(); - Wire.requestFrom( DS3231_I2C_ADDRESS, amount ); - if( Wire.available() ){ - received[amount]; - for( int i = 0; i < amount; i++){ - received[ i ] = Wire.read(); - } - wireWorked = true; - } - return wireWorked; -} - -void setByte( byte addr, byte newByte ) -{ - setBytes( addr, &newByte, 1); -} - -void setBytes( byte addr, byte newBytes[], int amount ) -{ - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - for( int i = 0; i < amount; i++ ) - Wire.write( newBytes[ i ] ); - Wire.endTransmission(); -} - -void getTime() -{ - if( getBytes( DS3231_TIME_CAL_ADDR, 7) ) - { - for(int i = 0; i < 7; i++) - time[ i ] = received[ i ]; - - time[ 0 ] = ( ( time[ 0 ] & B01110000 ) >> 4 ) * 10 + ( time[ 0 ] & B00001111 ); - time[ 1 ] = ( ( time[ 1 ] & B01110000 ) >> 4 ) * 10 + ( time[ 1 ] & B00001111 ); - time[ 2 ] = ( ( time[ 2 ] & B00110000 ) >> 4 ) * 10 + ( time[ 2 ] & B00001111 ); - time[ 4 ] = ( ( time[ 4 ] & B00110000 ) >> 4 ) * 10 + ( time[ 4 ] & B00001111 ); - time[ 5 ] = ( ( time[ 5 ] & B00010000 ) >> 4 ) * 10 + ( time[ 5 ] & B00001111 ); - time[ 6 ] = ( ( time[ 6 ] & B11110000 ) >> 4 ) * 10 + ( time[ 6 ] & B00001111 ); - } -} - -void setTime( byte newTime[ 7 ] ) -{ - for(int i = 0; i < 7; i++) - newTime[i] = decToBcd(newTime[i]); - setBytes( DS3231_TIME_CAL_ADDR, newTime, 7 ); -} - -void getRTCTemperature() -{ - - if( getBytes( DS3231_TEMPERATURE_ADDR, 2 ) ) - { - temperature = ( received[ 0 ] & B01111111 ); - temperature += ( ( received[ 1 ] >> 6 ) * 0.25 ); - } -} - -void gprsListen() -{ - if( GPRS.available() ) { - while( GPRS.available() ) { - buffer[ count++ ] = GPRS.read(); - if ( count == 64 ) - break; - } - Serial.write( buffer, count ); - analise( buffer, count ); - clearBufferArray(); - count = 0; - } - if (Serial.available()) - GPRS.write(Serial.read()); -} - -void printTime() -{ - getTime(); - Serial.print( int( time[ 3 ] ) ); - Serial.print( ' ' ); - Serial.print( int( time[ 2 ] ) ); - Serial.print( ':' ); - Serial.print( int( time[ 1 ] ) ); - Serial.print( ':' ); - Serial.print( int( time[ 0 ] ) ); - Serial.print( ' ' ); - Serial.print( int( time[ 4 ] ) ); - Serial.print( '/' ); - Serial.print( int( time[ 5 ] ) ); - Serial.print( "/20" ); - Serial.print( int( time[ 6 ] ) ); - Serial.println(); -} - - - - - -void setup() -{ - - GPRS.begin( 9600 ); - delay(1000); - setPowerStateTo(1); - delay(1000); - - - Wire.begin(); - delay(1000); - - Serial.begin(9600); - delay(1000); - -} - -void loop() -{ - gprsListen(); - getTime(); -} - diff --git a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.ino b/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.preprocessed.ino similarity index 94% rename from app/test/processing/app/preproc/RemoteCallLogger_v1e0.ino rename to app/test/processing/app/preproc/CharWithEscapedDoubleQuote.preprocessed.ino index 36e6e6397ea..26c15eba009 100644 --- a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.ino +++ b/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.preprocessed.ino @@ -1,4 +1,3 @@ - #include // required to send and receive AT commands from the GPRS Shield #include // required for I2C communication with the RTC @@ -13,6 +12,8 @@ #define DS3231_TEMPERATURE_ADDR 17 // 0x11 // Declarations for GPRS shield +#include +#line 15 SoftwareSerial GPRS( 7, 8 ); // A softwareSerial line is defined for the GPRS Shield byte buffer[ 64 ]; // Buffer is used to transfer data from the GPRS line to the serial line int count = 0, e = 0, count2 = 0, t = 0, q; @@ -37,6 +38,28 @@ Code Exclusively for GPRS shield: // Default set of instructions for GPRS Shield power control // +void setPowerStateTo( int newState ); +int getPowerState(); +void powerUpOrDown(); +void clearBufferArray(); +void makeMissedCall( char num[] ); +void sendTextMessage( char number[], char messg[] ); +void analise(byte incoming[], int length); +byte decToBcd( byte b ); +boolean getBit( byte addr, int pos ); +void setBit( byte addr, int pos, boolean newBit ); +byte getByte( byte addr ); +boolean getBytes( byte addr, int amount ); +void setByte( byte addr, byte newByte ); +void setBytes( byte addr, byte newBytes[], int amount ); +void getTime(); +void setTime( byte newTime[ 7 ] ); +void getRTCTemperature(); +void gprsListen(); +void printTime(); +void setup(); +void loop(); +#line 39 void setPowerStateTo( int newState ) { if( newState != 1 && newState != 0 ) { // tests for an invalid state. In this case no change is made to powerstate @@ -338,6 +361,3 @@ void loop() getTime(); // Updates the time. Todo: replace w interrupt } - - - diff --git a/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.stripped.ino b/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.stripped.ino deleted file mode 100644 index 1579c0907a2..00000000000 --- a/app/test/processing/app/preproc/CharWithEscapedDoubleQuote.stripped.ino +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - - - - - - - - - -SoftwareSerial GPRS( 7, 8 ); -byte buffer[ 64 ]; -int count = 0, e = 0, count2 = 0, t = 0, q; -char temp, lastCaller[13] = ; -boolean callIncoming = false, done; - - -byte time[ 7 ]; -byte time_A1[ 5 ]; -byte time_A2[ 4 ]; -byte received[1]; -float temperature; - - -char telescopeNames[6][4]; - - - - - - - - - -void setPowerStateTo( int newState ) -{ - if( newState != 1 && newState != 0 ) { - Serial.print( ); - Serial.print( getPowerState() ); - Serial.print( ); - } - else { - if( newState == getPowerState() ) { - Serial.print( ); - Serial.print( newState ); - Serial.print( ); - } - else { - powerUpOrDown(); - Serial.print( ); - Serial.print( 1 - newState ); - Serial.print( ); - Serial.print( newState ); - Serial.print( ); - } - } - delay( 5000 ); -} - -int getPowerState() -{ - int ret; - if ( digitalRead(18) == 0 && digitalRead(19) == 0 ) - ret = 1; - else - ret = 0; - - return ret; -} - -void powerUpOrDown() -{ - pinMode( 9, OUTPUT ); - digitalWrite( 9, LOW ); - delay( 1000 ); - digitalWrite( 9, HIGH ); - delay( 2000 ); - digitalWrite( 9, LOW ); - delay( 3000 ); -} - - - - - -void clearBufferArray() -{ - for( int i = 0; i < count; i++ ) - buffer[ i ] = NULL; -} - -void makeMissedCall( char num[] ) -{ - int i; - char in[ 18 ] = ; - for( i = 3; i <= 14; i++ ) - in[ i ] = num[ i - 3] ; - in[ 15 ] = ; - in[ 16 ] = '\r'; - in[ 17 ] = '\0'; - GPRS.write( in ); - delay( 10000 ); - GPRS.write( ); - delay( 1000 ); -} - -void sendTextMessage( char number[], char messg[] ) -{ - char temp[ 27 ] = ; - for( q = 0; q < 12; q++ ) - temp[ q + 13 ] = number[ q ]; - temp[ 25 ] = ; - temp[ 26 ] = '\0'; - - GPRS.println( ); - delay( 1000 ); - GPRS.println( temp ); - delay( 1000 ); - GPRS.println( messg ); - delay( 1000 ); - GPRS.println( (char) 26 ); - delay( 1000 ); -} - -void analise(byte incoming[], int length) -{ - e = 0; - done = false; - while( e < length && !done){ - temp = char( incoming[e] ); - switch( temp ){ - case : - { - if( length > e + 3 && !callIncoming ) { - if(char( incoming[e + 1] ) == - && char( incoming[e + 2] ) == - && char( incoming[e + 3] ) == ){ - GPRS.write( ); - delay(500); - GPRS.write( ); - callIncoming = true; - done = true; - } - } - } - break; - case : - { - if(char( buffer[ e + 1]) == && length > e + 11 && callIncoming){ - for(t = 0; t < 12; t++) - lastCaller[t] = char( buffer[ e + t ]); - lastCaller[12] = '\0'; - callIncoming = false; - done = true; - } - } - break; - case : - Serial.println(lastCaller); - break; - } - e++; - } -} - - - - - - - - - - -byte decToBcd( byte b ) -{ - return ( b / 10 << 4 ) + b % 10; -} - -boolean getBit( byte addr, int pos ) -{ - byte temp = getByte( addr ); - return boolean( (temp >> pos) & B00000001 ); -} - -void setBit( byte addr, int pos, boolean newBit ) -{ - boolean oldBit = getBit( addr, pos ); - byte temp = received[ 0 ]; - if ( oldBit != newBit ) - { - if( newBit ) - temp += (B00000001 << pos); - else - temp -= (B00000001 << pos); - } - setByte( addr, temp ); -} - -byte getByte( byte addr ) -{ - byte temp; - if( getBytes( addr, 1) ) - temp = received[ 0 ]; - else temp = -1; - return temp; -} - -boolean getBytes( byte addr, int amount ) -{ - boolean wireWorked = false; - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - Wire.endTransmission(); - Wire.requestFrom( DS3231_I2C_ADDRESS, amount ); - if( Wire.available() ){ - received[amount]; - for( int i = 0; i < amount; i++){ - received[ i ] = Wire.read(); - } - wireWorked = true; - } - return wireWorked; -} - -void setByte( byte addr, byte newByte ) -{ - setBytes( addr, &newByte, 1); -} - -void setBytes( byte addr, byte newBytes[], int amount ) -{ - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - for( int i = 0; i < amount; i++ ) - Wire.write( newBytes[ i ] ); - Wire.endTransmission(); -} - -void getTime() -{ - if( getBytes( DS3231_TIME_CAL_ADDR, 7) ) - { - for(int i = 0; i < 7; i++) - time[ i ] = received[ i ]; - - time[ 0 ] = ( ( time[ 0 ] & B01110000 ) >> 4 ) * 10 + ( time[ 0 ] & B00001111 ); - time[ 1 ] = ( ( time[ 1 ] & B01110000 ) >> 4 ) * 10 + ( time[ 1 ] & B00001111 ); - time[ 2 ] = ( ( time[ 2 ] & B00110000 ) >> 4 ) * 10 + ( time[ 2 ] & B00001111 ); - time[ 4 ] = ( ( time[ 4 ] & B00110000 ) >> 4 ) * 10 + ( time[ 4 ] & B00001111 ); - time[ 5 ] = ( ( time[ 5 ] & B00010000 ) >> 4 ) * 10 + ( time[ 5 ] & B00001111 ); - time[ 6 ] = ( ( time[ 6 ] & B11110000 ) >> 4 ) * 10 + ( time[ 6 ] & B00001111 ); - } -} - -void setTime( byte newTime[ 7 ] ) -{ - for(int i = 0; i < 7; i++) - newTime[i] = decToBcd(newTime[i]); - setBytes( DS3231_TIME_CAL_ADDR, newTime, 7 ); -} - -void getRTCTemperature() -{ - - if( getBytes( DS3231_TEMPERATURE_ADDR, 2 ) ) - { - temperature = ( received[ 0 ] & B01111111 ); - temperature += ( ( received[ 1 ] >> 6 ) * 0.25 ); - } -} - -void gprsListen() -{ - if( GPRS.available() ) { - while( GPRS.available() ) { - buffer[ count++ ] = GPRS.read(); - if ( count == 64 ) - break; - } - Serial.write( buffer, count ); - analise( buffer, count ); - clearBufferArray(); - count = 0; - } - if (Serial.available()) - GPRS.write(Serial.read()); -} - -void printTime() -{ - getTime(); - Serial.print( int( time[ 3 ] ) ); - Serial.print( ); - Serial.print( int( time[ 2 ] ) ); - Serial.print( ); - Serial.print( int( time[ 1 ] ) ); - Serial.print( ); - Serial.print( int( time[ 0 ] ) ); - Serial.print( ); - Serial.print( int( time[ 4 ] ) ); - Serial.print( ); - Serial.print( int( time[ 5 ] ) ); - Serial.print( ); - Serial.print( int( time[ 6 ] ) ); - Serial.println(); -} - - - - - -void setup() -{ - - GPRS.begin( 9600 ); - delay(1000); - setPowerStateTo(1); - delay(1000); - - - Wire.begin(); - delay(1000); - - Serial.begin(9600); - delay(1000); - -} - -void loop() -{ - gprsListen(); - getTime(); -} diff --git a/app/test/processing/app/preproc/IncludeBetweenMultilineComment.nocomments.ino b/app/test/processing/app/preproc/IncludeBetweenMultilineComment.preprocessed.ino similarity index 71% rename from app/test/processing/app/preproc/IncludeBetweenMultilineComment.nocomments.ino rename to app/test/processing/app/preproc/IncludeBetweenMultilineComment.preprocessed.ino index 9981e580624..004294c5727 100644 --- a/app/test/processing/app/preproc/IncludeBetweenMultilineComment.nocomments.ino +++ b/app/test/processing/app/preproc/IncludeBetweenMultilineComment.preprocessed.ino @@ -1,8 +1,13 @@ #include - - - +/* +#include +*/ +#include +#line 5 CapacitiveSensorDue cs_13_8 = CapacitiveSensorDue(13,8); +void setup(); +void loop(); +#line 6 void setup() { Serial.begin(9600); diff --git a/app/test/processing/app/preproc/IncludeBetweenMultilineComment.stripped.ino b/app/test/processing/app/preproc/IncludeBetweenMultilineComment.stripped.ino deleted file mode 100644 index aeb99c23509..00000000000 --- a/app/test/processing/app/preproc/IncludeBetweenMultilineComment.stripped.ino +++ /dev/null @@ -1,15 +0,0 @@ - - - - -CapacitiveSensorDue cs_13_8 = CapacitiveSensorDue(13,8); -void setup() -{ - Serial.begin(9600); -} -void loop() -{ - long total1 = cs_13_8.read(30); - Serial.println(total1); - delay(100); -} diff --git a/app/test/processing/app/preproc/IncludesFinderTest.java b/app/test/processing/app/preproc/IncludesFinderTest.java new file mode 100644 index 00000000000..7515ad0bbcf --- /dev/null +++ b/app/test/processing/app/preproc/IncludesFinderTest.java @@ -0,0 +1,45 @@ +package processing.app.preproc; + +import org.junit.Test; +import processing.app.AbstractWithPreferencesTest; +import processing.app.BaseNoGui; +import processing.app.PreferencesData; +import processing.app.helpers.FileUtils; +import processing.app.helpers.PreferencesMap; + +import java.io.File; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +public class IncludesFinderTest extends AbstractWithPreferencesTest { + + @Test + public void shouldListIncludes() throws Exception { + String input = FileUtils.readFileToString(new File(IncludesFinderTest.class.getResource("SketchWithIfDef.ino").getFile())); + + PreferencesData.set("target_package", "arduino"); + PreferencesData.set("target_platform", "avr"); + + PreferencesMap prefs = new PreferencesMap(); + prefs.putAll(PreferencesData.getMap()); + prefs.putAll(BaseNoGui.getTargetBoard().getPreferences()); + prefs.putAll(BaseNoGui.getTargetBoard().getContainerPlatform().getPreferences()); + prefs.put("build.arch", "AVR"); + + IncludesFinder includesFinder = new IncludesFinder(prefs, true); + + Map context = new HashMap(); + context.put("source", input); + includesFinder.preprocess(context); + List includes = (List) context.get("includes"); + + assertEquals(2, includes.size()); + assertEquals("empty_1.h", includes.get(0)); + assertEquals("empty_2.h", includes.get(1)); + } + +} diff --git a/app/test/processing/app/preproc/LineContinuations.nocomments.ino b/app/test/processing/app/preproc/LineContinuations.preprocessed.ino similarity index 76% rename from app/test/processing/app/preproc/LineContinuations.nocomments.ino rename to app/test/processing/app/preproc/LineContinuations.preprocessed.ino index 1f220926adf..14ffc33c8b1 100644 --- a/app/test/processing/app/preproc/LineContinuations.nocomments.ino +++ b/app/test/processing/app/preproc/LineContinuations.preprocessed.ino @@ -1,9 +1,14 @@ +#include +#line 1 const char *foo = "\ hello \ world\n"; - +//" delete this comment line and the IDE parser will crash +void setup(); +void loop(); +#line 7 void setup() { } @@ -11,25 +16,25 @@ void setup() void loop() { } - - - - - - - - - - - - - - - - - - - - - +/* +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +*/ diff --git a/app/test/processing/app/preproc/LineContinuations.stripped.ino b/app/test/processing/app/preproc/LineContinuations.stripped.ino deleted file mode 100644 index 62292875128..00000000000 --- a/app/test/processing/app/preproc/LineContinuations.stripped.ino +++ /dev/null @@ -1,34 +0,0 @@ -const char *foo = - - ; - - - -void setup() -{ -} - -void loop() -{ -} - - - - - - - - - - - - - - - - - - - - - diff --git a/app/test/processing/app/preproc/PdePreprocessorTest.java b/app/test/processing/app/preproc/PdePreprocessorTest.java deleted file mode 100644 index aa66a84b60a..00000000000 --- a/app/test/processing/app/preproc/PdePreprocessorTest.java +++ /dev/null @@ -1,146 +0,0 @@ -package processing.app.preproc; - -import org.junit.Test; -import processing.app.helpers.FileUtils; - -import java.io.File; - -import static org.junit.Assert.assertEquals; - -public class PdePreprocessorTest { - - @Test - public void testSourceWithQuoteAndDoubleQuotesEscapedAndFinalQuoteShouldNotRaiseException() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("RemoteCallLogger_v1e0.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("RemoteCallLogger_v1e0.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("RemoteCallLogger_v1e0.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(2, pdePreprocessor.getExtraImports().size()); - assertEquals("SoftwareSerial.h", pdePreprocessor.getExtraImports().get(0)); - assertEquals("Wire.h", pdePreprocessor.getExtraImports().get(1)); - } - - @Test - public void testIncludeInsideMultilineComment() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("IncludeBetweenMultilineComment.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("IncludeBetweenMultilineComment.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("IncludeBetweenMultilineComment.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(1, pdePreprocessor.getExtraImports().size()); - assertEquals("CapacitiveSensorDue.h", pdePreprocessor.getExtraImports().get(0)); - } - - @Test - public void testPdePreprocessorRegressionBaladuino() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("Baladuino.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("Baladuino.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("Baladuino.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(9, pdePreprocessor.getExtraImports().size()); - assertEquals("Balanduino.h", pdePreprocessor.getExtraImports().get(0)); - assertEquals("Wire.h", pdePreprocessor.getExtraImports().get(1)); - assertEquals("usbhub.h", pdePreprocessor.getExtraImports().get(2)); - assertEquals("adk.h", pdePreprocessor.getExtraImports().get(3)); - assertEquals("Kalman.h", pdePreprocessor.getExtraImports().get(4)); - assertEquals("XBOXRECV.h", pdePreprocessor.getExtraImports().get(5)); - assertEquals("SPP.h", pdePreprocessor.getExtraImports().get(6)); - assertEquals("PS3BT.h", pdePreprocessor.getExtraImports().get(7)); - assertEquals("Wii.h", pdePreprocessor.getExtraImports().get(8)); - } - - @Test - public void testStringWithCcomment() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("StringWithCcomment.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("StringWithCcomment.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("StringWithCcomment.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(0, pdePreprocessor.getExtraImports().size()); - } - - @Test - public void testCharWithEscapedDoubleQuote() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("CharWithEscapedDoubleQuote.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("CharWithEscapedDoubleQuote.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("CharWithEscapedDoubleQuote.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(2, pdePreprocessor.getExtraImports().size()); - assertEquals("SoftwareSerial.h", pdePreprocessor.getExtraImports().get(0)); - assertEquals("Wire.h", pdePreprocessor.getExtraImports().get(1)); - } - - @Test - public void testLineContinuations() throws Exception { - String s = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("LineContinuations.ino").getFile())); - - PdePreprocessor pdePreprocessor = new PdePreprocessor(); - String strippedOutput = pdePreprocessor.strip(s); - String expectedStrippedOutput = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("LineContinuations.stripped.ino").getFile())); - - assertEquals(expectedStrippedOutput, strippedOutput); - - pdePreprocessor.writePrefix(s); - - String actualCodeWithoutComments = pdePreprocessor.program; - String expectedCodeWithoutComments = FileUtils.readFileToString(new File(PdePreprocessorTest.class.getResource("LineContinuations.nocomments.ino").getFile())); - - assertEquals(expectedCodeWithoutComments, actualCodeWithoutComments); - - assertEquals(0, pdePreprocessor.getExtraImports().size()); - } - -} \ No newline at end of file diff --git a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.nocomments.ino b/app/test/processing/app/preproc/RemoteCallLogger_v1e0.nocomments.ino deleted file mode 100644 index bbf15560eef..00000000000 --- a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.nocomments.ino +++ /dev/null @@ -1,344 +0,0 @@ - -#include -#include - - -#define DS3231_I2C_ADDRESS 104 -#define DS3231_TIME_CAL_ADDR 0 -#define DS3231_ALARM1_ADDR 7 -#define DS3231_ALARM2_ADDR 11 -#define DS3231_CONTROL_ADDR 14 -#define DS3231_STATUS_ADDR 15 - -#define DS3231_TEMPERATURE_ADDR 17 - - -SoftwareSerial GPRS( 7, 8 ); -byte buffer[ 64 ]; -int count = 0, e = 0, count2 = 0, t = 0, q; -char temp, lastCaller[13] = "blank"; -boolean callIncoming = false, done; - - -byte time[ 7 ]; -byte time_A1[ 5 ]; -byte time_A2[ 4 ]; -byte received[1]; -float temperature; - - -char telescopeNames[6][4]; - - - - - - - - - -void setPowerStateTo( int newState ) -{ - if( newState != 1 && newState != 0 ) { - Serial.print( "Error: Invalid powerstate. Current powerstate = " ); - Serial.print( getPowerState() ); - Serial.print( "\n" ); - } - else { - if( newState == getPowerState() ) { - Serial.print( "Powerstate = " ); - Serial.print( newState ); - Serial.print( " remains unchanged.\n" ); - } - else { - powerUpOrDown(); - Serial.print( "Powerstate changed from " ); - Serial.print( 1 - newState ); - Serial.print( " to " ); - Serial.print( newState ); - Serial.print( "\n" ); - } - } - delay( 5000 ); -} - -int getPowerState() -{ - int ret; - if ( digitalRead(18) == 0 && digitalRead(19) == 0 ) - ret = 1; - else - ret = 0; - - return ret; -} - -void powerUpOrDown() -{ - pinMode( 9, OUTPUT ); - digitalWrite( 9, LOW ); - delay( 1000 ); - digitalWrite( 9, HIGH ); - delay( 2000 ); - digitalWrite( 9, LOW ); - delay( 3000 ); -} - - - - - -void clearBufferArray() -{ - for( int i = 0; i < count; i++ ) - buffer[ i ] = NULL; -} - -void makeMissedCall( char num[] ) -{ - int i; - char in[ 18 ] = "ATD"; - for( i = 3; i <= 14; i++ ) - in[ i ] = num[ i - 3] ; - in[ 15 ] = ';'; - in[ 16 ] = '\r'; - in[ 17 ] = '\0'; - GPRS.write( in ); - delay( 10000 ); - GPRS.write( "ATH\r\0" ); - delay( 1000 ); -} - -void sendTextMessage( char number[], char messg[] ) -{ - char temp[ 27 ] = "AT + CMGS = \""; - for( q = 0; q < 12; q++ ) - temp[ q + 13 ] = number[ q ]; - temp[ 25 ] = '\"'; - temp[ 26 ] = '\0'; - - GPRS.println( "AT+CMGF=1\r" ); - delay( 1000 ); - GPRS.println( temp ); - delay( 1000 ); - GPRS.println( messg ); - delay( 1000 ); - GPRS.println( (char) 26 ); - delay( 1000 ); -} - -void analise(byte incoming[], int length) -{ - e = 0; - done = false; - while( e < length && !done){ - temp = char( incoming[e] ); - switch( temp ){ - case 'R': - { - if( length > e + 3 && !callIncoming ) { - if(char( incoming[e + 1] ) == 'I' - && char( incoming[e + 2] ) == 'N' - && char( incoming[e + 3] ) == 'G'){ - GPRS.write("AT+CLCC\r"); - delay(500); - GPRS.write("ATH\r"); - callIncoming = true; - done = true; - } - } - } - break; - case '+': - { - if(char( buffer[ e + 1]) == '2' && length > e + 11 && callIncoming){ - for(t = 0; t < 12; t++) - lastCaller[t] = char( buffer[ e + t ]); - lastCaller[12] = '\0'; - callIncoming = false; - done = true; - } - } - break; - case 'l': - Serial.println(lastCaller); - break; - } - e++; - } -} - - - - - - - - - - -byte decToBcd( byte b ) -{ - return ( b / 10 << 4 ) + b % 10; -} - -boolean getBit( byte addr, int pos ) -{ - byte temp = getByte( addr ); - return boolean( (temp >> pos) & B00000001 ); -} - -void setBit( byte addr, int pos, boolean newBit ) -{ - boolean oldBit = getBit( addr, pos ); - byte temp = received[ 0 ]; - if ( oldBit != newBit ) - { - if( newBit ) - temp += (B00000001 << pos); - else - temp -= (B00000001 << pos); - } - setByte( addr, temp ); -} - -byte getByte( byte addr ) -{ - byte temp; - if( getBytes( addr, 1) ) - temp = received[ 0 ]; - else temp = -1; - return temp; -} - -boolean getBytes( byte addr, int amount ) -{ - boolean wireWorked = false; - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - Wire.endTransmission(); - Wire.requestFrom( DS3231_I2C_ADDRESS, amount ); - if( Wire.available() ){ - received[amount]; - for( int i = 0; i < amount; i++){ - received[ i ] = Wire.read(); - } - wireWorked = true; - } - return wireWorked; -} - -void setByte( byte addr, byte newByte ) -{ - setBytes( addr, &newByte, 1); -} - -void setBytes( byte addr, byte newBytes[], int amount ) -{ - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - for( int i = 0; i < amount; i++ ) - Wire.write( newBytes[ i ] ); - Wire.endTransmission(); -} - -void getTime() -{ - if( getBytes( DS3231_TIME_CAL_ADDR, 7) ) - { - for(int i = 0; i < 7; i++) - time[ i ] = received[ i ]; - - time[ 0 ] = ( ( time[ 0 ] & B01110000 ) >> 4 ) * 10 + ( time[ 0 ] & B00001111 ); - time[ 1 ] = ( ( time[ 1 ] & B01110000 ) >> 4 ) * 10 + ( time[ 1 ] & B00001111 ); - time[ 2 ] = ( ( time[ 2 ] & B00110000 ) >> 4 ) * 10 + ( time[ 2 ] & B00001111 ); - time[ 4 ] = ( ( time[ 4 ] & B00110000 ) >> 4 ) * 10 + ( time[ 4 ] & B00001111 ); - time[ 5 ] = ( ( time[ 5 ] & B00010000 ) >> 4 ) * 10 + ( time[ 5 ] & B00001111 ); - time[ 6 ] = ( ( time[ 6 ] & B11110000 ) >> 4 ) * 10 + ( time[ 6 ] & B00001111 ); - } -} - -void setTime( byte newTime[ 7 ] ) -{ - for(int i = 0; i < 7; i++) - newTime[i] = decToBcd(newTime[i]); - setBytes( DS3231_TIME_CAL_ADDR, newTime, 7 ); -} - -void getRTCTemperature() -{ - - if( getBytes( DS3231_TEMPERATURE_ADDR, 2 ) ) - { - temperature = ( received[ 0 ] & B01111111 ); - temperature += ( ( received[ 1 ] >> 6 ) * 0.25 ); - } -} - -void gprsListen() -{ - if( GPRS.available() ) { - while( GPRS.available() ) { - buffer[ count++ ] = GPRS.read(); - if ( count == 64 ) - break; - } - Serial.write( buffer, count ); - analise( buffer, count ); - clearBufferArray(); - count = 0; - } - if (Serial.available()) - GPRS.write(Serial.read()); -} - -void printTime() -{ - getTime(); - Serial.print( int( time[ 3 ] ) ); - Serial.print( ' ' ); - Serial.print( int( time[ 2 ] ) ); - Serial.print( ':' ); - Serial.print( int( time[ 1 ] ) ); - Serial.print( ':' ); - Serial.print( int( time[ 0 ] ) ); - Serial.print( ' ' ); - Serial.print( int( time[ 4 ] ) ); - Serial.print( '/' ); - Serial.print( int( time[ 5 ] ) ); - Serial.print( "/20" ); - Serial.print( int( time[ 6 ] ) ); - Serial.println(); -} - - - - - -void setup() -{ - - GPRS.begin( 9600 ); - delay(1000); - setPowerStateTo(1); - delay(1000); - - - Wire.begin(); - delay(1000); - - Serial.begin(9600); - delay(1000); - -} - -void loop() -{ - gprsListen(); - getTime(); -} - - - - - diff --git a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.stripped.ino b/app/test/processing/app/preproc/RemoteCallLogger_v1e0.stripped.ino deleted file mode 100644 index 75b4393ff70..00000000000 --- a/app/test/processing/app/preproc/RemoteCallLogger_v1e0.stripped.ino +++ /dev/null @@ -1,343 +0,0 @@ - - - - - - - - - - - - - - - -SoftwareSerial GPRS( 7, 8 ); -byte buffer[ 64 ]; -int count = 0, e = 0, count2 = 0, t = 0, q; -char temp, lastCaller[13] = ; -boolean callIncoming = false, done; - - -byte time[ 7 ]; -byte time_A1[ 5 ]; -byte time_A2[ 4 ]; -byte received[1]; -float temperature; - - -char telescopeNames[6][4]; - - - - - - - - - -void setPowerStateTo( int newState ) -{ - if( newState != 1 && newState != 0 ) { - Serial.print( ); - Serial.print( getPowerState() ); - Serial.print( ); - } - else { - if( newState == getPowerState() ) { - Serial.print( ); - Serial.print( newState ); - Serial.print( ); - } - else { - powerUpOrDown(); - Serial.print( ); - Serial.print( 1 - newState ); - Serial.print( ); - Serial.print( newState ); - Serial.print( ); - } - } - delay( 5000 ); -} - -int getPowerState() -{ - int ret; - if ( digitalRead(18) == 0 && digitalRead(19) == 0 ) - ret = 1; - else - ret = 0; - - return ret; -} - -void powerUpOrDown() -{ - pinMode( 9, OUTPUT ); - digitalWrite( 9, LOW ); - delay( 1000 ); - digitalWrite( 9, HIGH ); - delay( 2000 ); - digitalWrite( 9, LOW ); - delay( 3000 ); -} - - - - - -void clearBufferArray() -{ - for( int i = 0; i < count; i++ ) - buffer[ i ] = NULL; -} - -void makeMissedCall( char num[] ) -{ - int i; - char in[ 18 ] = ; - for( i = 3; i <= 14; i++ ) - in[ i ] = num[ i - 3] ; - in[ 15 ] = ; - in[ 16 ] = '\r'; - in[ 17 ] = '\0'; - GPRS.write( in ); - delay( 10000 ); - GPRS.write( ); - delay( 1000 ); -} - -void sendTextMessage( char number[], char messg[] ) -{ - char temp[ 27 ] = ; - for( q = 0; q < 12; q++ ) - temp[ q + 13 ] = number[ q ]; - temp[ 25 ] = ; - temp[ 26 ] = '\0'; - - GPRS.println( ); - delay( 1000 ); - GPRS.println( temp ); - delay( 1000 ); - GPRS.println( messg ); - delay( 1000 ); - GPRS.println( (char) 26 ); - delay( 1000 ); -} - -void analise(byte incoming[], int length) -{ - e = 0; - done = false; - while( e < length && !done){ - temp = char( incoming[e] ); - switch( temp ){ - case : - { - if( length > e + 3 && !callIncoming ) { - if(char( incoming[e + 1] ) == - && char( incoming[e + 2] ) == - && char( incoming[e + 3] ) == ){ - GPRS.write( ); - delay(500); - GPRS.write( ); - callIncoming = true; - done = true; - } - } - } - break; - case : - { - if(char( buffer[ e + 1]) == && length > e + 11 && callIncoming){ - for(t = 0; t < 12; t++) - lastCaller[t] = char( buffer[ e + t ]); - lastCaller[12] = '\0'; - callIncoming = false; - done = true; - } - } - break; - case : - Serial.println(lastCaller); - break; - } - e++; - } -} - - - - - - - - - - -byte decToBcd( byte b ) -{ - return ( b / 10 << 4 ) + b % 10; -} - -boolean getBit( byte addr, int pos ) -{ - byte temp = getByte( addr ); - return boolean( (temp >> pos) & B00000001 ); -} - -void setBit( byte addr, int pos, boolean newBit ) -{ - boolean oldBit = getBit( addr, pos ); - byte temp = received[ 0 ]; - if ( oldBit != newBit ) - { - if( newBit ) - temp += (B00000001 << pos); - else - temp -= (B00000001 << pos); - } - setByte( addr, temp ); -} - -byte getByte( byte addr ) -{ - byte temp; - if( getBytes( addr, 1) ) - temp = received[ 0 ]; - else temp = -1; - return temp; -} - -boolean getBytes( byte addr, int amount ) -{ - boolean wireWorked = false; - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - Wire.endTransmission(); - Wire.requestFrom( DS3231_I2C_ADDRESS, amount ); - if( Wire.available() ){ - received[amount]; - for( int i = 0; i < amount; i++){ - received[ i ] = Wire.read(); - } - wireWorked = true; - } - return wireWorked; -} - -void setByte( byte addr, byte newByte ) -{ - setBytes( addr, &newByte, 1); -} - -void setBytes( byte addr, byte newBytes[], int amount ) -{ - Wire.beginTransmission( DS3231_I2C_ADDRESS ); - Wire.write( addr ); - for( int i = 0; i < amount; i++ ) - Wire.write( newBytes[ i ] ); - Wire.endTransmission(); -} - -void getTime() -{ - if( getBytes( DS3231_TIME_CAL_ADDR, 7) ) - { - for(int i = 0; i < 7; i++) - time[ i ] = received[ i ]; - - time[ 0 ] = ( ( time[ 0 ] & B01110000 ) >> 4 ) * 10 + ( time[ 0 ] & B00001111 ); - time[ 1 ] = ( ( time[ 1 ] & B01110000 ) >> 4 ) * 10 + ( time[ 1 ] & B00001111 ); - time[ 2 ] = ( ( time[ 2 ] & B00110000 ) >> 4 ) * 10 + ( time[ 2 ] & B00001111 ); - time[ 4 ] = ( ( time[ 4 ] & B00110000 ) >> 4 ) * 10 + ( time[ 4 ] & B00001111 ); - time[ 5 ] = ( ( time[ 5 ] & B00010000 ) >> 4 ) * 10 + ( time[ 5 ] & B00001111 ); - time[ 6 ] = ( ( time[ 6 ] & B11110000 ) >> 4 ) * 10 + ( time[ 6 ] & B00001111 ); - } -} - -void setTime( byte newTime[ 7 ] ) -{ - for(int i = 0; i < 7; i++) - newTime[i] = decToBcd(newTime[i]); - setBytes( DS3231_TIME_CAL_ADDR, newTime, 7 ); -} - -void getRTCTemperature() -{ - - if( getBytes( DS3231_TEMPERATURE_ADDR, 2 ) ) - { - temperature = ( received[ 0 ] & B01111111 ); - temperature += ( ( received[ 1 ] >> 6 ) * 0.25 ); - } -} - -void gprsListen() -{ - if( GPRS.available() ) { - while( GPRS.available() ) { - buffer[ count++ ] = GPRS.read(); - if ( count == 64 ) - break; - } - Serial.write( buffer, count ); - analise( buffer, count ); - clearBufferArray(); - count = 0; - } - if (Serial.available()) - GPRS.write(Serial.read()); -} - -void printTime() -{ - getTime(); - Serial.print( int( time[ 3 ] ) ); - Serial.print( ); - Serial.print( int( time[ 2 ] ) ); - Serial.print( ); - Serial.print( int( time[ 1 ] ) ); - Serial.print( ); - Serial.print( int( time[ 0 ] ) ); - Serial.print( ); - Serial.print( int( time[ 4 ] ) ); - Serial.print( ); - Serial.print( int( time[ 5 ] ) ); - Serial.print( ); - Serial.print( int( time[ 6 ] ) ); - Serial.println(); -} - - - - - -void setup() -{ - - GPRS.begin( 9600 ); - delay(1000); - setPowerStateTo(1); - delay(1000); - - - Wire.begin(); - delay(1000); - - Serial.begin(9600); - delay(1000); - -} - -void loop() -{ - gprsListen(); - getTime(); -} - - - - diff --git a/app/test/processing/app/preproc/SketchWithIfDef.ino b/app/test/processing/app/preproc/SketchWithIfDef.ino new file mode 100644 index 00000000000..53731565f9a --- /dev/null +++ b/app/test/processing/app/preproc/SketchWithIfDef.ino @@ -0,0 +1,50 @@ +#define DEBUG 1 +#define DISABLED 0 + +#if DISABLED +#include +#endif + +#ifdef DISABLED +#include "empty_1.h" +#endif + +#include "empty_2.h" + +typedef MyType int; + +void setup() { + // put your setup code here, to run once: + +} + +void loop() { + // put your main code here, to run repeatedly: + +} + +#if DISABLED +void shouldNotBePrototyped() { + +} +#endif + +#if DEBUG +void debug() { + +} +#endif + +#ifdef UNDEFINED +void undefinedFunction() { +} +#endif + +#ifdef DISABLED +void disabledIsDefined() { +} +#endif + +int useMyType(MyType type) { + +} \ No newline at end of file diff --git a/app/test/processing/app/preproc/SketchWithIfDef.preprocessed.ino b/app/test/processing/app/preproc/SketchWithIfDef.preprocessed.ino new file mode 100644 index 00000000000..71e83bc4176 --- /dev/null +++ b/app/test/processing/app/preproc/SketchWithIfDef.preprocessed.ino @@ -0,0 +1,59 @@ +#define DEBUG 1 +#define DISABLED 0 + + + + + + +#include "empty_1.h" + + +#include "empty_2.h" + +#include +#line 14 +typedef MyType int; + +void setup(); +void loop(); +void debug(); +void disabledIsDefined(); +int useMyType(MyType type); +#line 16 +void setup() { + // put your setup code here, to run once: + +} + +void loop() { + // put your main code here, to run repeatedly: + +} + + + + + + + + +void debug() { + +} + + + + + + + + +void disabledIsDefined() { +} + + +int useMyType(MyType type) { + +} + diff --git a/app/test/processing/app/preproc/SketchWithStruct.ino b/app/test/processing/app/preproc/SketchWithStruct.ino new file mode 100644 index 00000000000..05f277dab43 --- /dev/null +++ b/app/test/processing/app/preproc/SketchWithStruct.ino @@ -0,0 +1,22 @@ +/* START CODE */ + +struct A_NEW_TYPE { + int a = 10; + int b; + int c; +} foo; + +void setup() { + +} + +void loop() { + dostuff(&foo); +} + +void dostuff (A_NEW_TYPE * bar) +{ + Serial.print("bar.a: "); + Serial.print(bar->a); +} +/* END CODE */ \ No newline at end of file diff --git a/app/test/processing/app/preproc/SketchWithStruct.preprocessed.ino b/app/test/processing/app/preproc/SketchWithStruct.preprocessed.ino new file mode 100644 index 00000000000..3d3b7e7e919 --- /dev/null +++ b/app/test/processing/app/preproc/SketchWithStruct.preprocessed.ino @@ -0,0 +1,29 @@ +/* START CODE */ + +#include +#line 3 +struct A_NEW_TYPE { + int a = 10; + int b; + int c; +} foo; + +void setup(); +void loop(); +void dostuff(A_NEW_TYPE * bar); +#line 9 +void setup() { + +} + +void loop() { + dostuff(&foo); +} + +void dostuff (A_NEW_TYPE * bar) +{ + Serial.print("bar.a: "); + Serial.print(bar->a); +} +/* END CODE */ + diff --git a/app/test/processing/app/preproc/StringWithCcomment.nocomments.ino b/app/test/processing/app/preproc/StringWithCcomment.nocomments.ino deleted file mode 100644 index 9655c4ad4c8..00000000000 --- a/app/test/processing/app/preproc/StringWithCcomment.nocomments.ino +++ /dev/null @@ -1,14 +0,0 @@ -void setup() { - - - - Serial.println("Accept: */*"); - Serial.println("Accept: \" */*"); - Serial.println("Accept: \\"); // */*"); -} - -void loop() { - - -} - diff --git a/app/test/processing/app/preproc/StringWithCcomment.stripped.ino b/app/test/processing/app/preproc/StringWithCcomment.stripped.ino deleted file mode 100644 index e5fe155835a..00000000000 --- a/app/test/processing/app/preproc/StringWithCcomment.stripped.ino +++ /dev/null @@ -1,13 +0,0 @@ -void setup() { - - - - Serial.println( ); - Serial.println( ); - Serial.println( ); -} - -void loop() { - - -} diff --git a/app/test/processing/app/preproc/StringWithCcomment.ino b/app/test/processing/app/preproc/StringWithComment.ino similarity index 100% rename from app/test/processing/app/preproc/StringWithCcomment.ino rename to app/test/processing/app/preproc/StringWithComment.ino diff --git a/app/test/processing/app/preproc/StringWithComment.preprocessed.ino b/app/test/processing/app/preproc/StringWithComment.preprocessed.ino new file mode 100644 index 00000000000..0413c703299 --- /dev/null +++ b/app/test/processing/app/preproc/StringWithComment.preprocessed.ino @@ -0,0 +1,19 @@ +#include +#line 1 +void setup(); +void loop(); +#line 1 +void setup() { + // put your setup code here, to run once: + // "comment with a double quote + /* \" other comment with double quote */ + Serial.println("Accept: */*"); + Serial.println("Accept: \" */*"); + Serial.println("Accept: \\"); // */*"); +} + +void loop() { + // put your main code here, to run repeatedly: + +} + diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index 0f7b0c885d2..cb2fd3bd0f0 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -584,8 +584,7 @@ static public void initLogger() { static public void initPackages() { packages = new HashMap(); - loadHardware(getHardwareFolder()); - loadHardware(getSketchbookHardwareFolder()); + loadHardware(getHardwareFolder(), getSketchbookHardwareFolder()); if (packages.size() == 0) { System.out.println(_("No valid configured cores found! Exiting...")); System.exit(3); @@ -630,29 +629,39 @@ static public boolean isSanitaryName(String name) { return sanitizeName(name).equals(name); } - static protected void loadHardware(File folder) { - if (!folder.isDirectory()) return; + static protected void loadHardware(File... folders) { + PreferencesMap mainHardwarePlatformTxt = null; + for (File folder : folders) { + if (!folder.isDirectory()) return; - String list[] = folder.list(new OnlyDirs()); + // Assuming first folder is NOT the sketchbook one + if (mainHardwarePlatformTxt == null) { + mainHardwarePlatformTxt = PreferencesMap.safeLoad(new File(folder, "platform.txt")); + } - // if a bad folder or something like that, this might come back null - if (list == null) return; + PreferencesMap hardwarePlatformTxt = mainHardwarePlatformTxt.merge(PreferencesMap.safeLoad(new File(folder, "platform.txt"))); - // alphabetize list, since it's not always alpha order - // replaced hella slow bubble sort with this feller for 0093 - Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); + String list[] = folder.list(new OnlyDirs()); - for (String target : list) { - // Skip reserved 'tools' folder. - if (target.equals("tools")) - continue; - File subfolder = new File(folder, target); - - try { - packages.put(target, new TargetPackage(target, subfolder)); - } catch (TargetPlatformException e) { - System.out.println("WARNING: Error loading hardware folder " + target); - System.out.println(" " + e.getMessage()); + // if a bad folder or something like that, this might come back null + if (list == null) return; + + // alphabetize list, since it's not always alpha order + // replaced hella slow bubble sort with this feller for 0093 + Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); + + for (String target : list) { + // Skip reserved 'tools' folder. + if (target.equals("tools")) + continue; + File subfolder = new File(folder, target); + + try { + packages.put(target, new TargetPackage(target, subfolder, hardwarePlatformTxt)); + } catch (TargetPlatformException e) { + System.out.println("WARNING: Error loading hardware folder " + target); + System.out.println(" " + e.getMessage()); + } } } } diff --git a/arduino-core/src/processing/app/SketchData.java b/arduino-core/src/processing/app/SketchData.java index 36f5a8fceab..59497b518d0 100644 --- a/arduino-core/src/processing/app/SketchData.java +++ b/arduino-core/src/processing/app/SketchData.java @@ -222,6 +222,15 @@ public SketchCode getCode(int i) { return codes.get(i); } + public SketchCode getPrimaryCode() { + for (SketchCode code : codes) { + if (code.getFile().equals(primaryFile)) { + return code; + } + } + throw new IllegalStateException("No primary file for this sketch!"); + } + protected void removeCode(SketchCode which) { for (SketchCode code : codes) { if (code == which) { diff --git a/arduino-core/src/processing/app/debug/Compiler.java b/arduino-core/src/processing/app/debug/Compiler.java index dd5d7128f65..346c39cf457 100644 --- a/arduino-core/src/processing/app/debug/Compiler.java +++ b/arduino-core/src/processing/app/debug/Compiler.java @@ -23,39 +23,21 @@ package processing.app.debug; -import static processing.app.I18n._; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - import cc.arduino.packages.BoardPort; import cc.arduino.packages.Uploader; import cc.arduino.packages.UploaderFactory; - -import processing.app.BaseNoGui; -import processing.app.I18n; -import processing.app.PreferencesData; -import processing.app.SketchCode; -import processing.app.SketchData; +import processing.app.*; import processing.app.helpers.*; import processing.app.helpers.filefilters.OnlyDirs; +import processing.app.legacy.PApplet; import processing.app.packages.Library; import processing.app.packages.LibraryList; -import processing.app.preproc.PdePreprocessor; -import processing.app.legacy.PApplet; +import processing.app.preproc.*; + +import java.io.*; +import java.util.*; + +import static processing.app.I18n._; public class Compiler implements MessageConsumer { @@ -72,7 +54,7 @@ public class Compiler implements MessageConsumer { private List objectFiles; private boolean sketchIsCompiled; - + private RunnerException exception; /** @@ -87,7 +69,7 @@ public interface ProgressListener { static public String build(SketchData data, String buildPath, File tempBuildFolder, ProgressListener progListener, boolean verbose) throws RunnerException, PreferencesMapException { if (SketchData.checkSketchFile(data.getPrimaryFile()) == null) BaseNoGui.showError(_("Bad file selected"), - _("Bad sketch primary file or bad sketch directory structure"), null); + _("Bad sketch primary file or bad sketch directory structure"), null); String primaryClassName = data.getName() + ".cpp"; Compiler compiler = new Compiler(data, buildPath, primaryClassName); @@ -110,7 +92,7 @@ static public String build(SketchData data, String buildPath, File tempBuildFold } compiler.setProgressListener(progListener); - + // compile the program. errors will happen as a RunnerException // that will bubble up to whomever called build(). if (compiler.compile(verbose)) { @@ -119,17 +101,14 @@ static public String build(SketchData data, String buildPath, File tempBuildFold } return null; } - + static public Uploader getUploaderByPreferences(boolean noUploadPort) { TargetPlatform target = BaseNoGui.getTargetPlatform(); String board = PreferencesData.get("board"); - if (noUploadPort) - { + if (noUploadPort) { return new UploaderFactory().newUploader(target.getBoards().get(board), null, noUploadPort); - } - else - { + } else { BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port")); return new UploaderFactory().newUploader(target.getBoards().get(board), boardPort, noUploadPort); } @@ -144,7 +123,7 @@ static public boolean upload(SketchData data, Uploader uploader, String buildPat if (uploader.requiresAuthorization() && !PreferencesData.has(uploader.getAuthorizationKey())) { BaseNoGui.showError(_("Authorization required"), - _("No athorization data found"), null); + _("No athorization data found"), null); } boolean useNewWarningsAccumulator = false; @@ -174,12 +153,13 @@ static public boolean upload(SketchData data, Uploader uploader, String buildPat /** * Create a new Compiler - * @param _sketch Sketch object to be compiled. - * @param _buildPath Where the temporary files live and will be built from. + * + * @param _sketch Sketch object to be compiled. + * @param _buildPath Where the temporary files live and will be built from. * @param _primaryClassName the name of the combined sketch file w/ extension */ public Compiler(SketchData _sketch, String _buildPath, String _primaryClassName) - throws RunnerException { + throws RunnerException { sketch = _sketch; prefs = createBuildPreferences(_buildPath, _primaryClassName); @@ -223,7 +203,8 @@ protected boolean buildPreferencesChanged(File buildPrefsFile, String newBuildPr * Returns the build preferences of the given compiler as a string. * Only includes build-specific preferences, to make sure unrelated * preferences don't cause a rebuild (in particular preferences that - * change on every start, like last.ide.xxx.daterun). */ + * change on every start, like last.ide.xxx.daterun). + */ protected String buildPrefsString() { PreferencesMap buildPrefs = getBuildPreferences(); String res = ""; @@ -237,13 +218,13 @@ protected String buildPrefsString() { protected void setProgressListener(ProgressListener _progressListener) { progressListener = (_progressListener == null ? - new ProgressListener() { - @Override - public void progress(int percent) { - } - } : _progressListener); + new ProgressListener() { + @Override + public void progress(int percent) { + } + } : _progressListener); } - + /** * Cleanup temporary files used during a build/run. */ @@ -300,7 +281,7 @@ protected void size(PreferencesMap prefs) throws RunnerException { sizes = sizer.computeSize(); } catch (RunnerException e) { System.err.println(I18n.format(_("Couldn't determine program size: {0}"), - e.getMessage())); + e.getMessage())); return; } @@ -308,45 +289,43 @@ protected void size(PreferencesMap prefs) throws RunnerException { long dataSize = sizes[1]; System.out.println(); System.out.println(I18n - .format(_("Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes."), - textSize, maxTextSize, textSize * 100 / maxTextSize)); + .format(_("Sketch uses {0} bytes ({2}%%) of program storage space. Maximum is {1} bytes."), + textSize, maxTextSize, textSize * 100 / maxTextSize)); if (dataSize >= 0) { if (maxDataSize > 0) { System.out - .println(I18n - .format( - _("Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes."), - dataSize, maxDataSize, dataSize * 100 / maxDataSize, - maxDataSize - dataSize)); + .println(I18n + .format( + _("Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes."), + dataSize, maxDataSize, dataSize * 100 / maxDataSize, + maxDataSize - dataSize)); } else { System.out.println(I18n - .format(_("Global variables use {0} bytes of dynamic memory."), dataSize)); + .format(_("Global variables use {0} bytes of dynamic memory."), dataSize)); } } if (textSize > maxTextSize) throw new RunnerException( - _("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.")); + _("Sketch too big; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it.")); if (maxDataSize > 0 && dataSize > maxDataSize) throw new RunnerException( - _("Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.")); + _("Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.")); int warnDataPercentage = Integer.parseInt(prefs.get("build.warn_data_percentage")); - if (maxDataSize > 0 && dataSize > maxDataSize*warnDataPercentage/100) + if (maxDataSize > 0 && dataSize > maxDataSize * warnDataPercentage / 100) System.err.println(_("Low memory available, stability problems may occur.")); } /** * Compile sketch. - * @param _verbose * + * @param _verbose * @return true if successful. * @throws RunnerException Only if there's a problem. Only then. */ public boolean compile(boolean _verbose) throws RunnerException, PreferencesMapException { - preprocess(prefs.get("build.path")); - verbose = _verbose || PreferencesData.getBoolean("build.verbose"); sketchIsCompiled = false; @@ -355,48 +334,43 @@ public boolean compile(boolean _verbose) throws RunnerException, PreferencesMapE objectFiles = new ArrayList(); - // 0. include paths for core + all libraries - progressListener.progress(20); - List includeFolders = new ArrayList(); - includeFolders.add(prefs.getFile("build.core.path")); - if (prefs.getFile("build.variant.path") != null) - includeFolders.add(prefs.getFile("build.variant.path")); - for (Library lib : importedLibraries) { - if (verbose) - System.out.println(I18n - .format(_("Using library {0} in folder: {1} {2}"), lib.getName(), - lib.getFolder(), lib.isLegacy() ? "(legacy)" : "")); - includeFolders.add(lib.getSrcFolder()); - } if (verbose) System.out.println(); - List archs = new ArrayList(); - archs.add(BaseNoGui.getTargetPlatform().getId()); - if (prefs.containsKey("architecture.override_check")) { - String[] overrides = prefs.get("architecture.override_check").split(","); - archs.addAll(Arrays.asList(overrides)); - } - for (Library lib : importedLibraries) { - if (!lib.supportsArchitecture(archs)) { - System.err.println(I18n - .format(_("WARNING: library {0} claims to run on {1} " - + "architecture(s) and may be incompatible with your" - + " current board which runs on {2} architecture(s)."), lib - .getName(), lib.getArchitectures(), archs)); - System.err.println(); + List chainRings = new LinkedList(); + chainRings.add(new SketchCodeMerger()); + chainRings.add(new HeaderCppFilesCopier(prefs.get("build.path"))); + chainRings.add(new IncludesFinder(prefs, verbose)); + chainRings.add(new IncludesToIncludeFolders(prefs, verbose)); + //chainRings.add(new DumpContext()); + chainRings.add(new SetProgressListener(progressListener, 20)); + chainRings.add(new VerifyLibraryArch(prefs)); + chainRings.add(new CTagsBakedPreprocessor(prefs, verbose)); + chainRings.add(new SaveSketchToCpp(prefs.get("build.path"))); + chainRings.add(new SetProgressListener(progressListener, 30)); + + Map context = new HashMap(); + context.put("sketch", sketch); + + for (PreprocessorChainRing ring : chainRings) { + try { + ring.preprocess(context); + } catch (Exception e) { + throw new RunnerException(e); } } - + + List includeFolders = (List) context.get("includeFolders"); + LibraryList importedLibraries = (LibraryList) context.get("importedLibraries"); + // 1. compile the sketch (already in the buildPath) - progressListener.progress(30); compileSketch(includeFolders); sketchIsCompiled = true; // 2. compile the libraries, outputting .o files to: // // Doesn't really use configPreferences progressListener.progress(40); - compileLibraries(includeFolders); + compileLibraries(includeFolders, importedLibraries); // 3. compile the core, outputting .o files to and then // collecting them into the core.a library file. @@ -429,11 +403,11 @@ public boolean compile(boolean _verbose) throws RunnerException, PreferencesMapE private PreferencesMap createBuildPreferences(String _buildPath, String _primaryClassName) - throws RunnerException { - + throws RunnerException { + if (BaseNoGui.getBoardPreferences() == null) { RunnerException re = new RunnerException( - _("No board selected; please choose a board from the Tools > Board menu.")); + _("No board selected; please choose a board from the Tools > Board menu.")); re.hideStackTrace(); throw re; } @@ -449,13 +423,13 @@ private PreferencesMap createBuildPreferences(String _buildPath, corePlatform = BaseNoGui.getTargetPlatform(split[0], targetPlatform.getId()); if (corePlatform == null) { RunnerException re = new RunnerException(I18n - .format(_("Selected board depends on '{0}' core (not installed)."), - split[0])); + .format(_("Selected board depends on '{0}' core (not installed)."), + split[0])); re.hideStackTrace(); throw re; } } - + // Merge all the global preference configuration in order of priority PreferencesMap p = new PreferencesMap(); p.putAll(PreferencesData.getMap()); @@ -471,7 +445,7 @@ private PreferencesMap createBuildPreferences(String _buildPath, p.put("build.path", _buildPath); p.put("build.project_name", _primaryClassName); p.put("build.arch", targetPlatform.getId().toUpperCase()); - + // Platform.txt should define its own compiler.path. For // compatibility with earlier 1.5 versions, we define a (ugly, // avr-specific) default for it, but this should be removed at some @@ -489,12 +463,12 @@ private PreferencesMap createBuildPreferences(String _buildPath, coreFolder = new File(coreFolder, core); p.put("build.core", core); p.put("build.core.path", coreFolder.getAbsolutePath()); - + // System Folder File systemFolder = tp.getFolder(); systemFolder = new File(systemFolder, "system"); p.put("build.system.path", systemFolder.getAbsolutePath()); - + // Variant Folder String variant = p.get("build.variant"); if (variant != null) { @@ -512,7 +486,7 @@ private PreferencesMap createBuildPreferences(String _buildPath, } else { p.put("build.variant.path", ""); } - + return p; } @@ -530,7 +504,7 @@ private List compileFiles(File outputPath, File sourcePath, String[] cmd = getCommandCompilerByRecipe(includeFolders, file, objectFile, "recipe.S.o.pattern"); execAsynchronously(cmd); } - + for (File file : cSources) { File objectFile = new File(outputPath, file.getName() + ".o"); File dependFile = new File(outputPath, file.getName() + ".d"); @@ -550,7 +524,7 @@ private List compileFiles(File outputPath, File sourcePath, String[] cmd = getCommandCompilerByRecipe(includeFolders, file, objectFile, "recipe.cpp.o.pattern"); execAsynchronously(cmd); } - + return objectPaths; } @@ -572,7 +546,7 @@ protected static String unescapeDepFile(String line) { } private boolean isAlreadyCompiled(File src, File obj, File dep, Map prefs) { - boolean ret=true; + boolean ret = true; try { //System.out.println("\n isAlreadyCompiled: begin checks: " + obj.getPath()); if (!obj.exists()) return false; // object file (.o) does not exist @@ -681,7 +655,8 @@ private void execAsynchronously(String[] command) throws RunnerException { result = process.waitFor(); //System.out.println("result is " + result); compiling = false; - } catch (InterruptedException ignored) { } + } catch (InterruptedException ignored) { + } } // an error was queued up by message(), barf this back to compile(), @@ -696,7 +671,7 @@ private void execAsynchronously(String[] command) throws RunnerException { if (result > 1) { // a failure in the tool (e.g. unable to locate a sub-executable) System.err - .println(I18n.format(_("{0} returned {1}"), command[0], result)); + .println(I18n.format(_("{0} returned {1}"), command[0], result)); } if (result != 0) { @@ -724,7 +699,7 @@ public void message(String s) { s = s.substring(0, i) + s.substring(i + (buildPath + File.separator).length()); } } - + // look for error line, which contains file name, line number, // and at least the first line of the error message String errorFormat = "([\\w\\d_]+.\\w+):(\\d+):\\s*error:\\s*(.*)\\s*"; @@ -734,62 +709,62 @@ public void message(String s) { // exception = sketch.placeException(pieces[3], pieces[1], PApplet.parseInt(pieces[2]) - 1); // if (exception != null) exception.hideStackTrace(); // } - + if (pieces != null) { String error = pieces[3], msg = ""; - + if (pieces[3].trim().equals("SPI.h: No such file or directory")) { error = _("Please import the SPI library from the Sketch > Import Library menu."); msg = _("\nAs of Arduino 0019, the Ethernet library depends on the SPI library." + - "\nYou appear to be using it or another library that depends on the SPI library.\n\n"); + "\nYou appear to be using it or another library that depends on the SPI library.\n\n"); } - + if (pieces[3].trim().equals("'BYTE' was not declared in this scope")) { error = _("The 'BYTE' keyword is no longer supported."); msg = _("\nAs of Arduino 1.0, the 'BYTE' keyword is no longer supported." + - "\nPlease use Serial.write() instead.\n\n"); + "\nPlease use Serial.write() instead.\n\n"); } - + if (pieces[3].trim().equals("no matching function for call to 'Server::Server(int)'")) { error = _("The Server class has been renamed EthernetServer."); msg = _("\nAs of Arduino 1.0, the Server class in the Ethernet library " + - "has been renamed to EthernetServer.\n\n"); + "has been renamed to EthernetServer.\n\n"); } - + if (pieces[3].trim().equals("no matching function for call to 'Client::Client(byte [4], int)'")) { error = _("The Client class has been renamed EthernetClient."); msg = _("\nAs of Arduino 1.0, the Client class in the Ethernet library " + - "has been renamed to EthernetClient.\n\n"); + "has been renamed to EthernetClient.\n\n"); } - + if (pieces[3].trim().equals("'Udp' was not declared in this scope")) { error = _("The Udp class has been renamed EthernetUdp."); msg = _("\nAs of Arduino 1.0, the Udp class in the Ethernet library " + - "has been renamed to EthernetUdp.\n\n"); + "has been renamed to EthernetUdp.\n\n"); } - + if (pieces[3].trim().equals("'class TwoWire' has no member named 'send'")) { error = _("Wire.send() has been renamed Wire.write()."); msg = _("\nAs of Arduino 1.0, the Wire.send() function was renamed " + - "to Wire.write() for consistency with other libraries.\n\n"); + "to Wire.write() for consistency with other libraries.\n\n"); } - + if (pieces[3].trim().equals("'class TwoWire' has no member named 'receive'")) { error = _("Wire.receive() has been renamed Wire.read()."); msg = _("\nAs of Arduino 1.0, the Wire.receive() function was renamed " + - "to Wire.read() for consistency with other libraries.\n\n"); + "to Wire.read() for consistency with other libraries.\n\n"); } if (pieces[3].trim().equals("'Mouse' was not declared in this scope")) { error = _("'Mouse' only supported on the Arduino Leonardo"); //msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n"); } - + if (pieces[3].trim().equals("'Keyboard' was not declared in this scope")) { error = _("'Keyboard' only supported on the Arduino Leonardo"); //msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n"); } - + RunnerException e = null; if (!sketchIsCompiled) { // Place errors when compiling the sketch, but never while compiling libraries @@ -803,32 +778,32 @@ public void message(String s) { SketchCode code = sketch.getCode(e.getCodeIndex()); String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName(); int lineNum = e.getCodeLine() + 1; - s = fileName + ":" + lineNum + ": error: " + pieces[3] + msg; + s = fileName + ":" + lineNum + ": error: " + pieces[3] + msg; } - + if (exception == null && e != null) { exception = e; exception.hideStackTrace(); - } + } } - + if (s.contains("undefined reference to `SPIClass::begin()'") && - s.contains("libraries/Robot_Control")) { + s.contains("libraries/Robot_Control")) { String error = _("Please import the SPI library from the Sketch > Import Library menu."); exception = new RunnerException(error); } if (s.contains("undefined reference to `Wire'") && - s.contains("libraries/Robot_Control")) { + s.contains("libraries/Robot_Control")) { String error = _("Please import the Wire library from the Sketch > Import Library menu."); exception = new RunnerException(error); } - + System.err.print(s); } private String[] getCommandCompilerByRecipe(List includeFolders, File sourceFile, File objectFile, String recipe) throws PreferencesMapException, RunnerException { - String includes = prepareIncludes(includeFolders); + String includes = Utils.prepareIncludes(includeFolders); PreferencesMap dict = new PreferencesMap(prefs); dict.put("ide_version", "" + BaseNoGui.REVISION); dict.put("includes", includes); @@ -880,7 +855,7 @@ static public List findFilesInFolder(File folder, String extension, return files; } - + // 1. compile the sketch (already in the buildPath) void compileSketch(List includeFolders) throws RunnerException, PreferencesMapException { File buildPath = prefs.getFile("build.path"); @@ -889,7 +864,7 @@ void compileSketch(List includeFolders) throws RunnerException, Preference // 2. compile the libraries, outputting .o files to: // // - void compileLibraries(List includeFolders) throws RunnerException, PreferencesMapException { + void compileLibraries(List includeFolders, List importedLibraries) throws RunnerException, PreferencesMapException { for (Library lib : importedLibraries) { compileLibrary(lib, includeFolders); } @@ -955,12 +930,12 @@ void compileCore() if (variantFolder != null) objectFiles.addAll(compileFiles(buildFolder, variantFolder, true, - includeFolders)); + includeFolders)); File afile = new File(buildFolder, "core.a"); List coreObjectFiles = compileFiles(buildFolder, coreFolder, true, - includeFolders); + includeFolders); // See if the .a file is already uptodate if (afile.exists()) { @@ -1010,7 +985,7 @@ void compileCore() throw e; } } - + // 4. link it all together into the .elf file void compileLink() throws RunnerException, PreferencesMapException { @@ -1071,153 +1046,32 @@ void runRecipe(String recipe) throws RunnerException, PreferencesMapException { execAsynchronously(cmdArray); } - private static String prepareIncludes(List includeFolders) { - String res = ""; - for (File p : includeFolders) - res += " \"-I" + p.getAbsolutePath() + '"'; - - // Remove first space - return res.substring(1); - } - public PreferencesMap getBuildPreferences() { return prefs; } - - /** - * Build all the code for this sketch. - * - * In an advanced program, the returned class name could be different, - * which is why the className is set based on the return value. - * A compilation error will burp up a RunnerException. - * - * Setting purty to 'true' will cause exception line numbers to be incorrect. - * Unless you know the code compiles, you should first run the preprocessor - * with purty set to false to make sure there are no errors, then once - * successful, re-export with purty set to true. - * - * @param buildPath Location to copy all the .java files - * @return null if compilation failed, main class name if not - */ - public void preprocess(String buildPath) throws RunnerException { - preprocess(buildPath, new PdePreprocessor()); - } - - public void preprocess(String buildPath, PdePreprocessor preprocessor) throws RunnerException { - - // 1. concatenate all .pde files to the 'main' pde - // store line number for starting point of each code bit - - StringBuffer bigCode = new StringBuffer(); - int bigCount = 0; - for (SketchCode sc : sketch.getCodes()) { - if (sc.isExtension("ino") || sc.isExtension("pde")) { - sc.setPreprocOffset(bigCount); - // These #line directives help the compiler report errors with - // correct the filename and line number (issue 281 & 907) - bigCode.append("#line 1 \"" + sc.getFileName() + "\"\n"); - bigCode.append(sc.getProgram()); - bigCode.append('\n'); - bigCount += sc.getLineCount(); - } - } - - // Note that the headerOffset isn't applied until compile and run, because - // it only applies to the code after it's been written to the .java file. - int headerOffset = 0; - try { - headerOffset = preprocessor.writePrefix(bigCode.toString()); - } catch (FileNotFoundException fnfe) { - fnfe.printStackTrace(); - String msg = _("Build folder disappeared or could not be written"); - throw new RunnerException(msg); - } - - // 2. run preproc on that code using the sugg class name - // to create a single .java file and write to buildpath - - try { - // Output file - File streamFile = new File(buildPath, sketch.getName() + ".cpp"); - FileOutputStream outputStream = new FileOutputStream(streamFile); - preprocessor.write(outputStream); - outputStream.close(); - } catch (FileNotFoundException fnfe) { - fnfe.printStackTrace(); - String msg = _("Build folder disappeared or could not be written"); - throw new RunnerException(msg); - } catch (RunnerException pe) { - // RunnerExceptions are caught here and re-thrown, so that they don't - // get lost in the more general "Exception" handler below. - throw pe; - - } catch (Exception ex) { - // TODO better method for handling this? - System.err.println(I18n.format(_("Uncaught exception type: {0}"), ex.getClass())); - ex.printStackTrace(); - throw new RunnerException(ex.toString()); - } - - // grab the imports from the code just preproc'd - - importedLibraries = new LibraryList(); - for (String item : preprocessor.getExtraImports()) { - Library lib = BaseNoGui.importToLibraryTable.get(item); - if (lib != null && !importedLibraries.contains(lib)) { - importedLibraries.add(lib); - } - } - - // 3. then loop over the code[] and save each .java file - - for (SketchCode sc : sketch.getCodes()) { - if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")) { - // no pre-processing services necessary for java files - // just write the the contents of 'program' to a .java file - // into the build directory. uses byte stream and reader/writer - // shtuff so that unicode bunk is properly handled - String filename = sc.getFileName(); //code[i].name + ".java"; - try { - BaseNoGui.saveFile(sc.getProgram(), new File(buildPath, filename)); - } catch (IOException e) { - e.printStackTrace(); - throw new RunnerException(I18n.format(_("Problem moving {0} to the build folder"), filename)); - } - - } else if (sc.isExtension("ino") || sc.isExtension("pde")) { - // The compiler and runner will need this to have a proper offset - sc.addPreprocOffset(headerOffset); - } - } - } - - - /** - * List of library folders. - */ - private LibraryList importedLibraries; /** * Map an error from a set of processed .java files back to its location * in the actual sketch. - * @param message The error message. + * + * @param message The error message. * @param dotJavaFilename The .java file where the exception was found. - * @param dotJavaLine Line number of the .java file for the exception (0-indexed!) + * @param dotJavaLine Line number of the .java file for the exception (0-indexed!) * @return A RunnerException to be sent to the editor, or null if it wasn't - * possible to place the exception to the sketch code. + * possible to place the exception to the sketch code. */ public RunnerException placeException(String message, String dotJavaFilename, int dotJavaLine) { - // Placing errors is simple, because we inserted #line directives - // into the preprocessed source. The compiler gives us correct - // the file name and line number. :-) - for (SketchCode code : sketch.getCodes()) { - if (dotJavaFilename.equals(code.getFileName())) { - return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine); - } - } - return null; + // Placing errors is simple, because we inserted #line directives + // into the preprocessed source. The compiler gives us correct + // the file name and line number. :-) + for (SketchCode code : sketch.getCodes()) { + if (dotJavaFilename.equals(code.getFileName())) { + return new RunnerException(message, sketch.indexOfCode(code), dotJavaLine); + } + } + return null; } } diff --git a/arduino-core/src/processing/app/debug/TargetPackage.java b/arduino-core/src/processing/app/debug/TargetPackage.java index dce91d1786a..606f3dc5600 100644 --- a/arduino-core/src/processing/app/debug/TargetPackage.java +++ b/arduino-core/src/processing/app/debug/TargetPackage.java @@ -29,6 +29,7 @@ import java.util.Map; import processing.app.I18n; +import processing.app.helpers.PreferencesMap; import processing.app.helpers.filefilters.OnlyDirs; public class TargetPackage { @@ -37,9 +38,12 @@ public class TargetPackage { Map platforms = new LinkedHashMap(); - public TargetPackage(String _id, File _folder) throws TargetPlatformException { + public TargetPackage(String _id, File _folder, PreferencesMap hardwarePlatformTxt) throws TargetPlatformException { id = _id; + PreferencesMap packagePlatformTxt = PreferencesMap.safeLoad(new File(_folder, "platform.txt")); + packagePlatformTxt = hardwarePlatformTxt.merge(packagePlatformTxt); + File[] folders = _folder.listFiles(new OnlyDirs()); if (folders == null) return; @@ -49,7 +53,7 @@ public TargetPackage(String _id, File _folder) throws TargetPlatformException { continue; String arch = subFolder.getName(); try { - TargetPlatform platform = new TargetPlatform(arch, subFolder, this); + TargetPlatform platform = new TargetPlatform(arch, subFolder, this, packagePlatformTxt); platforms.put(arch, platform); } catch (TargetPlatformException e) { System.out.println(e.getMessage()); diff --git a/arduino-core/src/processing/app/debug/TargetPlatform.java b/arduino-core/src/processing/app/debug/TargetPlatform.java index 611784618bc..ecc4301d95b 100644 --- a/arduino-core/src/processing/app/debug/TargetPlatform.java +++ b/arduino-core/src/processing/app/debug/TargetPlatform.java @@ -52,14 +52,14 @@ public class TargetPlatform { /** * Contains preferences for platform */ - private PreferencesMap preferences = new PreferencesMap(); + private PreferencesMap preferences; /** * Contains labels for top level menus */ private PreferencesMap customMenus = new PreferencesMap(); - public TargetPlatform(String _name, File _folder, TargetPackage parent) + public TargetPlatform(String _name, File _folder, TargetPackage parent, PreferencesMap packagePlatformTxt) throws TargetPlatformException { id = _name; @@ -100,6 +100,8 @@ public TargetPlatform(String _name, File _folder, TargetPackage parent) boardsFile.getAbsolutePath()), e); } + this.preferences = new PreferencesMap(packagePlatformTxt); + File platformsFile = new File(folder, "platform.txt"); try { if (platformsFile.exists() && platformsFile.canRead()) { diff --git a/arduino-core/src/processing/app/debug/Utils.java b/arduino-core/src/processing/app/debug/Utils.java new file mode 100644 index 00000000000..f5e821e730d --- /dev/null +++ b/arduino-core/src/processing/app/debug/Utils.java @@ -0,0 +1,18 @@ +package processing.app.debug; + +import java.io.File; +import java.util.List; + +public class Utils { + + public static String prepareIncludes(List includeFolders) { + StringBuilder sb = new StringBuilder(); + for (File p : includeFolders) { + sb.append(" \"-I").append(p.getAbsolutePath()).append('"'); + } + + // Remove first space + return sb.substring(1).toString(); + } + +} diff --git a/arduino-core/src/processing/app/helpers/FileUtils.java b/arduino-core/src/processing/app/helpers/FileUtils.java index 39e49217c2b..7993e823824 100644 --- a/arduino-core/src/processing/app/helpers/FileUtils.java +++ b/arduino-core/src/processing/app/helpers/FileUtils.java @@ -249,5 +249,19 @@ public static List listFiles(File folder, boolean recursive, return result; } + public static File saveToTempFile(String content, String prefix, String suffix) throws IOException { + File tempFile = File.createTempFile(prefix, suffix); + FileWriter fileWriter = null; + try { + fileWriter = new FileWriter(tempFile); + fileWriter.write(content); + return tempFile; + } finally { + if (fileWriter != null) { + fileWriter.close(); + } + } + } + } diff --git a/arduino-core/src/processing/app/helpers/PreferencesMap.java b/arduino-core/src/processing/app/helpers/PreferencesMap.java index 09a095447d5..e016613a579 100644 --- a/arduino-core/src/processing/app/helpers/PreferencesMap.java +++ b/arduino-core/src/processing/app/helpers/PreferencesMap.java @@ -336,4 +336,23 @@ public String get(String key, String defaultValue) { return defaultValue; } + public PreferencesMap merge(PreferencesMap map) { + PreferencesMap mergedPref = new PreferencesMap(this); + mergedPref.putAll(map); + + return mergedPref; + } + + public static PreferencesMap safeLoad(File file) { + PreferencesMap pref = new PreferencesMap(); + if (file.exists() && file.canRead()) { + try { + pref.load(file); + } catch (IOException e) { + // ignored + } + } + return pref; + } + } diff --git a/arduino-core/src/processing/app/helpers/StringUtils.java b/arduino-core/src/processing/app/helpers/StringUtils.java index ea623d90111..deb57e18c9d 100644 --- a/arduino-core/src/processing/app/helpers/StringUtils.java +++ b/arduino-core/src/processing/app/helpers/StringUtils.java @@ -20,10 +20,25 @@ public static boolean stringContainsOneOf(String input, List listOfStrin * @param input The string to be checked * @param pattern The pattern to match * @return true if the input matches the pattern, - * false otherwise. + * false otherwise. */ public static boolean wildcardMatch(String input, String pattern) { String regex = pattern.replace("?", ".?").replace("*", ".*?"); return input.matches(regex); } + + public static String join(List input, String sep) { + return join(input, sep, true); + } + + public static String join(List input, String sep, boolean removeLastSeparator) { + StringBuilder sb = new StringBuilder(); + for (String s : input) { + sb.append(s).append(sep); + } + if (sb.length() > 0 && removeLastSeparator) { + sb.delete(sb.length() - sep.length(), sb.length()); + } + return sb.toString(); + } } diff --git a/arduino-core/src/processing/app/preproc/.cvsignore b/arduino-core/src/processing/app/preproc/.cvsignore deleted file mode 100644 index b010c249c44..00000000000 --- a/arduino-core/src/processing/app/preproc/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -*Lexer.java -*Recognizer.java -*TokenTypes.java -*TokenTypes.txt -*TreeParser.java -*TreeParserTokenTypes.java -*TreeParserTokenTypes.txt -expanded*.g - diff --git a/arduino-core/src/processing/app/preproc/CTagsBakedPreprocessor.java b/arduino-core/src/processing/app/preproc/CTagsBakedPreprocessor.java new file mode 100644 index 00000000000..8ba61205b9f --- /dev/null +++ b/arduino-core/src/processing/app/preproc/CTagsBakedPreprocessor.java @@ -0,0 +1,174 @@ +package processing.app.preproc; + +import org.apache.commons.exec.CommandLine; +import org.apache.commons.exec.Executor; +import processing.app.BaseNoGui; +import processing.app.debug.Utils; +import processing.app.helpers.FileUtils; +import processing.app.helpers.PreferencesMap; +import processing.app.helpers.StringReplacer; +import processing.app.helpers.StringUtils; +import processing.app.tools.ArgumentsWithSpaceAwareCommandLine; +import processing.app.tools.CollectStdOutStdErrExecutor; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CTagsBakedPreprocessor implements PreprocessorChainRing { + + private final PreferencesMap prefs; + private final boolean verbose; + + public CTagsBakedPreprocessor(PreferencesMap prefs, boolean verbose) { + this.prefs = prefs; + this.verbose = verbose; + } + + @Override + public void preprocess(Map context) throws Exception { + List includeFolders = (List) context.get("includeFolders"); + + String includes = Utils.prepareIncludes(includeFolders); + PreferencesMap dict = new PreferencesMap(prefs); + dict.putAll(prefs.subTree("tools").subTree("ctags")); + dict.put("ide_version", "" + BaseNoGui.REVISION); + dict.put("includes", includes); + + preprocess(context, dict); + } + + public void preprocess(Map context, PreferencesMap prefs) throws Exception { + String source = (String) context.get("source"); + + File file = FileUtils.saveToTempFile(source, "sketch", ".cpp"); + + String ctagsOutput = runCTagsAndGetOutput(prefs, file); + + parseCTagsOutput(context, ctagsOutput); + + StringBuilder output = new StringBuilder(source); + + int lineWhereToInsertInclude = composeIncludeSection(context); + int charWhereToInsertInclude = charPositionOfLine(source, lineWhereToInsertInclude); + output.insert(charWhereToInsertInclude, context.get("includeSection")); + + int lineWhereToInsertPrototypes = composePrototypeSection(context); + int charWhereToInsertPrototypes = charPositionOfLine(source, lineWhereToInsertPrototypes) + context.get("includeSection").toString().length(); + output.insert(charWhereToInsertPrototypes, context.get("prototypesSection")); + + context.put("source", output.toString()); + + if (!verbose) { + file.delete(); + } + } + + private int composeIncludeSection(Map context) { + int firstStatementAtLine = firstStatementAtLine((String) context.get("source")); + + int line = firstStatementAtLine; + if (line > 1) { + line -= (Integer) context.get("lineOffset"); + } + + StringBuilder section = new StringBuilder(); + section.append("#include \n"); + section.append("#line ").append(line).append("\n"); + + context.put("includeSection", section); + + return firstStatementAtLine; + } + + private int composePrototypeSection(Map context) { + int firstFunctionAtLine = 1; + if (context.containsKey("firstFunctionAtLine")) { + firstFunctionAtLine = (Integer) context.get("firstFunctionAtLine"); + } + + int line = firstFunctionAtLine; + + if (line > 1) { + line -= (Integer) context.get("lineOffset"); + } + + StringBuilder section = new StringBuilder(); + + List prototypes = (List) context.get("prototypes"); + section.append(StringUtils.join(prototypes, "\n")).append("\n"); + section.append("#line ").append(line).append("\n"); + + context.put("prototypesSection", section); + + return firstFunctionAtLine; + } + + private void parseCTagsOutput(Map context, String ctagsOutput) throws Exception { + context.put("ctagsOutput", ctagsOutput); + new CTagsParser().preprocess(context); + } + + private String runCTagsAndGetOutput(PreferencesMap prefs, File file) throws Exception { + prefs.put("source_file", file.getAbsolutePath()); + + String[] patterns = StringReplacer.formatAndSplit(prefs.getOrExcept("pattern"), prefs, true); + CommandLine commandLine = new ArgumentsWithSpaceAwareCommandLine(patterns[0]); + for (int i = 1; i < patterns.length; i++) { + commandLine.addArgument(patterns[i], false); + } + + if (verbose) { + System.out.println(commandLine); + } + + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + + Executor executor = new CollectStdOutStdErrExecutor(stdout, stderr); + executor.execute(commandLine); + + stdout.flush(); + return new String(stdout.toByteArray()); + } + + private int charPositionOfLine(String input, int firstFunctionAtLine) { + List rows = Arrays.asList(input.split("\n", -1)).subList(0, firstFunctionAtLine - 1); + + String inputUntilFirstFunction = StringUtils.join(rows, "\n", false); + + return inputUntilFirstFunction.length(); + } + + + private int firstStatementAtLine(String input) { + // whitespace + String p = "\\s+"; + + // multi-line and single-line comment + //p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)"; + p += "|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)|(//.*?$)"; + + // pre-processor directive + p += "|(#(?:\\\\\\n|.)*)"; + + Pattern pattern = Pattern.compile(p, Pattern.MULTILINE); + + Matcher matcher = pattern.matcher(input); + int charPosition = 0; + while (matcher.find()) { + if (matcher.start() != charPosition) { + break; + } + charPosition = matcher.end(); + } + + String[] lines = input.substring(0, charPosition).split("\n", -1); + return lines.length; + } + +} diff --git a/arduino-core/src/processing/app/preproc/CTagsParser.java b/arduino-core/src/processing/app/preproc/CTagsParser.java new file mode 100644 index 00000000000..c6c531a1a14 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/CTagsParser.java @@ -0,0 +1,128 @@ +package processing.app.preproc; + +import processing.app.helpers.StringUtils; + +import java.util.*; + +public class CTagsParser implements PreprocessorChainRing { + + private static final List FIELDS = Arrays.asList("kind", "line", "typeref", "signature", "returntype"); + private static final List KNOWN_TAG_KINDS = Arrays.asList("prototype", "function"); + + @Override + public void preprocess(Map context) throws Exception { + List rows = Arrays.asList(context.get("ctagsOutput").toString().split("\n")); + + rows = removeEmptyRows(rows); + + List> tags = new LinkedList>(); + + for (String row : rows) { + Map tag = new HashMap(); + String[] columns = row.split("\t"); + tag.put("functionName", columns[0]); + + for (int i = 1; i < columns.length; i++) { + if (columns[i].contains(":") && FIELDS.contains(columns[i].substring(0, columns[i].indexOf(":")))) { + tag.put(columns[i].substring(0, columns[i].indexOf(":")), columns[i].substring(columns[i].indexOf(":") + 1).trim()); + } + } + if (row.contains("/^") && row.contains("/;")) { + tag.put("code", row.substring(row.indexOf("/^") + 2, row.indexOf("/;")).trim()); + } + tags.add(tag); + } + + filterOutUnknownTags(tags); + removeDefinedProtypes(tags); + addPrototypes(tags); + removeDefaultArgsValues(tags); + + if (!tags.isEmpty()) { + context.put("firstFunctionAtLine", Integer.valueOf(tags.get(0).get("line"))); + } + + List prototypes = new LinkedList(); + for (Map tag : tags) { + prototypes.add(tag.get("prototype")); + } + context.put("prototypes", prototypes); + } + + private void removeDefaultArgsValues(List> tags) { + for (Map tag : tags) { + String prototype = tag.get("prototype"); + if (prototype.contains("=")) { + int argsStartAt = prototype.indexOf("(") + 1; + int argsEndAt = prototype.lastIndexOf(")"); + String[] args = prototype.substring(argsStartAt, argsEndAt).split(","); + for (int i = 0; i < args.length; i++) { + if (args[i].contains("=")) { + args[i] = args[i].substring(0, args[i].indexOf("=")); + } + args[i] = args[i].trim(); + } + StringBuilder sb = new StringBuilder(prototype); + sb.replace(argsStartAt, argsEndAt, StringUtils.join(Arrays.asList(args), ", ")); + tag.put("prototype", sb.toString()); + } + } + } + + private List removeEmptyRows(List rows) { + List goodRows = new LinkedList(); + for (String row : rows) { + if (!row.isEmpty()) { + goodRows.add(row); + } + } + return goodRows; + } + + private void filterOutUnknownTags(List> tags) { + List> tagsToRemove = new LinkedList>(); + for (Map tag : tags) { + if (!KNOWN_TAG_KINDS.contains(tag.get("kind"))) { + tagsToRemove.add(tag); + } + } + tags.removeAll(tagsToRemove); + } + + private void addPrototypes(List> tags) { + for (Map tag : tags) { + if (tag.get("returntype").startsWith("template") || tag.get("code").startsWith("template")) { + String code = tag.get("code"); + if (code.contains("{")) { + code = code.substring(0, code.indexOf("{")); + } else { + code = code.substring(0, code.lastIndexOf(")") + 1); + } + tag.put("prototype", code.trim() + ";"); + } else { + tag.put("prototype", tag.get("returntype") + " " + tag.get("functionName") + tag.get("signature") + ";"); + } + } + } + + private void removeDefinedProtypes(List> tags) { + List> tagsToRemove = new LinkedList>(); + for (Map tag : tags) { + if ("prototype".equals(tag.get("kind"))) { + tagsToRemove.add(tag); + tagsToRemove.add(findFunctionByName(tags, tag.get("functionName"))); + } + } + tags.removeAll(tagsToRemove); + } + + private Map findFunctionByName(List> tags, String functionName) { + for (Map tag : tags) { + if ("function".equals(tag.get("kind")) && functionName.equals(tag.get("functionName"))) { + return tag; + } + } + return new HashMap(); + } + +} diff --git a/arduino-core/src/processing/app/preproc/DumpContext.java b/arduino-core/src/processing/app/preproc/DumpContext.java new file mode 100644 index 00000000000..526fee798c6 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/DumpContext.java @@ -0,0 +1,10 @@ +package processing.app.preproc; + +import java.util.Map; + +public class DumpContext implements PreprocessorChainRing { + @Override + public void preprocess(Map context) throws Exception { + System.out.println(context); + } +} diff --git a/arduino-core/src/processing/app/preproc/HeaderCppFilesCopier.java b/arduino-core/src/processing/app/preproc/HeaderCppFilesCopier.java new file mode 100644 index 00000000000..35c9de748d3 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/HeaderCppFilesCopier.java @@ -0,0 +1,29 @@ +package processing.app.preproc; + +import processing.app.BaseNoGui; +import processing.app.SketchCode; +import processing.app.SketchData; + +import java.io.File; +import java.util.Map; + +public class HeaderCppFilesCopier implements PreprocessorChainRing { + + private final String buildPath; + + public HeaderCppFilesCopier(String buildPath) { + this.buildPath = buildPath; + } + + @Override + public void preprocess(Map context) throws Exception { + SketchData sketch = (SketchData) context.get("sketch"); + + for (SketchCode sc : sketch.getCodes()) { + if (sc.isExtension("c") || sc.isExtension("cpp") || sc.isExtension("h")) { + BaseNoGui.saveFile(sc.getProgram(), new File(buildPath, sc.getFileName())); + } + } + } + +} diff --git a/arduino-core/src/processing/app/preproc/IncludesFinder.java b/arduino-core/src/processing/app/preproc/IncludesFinder.java new file mode 100644 index 00000000000..8038bc2e2fd --- /dev/null +++ b/arduino-core/src/processing/app/preproc/IncludesFinder.java @@ -0,0 +1,81 @@ +package processing.app.preproc; + +import org.apache.commons.exec.CommandLine; +import org.apache.commons.exec.Executor; +import processing.app.helpers.FileUtils; +import processing.app.helpers.PreferencesMap; +import processing.app.helpers.StringReplacer; +import processing.app.legacy.PApplet; +import processing.app.tools.ArgumentsWithSpaceAwareCommandLine; +import processing.app.tools.CollectStdOutStdErrExecutor; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +public class IncludesFinder implements PreprocessorChainRing { + + private static final Pattern ALLOWED_ARG = Pattern.compile("^source$|\\-E$|\\-m$|\\-P$|\\-kb$|\\-D.*"); + private static final String INCLUDE_REGEXP = "^\\s*#include\\s*[<\"](\\S+)[\">]"; + + private final PreferencesMap prefs; + private final boolean verbose; + + public IncludesFinder(PreferencesMap prefs, boolean verbose) { + this.prefs = prefs; + this.verbose = verbose; + } + + @Override + public void preprocess(Map context) throws Exception { + String source = (String) context.get("source"); + source = source + "\n"; + + File file = FileUtils.saveToTempFile(source, "sketch", ".cpp"); + + PreferencesMap dict = new PreferencesMap(prefs); + dict.putAll(prefs.subTree("tools").subTree("coan")); + dict.put("source_file", file.getAbsolutePath()); + + String[] patterns = StringReplacer.formatAndSplit(dict.getOrExcept("pattern"), dict, true); + CommandLine commandLine = new ArgumentsWithSpaceAwareCommandLine(patterns[0]); + for (int i = 1; i < patterns.length; i++) { + String pattern = patterns[i]; + if (i == patterns.length - 1 || ALLOWED_ARG.matcher(pattern).matches()) { + commandLine.addArgument(pattern, false); + } + } + if (verbose) { + System.out.println(commandLine); + } + + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + ByteArrayOutputStream stderr = new ByteArrayOutputStream(); + Executor executor = new CollectStdOutStdErrExecutor(stdout, stderr); + executor.setExitValues(null); + executor.execute(commandLine); + + if (!verbose) { + file.delete(); + } + + stdout.flush(); + source = new String(stdout.toByteArray()); + + String[][] pieces = PApplet.matchAll(source, INCLUDE_REGEXP); + + List includes = new LinkedList(); + if (pieces != null) { + for (String[] piece : pieces) { + includes.add(piece[1]); + } + } + + context.put("source", source); + context.put("includes", includes); + } + +} diff --git a/arduino-core/src/processing/app/preproc/IncludesToIncludeFolders.java b/arduino-core/src/processing/app/preproc/IncludesToIncludeFolders.java new file mode 100644 index 00000000000..6fd4a95fb7c --- /dev/null +++ b/arduino-core/src/processing/app/preproc/IncludesToIncludeFolders.java @@ -0,0 +1,62 @@ +package processing.app.preproc; + +import processing.app.BaseNoGui; +import processing.app.I18n; +import processing.app.helpers.PreferencesMap; +import processing.app.packages.Library; +import processing.app.packages.LibraryList; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static processing.app.I18n._; + +public class IncludesToIncludeFolders implements PreprocessorChainRing { + + private final PreferencesMap prefs; + private final boolean verbose; + + public IncludesToIncludeFolders(PreferencesMap prefs, boolean verbose) { + this.prefs = prefs; + this.verbose = verbose; + } + + @Override + public void preprocess(Map context) throws Exception { + LibraryList importedLibraries = listLibraries((List) context.get("includes")); + context.put("importedLibraries", importedLibraries); + + List includeFolders = listIncludeFolders(importedLibraries, verbose); + context.put("includeFolders", includeFolders); + } + + private LibraryList listLibraries(List includes) { + LibraryList importedLibraries = new LibraryList(); + for (String include : includes) { + Library lib = BaseNoGui.importToLibraryTable.get(include); + if (lib != null && !importedLibraries.contains(lib)) { + importedLibraries.add(lib); + } + } + return importedLibraries; + } + + private List listIncludeFolders(LibraryList importedLibraries, boolean verbose) { + List includeFolders = new ArrayList(); + includeFolders.add(prefs.getFile("build.core.path")); + if (prefs.getFile("build.variant.path") != null) + includeFolders.add(prefs.getFile("build.variant.path")); + for (Library lib : importedLibraries) { + if (verbose) + System.out.println(I18n + .format(_("Using library {0} in folder: {1} {2}"), lib.getName(), + lib.getFolder(), lib.isLegacy() ? "(legacy)" : "")); + includeFolders.add(lib.getSrcFolder()); + } + return includeFolders; + } + + +} diff --git a/arduino-core/src/processing/app/preproc/PdePreprocessor.java b/arduino-core/src/processing/app/preproc/PdePreprocessor.java deleted file mode 100644 index 576f7468b9d..00000000000 --- a/arduino-core/src/processing/app/preproc/PdePreprocessor.java +++ /dev/null @@ -1,420 +0,0 @@ -/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ - -/* - PdePreprocessor - wrapper for default ANTLR-generated parser - Part of the Wiring project - http://wiring.org.co - - Copyright (c) 2004-05 Hernando Barragan - - Processing version Copyright (c) 2004-05 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology - - ANTLR-generated parser and several supporting classes written - by Dan Mosedale via funding from the Interaction Institute IVREA. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -package processing.app.preproc; - -import static processing.app.I18n._; -import processing.app.*; -import processing.app.legacy.PApplet; - -import java.io.*; -import java.util.*; -import java.util.regex.*; - - -/** - * Class that orchestrates preprocessing p5 syntax into straight Java. - */ -public class PdePreprocessor { - // stores number of built user-defined function prototypes - public int prototypeCount = 0; - - // stores number of included library headers written - // we always write one header: Arduino.h - public int headerCount = 1; - - // the prototypes that are generated by the preprocessor - List prototypes; - - // these ones have the .* at the end, since a class name might be at the end - // instead of .* which would make trouble other classes using this can lop - // off the . and anything after it to produce a package name consistently. - List programImports; - - // imports just from the code folder, treated differently - // than the others, since the imports are auto-generated. - List codeFolderImports; - - String program; - - - /** - * Setup a new preprocessor. - */ - public PdePreprocessor() { - } - - /** - * Writes out the head of the c++ code generated for a sketch. - * Called from processing.app.Sketch. - * @param program the concatenated code from all tabs containing pde-files - */ - public int writePrefix(String program) - throws FileNotFoundException { - // if the program ends with no CR or LF an OutOfMemoryError will happen. - // not gonna track down the bug now, so here's a hack for it: - // http://dev.processing.org/bugs/show_bug.cgi?id=5 - program += "\n"; - - // if the program ends with an unterminated multi-line comment, - // an OutOfMemoryError or NullPointerException will happen. - // again, not gonna bother tracking this down, but here's a hack. - // http://dev.processing.org/bugs/show_bug.cgi?id=16 - program = scrubComments(program); - // If there are errors, an exception is thrown and this fxn exits. - - if (PreferencesData.getBoolean("preproc.substitute_unicode")) { - program = substituteUnicode(program); - } - - //String importRegexp = "(?:^|\\s|;)(import\\s+)(\\S+)(\\s*;)"; - String importRegexp = "^\\s*#include\\s*[<\"](\\S+)[\">]"; - programImports = new ArrayList(); - - String[][] pieces = PApplet.matchAll(program, importRegexp); - - if (pieces != null) - for (int i = 0; i < pieces.length; i++) - programImports.add(pieces[i][1]); // the package name - - codeFolderImports = new ArrayList(); -// if (codeFolderPackages != null) { -// for (String item : codeFolderPackages) { -// codeFolderImports.add(item + ".*"); -// } -// } - - prototypes = prototypes(program); - - // store # of prototypes so that line number reporting can be adjusted - prototypeCount = prototypes.size(); - - // do this after the program gets re-combobulated - this.program = program; - - return headerCount + prototypeCount; - } - - - static String substituteUnicode(String program) { - // check for non-ascii chars (these will be/must be in unicode format) - char p[] = program.toCharArray(); - int unicodeCount = 0; - for (int i = 0; i < p.length; i++) { - if (p[i] > 127) unicodeCount++; - } - // if non-ascii chars are in there, convert to unicode escapes - if (unicodeCount != 0) { - // add unicodeCount * 5.. replacing each unicode char - // with six digit uXXXX sequence (xxxx is in hex) - // (except for nbsp chars which will be a replaced with a space) - int index = 0; - char p2[] = new char[p.length + unicodeCount*5]; - for (int i = 0; i < p.length; i++) { - if (p[i] < 128) { - p2[index++] = p[i]; - - } else if (p[i] == 160) { // unicode for non-breaking space - p2[index++] = ' '; - - } else { - int c = p[i]; - p2[index++] = '\\'; - p2[index++] = 'u'; - char str[] = Integer.toHexString(c).toCharArray(); - // add leading zeros, so that the length is 4 - //for (int i = 0; i < 4 - str.length; i++) p2[index++] = '0'; - for (int m = 0; m < 4 - str.length; m++) p2[index++] = '0'; - System.arraycopy(str, 0, p2, index, str.length); - index += str.length; - } - } - program = new String(p2, 0, index); - } - return program; - } - - /** - * preprocesses a pde file and writes out a cpp file into the specified - * OutputStream - * - * @param output - * @throws Exception - */ - public void write(OutputStream output) throws Exception { - PrintStream stream = new PrintStream(output); - writeProgram(stream, program, prototypes); - writeFooter(stream); - } - - // Write the pde program to the cpp file - protected void writeProgram(PrintStream out, String program, List prototypes) { - int prototypeInsertionPoint = firstStatement(program); - - out.print(program.substring(0, prototypeInsertionPoint)); - out.print("#include \"Arduino.h\"\n"); - - // print user defined prototypes - for (int i = 0; i < prototypes.size(); i++) { - out.print(prototypes.get(i) + "\n"); - } - String[] lines = program.substring(0, prototypeInsertionPoint).split("\n", -1); - out.println("#line " + (lines.length - 1)); - out.print(program.substring(prototypeInsertionPoint)); - } - - - /** - * Write any necessary closing text. - * - * @param out PrintStream to write it to. - */ - protected void writeFooter(PrintStream out) throws java.lang.Exception {} - - - public List getExtraImports() { - return programImports; - } - - - - - - /** - * Returns the index of the first character that's not whitespace, a comment - * or a pre-processor directive. - */ - public int firstStatement(String in) { - // whitespace - String p = "\\s+"; - - // multi-line and single-line comment - //p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)"; - p += "|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)|(//.*?$)"; - - // pre-processor directive - p += "|(#(?:\\\\\\n|.)*)"; - Pattern pattern = Pattern.compile(p, Pattern.MULTILINE); - - Matcher matcher = pattern.matcher(in); - int i = 0; - while (matcher.find()) { - if (matcher.start()!=i) - break; - i = matcher.end(); - } - - return i; - } - - /** - * Strips comments, pre-processor directives, single- and double-quoted - * strings from a string. - * @param in the String to strip - * @return the stripped String - */ - public String strip(String in) { - // XXX: doesn't properly handle special single-quoted characters - // single-quoted character - String p = "('.')"; - - p += "|('\\\\\"')"; - - // double-quoted string - p += "|(\"(?:[^\"\\\\]|\\\\.)*\")"; - - // single and multi-line comment - //p += "|" + "(//\\s*?$)|(/\\*\\s*?\\*/)"; - p += "|(//.*?$)|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)"; - - // pre-processor directive - p += "|" + "(^\\s*#.*?$)"; - - StringBuilder sb = new StringBuilder(in); - Pattern pattern = Pattern.compile(p, Pattern.MULTILINE | Pattern.DOTALL); - Matcher matcher = pattern.matcher(sb); - while (matcher.find()) { - String replacement = composeReplacementString(new StringBuilder(sb.subSequence(matcher.start(), matcher.end()))); - sb.replace(matcher.start(), matcher.end(), replacement); - } - return sb.toString(); - } - - private String composeReplacementString(StringBuilder sb) { - for (int i = 0; i < sb.length(); i++) { - if (sb.charAt(i) != '\n') { - sb.setCharAt(i, ' '); - } - } - return sb.toString(); - } - - /** - * Removes the contents of all top-level curly brace pairs {}. - * @param in the String to collapse - * @return the collapsed String - */ - private String collapseBraces(String in) { - StringBuffer buffer = new StringBuffer(); - int nesting = 0; - int start = 0; - - // XXX: need to keep newlines inside braces so we can determine the line - // number of a prototype - for (int i = 0; i < in.length(); i++) { - if (in.charAt(i) == '{') { - if (nesting == 0) { - buffer.append(in.substring(start, i + 1)); // include the '{' - } - nesting++; - } - if (in.charAt(i) == '}') { - nesting--; - if (nesting == 0) { - start = i; // include the '}' - } - } - } - - buffer.append(in.substring(start)); - - return buffer.toString(); - } - - public ArrayList prototypes(String in) { - in = collapseBraces(strip(in)); - - // XXX: doesn't handle ... varargs - // XXX: doesn't handle function pointers - Pattern prototypePattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*;)"); - Pattern functionPattern = Pattern.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*\\{)"); - - // Find already declared prototypes - ArrayList prototypeMatches = new ArrayList(); - Matcher prototypeMatcher = prototypePattern.matcher(in); - while (prototypeMatcher.find()) - prototypeMatches.add(prototypeMatcher.group(0) + ";"); - - // Find all functions and generate prototypes for them - ArrayList functionMatches = new ArrayList(); - Matcher functionMatcher = functionPattern.matcher(in); - while (functionMatcher.find()) - functionMatches.add(functionMatcher.group(0) + ";"); - - // Remove generated prototypes that exactly match ones found in the source file - for (int functionIndex=functionMatches.size() - 1; functionIndex >= 0; functionIndex--) { - for (int prototypeIndex=0; prototypeIndex < prototypeMatches.size(); prototypeIndex++) { - if ((functionMatches.get(functionIndex)).equals(prototypeMatches.get(prototypeIndex))) { - functionMatches.remove(functionIndex); - break; - } - } - } - - return functionMatches; - } - - private boolean isStartOrEndOfString(char p[], int index) { - if (p[index] != '\"') { - return false; - } - - if (index == 0) { - return true; - } - - if (p[index - 1] == '\\') { - return false; - } - - if (index - 2 >= 0 && p[index - 2] == '\\') { - return true; - } - - return true; - } - - /** - * Replace all commented portions of a given String as spaces. - * Utility function used here and in the preprocessor. - */ - public String scrubComments(String what) { - char p[] = what.toCharArray(); - - int index = 0; - boolean insideString = false; - while (index < p.length) { - if (isStartOrEndOfString(p, index)) { - insideString = !insideString; - } - // for any double slash comments, ignore until the end of the line - if (!insideString && (p[index] == '/') && - (index < p.length - 1) && - (p[index+1] == '/')) { - p[index++] = ' '; - p[index++] = ' '; - while ((index < p.length) && - (p[index] != '\n')) { - p[index++] = ' '; - } - - // check to see if this is the start of a new multiline comment. - // if it is, then make sure it's actually terminated somewhere. - } else if (!insideString && (p[index] == '/') && - (index < p.length - 1) && - (p[index+1] == '*')) { - p[index++] = ' '; - p[index++] = ' '; - boolean endOfRainbow = false; - while (index < p.length - 1) { - if ((p[index] == '*') && (p[index+1] == '/')) { - p[index++] = ' '; - p[index++] = ' '; - endOfRainbow = true; - break; - - } else { - // continue blanking this area - if (p[index] != '\n') { - p[index] = ' '; - } - index++; - } - } - if (!endOfRainbow) { - throw new RuntimeException(_("Missing the */ from the end of a " + - "/* comment */")); - } - } else { // any old character, move along - index++; - } - } - return new String(p); - } -} diff --git a/arduino-core/src/processing/app/preproc/Preprocessor.java b/arduino-core/src/processing/app/preproc/Preprocessor.java new file mode 100644 index 00000000000..fbf40a1a372 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/Preprocessor.java @@ -0,0 +1,11 @@ +package processing.app.preproc; + +import processing.app.helpers.PreferencesMap; + +import java.util.Map; + +public interface Preprocessor { + + void preprocess(Map context, PreferencesMap dict) throws Exception; + +} diff --git a/arduino-core/src/processing/app/preproc/PreprocessorChainRing.java b/arduino-core/src/processing/app/preproc/PreprocessorChainRing.java new file mode 100644 index 00000000000..d4182a0a162 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/PreprocessorChainRing.java @@ -0,0 +1,9 @@ +package processing.app.preproc; + +import java.util.Map; + +public interface PreprocessorChainRing { + + void preprocess(Map context) throws Exception; + +} diff --git a/arduino-core/src/processing/app/preproc/SaveSketchToCpp.java b/arduino-core/src/processing/app/preproc/SaveSketchToCpp.java new file mode 100644 index 00000000000..af6de413ccc --- /dev/null +++ b/arduino-core/src/processing/app/preproc/SaveSketchToCpp.java @@ -0,0 +1,37 @@ +package processing.app.preproc; + +import processing.app.SketchCode; +import processing.app.SketchData; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Map; + +public class SaveSketchToCpp implements PreprocessorChainRing { + + private final String buildPath; + + public SaveSketchToCpp(String buildPath) { + this.buildPath = buildPath; + } + + @Override + public void preprocess(Map context) throws Exception { + SketchData sketch = (SketchData) context.get("sketch"); + String source = (String) context.get("source"); + + File sketchFile = new File(buildPath, sketch.getName() + ".cpp"); + Writer writer = null; + try { + writer = new OutputStreamWriter(new FileOutputStream(sketchFile)); + writer.write(source); + } finally { + if (writer != null) { + writer.close(); + } + } + + } +} diff --git a/arduino-core/src/processing/app/preproc/SetProgressListener.java b/arduino-core/src/processing/app/preproc/SetProgressListener.java new file mode 100644 index 00000000000..5b66b565105 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/SetProgressListener.java @@ -0,0 +1,20 @@ +package processing.app.preproc; + +import processing.app.debug.Compiler; + +import java.util.Map; + +public class SetProgressListener implements PreprocessorChainRing { + private final int value; + private final Compiler.ProgressListener progressListener; + + public SetProgressListener(Compiler.ProgressListener progressListener, int value) { + this.value = value; + this.progressListener = progressListener; + } + + @Override + public void preprocess(Map context) throws Exception { + progressListener.progress(value); + } +} diff --git a/arduino-core/src/processing/app/preproc/SketchCodeMerger.java b/arduino-core/src/processing/app/preproc/SketchCodeMerger.java new file mode 100644 index 00000000000..5457859b023 --- /dev/null +++ b/arduino-core/src/processing/app/preproc/SketchCodeMerger.java @@ -0,0 +1,27 @@ +package processing.app.preproc; + +import processing.app.SketchCode; +import processing.app.SketchData; + +import java.util.Map; + +public class SketchCodeMerger implements PreprocessorChainRing { + + @Override + public void preprocess(Map context) throws Exception { + SketchData sketch = (SketchData) context.get("sketch"); + StringBuilder source = new StringBuilder(); + + for (SketchCode code : sketch.getCodes()) { + if (code.isExtension("ino") || code.isExtension("pde")) { + source.append("#line 1 \"").append(code.getFileName()).append("\"").append("\n"); + source.append(code.getProgram()); + source.append("\n"); + } + } + + context.put("lineOffset", 1); + context.put("source", source.toString()); + } + +} diff --git a/arduino-core/src/processing/app/preproc/VerifyLibraryArch.java b/arduino-core/src/processing/app/preproc/VerifyLibraryArch.java new file mode 100644 index 00000000000..4d73f29fcba --- /dev/null +++ b/arduino-core/src/processing/app/preproc/VerifyLibraryArch.java @@ -0,0 +1,47 @@ +package processing.app.preproc; + +import processing.app.BaseNoGui; +import processing.app.I18n; +import processing.app.helpers.PreferencesMap; +import processing.app.packages.Library; +import processing.app.packages.LibraryList; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static processing.app.I18n._; + +public class VerifyLibraryArch implements PreprocessorChainRing { + + private final PreferencesMap prefs; + + public VerifyLibraryArch(PreferencesMap prefs) { + this.prefs = prefs; + } + + @Override + public void preprocess(Map context) throws Exception { + LibraryList importedLibraries = (LibraryList) context.get("importedLibraries"); + + List archs = new ArrayList(); + archs.add(BaseNoGui.getTargetPlatform().getId()); + if (prefs.containsKey("architecture.override_check")) { + String[] overrides = prefs.get("architecture.override_check").split(","); + archs.addAll(Arrays.asList(overrides)); + } + + for (Library lib : importedLibraries) { + if (!lib.supportsArchitecture(archs)) { + System.err.println(I18n + .format(_("WARNING: library {0} claims to run on {1} " + + "architecture(s) and may be incompatible with your" + + " current board which runs on {2} architecture(s)."), lib + .getName(), lib.getArchitectures(), archs)); + System.err.println(); + } + } + + } +} diff --git a/arduino-core/src/processing/app/tools/ArgumentsWithSpaceAwareCommandLine.java b/arduino-core/src/processing/app/tools/ArgumentsWithSpaceAwareCommandLine.java new file mode 100644 index 00000000000..775b4c2b085 --- /dev/null +++ b/arduino-core/src/processing/app/tools/ArgumentsWithSpaceAwareCommandLine.java @@ -0,0 +1,32 @@ +package processing.app.tools; + +import org.apache.commons.exec.CommandLine; +import processing.app.BaseNoGui; +import processing.app.Platform; +import processing.app.helpers.OSUtils; + +import java.io.File; + +public class ArgumentsWithSpaceAwareCommandLine extends CommandLine { + + public ArgumentsWithSpaceAwareCommandLine(String executable) { + super(executable); + } + + public ArgumentsWithSpaceAwareCommandLine(File executable) { + super(executable); + } + + public ArgumentsWithSpaceAwareCommandLine(CommandLine other) { + super(other); + } + + @Override + public CommandLine addArgument(String argument, boolean handleQuoting) { + if (argument.contains(" ") && OSUtils.isWindows()) { + argument = argument.replaceAll("\"", "").replaceAll("'", ""); + } + + return super.addArgument(argument, handleQuoting); + } +} diff --git a/build/build.xml b/build/build.xml index a1bc1fa4804..4b01ec758b8 100644 --- a/build/build.xml +++ b/build/build.xml @@ -375,6 +375,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -583,13 +603,15 @@ + + + - + + - - @@ -602,6 +624,24 @@ + + + + + + + + + + + + + + + + + + @@ -843,6 +883,22 @@ + + + + + + + + + + + + + + + + @@ -851,6 +907,8 @@ + + diff --git a/build/coan-5.2.zip.sha b/build/coan-5.2.zip.sha new file mode 100644 index 00000000000..18e627f781a --- /dev/null +++ b/build/coan-5.2.zip.sha @@ -0,0 +1 @@ +7142d9853c24a372dbdba80b1154a9a16c8961c2 diff --git a/build/compile_every_example.sh b/build/compile_every_example.sh new file mode 100755 index 00000000000..e84a33a5bfd --- /dev/null +++ b/build/compile_every_example.sh @@ -0,0 +1,36 @@ +#!/bin/bash -e + +EXAMPLES=`find $1 -name '*.ino' | sort` + +echo +echo +echo "### Testing Uno ###" +echo +echo + +for EX in $EXAMPLES ; do + echo $EX + if [[ "$EX" == "examples/10.StarterKit/p13_TouchSensorLamp/p13_TouchSensorLamp.ino" || $EX == "examples/04.Communication/MultiSerialMega/MultiSerialMega.ino" || $EX == "examples/09.USB/"* ]] ; then + echo "...skipping" + continue; + fi + ./arduino --verify --board arduino:avr:uno $EX + echo +done + +echo +echo +echo "### Testing Leonardo ###" +echo +echo + +for EX in $EXAMPLES ; do + echo $EX + if [[ "$EX" == "examples/10.StarterKit/p13_TouchSensorLamp/p13_TouchSensorLamp.ino" ]] ; then + echo "...skipping" + continue; + fi + ./arduino --verify --board arduino:avr:leonardo $EX + echo +done + diff --git a/build/ctags-5.8-patched.zip.sha b/build/ctags-5.8-patched.zip.sha new file mode 100644 index 00000000000..7843389b056 --- /dev/null +++ b/build/ctags-5.8-patched.zip.sha @@ -0,0 +1 @@ +53a712600eef562bfcacd771ebe7469bfb504180 diff --git a/hardware/arduino/avr/platform.txt b/hardware/arduino/avr/platform.txt index 5280b9b7d36..d22f033e66b 100644 --- a/hardware/arduino/avr/platform.txt +++ b/hardware/arduino/avr/platform.txt @@ -100,3 +100,4 @@ tools.avrdude.bootloader.pattern="{cmd.path}" "-C{config.path}" {bootloader.verb # - from numeric vendor ID, set to Unknown otherwise build.usb_manufacturer="Unknown" build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' + diff --git a/hardware/arduino/sam/platform.txt b/hardware/arduino/sam/platform.txt index 0880f4758ba..0f8e199216f 100644 --- a/hardware/arduino/sam/platform.txt +++ b/hardware/arduino/sam/platform.txt @@ -84,3 +84,6 @@ tools.bossac.upload.params.verbose=-i -d tools.bossac.upload.params.quiet= tools.bossac.upload.pattern="{path}/{cmd}" {upload.verbose} --port={serial.port.file} -U {upload.native_usb} -e -w -v -b "{build.path}/{build.project_name}.bin" -R +# coan +tools.coan.pattern="{cmd.path}" source -m -E -P -kb {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.libsam.c.flags} "{source_file}" + diff --git a/hardware/platform.txt b/hardware/platform.txt new file mode 100644 index 00000000000..e9be4664855 --- /dev/null +++ b/hardware/platform.txt @@ -0,0 +1,10 @@ +# ctags +# ------------------------------ +tools.ctags.cmd.path={runtime.ide.path}/hardware/tools/ctags +tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzn "{source_file}" + +# coan +# ------------------------------ +tools.coan.cmd.path={runtime.ide.path}/hardware/tools/coan +tools.coan.pattern="{cmd.path}" source -m -E -P -kb {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} "{source_file}" +