diff --git a/packages/arduino-cli/README.md b/packages/arduino-cli/README.md index 5a66a792..29b0d656 100644 --- a/packages/arduino-cli/README.md +++ b/packages/arduino-cli/README.md @@ -36,6 +36,14 @@ Wraps `arduino-cli config dump`. - Returns `Promise` +### updateConfig(newConfig) +Replaces old config with the new one. + +Accepts: +- `newConfig` `` — Plain JS object representation of `.cli-config.yml` + +- Returns `` with the new config + ### listConnectedBoards() A wrapper with a custom extension over `arduino-cli board list`. diff --git a/packages/arduino-cli/src/config.js b/packages/arduino-cli/src/config.js index d08e6198..84b21599 100644 --- a/packages/arduino-cli/src/config.js +++ b/packages/arduino-cli/src/config.js @@ -9,10 +9,8 @@ const getDefaultConfig = configDir => ({ arduino_data: resolve(configDir, 'data'), }); -export const configure = inputConfig => { - const configDir = fse.mkdtempSync(resolve(tmpdir(), 'arduino-cli')); - const configPath = resolve(configDir, '.cli-config.yml'); - const config = inputConfig || getDefaultConfig(configDir); +// :: Path -> Object -> { config: Object, path: Path } +export const saveConfig = (configPath, config) => { const yamlString = YAML.stringify(config, 2); // Write config @@ -28,6 +26,14 @@ export const configure = inputConfig => { }; }; +// :: Object -> { config: Object, path: Path } +export const configure = inputConfig => { + const configDir = fse.mkdtempSync(resolve(tmpdir(), 'arduino-cli')); + const configPath = resolve(configDir, '.cli-config.yml'); + const config = inputConfig || getDefaultConfig(configDir); + return saveConfig(configPath, config); +}; + // :: Path -> [URL] -> Promise [URL] Error export const addPackageIndexUrls = (configPath, urls) => fse diff --git a/packages/arduino-cli/src/index.js b/packages/arduino-cli/src/index.js index 30c1a32a..67723736 100644 --- a/packages/arduino-cli/src/index.js +++ b/packages/arduino-cli/src/index.js @@ -5,7 +5,12 @@ import { exec, spawn } from 'child-process-promise'; import YAML from 'yamljs'; import { remove } from 'fs-extra'; -import { configure, addPackageIndexUrl, addPackageIndexUrls } from './config'; +import { + saveConfig, + configure, + addPackageIndexUrl, + addPackageIndexUrls, +} from './config'; import { patchBoardsWithOptions } from './optionParser'; import listAvailableBoards from './listAvailableBoards'; import parseProgressLog from './parseProgressLog'; @@ -19,7 +24,7 @@ const escapeSpacesNonWin = R.unless(() => IS_WIN, R.replace(/\s/g, '\\ ')); * @param {Object} config Plain-object representation of `.cli-config.yml` */ const ArduinoCli = (pathToBin, config = null) => { - const { path: configPath, config: cfg } = configure(config); + let { path: configPath, config: cfg } = configure(config); const escapedConfigPath = escapeSpacesNonWin(configPath); const run = args => @@ -68,6 +73,12 @@ const ArduinoCli = (pathToBin, config = null) => { return { dumpConfig: getConfig, + updateConfig: newConfig => { + const newCfg = saveConfig(configPath, newConfig); + configPath = newCfg.path; + cfg = newCfg.config; + return cfg; + }, listConnectedBoards: () => listBoardsWith('list', R.prop('serialBoards')), listInstalledBoards: () => listBoardsWith('listall', R.prop('boards')), listAvailableBoards: () => listAvailableBoards(cfg.arduino_data), diff --git a/packages/arduino-cli/src/optionParser.js b/packages/arduino-cli/src/optionParser.js index 32c529cb..9e5dd5f8 100644 --- a/packages/arduino-cli/src/optionParser.js +++ b/packages/arduino-cli/src/optionParser.js @@ -45,9 +45,9 @@ export const getLines = R.compose( const menuRegExp = /^menu\./; -const optionNameRegExp = /^menu\.([a-zA-Z0-9_]+)=([a-zA-Z0-9-_ ]+)$/; +const optionNameRegExp = /^menu\.([a-zA-Z0-9_]+)=(.+)$/; -const boardOptionRegExp = /^([a-zA-Z0-9_]+)\.menu\.([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)=([a-zA-Z0-9-_ ()]+)$/; +const boardOptionRegExp = /^([a-zA-Z0-9_]+)\.menu\.([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)=(.+)$/; const osRegExp = /(linux|macosx|windows)/; diff --git a/packages/arduino-cli/test-func/index.spec.js b/packages/arduino-cli/test-func/index.spec.js index f394218e..d3a8a084 100644 --- a/packages/arduino-cli/test-func/index.spec.js +++ b/packages/arduino-cli/test-func/index.spec.js @@ -1,3 +1,4 @@ +import * as R from 'ramda'; import { resolve } from 'path'; import * as fse from 'fs-extra'; import { assert } from 'chai'; @@ -42,6 +43,27 @@ describe('Arduino Cli', () => { })); }); + describe('Update arduino-cli config', () => { + afterEach(() => fse.remove(tmpDir)); + it('updates config', async () => { + const cli = arduinoCli(PATH_TO_CLI, cfg); + const curConf = await cli.dumpConfig(); + + assert.strictEqual(curConf.sketchbook_path, cfg.sketchbook_path); + assert.strictEqual(curConf.arduino_data, cfg.arduino_data); + + const newDataDir = resolve(tmpDir, 'newData'); + const newConf = R.assoc('arduino_data', newDataDir, curConf); + cli.updateConfig(newConf); + const updatedConf = await cli.dumpConfig(); + + assert.strictEqual(updatedConf.sketchbook_path, cfg.sketchbook_path); + assert.strictEqual(updatedConf.arduino_data, newDataDir); + + return cli; + }); + }); + describe('Installs additional package index', () => { afterEach(() => fse.remove(tmpDir)); const url = diff --git a/packages/arduino-cli/test/fixtures/packages/esp8266/hardware/esp8266/2.4.2/boards.txt b/packages/arduino-cli/test/fixtures/packages/esp8266/hardware/esp8266/2.4.2/boards.txt index c0983dab..05bbcc97 100644 --- a/packages/arduino-cli/test/fixtures/packages/esp8266/hardware/esp8266/2.4.2/boards.txt +++ b/packages/arduino-cli/test/fixtures/packages/esp8266/hardware/esp8266/2.4.2/boards.txt @@ -1,15 +1,13 @@ -#### JUST A PART OF BOARDS.TXT FILE FROM ESP8266 PACKAGE -#### SOME OPTIONS WAS REMOVED TO MINIFY FIXTURE +#### A PART OF BOARDS.TXT FILE FROM ESP8266 PACKAGE +#### WITH SOME CHANGES: MENU AND OPTION NAMES +#### NOW CONTAINS SPECIAL CHARACTERS AND CYRILLIC SYMBOLS +#### TO MAKE SURE IN THE UNIT TESTS IT WILL WORK FINE +#### WITH ANY PACKAGE. +#### #### ONLY FOR TESTS! -# -# Do not create pull-requests for this file only, CI will not accept them. -# You *must* edit/modify/run boards.txt.py to regenerate boards.txt. -# All modified files after running with option "--allgen" must be included in the pull-request. -# - -menu.UploadSpeed=Upload Speed -menu.CpuFrequency=CPU Frequency +menu.UploadSpeed=Uplo@d Speed (Скорость загрузки) +menu.CpuFrequency=CPU Frequency 123,-_[]():@we$ome ############################################################## generic.name=Generic ESP8266 Module @@ -26,7 +24,7 @@ generic.build.variant=generic generic.build.spiffs_pagesize=256 generic.build.debug_port= generic.build.debug_level= -generic.menu.CpuFrequency.80=80 MHz +generic.menu.CpuFrequency.80=80 MHz (!@#$$%^&*()[]_-+,./) generic.menu.CpuFrequency.80.build.f_cpu=80000000L generic.menu.CpuFrequency.160=160 MHz generic.menu.CpuFrequency.160.build.f_cpu=160000000L @@ -64,7 +62,7 @@ wifi_slot.build.core=esp8266 wifi_slot.build.spiffs_pagesize=256 wifi_slot.build.debug_port= wifi_slot.build.debug_level= -wifi_slot.menu.CpuFrequency.80=80 MHz +wifi_slot.menu.CpuFrequency.80=80 MHz (!@#$$%^&*()[]_-+,./) wifi_slot.menu.CpuFrequency.80.build.f_cpu=80000000L wifi_slot.menu.CpuFrequency.160=160 MHz wifi_slot.menu.CpuFrequency.160.build.f_cpu=160000000L diff --git a/packages/arduino-cli/test/optionParser.spec.js b/packages/arduino-cli/test/optionParser.spec.js index cd3b11a3..20757251 100644 --- a/packages/arduino-cli/test/optionParser.spec.js +++ b/packages/arduino-cli/test/optionParser.spec.js @@ -22,8 +22,8 @@ const fixtureDir = path.resolve(__dirname, 'fixtures'); // ============================================================================= const espOptionNames = { - UploadSpeed: 'Upload Speed', - CpuFrequency: 'CPU Frequency', + UploadSpeed: 'Uplo@d Speed (Скорость загрузки)', + CpuFrequency: 'CPU Frequency 123,-_[]():@we$ome', }; const espOptions = { @@ -47,7 +47,7 @@ const espOptions = { ], CpuFrequency: [ { - name: '80 MHz', + name: '80 MHz (!@#$$%^&*()[]_-+,./)', value: '80', }, { @@ -58,7 +58,7 @@ const espOptions = { }; const uploadSpeedOptions = { - optionName: 'Upload Speed', + optionName: 'Uplo@d Speed (Скорость загрузки)', optionId: 'UploadSpeed', values: [ { @@ -80,11 +80,11 @@ const uploadSpeedOptions = { ], }; const cpuFrequencyOptions = { - optionName: 'CPU Frequency', + optionName: 'CPU Frequency 123,-_[]():@we$ome', optionId: 'CpuFrequency', values: [ { - name: '80 MHz', + name: '80 MHz (!@#$$%^&*()[]_-+,./)', value: '80', }, { diff --git a/packages/xod-arduino/platform/runtime.cpp b/packages/xod-arduino/platform/runtime.cpp index 3df224dc..55fae8b5 100644 --- a/packages/xod-arduino/platform/runtime.cpp +++ b/packages/xod-arduino/platform/runtime.cpp @@ -198,6 +198,22 @@ bool isTimedOut(const ContextT* ctx) { return detail::isTimedOut(ctx->_node); } +bool isValidDigitalPort(uint8_t port) { +#ifdef NUM_DIGITAL_PINS + return port < NUM_DIGITAL_PINS; +#else + return true; +#endif +} + +bool isValidAnalogPort(uint8_t port) { +#ifdef NUM_ANALOG_INPUTS + return port >= A0 && port < A0 + NUM_ANALOG_INPUTS; +#else + return port >= A0; +#endif +} + } // namespace xod //---------------------------------------------------------------------------- diff --git a/packages/xod-client-electron/src/app/arduinoCli.js b/packages/xod-client-electron/src/app/arduinoCli.js index abcb3196..c5ffa499 100644 --- a/packages/xod-client-electron/src/app/arduinoCli.js +++ b/packages/xod-client-electron/src/app/arduinoCli.js @@ -97,12 +97,16 @@ const copyLibraries = async (bundledLibDir, userLibDir, sketchbookLibDir) => { return sketchbookLibDir; }; -// :: _ -> Promise Path Error -const ensureExtraTxt = R.composeP( - extraFilePath => fse.ensureFile(extraFilePath).then(R.always(extraFilePath)), - ws => path.join(ws, ARDUINO_PACKAGES_DIRNAME, ARDUINO_EXTRA_URLS_FILENAME), - loadWorkspacePath -); +// :: Path -> Promise Path Error +const ensureExtraTxt = async wsPath => { + const extraTxtFilePath = path.join( + wsPath, + ARDUINO_PACKAGES_DIRNAME, + ARDUINO_EXTRA_URLS_FILENAME + ); + await fse.ensureFile(extraTxtFilePath); + return extraTxtFilePath; +}; const copyPackageIndexes = async wsPackageDir => { const filesToCopy = await R.composeP( @@ -209,6 +213,30 @@ const patchFqbnWithOptions = board => { )(selectedBoardOptions); }; +// ============================================================================= +// +// Error wrappers +// +// ============================================================================= + +// :: Error -> RejectedPromise Error +const wrapCompileError = err => + Promise.reject( + createError('COMPILE_TOOL_ERROR', { + message: err.message, + code: err.code, + }) + ); + +// :: Error -> RejectedPromise Error +const wrapUploadError = err => + Promise.reject( + createError('UPLOAD_TOOL_ERROR', { + message: err.message, + code: err.code, + }) + ); + // ============================================================================= // // Handlers @@ -225,6 +253,26 @@ const patchFqbnWithOptions = board => { export const prepareSketchDir = () => fse.mkdtemp(path.resolve(os.tmpdir(), 'xod_temp_sketchbook')); +/** + * Prepare `__packages__` directory inside user's workspace if + * it does not prepared earlier: + * - copy bundled package index json files + * - migrate old arduino packages if they are exist + * - create `extra.txt` file + * + * Returns Path to the `__packages__` directory inside user's workspace + * + * :: Path -> Promise Path Error + */ +const prepareWorkspacePackagesDir = async wsPath => { + const packagesDirPath = getArduinoPackagesPath(wsPath); + + await copyPackageIndexes(packagesDirPath); + await migrateArduinoPackages(wsPath); + await ensureExtraTxt(wsPath); + + return packagesDirPath; +}; /** * Creates an instance of ArduinoCli. * @@ -237,31 +285,42 @@ export const prepareSketchDir = () => * * :: Path -> Promise ArduinoCli Error */ -export const create = sketchDir => - loadWorkspacePath().then(async wsPath => { - const arduinoCliPath = await getArduinoCliPath(); +export const create = async sketchDir => { + const wsPath = await loadWorkspacePath(); + const arduinoCliPath = await getArduinoCliPath(); + const packagesDirPath = await prepareWorkspacePackagesDir(wsPath); - const packagesDirPath = getArduinoPackagesPath(wsPath); - - await copyPackageIndexes(packagesDirPath); - await migrateArduinoPackages(); - await ensureExtraTxt(); - - if (!await fse.pathExists(arduinoCliPath)) { - throw createError('ARDUINO_CLI_NOT_FOUND', { - path: arduinoCliPath, - isDev: IS_DEV, - }); - } - - return arduinoCli(arduinoCliPath, { - arduino_data: packagesDirPath, - sketchbook_path: sketchDir, - board_manager: { - additional_urls: BUNDLED_ADDITIONAL_URLS, - }, + if (!await fse.pathExists(arduinoCliPath)) { + throw createError('ARDUINO_CLI_NOT_FOUND', { + path: arduinoCliPath, + isDev: IS_DEV, }); + } + + return arduinoCli(arduinoCliPath, { + arduino_data: packagesDirPath, + sketchbook_path: sketchDir, + board_manager: { + additional_urls: BUNDLED_ADDITIONAL_URLS, + }, }); +}; + +/** + * Updates path to the `arduino_data` in the arduino-cli `.cli-config.yml` + * and prepares `__packages__` directory in the user's workspace if needed. + * + * We have to call this function when user changes workspace to make all + * functions provided by this module works properly without restarting the IDE. + * + * :: ArduinoCli -> Path -> Promise Object Error + */ +export const switchWorkspace = async (cli, newWsPath) => { + const oldConfig = await cli.dumpConfig(); + const packagesDirPath = await prepareWorkspacePackagesDir(newWsPath); + const newConfig = R.assoc('arduino_data', packagesDirPath, oldConfig); + return cli.updateConfig(newConfig); +}; /** * Updates package index json files. @@ -280,7 +339,8 @@ const updateIndexes = async cli => { R.reject(isAmong(urls)), R.split('\r\n'), p => fse.readFile(p, { encoding: 'utf8' }), - ensureExtraTxt + ensureExtraTxt, + loadWorkspacePath )(); }; @@ -369,18 +429,20 @@ const uploadThroughCloud = async (onProgress, cli, payload) => { message: CODE_COMPILED, tab: 'compiler', }); - const uploadLog = await cli.upload( - stdout => - onProgress({ - percentage: 60, - message: stdout, - tab: 'uploader', - }), - payload.port.comName, - payload.board.fqbn, - sketchName, - false - ); + const uploadLog = await cli + .upload( + stdout => + onProgress({ + percentage: 60, + message: stdout, + tab: 'uploader', + }), + payload.port.comName, + payload.board.fqbn, + sketchName, + false + ) + .catch(wrapUploadError); onProgress({ percentage: 100, message: '', @@ -416,17 +478,19 @@ const uploadThroughUSB = async (onProgress, cli, payload) => { tab: 'compiler', }); - const compileLog = await cli.compile( - stdout => - onProgress({ - percentage: 40, - message: stdout, - tab: 'compiler', - }), - payload.board.fqbn, - sketchName, - false - ); + const compileLog = await cli + .compile( + stdout => + onProgress({ + percentage: 40, + message: stdout, + tab: 'compiler', + }), + payload.board.fqbn, + sketchName, + false + ) + .catch(wrapCompileError); onProgress({ percentage: 50, @@ -434,18 +498,20 @@ const uploadThroughUSB = async (onProgress, cli, payload) => { tab: 'uploader', }); - const uploadLog = await cli.upload( - stdout => - onProgress({ - percentage: 60, - message: stdout, - tab: 'uploader', - }), - payload.port.comName, - payload.board.fqbn, - sketchName, - false - ); + const uploadLog = await cli + .upload( + stdout => + onProgress({ + percentage: 60, + message: stdout, + tab: 'uploader', + }), + payload.port.comName, + payload.board.fqbn, + sketchName, + false + ) + .catch(wrapUploadError); onProgress({ percentage: 100, message: '', diff --git a/packages/xod-client-electron/src/app/main.js b/packages/xod-client-electron/src/app/main.js index cbe24e59..e6648ccd 100644 --- a/packages/xod-client-electron/src/app/main.js +++ b/packages/xod-client-electron/src/app/main.js @@ -241,13 +241,17 @@ const onReady = () => { .prepareSketchDir() .then(aCli.create) .then(arduinoCli => { - // TODO: Refactor (WS) aCli.subscribeListBoards(arduinoCli); aCli.subscribeUpload(arduinoCli); aCli.subscribeUpdateIndexes(arduinoCli); aCli.subscibeCheckUpdates(arduinoCli); aCli.subscribeUpgradeArduinoPackages(arduinoCli); + // On switching workspace -> update arduino-cli config + ipcMain.on(EVENTS.SWITCH_WORKSPACE, (event, newWsPath) => + aCli.switchWorkspace(arduinoCli, newWsPath) + ); + subscribeOnCheckArduinoDependencies(arduinoCli); subscribeOnInstallArduinoDependencies(arduinoCli); }) diff --git a/packages/xod-client-electron/src/app/migrateArduinoPackages.js b/packages/xod-client-electron/src/app/migrateArduinoPackages.js index 6ab60061..a0863ad4 100644 --- a/packages/xod-client-electron/src/app/migrateArduinoPackages.js +++ b/packages/xod-client-electron/src/app/migrateArduinoPackages.js @@ -12,7 +12,6 @@ import * as R from 'ramda'; import * as fse from 'fs-extra'; import { app } from 'electron'; -import { loadWorkspacePath } from './workspaceActions'; import { ARDUINO_PACKAGES_DIRNAME } from './constants'; const OLD_PACKAGE_VERSIONS = { @@ -32,9 +31,9 @@ const moveWithoutEexistError = (from, to) => /** * Moves old packages into Users' workspace. * - * :: _ -> Promise 0 Error + * :: Path -> Promise 0 Error */ -export default async () => { +export default async wsPath => { const appData = app.getPath('userData'); const oldPackagesDir = path.join(appData, 'packages'); if (!await fse.pathExists(oldPackagesDir)) return 0; @@ -42,7 +41,6 @@ export default async () => { const oldHardwareDir = path.join(oldPackagesDir, 'arduino', 'hardware'); const archs = await fse.readdir(oldHardwareDir); - const wsPath = await loadWorkspacePath(); const wsPackagesDir = path.join(wsPath, ARDUINO_PACKAGES_DIRNAME, 'packages'); const wsHardwareDir = path.join(wsPackagesDir, 'arduino', 'hardware'); diff --git a/packages/xod-client-electron/src/upload/messages.js b/packages/xod-client-electron/src/upload/messages.js index c4a58414..fa9ee9e7 100644 --- a/packages/xod-client-electron/src/upload/messages.js +++ b/packages/xod-client-electron/src/upload/messages.js @@ -4,8 +4,14 @@ export default { note: `Cloud compilation does not support ${boardName} yet.`, solution: 'Try to compile it on your own computer', }), + COMPILE_TOOL_ERROR: ({ message }) => ({ + title: 'Compilation failed', + note: `Command ${message}`, + solution: + 'The generated C++ code contains errors. It can be due to a bad node implementation or if your board is not compatible with XOD runtime code. The original compiler error message is above. Fix C++ errors to continue. If you believe it is a bug, report the problem to XOD developers.', + }), UPLOAD_TOOL_ERROR: ({ message }) => ({ - title: 'Upload tool exited with error', + title: 'Upload failed', note: `Command ${message}`, solution: 'Make sure the board is connected, the cable is working, the board model set correctly, the upload port belongs to the board, the board drivers are installed, the upload options (if any) match your board specs.', diff --git a/packages/xod-client-electron/src/view/containers/App.jsx b/packages/xod-client-electron/src/view/containers/App.jsx index d77b14c2..95c4fce2 100644 --- a/packages/xod-client-electron/src/view/containers/App.jsx +++ b/packages/xod-client-electron/src/view/containers/App.jsx @@ -331,15 +331,7 @@ class App extends client.App { board, port, } - ).catch(err => { - console.error(err); // eslint-disable-line no-console - return Promise.reject( - createError('UPLOAD_TOOL_ERROR', { - message: err.message, - code: err.code, - }) - ); - }) + ) ) .then(() => proc.success()) .then(() => { diff --git a/packages/xod-client/src/utils/menu.js b/packages/xod-client/src/utils/menu.js index 165b0d31..9223df02 100644 --- a/packages/xod-client/src/utils/menu.js +++ b/packages/xod-client/src/utils/menu.js @@ -107,7 +107,7 @@ const rawItems = { label: 'Upload to Arduino...', }, updatePackages: { - label: 'Upgrade Arduino Packages & Toolchains...', + label: 'Upgrade Arduino Packages && Toolchains...', }, view: { diff --git a/packages/xod-tabtest/cpp/Arduino.h b/packages/xod-tabtest/cpp/Arduino.h index b3e08b16..9c53c915 100644 --- a/packages/xod-tabtest/cpp/Arduino.h +++ b/packages/xod-tabtest/cpp/Arduino.h @@ -11,6 +11,8 @@ void setup(); void loop(); +#define A0 14 + uint32_t millis(); void delay(uint32_t); diff --git a/workspace/__lib__/xod/common-hardware/servo/patch.cpp b/workspace/__lib__/xod/common-hardware/servo/patch.cpp index 74b732fb..f168ceb9 100644 --- a/workspace/__lib__/xod/common-hardware/servo/patch.cpp +++ b/workspace/__lib__/xod/common-hardware/servo/patch.cpp @@ -16,7 +16,7 @@ void evaluate(Context ctx) { State* state = getState(ctx); auto port = (int)getValue(ctx); - if (port > NUM_DIGITAL_PINS - 1) { + if (!isValidDigitalPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/__lib__/xod/gpio/analog-read/patch.cpp b/workspace/__lib__/xod/gpio/analog-read/patch.cpp index b0fe4f86..ca855b56 100644 --- a/workspace/__lib__/xod/gpio/analog-read/patch.cpp +++ b/workspace/__lib__/xod/gpio/analog-read/patch.cpp @@ -8,8 +8,8 @@ void evaluate(Context ctx) { return; const uint8_t port = getValue(ctx); - bool err = (port < A0 || port > A0 + NUM_ANALOG_INPUTS - 1); - if (err) { + + if (!isValidAnalogPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/__lib__/xod/gpio/digital-read/patch.cpp b/workspace/__lib__/xod/gpio/digital-read/patch.cpp index 8f923d9c..fa793d14 100644 --- a/workspace/__lib__/xod/gpio/digital-read/patch.cpp +++ b/workspace/__lib__/xod/gpio/digital-read/patch.cpp @@ -8,8 +8,7 @@ void evaluate(Context ctx) { return; const uint8_t port = getValue(ctx); - bool err = (port > NUM_DIGITAL_PINS - 1); - if (err) { + if (!isValidDigitalPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/__lib__/xod/gpio/digital-write/patch.cpp b/workspace/__lib__/xod/gpio/digital-write/patch.cpp index 8c35d630..f4aa82e9 100644 --- a/workspace/__lib__/xod/gpio/digital-write/patch.cpp +++ b/workspace/__lib__/xod/gpio/digital-write/patch.cpp @@ -8,8 +8,7 @@ void evaluate(Context ctx) { return; const uint8_t port = getValue(ctx); - bool err = (port > NUM_DIGITAL_PINS - 1); - if (err) { + if (!isValidDigitalPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/__lib__/xod/gpio/pwm-write/patch.cpp b/workspace/__lib__/xod/gpio/pwm-write/patch.cpp index 519eadd1..041190d8 100644 --- a/workspace/__lib__/xod/gpio/pwm-write/patch.cpp +++ b/workspace/__lib__/xod/gpio/pwm-write/patch.cpp @@ -14,9 +14,8 @@ void evaluate(Context ctx) { return; const uint8_t port = getValue(ctx); - bool err = (port > NUM_DIGITAL_PINS - 1); - if (err) { + if (!isValidDigitalPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/blink/__fixtures__/arduino.cpp b/workspace/blink/__fixtures__/arduino.cpp index c18b1484..289473d4 100644 --- a/workspace/blink/__fixtures__/arduino.cpp +++ b/workspace/blink/__fixtures__/arduino.cpp @@ -777,6 +777,22 @@ bool isTimedOut(const ContextT* ctx) { return detail::isTimedOut(ctx->_node); } +bool isValidDigitalPort(uint8_t port) { +#ifdef NUM_DIGITAL_PINS + return port < NUM_DIGITAL_PINS; +#else + return true; +#endif +} + +bool isValidAnalogPort(uint8_t port) { +#ifdef NUM_ANALOG_INPUTS + return port >= A0 && port < A0 + NUM_ANALOG_INPUTS; +#else + return port >= A0; +#endif +} + } // namespace xod //---------------------------------------------------------------------------- @@ -1235,8 +1251,7 @@ void evaluate(Context ctx) { return; const uint8_t port = getValue(ctx); - bool err = (port > NUM_DIGITAL_PINS - 1); - if (err) { + if (!isValidDigitalPort(port)) { emitValue(ctx, 1); return; } diff --git a/workspace/count-with-feedback-loops/__fixtures__/arduino.cpp b/workspace/count-with-feedback-loops/__fixtures__/arduino.cpp index 7595d95b..8dc6aab7 100644 --- a/workspace/count-with-feedback-loops/__fixtures__/arduino.cpp +++ b/workspace/count-with-feedback-loops/__fixtures__/arduino.cpp @@ -777,6 +777,22 @@ bool isTimedOut(const ContextT* ctx) { return detail::isTimedOut(ctx->_node); } +bool isValidDigitalPort(uint8_t port) { +#ifdef NUM_DIGITAL_PINS + return port < NUM_DIGITAL_PINS; +#else + return true; +#endif +} + +bool isValidAnalogPort(uint8_t port) { +#ifdef NUM_ANALOG_INPUTS + return port >= A0 && port < A0 + NUM_ANALOG_INPUTS; +#else + return port >= A0; +#endif +} + } // namespace xod //---------------------------------------------------------------------------- diff --git a/workspace/lcd-time/__fixtures__/arduino.cpp b/workspace/lcd-time/__fixtures__/arduino.cpp index ef38d140..6391038c 100644 --- a/workspace/lcd-time/__fixtures__/arduino.cpp +++ b/workspace/lcd-time/__fixtures__/arduino.cpp @@ -777,6 +777,22 @@ bool isTimedOut(const ContextT* ctx) { return detail::isTimedOut(ctx->_node); } +bool isValidDigitalPort(uint8_t port) { +#ifdef NUM_DIGITAL_PINS + return port < NUM_DIGITAL_PINS; +#else + return true; +#endif +} + +bool isValidAnalogPort(uint8_t port) { +#ifdef NUM_ANALOG_INPUTS + return port >= A0 && port < A0 + NUM_ANALOG_INPUTS; +#else + return port >= A0; +#endif +} + } // namespace xod //---------------------------------------------------------------------------- diff --git a/workspace/two-button-switch/__fixtures__/arduino.cpp b/workspace/two-button-switch/__fixtures__/arduino.cpp index 5402b3b2..b8e41fb6 100644 --- a/workspace/two-button-switch/__fixtures__/arduino.cpp +++ b/workspace/two-button-switch/__fixtures__/arduino.cpp @@ -777,6 +777,22 @@ bool isTimedOut(const ContextT* ctx) { return detail::isTimedOut(ctx->_node); } +bool isValidDigitalPort(uint8_t port) { +#ifdef NUM_DIGITAL_PINS + return port < NUM_DIGITAL_PINS; +#else + return true; +#endif +} + +bool isValidAnalogPort(uint8_t port) { +#ifdef NUM_ANALOG_INPUTS + return port >= A0 && port < A0 + NUM_ANALOG_INPUTS; +#else + return port >= A0; +#endif +} + } // namespace xod //----------------------------------------------------------------------------