├── .gitignore ├── .idea ├── .name ├── compiler.iml ├── dictionaries │ └── iluvatar.xml ├── encodings.xml ├── frameworkRootSettings.xml ├── inspectionProfiles │ ├── Project_Default.xml │ └── profiles_settings.xml ├── modules.xml ├── scopes │ └── scope_settings.xml └── vcs.xml ├── .travis.yml ├── LICENSE ├── README.md ├── Symfony ├── .gitignore ├── LICENSE ├── README.md ├── UPGRADE-2.2.md ├── UPGRADE.md ├── app │ ├── .htaccess │ ├── AppCache.php │ ├── AppKernel.php │ ├── Resources │ │ ├── autocompletion │ │ │ ├── .gitignore │ │ │ ├── complete.py │ │ │ ├── logger.py │ │ │ ├── main.py │ │ │ ├── request.py │ │ │ └── response.py │ │ └── views │ │ │ └── base.html.twig │ ├── SymfonyRequirements.php │ ├── autoload.php │ ├── check.php │ ├── config │ │ ├── config.yml │ │ ├── config_dev.yml │ │ ├── config_prod.yml │ │ ├── config_test.yml │ │ ├── parameters.yml.dist │ │ ├── routing.yml │ │ ├── routing_dev.yml │ │ └── security.yml │ ├── console │ └── phpunit.xml.dist ├── composer.json ├── composer.lock ├── src │ ├── .htaccess │ └── Codebender │ │ └── CompilerBundle │ │ ├── CodebenderCompilerBundle.php │ │ ├── Controller │ │ └── DefaultController.php │ │ ├── DependencyInjection │ │ ├── CodebenderCompilerExtension.php │ │ └── Configuration.php │ │ ├── Handler │ │ ├── CompilerHandler.php │ │ ├── CompilerV2Handler.php │ │ ├── DeletionHandler.php │ │ ├── MCUHandler.php │ │ ├── PostprocessingHandler.php │ │ ├── PreprocessingHandler.php │ │ └── UtilityHandler.php │ │ ├── Resources │ │ └── config │ │ │ ├── routing.yml │ │ │ └── services.yml │ │ └── Tests │ │ └── Controller │ │ └── DefaultControllerFunctionalTest.php └── web │ ├── .htaccess │ ├── app.php │ ├── app_dev.php │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── robots.txt ├── apache-config └── scripts ├── clear_cache.sh ├── install.sh ├── install_composer.sh ├── install_dependencies.sh ├── run_local_tests.sh ├── run_tests.sh └── warmup_cache.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/workspace.xml 2 | vagrant/ 3 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | compiler -------------------------------------------------------------------------------- /.idea/compiler.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/dictionaries/iluvatar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/frameworkRootSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.5 4 | 5 | before_install: 6 | - sudo apt-get update 7 | 8 | before_script: 9 | - scripts/install.sh 10 | - cd /opt/codebender/compiler/Symfony 11 | script: 12 | - mkdir -p build/logs 13 | - ../scripts/run_tests.sh 14 | 15 | after_script: 16 | - php bin/coveralls -v 17 | 18 | notifications: 19 | irc: "chat.freenode.net#codebender.cc" 20 | email: 21 | recipients: 22 | - girder@codebender.cc 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013, The Codebender Development Team. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository is part of the [codebender.cc](http://www.codebender.cc) maker and artist web platform. 2 | 3 | [![Build Status](https://travis-ci.org/codebendercc/compiler.svg?branch=master)](https://travis-ci.org/codebendercc/compiler) 4 | [![Coverage Status](https://coveralls.io/repos/codebendercc/compiler/badge.svg?branch=master)](https://coveralls.io/r/codebendercc/compiler?branch=master) 5 | 6 | ## And what's that? 7 | 8 | codebender fills the need for reliable, easy to use tools for makers, a need that couldn't be completely fulfilled by any existing solution according to our experience. 9 | 10 | Things like installing libraries or the IDE and updating software sometimes were (and still are) quite a painful process. But in addition to the above, the limited features provided (e.g. insufficient highlighting, indentation and autocompletion) got us to start codebender, a completely web-based IDE that requires virtually no installation and offers a great code editor. Plus it stores your sketches on the cloud. Yeah! 11 | 12 | With your code on the cloud, you can access your sketches safely even if your laptop is stolen or your hard drive fails! codebender also compiles your code giving you extremely descriptive error descriptions on terrible code. There's even more, you can upload your code to your Arduino straight from the browser. 13 | 14 | ## How does the compiler come into the picture? 15 | 16 | The compiler repository includes all the necessary files needed to run the compiler as a service. It receives the code as input and outputs the compiled output if the compilation was successful or the errors present in the code. We provide an easy interface to send the code to the compiler. 17 | 18 | Here's a list of open source projects we use 19 | * Clang 20 | * gcc-avr 21 | * avr binutils (avrsize) 22 | 23 | For development we've run it on a variety of Linux and Mac OS X machines. 24 | 25 | For production we are using Ubuntu Server 12.04. We know the compiler works perfectly on it, so we suggest you using it as well. 26 | 27 | ## How to install 28 | 29 | Check out the code in any directory you wish 30 | 31 | `git clone https://github.com/codebendercc/compiler.git` 32 | 33 | Then cd in the created directory (if you run the command as is above, it would be named `compiler`) and run 34 | 35 | `scripts/install.sh` 36 | 37 | (don't cd into scripts directory and run install.sh from there, it won't work) 38 | 39 | If you now visit `http://localhost/status` you'll see a JSON response telling you everything's ok: 40 | `{"success":true,"status":"OK"}` 41 | 42 | ## What's next? 43 | 44 | Visit the [wiki](https://github.com/codebendercc/compiler/wiki) for more information. 45 | 46 | ## How can someone contribute? 47 | 48 | Contribution is always welcome whether it is by creating an issue for a bug or suggestion you can't fix yourself or a pull request for something you can. 49 | 50 | If you write new code or edit old code please don't forget to add/update relative unit tests that come with it. It is always a good idea to run tests localy to make sure nothing breaks before you create a pull request. 51 | 52 | We expect new code to be [PSR-2](http://www.php-fig.org/psr/psr-2/) but we know we carry legacy code with different coding styles. You're welcome to fix that. 53 | -------------------------------------------------------------------------------- /Symfony/.gitignore: -------------------------------------------------------------------------------- 1 | /web/bundles/ 2 | /app/bootstrap.php.cache 3 | /app/cache/* 4 | /app/config/parameters.yml 5 | /app/logs/* 6 | /build/ 7 | /vendor/ 8 | /bin/ 9 | /composer.phar 10 | -------------------------------------------------------------------------------- /Symfony/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2013 Fabien Potencier 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Symfony/README.md: -------------------------------------------------------------------------------- 1 | Symfony Standard Edition 2 | ======================== 3 | 4 | Welcome to the Symfony Standard Edition - a fully-functional Symfony2 5 | application that you can use as the skeleton for your new applications. 6 | 7 | This document contains information on how to download, install, and start 8 | using Symfony. For a more detailed explanation, see the [Installation][1] 9 | chapter of the Symfony Documentation. 10 | 11 | 1) Installing the Standard Edition 12 | ---------------------------------- 13 | 14 | When it comes to installing the Symfony Standard Edition, you have the 15 | following options. 16 | 17 | ### Use Composer (*recommended*) 18 | 19 | As Symfony uses [Composer][2] to manage its dependencies, the recommended way 20 | to create a new project is to use it. 21 | 22 | If you don't have Composer yet, download it following the instructions on 23 | http://getcomposer.org/ or just run the following command: 24 | 25 | curl -s http://getcomposer.org/installer | php 26 | 27 | Then, use the `create-project` command to generate a new Symfony application: 28 | 29 | php composer.phar create-project symfony/framework-standard-edition path/to/install 30 | 31 | Composer will install Symfony and all its dependencies under the 32 | `path/to/install` directory. 33 | 34 | ### Download an Archive File 35 | 36 | To quickly test Symfony, you can also download an [archive][3] of the Standard 37 | Edition and unpack it somewhere under your web server root directory. 38 | 39 | If you downloaded an archive "without vendors", you also need to install all 40 | the necessary dependencies. Download composer (see above) and run the 41 | following command: 42 | 43 | php composer.phar install 44 | 45 | 2) Checking your System Configuration 46 | ------------------------------------- 47 | 48 | Before starting coding, make sure that your local system is properly 49 | configured for Symfony. 50 | 51 | Execute the `check.php` script from the command line: 52 | 53 | php app/check.php 54 | 55 | The script returns a status code of `0` if all mandatory requirements are met, 56 | `1` otherwise. 57 | 58 | Access the `config.php` script from a browser: 59 | 60 | http://localhost/path/to/symfony/app/web/config.php 61 | 62 | If you get any warnings or recommendations, fix them before moving on. 63 | 64 | 3) Browsing the Demo Application 65 | -------------------------------- 66 | 67 | Congratulations! You're now ready to use Symfony. 68 | 69 | From the `config.php` page, click the "Bypass configuration and go to the 70 | Welcome page" link to load up your first Symfony page. 71 | 72 | You can also use a web-based configurator by clicking on the "Configure your 73 | Symfony Application online" link of the `config.php` page. 74 | 75 | To see a real-live Symfony page in action, access the following page: 76 | 77 | web/app_dev.php/demo/hello/Fabien 78 | 79 | 4) Getting started with Symfony 80 | ------------------------------- 81 | 82 | This distribution is meant to be the starting point for your Symfony 83 | applications, but it also contains some sample code that you can learn from 84 | and play with. 85 | 86 | A great way to start learning Symfony is via the [Quick Tour][4], which will 87 | take you through all the basic features of Symfony2. 88 | 89 | Once you're feeling good, you can move onto reading the official 90 | [Symfony2 book][5]. 91 | 92 | A default bundle, `AcmeDemoBundle`, shows you Symfony2 in action. After 93 | playing with it, you can remove it by following these steps: 94 | 95 | * delete the `src/Acme` directory; 96 | 97 | * remove the routing entry referencing AcmeDemoBundle in `app/config/routing_dev.yml`; 98 | 99 | * remove the AcmeDemoBundle from the registered bundles in `app/AppKernel.php`; 100 | 101 | * remove the `web/bundles/acmedemo` directory; 102 | 103 | * remove the `security.providers`, `security.firewalls.login` and 104 | `security.firewalls.secured_area` entries in the `security.yml` file or 105 | tweak the security configuration to fit your needs. 106 | 107 | What's inside? 108 | --------------- 109 | 110 | The Symfony Standard Edition is configured with the following defaults: 111 | 112 | * Twig is the only configured template engine; 113 | 114 | * Doctrine ORM/DBAL is configured; 115 | 116 | * Swiftmailer is configured; 117 | 118 | * Annotations for everything are enabled. 119 | 120 | It comes pre-configured with the following bundles: 121 | 122 | * **FrameworkBundle** - The core Symfony framework bundle 123 | 124 | * [**SensioFrameworkExtraBundle**][6] - Adds several enhancements, including 125 | template and routing annotation capability 126 | 127 | * [**DoctrineBundle**][7] - Adds support for the Doctrine ORM 128 | 129 | * [**TwigBundle**][8] - Adds support for the Twig templating engine 130 | 131 | * [**SecurityBundle**][9] - Adds security by integrating Symfony's security 132 | component 133 | 134 | * [**SwiftmailerBundle**][10] - Adds support for Swiftmailer, a library for 135 | sending emails 136 | 137 | * [**MonologBundle**][11] - Adds support for Monolog, a logging library 138 | 139 | * [**AsseticBundle**][12] - Adds support for Assetic, an asset processing 140 | library 141 | 142 | * **WebProfilerBundle** (in dev/test env) - Adds profiling functionality and 143 | the web debug toolbar 144 | 145 | * **SensioDistributionBundle** (in dev/test env) - Adds functionality for 146 | configuring and working with Symfony distributions 147 | 148 | * [**SensioGeneratorBundle**][13] (in dev/test env) - Adds code generation 149 | capabilities 150 | 151 | * **AcmeDemoBundle** (in dev/test env) - A demo bundle with some example 152 | code 153 | 154 | All libraries and bundles included in the Symfony Standard Edition are 155 | released under the MIT or BSD license. 156 | 157 | Enjoy! 158 | 159 | [1]: http://symfony.com/doc/2.3/book/installation.html 160 | [2]: http://getcomposer.org/ 161 | [3]: http://symfony.com/download 162 | [4]: http://symfony.com/doc/2.3/quick_tour/the_big_picture.html 163 | [5]: http://symfony.com/doc/2.3/index.html 164 | [6]: http://symfony.com/doc/2.3/bundles/SensioFrameworkExtraBundle/index.html 165 | [7]: http://symfony.com/doc/2.3/book/doctrine.html 166 | [8]: http://symfony.com/doc/2.3/book/templating.html 167 | [9]: http://symfony.com/doc/2.3/book/security.html 168 | [10]: http://symfony.com/doc/2.3/cookbook/email.html 169 | [11]: http://symfony.com/doc/2.3/cookbook/logging/monolog.html 170 | [12]: http://symfony.com/doc/2.3/cookbook/assetic/asset_management.html 171 | [13]: http://symfony.com/doc/2.3/bundles/SensioGeneratorBundle/index.html 172 | -------------------------------------------------------------------------------- /Symfony/UPGRADE-2.2.md: -------------------------------------------------------------------------------- 1 | UPGRADE FROM 2.1 to 2.2 2 | ======================= 3 | 4 | * The [`web/.htaccess`](https://github.com/symfony/symfony-standard/blob/2.2/web/.htaccess) 5 | file has been enhanced substantially to prevent duplicate content with and 6 | without `/app.php` in the URI. It also improves functionality when using 7 | Apache aliases or when mod_rewrite is not available. So you might want to 8 | update your `.htaccess` file as well. 9 | 10 | * The ``_internal`` route is not used any more. It should then be removed 11 | from both your routing and security configurations. A ``fragments`` key has 12 | been added to the framework configuration and must be specified when ESI or 13 | Hinclude are in use. No security configuration is required for this path as 14 | by default ESI access is only permitted for trusted hosts and Hinclude 15 | access uses an URL signing mechanism. 16 | 17 | ``` 18 | framework: 19 | # ... 20 | fragments: { path: /_proxy } 21 | ``` 22 | 23 | Functional Tests 24 | ---------------- 25 | 26 | * The profiler has been disabled by default in the test environment. You can 27 | enable it again by modifying the ``config_test.yml`` configuration file or 28 | even better, you can just enable it for the very next request by calling 29 | ``$client->enableProfiler()`` when you need the profiler in a test (that 30 | speeds up functional tests quite a bit). 31 | -------------------------------------------------------------------------------- /Symfony/UPGRADE.md: -------------------------------------------------------------------------------- 1 | Symfony Standard Edition Upgrade 2 | ================================ 3 | 4 | From Symfony 2.0 to Symfony 2.1 5 | ------------------------------- 6 | 7 | ### Project Dependencies 8 | 9 | As of Symfony 2.1, project dependencies are managed by 10 | [Composer](http://getcomposer.org/): 11 | 12 | * The `bin/vendors` script can be removed as `composer.phar` does all the work 13 | now (it is recommended to install it globally on your machine). 14 | 15 | * The `deps` file need to be replaced with the `composer.json` one. 16 | 17 | * The `composer.lock` is the equivalent of the generated `deps.lock` file and 18 | it is automatically generated by Composer. 19 | 20 | Download the default 21 | [`composer.json`](https://raw.github.com/symfony/symfony-standard/2.1/composer.json) 22 | and 23 | [`composer.lock`](https://raw.github.com/symfony/symfony-standard/2.1/composer.lock) 24 | files for Symfony 2.1 and put them into the main directory of your project. If 25 | you have customized your `deps` file, move the added dependencies to the 26 | `composer.json` file (many bundles and PHP libraries are already available as 27 | Composer packages -- search for them on [Packagist](http://packagist.org/)). 28 | 29 | Remove your current `vendor` directory. 30 | 31 | Finally, run Composer: 32 | 33 | $ composer.phar install 34 | 35 | Note: You must complete the upgrade steps below so composer can successfully generate the autoload files. 36 | 37 | ### `app/autoload.php` 38 | 39 | The default `autoload.php` reads as follows (it has been simplified a lot as 40 | autoloading for libraries and bundles declared in your `composer.json` file is 41 | automatically managed by the Composer autoloader): 42 | 43 | add('', __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs'); 54 | } 55 | 56 | AnnotationRegistry::registerLoader(array($loader, 'loadClass')); 57 | 58 | return $loader; 59 | 60 | ### `app/config/config.yml` 61 | 62 | The `framework.charset` setting must be removed. If you are not using `UTF-8` 63 | for your application, override the `getCharset()` method in your `AppKernel` 64 | class instead: 65 | 66 | class AppKernel extends Kernel 67 | { 68 | public function getCharset() 69 | { 70 | return 'ISO-8859-1'; 71 | } 72 | 73 | // ... 74 | } 75 | 76 | You might want to add the new `strict_requirements` parameter to 77 | `framework.router` (it avoids fatal errors in the production environment when 78 | a link cannot be generated): 79 | 80 | framework: 81 | router: 82 | strict_requirements: %kernel.debug% 83 | 84 | You can even disable the requirements check on production with `null` as you should 85 | know that the parameters for URL generation always pass the requirements, e.g. by 86 | validating them beforehand. This additionally enhances performance. See 87 | [config_prod.yml](https://github.com/symfony/symfony-standard/blob/master/app/config/config_prod.yml). 88 | 89 | The `default_locale` parameter is now a setting of the main `framework` 90 | configuration (it was under the `framework.session` in 2.0): 91 | 92 | framework: 93 | default_locale: %locale% 94 | 95 | The `auto_start` setting under `framework.session` must be removed as it is 96 | not used anymore (the session is now always started on-demand). If 97 | `auto_start` was the only setting under the `framework.session` entry, don't 98 | remove it entirely, but set its value to `~` (`~` means `null` in YAML) 99 | instead: 100 | 101 | framework: 102 | session: ~ 103 | 104 | The `trust_proxy_headers` setting was added in the default configuration file 105 | (as it should be set to `true` when you install your application behind a 106 | reverse proxy): 107 | 108 | framework: 109 | trust_proxy_headers: false 110 | 111 | An empty `bundles` entry was added to the `assetic` configuration: 112 | 113 | assetic: 114 | bundles: [] 115 | 116 | The default `swiftmailer` configuration now has the `spool` setting configured 117 | to the `memory` type to defer email sending after the response is sent to the 118 | user (recommended for better end-user performance): 119 | 120 | swiftmailer: 121 | spool: { type: memory } 122 | 123 | The `jms_security_extra` configuration was moved to the `security.yml` 124 | configuration file. 125 | 126 | ### `app/config/config_dev.yml` 127 | 128 | An example of how to send all emails to a unique address was added: 129 | 130 | #swiftmailer: 131 | # delivery_address: me@example.com 132 | 133 | ### `app/config/config_test.yml` 134 | 135 | The `storage_id` setting must be changed to `session.storage.mock_file`: 136 | 137 | framework: 138 | session: 139 | storage_id: session.storage.mock_file 140 | 141 | ### `app/config/parameters.ini` 142 | 143 | The file has been converted to a YAML file which reads as follows: 144 | 145 | parameters: 146 | database_driver: pdo_mysql 147 | database_host: localhost 148 | database_port: ~ 149 | database_name: symfony 150 | database_user: root 151 | database_password: ~ 152 | 153 | mailer_transport: smtp 154 | mailer_host: localhost 155 | mailer_user: ~ 156 | mailer_password: ~ 157 | 158 | locale: en 159 | secret: ThisTokenIsNotSoSecretChangeIt 160 | 161 | Note that if you convert your parameters file to YAML, you must also change 162 | its reference in `app/config/config.yml`. 163 | 164 | ### `app/config/routing_dev.yml` 165 | 166 | The `_assetic` entry was removed: 167 | 168 | #_assetic: 169 | # resource: . 170 | # type: assetic 171 | 172 | ### `app/config/security.yml` 173 | 174 | Under `security.access_control`, the default rule for internal routes was changed: 175 | 176 | security: 177 | access_control: 178 | #- { path: ^/_internal/secure, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 } 179 | 180 | Under `security.providers`, the `in_memory` example was updated to the following: 181 | 182 | security: 183 | providers: 184 | in_memory: 185 | memory: 186 | users: 187 | user: { password: userpass, roles: [ 'ROLE_USER' ] } 188 | admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } 189 | 190 | ### `app/AppKernel.php` 191 | 192 | The following bundles have been added to the list of default registered bundles: 193 | 194 | new JMS\AopBundle\JMSAopBundle(), 195 | new JMS\DiExtraBundle\JMSDiExtraBundle($this), 196 | 197 | You must also rename the DoctrineBundle from: 198 | 199 | new Symfony\Bundle\DoctrineBundle\DoctrineBundle(), 200 | 201 | to: 202 | 203 | new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(), 204 | 205 | ### `web/app.php` 206 | 207 | The default `web/app.php` file now reads as follows: 208 | 209 | register(true); 222 | */ 223 | 224 | require_once __DIR__.'/../app/AppKernel.php'; 225 | //require_once __DIR__.'/../app/AppCache.php'; 226 | 227 | $kernel = new AppKernel('prod', false); 228 | $kernel->loadClassCache(); 229 | //$kernel = new AppCache($kernel); 230 | $request = Request::createFromGlobals(); 231 | $response = $kernel->handle($request); 232 | $response->send(); 233 | $kernel->terminate($request, $response); 234 | 235 | ### `web/app_dev.php` 236 | 237 | The default `web/app_dev.php` file now reads as follows: 238 | 239 | loadClassCache(); 265 | $request = Request::createFromGlobals(); 266 | $response = $kernel->handle($request); 267 | $response->send(); 268 | $kernel->terminate($request, $response); 269 | -------------------------------------------------------------------------------- /Symfony/app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | 3 | -------------------------------------------------------------------------------- /Symfony/app/AppCache.php: -------------------------------------------------------------------------------- 1 | getEnvironment(), array('dev', 'test'))) { 23 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); 24 | $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); 25 | $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); 26 | } 27 | 28 | return $bundles; 29 | } 30 | 31 | public function registerContainerConfiguration(LoaderInterface $loader) 32 | { 33 | $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyc 3 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/complete.py: -------------------------------------------------------------------------------- 1 | # should configure PYTHONPATH environment variable at /etc/apache2/envvars 2 | from clang import cindex 3 | from logger import * 4 | 5 | def convert_diagnostics(cx_diagnostics): 6 | diagnostics = [] 7 | for i in range(len(cx_diagnostics)): 8 | diagnostics.append(Diagnostic(cx_diagnostics[i])) 9 | return diagnostics 10 | 11 | def convert_ccr_structure(ccr_structure): 12 | results = [] 13 | for i in range(ccr_structure.numResults): 14 | results.append(Result(ccr_structure.results[i])) 15 | 16 | return results 17 | 18 | class Diagnostic(object): 19 | def __init__(self, cx_diagnostic): 20 | self.cx_diagnostic = cx_diagnostic 21 | 22 | self.severity = cx_diagnostic.severity 23 | self.file = self.cx_diagnostic.location.file.name 24 | self.line = self.cx_diagnostic.location.line 25 | self.column = self.cx_diagnostic.location.column 26 | self.message = self.cx_diagnostic.spelling 27 | 28 | class CursorKind(object): 29 | def __init__(self, cx_cursor_kind): 30 | self.cx_cursor_kind = cx_cursor_kind 31 | 32 | self.name = cx_cursor_kind.name 33 | self.value = cx_cursor_kind.value 34 | self.is_declaration = cx_cursor_kind.is_declaration() 35 | self.is_reference = cx_cursor_kind.is_reference() 36 | self.is_expression = cx_cursor_kind.is_expression() 37 | self.is_statement = cx_cursor_kind.is_statement() 38 | self.is_attribute = cx_cursor_kind.is_attribute() 39 | self.is_invalid = cx_cursor_kind.is_invalid() 40 | self.is_translation_unit = cx_cursor_kind.is_translation_unit() 41 | self.is_preprocessing = cx_cursor_kind.is_preprocessing() 42 | self.is_unexposed = cx_cursor_kind.is_unexposed() 43 | 44 | class Chunk(object): 45 | def __init__(self, cx_completion_chunk): 46 | self.cx_completion_chunk = cx_completion_chunk 47 | 48 | self.kind = cx_completion_chunk.kind.name 49 | self.spelling = cx_completion_chunk.spelling 50 | 51 | self.is_kind_optional = cx_completion_chunk.isKindOptional() 52 | self.is_kind_typed_text = cx_completion_chunk.isKindTypedText() 53 | self.is_kind_place_holder = cx_completion_chunk.isKindPlaceHolder() 54 | self.is_kind_informative = cx_completion_chunk.isKindInformative() 55 | self.is_kind_result_type = cx_completion_chunk.isKindResultType() 56 | 57 | self.string = None 58 | if cx_completion_chunk.string is not None: 59 | self.string = String(cx_completion_chunk.string) 60 | 61 | """ 62 | availability: Available, Deprecated, NotAvailable, NotAccessible 63 | priority: 0 - 100 (smaller values mean more likely to select) 64 | 65 | """ 66 | class String(object): 67 | def __init__(self, cx_completion_string): 68 | self.cx_completion_string = cx_completion_string 69 | 70 | self.priority = cx_completion_string.priority 71 | self.availability = cx_completion_string.availability.name 72 | self.briefComment = cx_completion_string.briefComment.spelling 73 | 74 | self.typed_chunk = None 75 | self.chunks = [] 76 | for i in range(cx_completion_string.num_chunks): 77 | chunk = Chunk(cx_completion_string[i]) 78 | 79 | if chunk.is_kind_typed_text: 80 | self.typed_chunk = chunk 81 | 82 | self.chunks.append(chunk) 83 | 84 | def startswith(self, prefix, case_insensitive=True): 85 | if self.typed_chunk is None: 86 | return True 87 | 88 | spelling = self.typed_chunk.spelling 89 | 90 | if case_insensitive: 91 | prefix = prefix.lower() 92 | spelling = spelling.lower() 93 | 94 | return spelling.startswith(prefix) 95 | 96 | def contains(self, sub, case_insensitive=True): 97 | if self.typed_chunk is None: 98 | return True 99 | 100 | spelling = self.typed_chunk.spelling 101 | 102 | if case_insensitive: 103 | sub = sub.lower() 104 | spelling = spelling.lower() 105 | 106 | return sub in spelling 107 | 108 | class Result(object): 109 | def __init__(self, cx_code_completion_result): 110 | self.cx_code_completion_result = cx_code_completion_result 111 | 112 | self.cursor_kind = CursorKind(cx_code_completion_result.kind) 113 | self.string = String(cx_code_completion_result.string) 114 | 115 | def startswith(self, prefix, case_insensitive=True): 116 | return self.string.startswith(prefix, case_insensitive) 117 | 118 | def contains(self, sub, case_insensitive=True): 119 | return self.string.contains(sub, case_insensitive) 120 | 121 | class CodeCompletionResults(object): 122 | def __init__(self, cx_code_completion_results): 123 | self.cx_code_completion_results = cx_code_completion_results 124 | 125 | self.diagnostics = \ 126 | convert_diagnostics(cx_code_completion_results.diagnostics) 127 | 128 | self.results = \ 129 | convert_ccr_structure(cx_code_completion_results.results) 130 | 131 | class Completer(object): 132 | def __init__(self, fname, line, column, args): 133 | self.fname = fname 134 | self.line = line 135 | self.column = column 136 | self.args = args 137 | 138 | try: 139 | self.TU = cindex.TranslationUnit.from_source(fname, args) 140 | except cindex.TranslationUnitLoadError: 141 | log_error(COMPL_TU_LOAD) 142 | 143 | self.code_completion = \ 144 | self.TU.codeComplete(self.fname, self.line, self.column, include_macros=True) 145 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/logger.py: -------------------------------------------------------------------------------- 1 | import sys, syslog 2 | 3 | # number 1 is reserved for clang 4 | REQ_IO_ERROR = 2 5 | REQ_JSON_LOADS_ERROR = 3 6 | REQ_KEY_ERROR = 4 7 | REQ_ATTRIB_ERROR = 5 8 | REQ_INV_TYPES = 6 9 | COMPL_TU_LOAD = 7 10 | IVK_WRONG_NUM_ARGS = 8 11 | 12 | ERR_EXCEPTION = 9 13 | 14 | def log_error(exit_code, msg=""): 15 | s = "" 16 | 17 | if exit_code == REQ_IO_ERROR: 18 | s = "REQ_IO_ERROR" \ 19 | "JSON input file reading failed!" 20 | elif exit_code == REQ_JSON_LOADS_ERROR: 21 | s = "REQ_JSON_LOADS_ERROR: " \ 22 | "python's JSON module failed to convert input JSON file to dict" 23 | elif exit_code == REQ_KEY_ERROR: 24 | s = "REQ_KEY_ERROR: " \ 25 | "The JSON request is missing some key (see _parse_json_data)" 26 | elif exit_code == REQ_ATTRIB_ERROR: 27 | s = "REQ_ATTRIB_ERROR: " \ 28 | "JSON's 'command' key is not a split-able string (see _parse_json_data" 29 | elif exit_code == REQ_INV_TYPES: 30 | s = " REQ_INV_TYPES: " \ 31 | "Bad type of values in input JSON file (see _parse_json_data)" 32 | elif exit_code == COMPL_TU_LOAD: 33 | s = "COMPL_TU_LOAD: " \ 34 | "Clang failed to load the translation unit" 35 | elif exit_code == IVK_WRONG_NUM_ARGS: 36 | s = "INVK_WRONG_NUM_ARGS: " \ 37 | "The python script has been invoked with wrong arguments" \ 38 | "Usage: ./autocomplete number_of_results path_to_compiler_json" 39 | elif exit_code == ERR_EXCEPTION: 40 | s = "ERR_EXCEPTION: " \ 41 | "Unknown exception thrown." 42 | 43 | 44 | syslog.syslog(s + '\n' + msg) 45 | sys.exit(exit_code) 46 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/main.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from logger import * 3 | from request import Request 4 | 5 | if __name__ == "__main__": 6 | if len(sys.argv) != 3: 7 | log_error(IVK_WRONG_NUM_ARGS) 8 | 9 | # use the syslog utility instead of stderr 10 | try: 11 | request = Request(sys.argv[2]) 12 | response = request.get_response() 13 | except Exception as e: 14 | log_error(ERR_EXCEPTION, e.message) 15 | 16 | print response.toJSON(int(sys.argv[1])) 17 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/request.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from complete import Completer, CodeCompletionResults 4 | from response import Response 5 | from logger import * 6 | 7 | def _read_json_file(p): 8 | try: 9 | with open(p, 'r') as f: 10 | s = f.read() 11 | except IOError as e: 12 | log_error(REQ_IO_ERROR) 13 | 14 | return s 15 | 16 | def _load_json_string(s): 17 | try: 18 | d = json.loads(s) 19 | except: 20 | log_error(REQ_JSON_LOADS_ERROR) 21 | 22 | return d 23 | 24 | def _parse_json_data(d): 25 | try: 26 | fname = d['file'] 27 | line = d['row']; 28 | column = d['column']; 29 | prefix = d['prefix']; 30 | cmd = d['command'].split() 31 | 32 | valid = (isinstance(fname, str) or isinstance(fname, unicode)) and \ 33 | (isinstance(cmd[0], str) or isinstance(cmd[0], unicode)) and \ 34 | (isinstance(prefix, str) or isinstance(prefix, unicode)) and \ 35 | isinstance(line, int) and (isinstance(column, int)) 36 | if not valid: 37 | log_error(REQ_INV_TYPES) 38 | except KeyError as e: 39 | log_error(REQ_KEY_ERROR) 40 | except AttributeError as e: 41 | log_error(REQ_ATTRIB_ERROR) 42 | 43 | # Remove single quotes in filenames and update column position 44 | # base on the prefix's length 45 | return (fname.replace("'", ""), line, column - len(prefix), prefix, 46 | [str(x.replace("'", "")) for x in cmd]) 47 | 48 | def correct_clang_arguments(fname, args): 49 | clang_args = ['-c ' + fname] 50 | 51 | # find includes & defines 52 | for arg in args: 53 | if arg.startswith('-I') or arg.startswith('-D'): 54 | clang_args.append(arg) 55 | 56 | return clang_args 57 | 58 | def file_len(fname): 59 | with open(fname) as f: 60 | for i, l in enumerate(f): 61 | pass 62 | return i + 1 63 | 64 | def has_ino_origin(fname): 65 | import os.path 66 | 67 | return (fname.endswith('.cpp') or fname.endswith('.c')) and \ 68 | os.path.isfile(fname[:-4] + '.ino') 69 | 70 | def calculate_line_diff(fname): 71 | ln_diff = 0 72 | 73 | # if the cpp file was produced from an ino file 74 | # we need to calculate the correct line difference 75 | if has_ino_origin(fname): 76 | cpp_lines = file_len(fname) 77 | ino_lines = file_len(fname[:-4] + '.ino') 78 | ln_diff = cpp_lines - ino_lines 79 | 80 | return ln_diff 81 | 82 | class Request(object): 83 | def __init__(self, path): 84 | s = _read_json_file(path) 85 | d = _load_json_string(s) 86 | self.fname, self.line, self.column, self.prefix, cmd = _parse_json_data(d) 87 | self.args = correct_clang_arguments(self.fname, cmd) 88 | 89 | def get_response(self): 90 | self.line = self.line + calculate_line_diff(self.fname) 91 | 92 | completer = Completer(self.fname, self.line, self.column, self.args) 93 | code_completion = CodeCompletionResults(completer.code_completion) 94 | 95 | return Response(code_completion, self.prefix); 96 | 97 | def __str__(self): 98 | ret = '' 99 | ret = ret + 'file name: ' + self.fname + '\n' 100 | ret = ret + 'line: ' + str(self.line) + '\n' 101 | ret = ret + 'column: ' + str(self.column) + '\n' 102 | ret = ret + 'prefix: ' + str(self.prefix) + '\n' 103 | 104 | ret = ret + 'args:\n' 105 | for arg in self.args: 106 | ret = ret + '\t' + arg + '\n' 107 | 108 | return ret 109 | -------------------------------------------------------------------------------- /Symfony/app/Resources/autocompletion/response.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def get_entry_availability(availability): 4 | if availability == "Available": 5 | return "public" 6 | 7 | return "private" 8 | 9 | # ignore optional chunks for now since the ace editor doesn't 10 | # allow the same value attached to multiple captions 11 | def get_value_caption(string): 12 | caption = "" 13 | 14 | for chunk in string.chunks: 15 | if chunk.kind == "Equal" or chunk.kind == "ResultType": 16 | caption = caption + chunk.spelling + " " 17 | else: 18 | caption = caption + chunk.spelling 19 | 20 | # in the rather unfortunate case where the string doesn't 21 | # contain any typed text (!!!), we use the caption itself 22 | if string.typed_chunk is None: 23 | value = caption 24 | else: 25 | value = string.typed_chunk.spelling 26 | 27 | return (value, caption) 28 | 29 | 30 | class Entry(object): 31 | def __init__(self, result): 32 | self.priority = result.string.priority 33 | self.availability = get_entry_availability(result.string.availability) 34 | self.value, self.caption = get_value_caption(result.string) 35 | 36 | def to_dict(self): 37 | return { 38 | 'v': self.value, 39 | 'c': self.caption, 40 | 'm': self.availability, 41 | 's': self.priority 42 | } 43 | 44 | def get_results_with_prefix(results, prefix): 45 | return [r for r in results if r.startswith(prefix)] 46 | 47 | class Response(object): 48 | def __init__(self, code_completion, prefix): 49 | self.code_completion = code_completion 50 | self.prefix = prefix 51 | 52 | def toJSON(self, number_of_results=100): 53 | results = self.code_completion.results 54 | 55 | # get the results which have the specified prefix 56 | results = [ 57 | res for res in results if res.startswith(self.prefix) 58 | ] 59 | 60 | # sort them in-place by priority 61 | results.sort(key=lambda res: res.string.priority) 62 | 63 | # trim the final number of results 64 | self.code_completion.results = results[:number_of_results] 65 | 66 | # get the final entries 67 | entries = [Entry(r).to_dict() for r in self.code_completion.results] 68 | 69 | return json.dumps(entries) 70 | -------------------------------------------------------------------------------- /Symfony/app/Resources/views/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {% block title %}Welcome!{% endblock %} 6 | {% block stylesheets %}{% endblock %} 7 | 8 | 9 | 10 | {% block body %}{% endblock %} 11 | {% block javascripts %}{% endblock %} 12 | 13 | 14 | -------------------------------------------------------------------------------- /Symfony/app/SymfonyRequirements.php: -------------------------------------------------------------------------------- 1 | 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */ 11 | 12 | /* 13 | * Users of PHP 5.2 should be able to run the requirements checks. 14 | * This is why the file and all classes must be compatible with PHP 5.2+ 15 | * (e.g. not using namespaces and closures). 16 | * 17 | * ************** CAUTION ************** 18 | * 19 | * DO NOT EDIT THIS FILE as it will be overridden by Composer as part of 20 | * the installation/update process. The original file resides in the 21 | * SensioDistributionBundle. 22 | * 23 | * ************** CAUTION ************** 24 | */ 25 | 26 | /** 27 | * Represents a single PHP requirement, e.g. an installed extension. 28 | * It can be a mandatory requirement or an optional recommendation. 29 | * There is a special subclass, named PhpIniRequirement, to check a php.ini configuration. 30 | * 31 | * @author Tobias Schultze 32 | */ 33 | class Requirement 34 | { 35 | private $fulfilled; 36 | private $testMessage; 37 | private $helpText; 38 | private $helpHtml; 39 | private $optional; 40 | 41 | /** 42 | * Constructor that initializes the requirement. 43 | * 44 | * @param Boolean $fulfilled Whether the requirement is fulfilled 45 | * @param string $testMessage The message for testing the requirement 46 | * @param string $helpHtml The help text formatted in HTML for resolving the problem 47 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 48 | * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement 49 | */ 50 | public function __construct($fulfilled, $testMessage, $helpHtml, $helpText = null, $optional = false) 51 | { 52 | $this->fulfilled = (Boolean) $fulfilled; 53 | $this->testMessage = (string) $testMessage; 54 | $this->helpHtml = (string) $helpHtml; 55 | $this->helpText = null === $helpText ? strip_tags($this->helpHtml) : (string) $helpText; 56 | $this->optional = (Boolean) $optional; 57 | } 58 | 59 | /** 60 | * Returns whether the requirement is fulfilled. 61 | * 62 | * @return Boolean true if fulfilled, otherwise false 63 | */ 64 | public function isFulfilled() 65 | { 66 | return $this->fulfilled; 67 | } 68 | 69 | /** 70 | * Returns the message for testing the requirement. 71 | * 72 | * @return string The test message 73 | */ 74 | public function getTestMessage() 75 | { 76 | return $this->testMessage; 77 | } 78 | 79 | /** 80 | * Returns the help text for resolving the problem. 81 | * 82 | * @return string The help text 83 | */ 84 | public function getHelpText() 85 | { 86 | return $this->helpText; 87 | } 88 | 89 | /** 90 | * Returns the help text formatted in HTML. 91 | * 92 | * @return string The HTML help 93 | */ 94 | public function getHelpHtml() 95 | { 96 | return $this->helpHtml; 97 | } 98 | 99 | /** 100 | * Returns whether this is only an optional recommendation and not a mandatory requirement. 101 | * 102 | * @return Boolean true if optional, false if mandatory 103 | */ 104 | public function isOptional() 105 | { 106 | return $this->optional; 107 | } 108 | } 109 | 110 | /** 111 | * Represents a PHP requirement in form of a php.ini configuration. 112 | * 113 | * @author Tobias Schultze 114 | */ 115 | class PhpIniRequirement extends Requirement 116 | { 117 | /** 118 | * Constructor that initializes the requirement. 119 | * 120 | * @param string $cfgName The configuration name used for ini_get() 121 | * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, 122 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement 123 | * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. 124 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. 125 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. 126 | * @param string|null $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) 127 | * @param string|null $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) 128 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 129 | * @param Boolean $optional Whether this is only an optional recommendation not a mandatory requirement 130 | */ 131 | public function __construct($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null, $optional = false) 132 | { 133 | $cfgValue = ini_get($cfgName); 134 | 135 | if (is_callable($evaluation)) { 136 | if (null === $testMessage || null === $helpHtml) { 137 | throw new InvalidArgumentException('You must provide the parameters testMessage and helpHtml for a callback evaluation.'); 138 | } 139 | 140 | $fulfilled = call_user_func($evaluation, $cfgValue); 141 | } else { 142 | if (null === $testMessage) { 143 | $testMessage = sprintf('%s %s be %s in php.ini', 144 | $cfgName, 145 | $optional ? 'should' : 'must', 146 | $evaluation ? 'enabled' : 'disabled' 147 | ); 148 | } 149 | 150 | if (null === $helpHtml) { 151 | $helpHtml = sprintf('Set %s to %s in php.ini*.', 152 | $cfgName, 153 | $evaluation ? 'on' : 'off' 154 | ); 155 | } 156 | 157 | $fulfilled = $evaluation == $cfgValue; 158 | } 159 | 160 | parent::__construct($fulfilled || ($approveCfgAbsence && false === $cfgValue), $testMessage, $helpHtml, $helpText, $optional); 161 | } 162 | } 163 | 164 | /** 165 | * A RequirementCollection represents a set of Requirement instances. 166 | * 167 | * @author Tobias Schultze 168 | */ 169 | class RequirementCollection implements IteratorAggregate 170 | { 171 | private $requirements = array(); 172 | 173 | /** 174 | * Gets the current RequirementCollection as an Iterator. 175 | * 176 | * @return Traversable A Traversable interface 177 | */ 178 | public function getIterator() 179 | { 180 | return new ArrayIterator($this->requirements); 181 | } 182 | 183 | /** 184 | * Adds a Requirement. 185 | * 186 | * @param Requirement $requirement A Requirement instance 187 | */ 188 | public function add(Requirement $requirement) 189 | { 190 | $this->requirements[] = $requirement; 191 | } 192 | 193 | /** 194 | * Adds a mandatory requirement. 195 | * 196 | * @param Boolean $fulfilled Whether the requirement is fulfilled 197 | * @param string $testMessage The message for testing the requirement 198 | * @param string $helpHtml The help text formatted in HTML for resolving the problem 199 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 200 | */ 201 | public function addRequirement($fulfilled, $testMessage, $helpHtml, $helpText = null) 202 | { 203 | $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, false)); 204 | } 205 | 206 | /** 207 | * Adds an optional recommendation. 208 | * 209 | * @param Boolean $fulfilled Whether the recommendation is fulfilled 210 | * @param string $testMessage The message for testing the recommendation 211 | * @param string $helpHtml The help text formatted in HTML for resolving the problem 212 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 213 | */ 214 | public function addRecommendation($fulfilled, $testMessage, $helpHtml, $helpText = null) 215 | { 216 | $this->add(new Requirement($fulfilled, $testMessage, $helpHtml, $helpText, true)); 217 | } 218 | 219 | /** 220 | * Adds a mandatory requirement in form of a php.ini configuration. 221 | * 222 | * @param string $cfgName The configuration name used for ini_get() 223 | * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, 224 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement 225 | * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. 226 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. 227 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. 228 | * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) 229 | * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) 230 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 231 | */ 232 | public function addPhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) 233 | { 234 | $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, false)); 235 | } 236 | 237 | /** 238 | * Adds an optional recommendation in form of a php.ini configuration. 239 | * 240 | * @param string $cfgName The configuration name used for ini_get() 241 | * @param Boolean|callback $evaluation Either a Boolean indicating whether the configuration should evaluate to true or false, 242 | * or a callback function receiving the configuration value as parameter to determine the fulfillment of the requirement 243 | * @param Boolean $approveCfgAbsence If true the Requirement will be fulfilled even if the configuration option does not exist, i.e. ini_get() returns false. 244 | * This is helpful for abandoned configs in later PHP versions or configs of an optional extension, like Suhosin. 245 | * Example: You require a config to be true but PHP later removes this config and defaults it to true internally. 246 | * @param string $testMessage The message for testing the requirement (when null and $evaluation is a Boolean a default message is derived) 247 | * @param string $helpHtml The help text formatted in HTML for resolving the problem (when null and $evaluation is a Boolean a default help is derived) 248 | * @param string|null $helpText The help text (when null, it will be inferred from $helpHtml, i.e. stripped from HTML tags) 249 | */ 250 | public function addPhpIniRecommendation($cfgName, $evaluation, $approveCfgAbsence = false, $testMessage = null, $helpHtml = null, $helpText = null) 251 | { 252 | $this->add(new PhpIniRequirement($cfgName, $evaluation, $approveCfgAbsence, $testMessage, $helpHtml, $helpText, true)); 253 | } 254 | 255 | /** 256 | * Adds a requirement collection to the current set of requirements. 257 | * 258 | * @param RequirementCollection $collection A RequirementCollection instance 259 | */ 260 | public function addCollection(RequirementCollection $collection) 261 | { 262 | $this->requirements = array_merge($this->requirements, $collection->all()); 263 | } 264 | 265 | /** 266 | * Returns both requirements and recommendations. 267 | * 268 | * @return array Array of Requirement instances 269 | */ 270 | public function all() 271 | { 272 | return $this->requirements; 273 | } 274 | 275 | /** 276 | * Returns all mandatory requirements. 277 | * 278 | * @return array Array of Requirement instances 279 | */ 280 | public function getRequirements() 281 | { 282 | $array = array(); 283 | foreach ($this->requirements as $req) { 284 | if (!$req->isOptional()) { 285 | $array[] = $req; 286 | } 287 | } 288 | 289 | return $array; 290 | } 291 | 292 | /** 293 | * Returns the mandatory requirements that were not met. 294 | * 295 | * @return array Array of Requirement instances 296 | */ 297 | public function getFailedRequirements() 298 | { 299 | $array = array(); 300 | foreach ($this->requirements as $req) { 301 | if (!$req->isFulfilled() && !$req->isOptional()) { 302 | $array[] = $req; 303 | } 304 | } 305 | 306 | return $array; 307 | } 308 | 309 | /** 310 | * Returns all optional recommendations. 311 | * 312 | * @return array Array of Requirement instances 313 | */ 314 | public function getRecommendations() 315 | { 316 | $array = array(); 317 | foreach ($this->requirements as $req) { 318 | if ($req->isOptional()) { 319 | $array[] = $req; 320 | } 321 | } 322 | 323 | return $array; 324 | } 325 | 326 | /** 327 | * Returns the recommendations that were not met. 328 | * 329 | * @return array Array of Requirement instances 330 | */ 331 | public function getFailedRecommendations() 332 | { 333 | $array = array(); 334 | foreach ($this->requirements as $req) { 335 | if (!$req->isFulfilled() && $req->isOptional()) { 336 | $array[] = $req; 337 | } 338 | } 339 | 340 | return $array; 341 | } 342 | 343 | /** 344 | * Returns whether a php.ini configuration is not correct. 345 | * 346 | * @return Boolean php.ini configuration problem? 347 | */ 348 | public function hasPhpIniConfigIssue() 349 | { 350 | foreach ($this->requirements as $req) { 351 | if (!$req->isFulfilled() && $req instanceof PhpIniRequirement) { 352 | return true; 353 | } 354 | } 355 | 356 | return false; 357 | } 358 | 359 | /** 360 | * Returns the PHP configuration file (php.ini) path. 361 | * 362 | * @return string|false php.ini file path 363 | */ 364 | public function getPhpIniConfigPath() 365 | { 366 | return get_cfg_var('cfg_file_path'); 367 | } 368 | } 369 | 370 | /** 371 | * This class specifies all requirements and optional recommendations that 372 | * are necessary to run the Symfony Standard Edition. 373 | * 374 | * @author Tobias Schultze 375 | * @author Fabien Potencier 376 | */ 377 | class SymfonyRequirements extends RequirementCollection 378 | { 379 | const REQUIRED_PHP_VERSION = '5.3.3'; 380 | 381 | /** 382 | * Constructor that initializes the requirements. 383 | */ 384 | public function __construct() 385 | { 386 | /* mandatory requirements follow */ 387 | 388 | $installedPhpVersion = phpversion(); 389 | 390 | $this->addRequirement( 391 | version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>='), 392 | sprintf('PHP version must be at least %s (%s installed)', self::REQUIRED_PHP_VERSION, $installedPhpVersion), 393 | sprintf('You are running PHP version "%s", but Symfony needs at least PHP "%s" to run. 394 | Before using Symfony, upgrade your PHP installation, preferably to the latest version.', 395 | $installedPhpVersion, self::REQUIRED_PHP_VERSION), 396 | sprintf('Install PHP %s or newer (installed version is %s)', self::REQUIRED_PHP_VERSION, $installedPhpVersion) 397 | ); 398 | 399 | $this->addRequirement( 400 | version_compare($installedPhpVersion, '5.3.16', '!='), 401 | 'PHP version must not be 5.3.16 as Symfony won\'t work properly with it', 402 | 'Install PHP 5.3.17 or newer (or downgrade to an earlier PHP version)' 403 | ); 404 | 405 | $this->addRequirement( 406 | is_dir(__DIR__.'/../vendor/composer'), 407 | 'Vendor libraries must be installed', 408 | 'Vendor libraries are missing. Install composer following instructions from http://getcomposer.org/. ' . 409 | 'Then run "php composer.phar install" to install them.' 410 | ); 411 | 412 | $baseDir = basename(__DIR__); 413 | 414 | $this->addRequirement( 415 | is_writable(__DIR__.'/cache'), 416 | "$baseDir/cache/ directory must be writable", 417 | "Change the permissions of the \"$baseDir/cache/\" directory so that the web server can write into it." 418 | ); 419 | 420 | $this->addRequirement( 421 | is_writable(__DIR__.'/logs'), 422 | "$baseDir/logs/ directory must be writable", 423 | "Change the permissions of the \"$baseDir/logs/\" directory so that the web server can write into it." 424 | ); 425 | 426 | $this->addPhpIniRequirement( 427 | 'date.timezone', true, false, 428 | 'date.timezone setting must be set', 429 | 'Set the "date.timezone" setting in php.ini* (like Europe/Paris).' 430 | ); 431 | 432 | if (version_compare($installedPhpVersion, self::REQUIRED_PHP_VERSION, '>=')) { 433 | $timezones = array(); 434 | foreach (DateTimeZone::listAbbreviations() as $abbreviations) { 435 | foreach ($abbreviations as $abbreviation) { 436 | $timezones[$abbreviation['timezone_id']] = true; 437 | } 438 | } 439 | 440 | $this->addRequirement( 441 | isset($timezones[date_default_timezone_get()]), 442 | sprintf('Configured default timezone "%s" must be supported by your installation of PHP', date_default_timezone_get()), 443 | 'Your default timezone is not supported by PHP. Check for typos in your php.ini file and have a look at the list of deprecated timezones at http://php.net/manual/en/timezones.others.php.' 444 | ); 445 | } 446 | 447 | $this->addRequirement( 448 | function_exists('json_encode'), 449 | 'json_encode() must be available', 450 | 'Install and enable the JSON extension.' 451 | ); 452 | 453 | $this->addRequirement( 454 | function_exists('session_start'), 455 | 'session_start() must be available', 456 | 'Install and enable the session extension.' 457 | ); 458 | 459 | $this->addRequirement( 460 | function_exists('ctype_alpha'), 461 | 'ctype_alpha() must be available', 462 | 'Install and enable the ctype extension.' 463 | ); 464 | 465 | $this->addRequirement( 466 | function_exists('token_get_all'), 467 | 'token_get_all() must be available', 468 | 'Install and enable the Tokenizer extension.' 469 | ); 470 | 471 | $this->addRequirement( 472 | function_exists('simplexml_import_dom'), 473 | 'simplexml_import_dom() must be available', 474 | 'Install and enable the SimpleXML extension.' 475 | ); 476 | 477 | if (function_exists('apc_store') && ini_get('apc.enabled')) { 478 | if (version_compare($installedPhpVersion, '5.4.0', '>=')) { 479 | $this->addRequirement( 480 | version_compare(phpversion('apc'), '3.1.13', '>='), 481 | 'APC version must be at least 3.1.13 when using PHP 5.4', 482 | 'Upgrade your APC extension (3.1.13+).' 483 | ); 484 | } else { 485 | $this->addRequirement( 486 | version_compare(phpversion('apc'), '3.0.17', '>='), 487 | 'APC version must be at least 3.0.17', 488 | 'Upgrade your APC extension (3.0.17+).' 489 | ); 490 | } 491 | } 492 | 493 | $this->addPhpIniRequirement('detect_unicode', false); 494 | 495 | if (extension_loaded('suhosin')) { 496 | $this->addPhpIniRequirement( 497 | 'suhosin.executor.include.whitelist', 498 | create_function('$cfgValue', 'return false !== stripos($cfgValue, "phar");'), 499 | false, 500 | 'suhosin.executor.include.whitelist must be configured correctly in php.ini', 501 | 'Add "phar" to suhosin.executor.include.whitelist in php.ini*.' 502 | ); 503 | } 504 | 505 | if (extension_loaded('xdebug')) { 506 | $this->addPhpIniRequirement( 507 | 'xdebug.show_exception_trace', false, true 508 | ); 509 | 510 | $this->addPhpIniRequirement( 511 | 'xdebug.scream', false, true 512 | ); 513 | 514 | $this->addPhpIniRecommendation( 515 | 'xdebug.max_nesting_level', 516 | create_function('$cfgValue', 'return $cfgValue > 100;'), 517 | true, 518 | 'xdebug.max_nesting_level should be above 100 in php.ini', 519 | 'Set "xdebug.max_nesting_level" to e.g. "250" in php.ini* to stop Xdebug\'s infinite recursion protection erroneously throwing a fatal error in your project.' 520 | ); 521 | } 522 | 523 | $pcreVersion = defined('PCRE_VERSION') ? (float) PCRE_VERSION : null; 524 | 525 | $this->addRequirement( 526 | null !== $pcreVersion, 527 | 'PCRE extension must be available', 528 | 'Install the PCRE extension (version 8.0+).' 529 | ); 530 | 531 | /* optional recommendations follow */ 532 | 533 | if (file_exists(__DIR__.'/../vendor/composer')) { 534 | require_once __DIR__.'/../vendor/autoload.php'; 535 | 536 | try { 537 | $r = new \ReflectionClass('Sensio\Bundle\DistributionBundle\SensioDistributionBundle'); 538 | 539 | $contents = file_get_contents(dirname($r->getFileName()).'/Resources/skeleton/app/SymfonyRequirements.php'); 540 | } catch (\ReflectionException $e) { 541 | $contents = ''; 542 | } 543 | $this->addRecommendation( 544 | file_get_contents(__FILE__) === $contents, 545 | 'Requirements file should be up-to-date', 546 | 'Your requirements file is outdated. Run composer install and re-check your configuration.' 547 | ); 548 | } 549 | 550 | $this->addRecommendation( 551 | version_compare($installedPhpVersion, '5.3.4', '>='), 552 | 'You should use at least PHP 5.3.4 due to PHP bug #52083 in earlier versions', 553 | 'Your project might malfunction randomly due to PHP bug #52083 ("Notice: Trying to get property of non-object"). Install PHP 5.3.4 or newer.' 554 | ); 555 | 556 | $this->addRecommendation( 557 | version_compare($installedPhpVersion, '5.3.8', '>='), 558 | 'When using annotations you should have at least PHP 5.3.8 due to PHP bug #55156', 559 | 'Install PHP 5.3.8 or newer if your project uses annotations.' 560 | ); 561 | 562 | $this->addRecommendation( 563 | version_compare($installedPhpVersion, '5.4.0', '!='), 564 | 'You should not use PHP 5.4.0 due to the PHP bug #61453', 565 | 'Your project might not work properly due to the PHP bug #61453 ("Cannot dump definitions which have method calls"). Install PHP 5.4.1 or newer.' 566 | ); 567 | 568 | $this->addRecommendation( 569 | version_compare($installedPhpVersion, '5.4.11', '>='), 570 | 'When using the logout handler from the Symfony Security Component, you should have at least PHP 5.4.11 due to PHP bug #63379 (as a workaround, you can also set invalidate_session to false in the security logout handler configuration)', 571 | 'Install PHP 5.4.11 or newer if your project uses the logout handler from the Symfony Security Component.' 572 | ); 573 | 574 | $this->addRecommendation( 575 | (version_compare($installedPhpVersion, '5.3.18', '>=') && version_compare($installedPhpVersion, '5.4.0', '<')) 576 | || 577 | version_compare($installedPhpVersion, '5.4.8', '>='), 578 | 'You should use PHP 5.3.18+ or PHP 5.4.8+ to always get nice error messages for fatal errors in the development environment due to PHP bug #61767/#60909', 579 | 'Install PHP 5.3.18+ or PHP 5.4.8+ if you want nice error messages for all fatal errors in the development environment.' 580 | ); 581 | 582 | if (null !== $pcreVersion) { 583 | $this->addRecommendation( 584 | $pcreVersion >= 8.0, 585 | sprintf('PCRE extension should be at least version 8.0 (%s installed)', $pcreVersion), 586 | 'PCRE 8.0+ is preconfigured in PHP since 5.3.2 but you are using an outdated version of it. Symfony probably works anyway but it is recommended to upgrade your PCRE extension.' 587 | ); 588 | } 589 | 590 | $this->addRecommendation( 591 | class_exists('DomDocument'), 592 | 'PHP-DOM and PHP-XML modules should be installed', 593 | 'Install and enable the PHP-DOM and the PHP-XML modules.' 594 | ); 595 | 596 | $this->addRecommendation( 597 | function_exists('mb_strlen'), 598 | 'mb_strlen() should be available', 599 | 'Install and enable the mbstring extension.' 600 | ); 601 | 602 | $this->addRecommendation( 603 | function_exists('iconv'), 604 | 'iconv() should be available', 605 | 'Install and enable the iconv extension.' 606 | ); 607 | 608 | $this->addRecommendation( 609 | function_exists('utf8_decode'), 610 | 'utf8_decode() should be available', 611 | 'Install and enable the XML extension.' 612 | ); 613 | 614 | if (!defined('PHP_WINDOWS_VERSION_BUILD')) { 615 | $this->addRecommendation( 616 | function_exists('posix_isatty'), 617 | 'posix_isatty() should be available', 618 | 'Install and enable the php_posix extension (used to colorize the CLI output).' 619 | ); 620 | } 621 | 622 | $this->addRecommendation( 623 | class_exists('Locale'), 624 | 'intl extension should be available', 625 | 'Install and enable the intl extension (used for validators).' 626 | ); 627 | 628 | if (extension_loaded('intl')) { 629 | // in some WAMP server installations, new Collator() returns null 630 | $this->addRecommendation( 631 | null !== new Collator('fr_FR'), 632 | 'intl extension should be correctly configured', 633 | 'The intl extension does not behave properly. This problem is typical on PHP 5.3.X x64 WIN builds.' 634 | ); 635 | 636 | // check for compatible ICU versions (only done when you have the intl extension) 637 | if (defined('INTL_ICU_VERSION')) { 638 | $version = INTL_ICU_VERSION; 639 | } else { 640 | $reflector = new ReflectionExtension('intl'); 641 | 642 | ob_start(); 643 | $reflector->info(); 644 | $output = strip_tags(ob_get_clean()); 645 | 646 | preg_match('/^ICU version +(?:=> )?(.*)$/m', $output, $matches); 647 | $version = $matches[1]; 648 | } 649 | 650 | $this->addRecommendation( 651 | version_compare($version, '4.0', '>='), 652 | 'intl ICU version should be at least 4+', 653 | 'Upgrade your intl extension with a newer ICU version (4+).' 654 | ); 655 | 656 | $this->addPhpIniRecommendation( 657 | 'intl.error_level', 658 | create_function('$cfgValue', 'return (int) $cfgValue === 0;'), 659 | true, 660 | 'intl.error_level should be 0 in php.ini', 661 | 'Set "intl.error_level" to "0" in php.ini* to inhibit the messages when an error occurs in ICU functions.' 662 | ); 663 | } 664 | 665 | $accelerator = 666 | (extension_loaded('eaccelerator') && ini_get('eaccelerator.enable')) 667 | || 668 | (extension_loaded('apc') && ini_get('apc.enabled')) 669 | || 670 | (extension_loaded('Zend OPcache') && ini_get('opcache.enable')) 671 | || 672 | (extension_loaded('xcache') && ini_get('xcache.cacher')) 673 | || 674 | (extension_loaded('wincache') && ini_get('wincache.ocenabled')) 675 | ; 676 | 677 | $this->addRecommendation( 678 | $accelerator, 679 | 'a PHP accelerator should be installed', 680 | 'Install and enable a PHP accelerator like APC (highly recommended).' 681 | ); 682 | 683 | $this->addPhpIniRecommendation('short_open_tag', false); 684 | 685 | $this->addPhpIniRecommendation('magic_quotes_gpc', false, true); 686 | 687 | $this->addPhpIniRecommendation('register_globals', false, true); 688 | 689 | $this->addPhpIniRecommendation('session.auto_start', false); 690 | 691 | $this->addRecommendation( 692 | class_exists('PDO'), 693 | 'PDO should be installed', 694 | 'Install PDO (mandatory for Doctrine).' 695 | ); 696 | 697 | if (class_exists('PDO')) { 698 | $drivers = PDO::getAvailableDrivers(); 699 | $this->addRecommendation( 700 | count($drivers), 701 | sprintf('PDO should have some drivers installed (currently available: %s)', count($drivers) ? implode(', ', $drivers) : 'none'), 702 | 'Install PDO drivers (mandatory for Doctrine).' 703 | ); 704 | } 705 | } 706 | } 707 | -------------------------------------------------------------------------------- /Symfony/app/autoload.php: -------------------------------------------------------------------------------- 1 | getPhpIniConfigPath(); 8 | 9 | echo "********************************\n"; 10 | echo "* *\n"; 11 | echo "* Symfony requirements check *\n"; 12 | echo "* *\n"; 13 | echo "********************************\n\n"; 14 | 15 | echo $iniPath ? sprintf("* Configuration file used by PHP: %s\n\n", $iniPath) : "* WARNING: No configuration file (php.ini) used by PHP!\n\n"; 16 | 17 | echo "** ATTENTION **\n"; 18 | echo "* The PHP CLI can use a different php.ini file\n"; 19 | echo "* than the one used with your web server.\n"; 20 | if ('\\' == DIRECTORY_SEPARATOR) { 21 | echo "* (especially on the Windows platform)\n"; 22 | } 23 | echo "* To be on the safe side, please also launch the requirements check\n"; 24 | echo "* from your web server using the web/config.php script.\n"; 25 | 26 | echo_title('Mandatory requirements'); 27 | 28 | $checkPassed = true; 29 | foreach ($symfonyRequirements->getRequirements() as $req) { 30 | /** @var $req Requirement */ 31 | echo_requirement($req); 32 | if (!$req->isFulfilled()) { 33 | $checkPassed = false; 34 | } 35 | } 36 | 37 | echo_title('Optional recommendations'); 38 | 39 | foreach ($symfonyRequirements->getRecommendations() as $req) { 40 | echo_requirement($req); 41 | } 42 | 43 | exit($checkPassed ? 0 : 1); 44 | 45 | /** 46 | * Prints a Requirement instance 47 | */ 48 | function echo_requirement(Requirement $requirement) 49 | { 50 | $result = $requirement->isFulfilled() ? 'OK' : ($requirement->isOptional() ? 'WARNING' : 'ERROR'); 51 | echo ' ' . str_pad($result, 9); 52 | echo $requirement->getTestMessage() . "\n"; 53 | 54 | if (!$requirement->isFulfilled()) { 55 | echo sprintf(" %s\n\n", $requirement->getHelpText()); 56 | } 57 | } 58 | 59 | function echo_title($title) 60 | { 61 | echo "\n** $title **\n\n"; 62 | } 63 | -------------------------------------------------------------------------------- /Symfony/app/config/config.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: parameters.yml } 3 | - { resource: security.yml } 4 | 5 | framework: 6 | #esi: ~ 7 | #translator: { fallback: %locale% } 8 | secret: %secret% 9 | router: 10 | resource: "%kernel.root_dir%/config/routing.yml" 11 | strict_requirements: ~ 12 | form: ~ 13 | csrf_protection: ~ 14 | validation: { enable_annotations: true } 15 | templating: 16 | engines: ['twig'] 17 | #assets_version: SomeVersionScheme 18 | default_locale: "%locale%" 19 | trusted_proxies: ~ 20 | session: ~ 21 | fragments: ~ 22 | 23 | # Twig Configuration 24 | twig: 25 | debug: %kernel.debug% 26 | strict_variables: %kernel.debug% 27 | 28 | # Assetic Configuration 29 | assetic: 30 | debug: %kernel.debug% 31 | use_controller: false 32 | bundles: [ ] 33 | #java: /usr/bin/java 34 | filters: 35 | cssrewrite: ~ 36 | #closure: 37 | # jar: %kernel.root_dir%/Resources/java/compiler.jar 38 | #yui_css: 39 | # jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar 40 | # 41 | ## Doctrine Configuration 42 | #doctrine: 43 | # dbal: 44 | # driver: %database_driver% 45 | # host: %database_host% 46 | # port: %database_port% 47 | # dbname: %database_name% 48 | # user: %database_user% 49 | # password: %database_password% 50 | # charset: UTF8 51 | # # if using pdo_sqlite as your database driver, add the path in parameters.yml 52 | # # e.g. database_path: %kernel.root_dir%/data/data.db3 53 | # # path: %database_path% 54 | # 55 | # orm: 56 | # auto_generate_proxy_classes: %kernel.debug% 57 | # auto_mapping: true 58 | 59 | # Swiftmailer Configuration 60 | #swiftmailer: 61 | # transport: %mailer_transport% 62 | # host: %mailer_host% 63 | # username: %mailer_user% 64 | # password: %mailer_password% 65 | # spool: { type: memory } 66 | -------------------------------------------------------------------------------- /Symfony/app/config/config_dev.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | framework: 5 | router: 6 | resource: "%kernel.root_dir%/config/routing_dev.yml" 7 | strict_requirements: true 8 | profiler: { only_exceptions: false } 9 | 10 | web_profiler: 11 | toolbar: true 12 | intercept_redirects: false 13 | 14 | monolog: 15 | handlers: 16 | main: 17 | type: stream 18 | path: %kernel.logs_dir%/%kernel.environment%.log 19 | level: debug 20 | firephp: 21 | type: firephp 22 | level: info 23 | chromephp: 24 | type: chromephp 25 | level: info 26 | 27 | assetic: 28 | use_controller: true 29 | 30 | #swiftmailer: 31 | # delivery_address: me@example.com 32 | -------------------------------------------------------------------------------- /Symfony/app/config/config_prod.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config.yml } 3 | 4 | #framework: 5 | # validation: 6 | # cache: apc 7 | 8 | #doctrine: 9 | # orm: 10 | # metadata_cache_driver: apc 11 | # result_cache_driver: apc 12 | # query_cache_driver: apc 13 | 14 | monolog: 15 | handlers: 16 | main: 17 | type: fingers_crossed 18 | action_level: error 19 | handler: nested 20 | nested: 21 | type: stream 22 | path: %kernel.logs_dir%/%kernel.environment%.log 23 | level: debug 24 | -------------------------------------------------------------------------------- /Symfony/app/config/config_test.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: config_dev.yml } 3 | 4 | framework: 5 | test: ~ 6 | session: 7 | storage_id: session.storage.mock_file 8 | profiler: 9 | enabled: false 10 | 11 | web_profiler: 12 | toolbar: false 13 | intercept_redirects: false 14 | 15 | swiftmailer: 16 | disable_delivery: true 17 | -------------------------------------------------------------------------------- /Symfony/app/config/parameters.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | locale: en 3 | secret: CSRF-Token-Not-Really-Used 4 | 5 | # Path to cores. 6 | arduino_cores_dir: "/opt/codebender/codebender-arduino-core-files" 7 | external_core_files: "/opt/codebender/external-core-files" 8 | 9 | authorizationKey: "youMustChangeThis" 10 | 11 | # Paths to various executables used by the compiler. These depend on the 12 | # distribution used and the method of installation. Linking is performed by 13 | # avr-gcc (same as cc). 14 | binutils: "/usr/bin" 15 | python: "/usr/bin/python" 16 | clang: "/opt/codebender/codebender-arduino-core-files/clang/v3_5/bin/clang" 17 | temp_dir: "/tmp" 18 | objdir: "codebender_object_files" 19 | logdir: "codebender_log" 20 | archive_dir: "compiler_archives" 21 | autocompletion_dir: "autocompletion" 22 | autocompleter: "path_to_autocompleter_script" 23 | 24 | # -------- You shouldn't need to edit anything beyond this point. -------- \\ 25 | 26 | # Command-line arguments used when calling the external executables. More 27 | # arguments are used in compiler.php. During linking, the actual order of 28 | # flags is important. Thus, two variables have to be used: "ldflags" and 29 | # "ldflags_tail". 30 | cflags: "-Os -ffunction-sections -fdata-sections" 31 | cppflags: "-Os -ffunction-sections -fdata-sections -fno-exceptions" 32 | asflags: "-assembler-with-cpp" 33 | arflags: "rcs" 34 | ldflags: "-Os -Wl,--gc-sections" 35 | ldflags_tail: "-lm -lc" 36 | clang_flags: '--target=msp430 -w -fsyntax-only -fcolor-diagnostics -ferror-limit=0 -U__DBL_MIN_EXP__ -U__UINT_LEAST16_MAX__ -U__UINT_LEAST8_TYPE__ -U__INTMAX_C -U__UINT8_MAX__ -U__WINT_MAX__ -U__SIZE_MAX__ -U__WCHAR_MAX__ -U__DBL_DENORM_MIN__ -U__UINT_FAST64_MAX__ -U__SIG_ATOMIC_TYPE__ -U__DBL_MIN_10_EXP__ -U__GNUC_PATCHLEVEL__ -U__UINT_FAST8_MAX__ -U__DEC64_MAX_EXP__ -U__INT8_C -U__UINT_LEAST64_MAX__ -U__LDBL_MAX__ -U__UINT_LEAST8_MAX__ -U__UINTMAX_TYPE__ -U__DEC32_EPSILON__ -U__UINT32_MAX__ -U__LDBL_MAX_EXP__ -U__WINT_MIN__ -U__WCHAR_MIN__ -U__INT64_C -U__DBL_DIG__ -U__SIZEOF_INT__ -U__SIZEOF_POINTER__ -U__LDBL_MIN__ -U__DEC32_MAX__ -U__INT32_MAX__ -U__SIZEOF_LONG__ -U__UINT16_C -U__DECIMAL_DIG__ -U__AVR_2_BYTE_PC__ -U__SIZEOF_LONG_DOUBLE__ -U__BIGGEST_ALIGNMENT__ -U__DBL_MAX__ -U__INT_FAST32_MAX__ -U__DEC32_MIN_EXP__ -U__INT_FAST16_TYPE__ -U__DEC128_MAX__ -U__INT_LEAST32_MAX__ -U__USING_SJLJ_EXCEPTIONS__ -U__DEC32_MIN__ -U__DBL_MAX_EXP__ -U__DEC128_EPSILON__ -U__PTRDIFF_MAX__ -U__SIZEOF_SIZE_T__ -U__SIZEOF_WINT_T__ -U__INT_FAST64_TYPE__ -U__DBL_MIN__ -U__DEC128_MIN__ -U__UINT16_MAX__ -U__AVR_ARCH__ -U__UINT8_TYPE__ -U__VERSION__ -U__UINT64_C -U__INT32_C -U__DEC64_EPSILON__ -U__DEC128_MIN_EXP__ -U__INT_FAST32_TYPE__ -U__UINT_LEAST16_TYPE__ -U__INT16_MAX__ -U__SIZE_TYPE__ -U__UINT64_MAX__ -U__INT8_TYPE__ -U__INT_LEAST16_TYPE__ -U__LDBL_EPSILON__ -U__UINTMAX_C -U__SIG_ATOMIC_MAX__ -U__SIZEOF_PTRDIFF_T__ -U__AVR -U__DEC32_SUBNORMAL_MIN__ -U__INT_FAST16_MAX__ -U__UINT_FAST32_MAX__ -U__UINT_LEAST64_TYPE__ -U__LONG_MAX__ -U__DEC128_SUBNORMAL_MIN__ -U__UINT_FAST16_TYPE__ -U__DEC64_MAX__ -U__CHAR16_TYPE__ -U__INT_LEAST16_MAX__ -U__DEC64_MANT_DIG__ -U__INT64_MAX__ -U__UINT_LEAST32_MAX__ -U__INT_LEAST64_TYPE__ -U__INT16_TYPE__ -U__INT_LEAST8_TYPE__ -U__DEC32_MAX_EXP__ -U__INT_FAST8_MAX__ -U__INTPTR_MAX__ -U__LDBL_MANT_DIG__ -U__SIG_ATOMIC_MIN__ -UAVR -U__INTPTR_TYPE__ -U__UINT16_TYPE__ -U__AVR__ -U__UINTPTR_MAX__ -U__DEC64_MIN_EXP__ -U__INT_FAST64_MAX__ -U__UINT_FAST64_TYPE__ -U__INT_MAX__ -U__INT64_TYPE__ -U__DBL_MANT_DIG__ -U__INT_LEAST64_MAX__ -U__DEC64_MIN__ -U__UINT_LEAST32_TYPE__ -U__LDBL_MIN_EXP__ -U__INT_LEAST8_MAX__ -U__LDBL_MAX_10_EXP__ -U__DBL_EPSILON__ -U__UINT8_C -U__INT_LEAST32_TYPE__ -U__SIZEOF_WCHAR_T__ -U__UINT64_TYPE__ -U__INT_FAST8_TYPE__ -U__DEC_EVAL_METHOD__ -U__UINT32_C -U__INTMAX_MAX__ -U__INT8_MAX__ -U__UINT_FAST32_TYPE__ -U__CHAR32_TYPE__ -U__INT32_TYPE__ -U__SIZEOF_DOUBLE__ -U__INTMAX_TYPE__ -U__DEC128_MAX_EXP__ -U__AVR_HAVE_16BIT_SP__ -U__GNUC_MINOR__ -U__UINTMAX_MAX__ -U__DEC32_MANT_DIG__ -U__DBL_MAX_10_EXP__ -U__LDBL_DENORM_MIN__ -U__INT16_C -U__PTRDIFF_TYPE__ -U__UINT32_TYPE__ -U__UINTPTR_TYPE__ -U__DEC64_SUBNORMAL_MIN__ -U__DEC128_MANT_DIG__ -U__LDBL_MIN_10_EXP__ -U__LDBL_DIG__ -U__UINT_FAST16_MAX__ -U__GNUC_GNU_INLINE__ -U__UINT_FAST8_TYPE__ -D__DBL_MIN_EXP__=\(-125\) -D__UINT_LEAST16_MAX__=65535U -D__UINT_LEAST8_TYPE__=unsigned\ char -D__INTMAX_C\(c\)=c\ ##\ LL -D__UINT8_MAX__=255 -D__WINT_MAX__=65535U -D__SIZE_MAX__=65535U -D__WCHAR_MAX__=32767 -D__DBL_DENORM_MIN__=\(\(double\)1.40129846e-45L\) -D__UINT_FAST64_MAX__=18446744073709551615ULL -D__SIG_ATOMIC_TYPE__=int -D__DBL_MIN_10_EXP__=\(-37\) -D__GNUC_PATCHLEVEL__=3 -D__UINT_FAST8_MAX__=65535U -D__DEC64_MAX_EXP__=385 -D__INT8_C\(c\)=c -D__UINT_LEAST64_MAX__=18446744073709551615ULL -D__LDBL_MAX__=3.40282347e+38L -D__UINT_LEAST8_MAX__=255 -D__UINTMAX_TYPE__=long\ long\ unsigned\ int -D__DEC32_EPSILON__=1E-6DF -D__UINT32_MAX__=4294967295UL -D__LDBL_MAX_EXP__=128 -D__WINT_MIN__=0U -D__WCHAR_MIN__=\(-__WCHAR_MAX__\ -\ 1\) -D__INT64_C\(c\)=c\ ##\ LL -D__DBL_DIG__=6 -D__SIZEOF_INT__=2 -D__SIZEOF_POINTER__=2 -D__LDBL_MIN__=1.17549435e-38L -D__DEC32_MAX__=9.999999E96DF -D__INT32_MAX__=2147483647L -D__SIZEOF_LONG__=4 -D__UINT16_C\(c\)=c\ ##\ U -D__DECIMAL_DIG__=9 -D__AVR_2_BYTE_PC__=1 -D__SIZEOF_LONG_DOUBLE__=4 -D__BIGGEST_ALIGNMENT__=1 -D__DBL_MAX__=\(\(double\)3.40282347e+38L\) -D__INT_FAST32_MAX__=2147483647L -D__DEC32_MIN_EXP__=\(-94\) -D__INT_FAST16_TYPE__=int -D__DEC128_MAX__=9.999999999999999999999999999999999E6144DL -D__INT_LEAST32_MAX__=2147483647L -D__USING_SJLJ_EXCEPTIONS__=1 -D__DEC32_MIN__=1E-95DF -D__DBL_MAX_EXP__=128 -D__DEC128_EPSILON__=1E-33DL -D__PTRDIFF_MAX__=32767 -D__SIZEOF_SIZE_T__=2 -D__SIZEOF_WINT_T__=2 -D__INT_FAST64_TYPE__=long\ long\ int -D__DBL_MIN__=\(\(double\)1.17549435e-38L\) -D__DEC128_MIN__=1E-6143DL -D__UINT16_MAX__=65535U -D__AVR_ARCH__=2 -D__UINT8_TYPE__=unsigned\ char -D__VERSION__=\"4.5.3\" -D__UINT64_C\(c\)=c\ ##\ ULL -D__INT32_C\(c\)=c\ ##\ L -D__DEC64_EPSILON__=1E-15DD -D__DEC128_MIN_EXP__=\(-6142\) -D__INT_FAST32_TYPE__=long\ int -D__UINT_LEAST16_TYPE__=short\ unsigned\ int -D__INT16_MAX__=32767 -D__SIZE_TYPE__=unsigned\ int -D__UINT64_MAX__=18446744073709551615ULL -D__INT8_TYPE__=signed\ char -D__INT_LEAST16_TYPE__=short\ int -D__LDBL_EPSILON__=1.19209290e-7L -D__UINTMAX_C\(c\)=c\ ##\ ULL -D__SIG_ATOMIC_MAX__=32767 -D__SIZEOF_PTRDIFF_T__=2 -D__AVR=1 -D__DEC32_SUBNORMAL_MIN__=0.000001E-95DF -D__INT_FAST16_MAX__=32767 -D__UINT_FAST32_MAX__=4294967295UL -D__UINT_LEAST64_TYPE__=long\ long\ unsigned\ int -D__LONG_MAX__=2147483647L -D__DEC128_SUBNORMAL_MIN__=0.000000000000000000000000000000001E-6143DL -D__UINT_FAST16_TYPE__=unsigned\ int -D__DEC64_MAX__=9.999999999999999E384DD -D__CHAR16_TYPE__=short\ unsigned\ int -D__INT_LEAST16_MAX__=32767 -D__DEC64_MANT_DIG__=16 -D__INT64_MAX__=9223372036854775807LL -D__UINT_LEAST32_MAX__=4294967295UL -D__INT_LEAST64_TYPE__=long\ long\ int -D__INT16_TYPE__=short\ int -D__INT_LEAST8_TYPE__=signed\ char -D__DEC32_MAX_EXP__=97 -D__INT_FAST8_MAX__=32767 -D__INTPTR_MAX__=32767 -D__LDBL_MANT_DIG__=24 -D__SIG_ATOMIC_MIN__=\(-__SIG_ATOMIC_MAX__\ -\ 1\) -DAVR=1 -D__INTPTR_TYPE__=int -D__UINT16_TYPE__=short\ unsigned\ int -D__AVR__=1 -D__UINTPTR_MAX__=65535U -D__DEC64_MIN_EXP__=\(-382\) -D__INT_FAST64_MAX__=9223372036854775807LL -D__UINT_FAST64_TYPE__=long\ long\ unsigned\ int -D__INT_MAX__=32767 -D__INT64_TYPE__=long\ long\ int -D__DBL_MANT_DIG__=24 -D__INT_LEAST64_MAX__=9223372036854775807LL -D__DEC64_MIN__=1E-383DD -D__UINT_LEAST32_TYPE__=long\ unsigned\ int -D__LDBL_MIN_EXP__=\(-125\) -D__INT_LEAST8_MAX__=127 -D__LDBL_MAX_10_EXP__=38 -D__DBL_EPSILON__=\(\(double\)1.19209290e-7L\) -D__UINT8_C\(c\)=c -D__INT_LEAST32_TYPE__=long\ int -D__SIZEOF_WCHAR_T__=2 -D__UINT64_TYPE__=long\ long\ unsigned\ int -D__INT_FAST8_TYPE__=int -D__DEC_EVAL_METHOD__=2 -D__UINT32_C\(c\)=c\ ##\ UL -D__INTMAX_MAX__=9223372036854775807LL -D__INT8_MAX__=127 -D__UINT_FAST32_TYPE__=long\ unsigned\ int -D__CHAR32_TYPE__=long\ unsigned\ int -D__INT32_TYPE__=long\ int -D__SIZEOF_DOUBLE__=4 -D__INTMAX_TYPE__=long\ long\ int -D__DEC128_MAX_EXP__=6145 -D__AVR_HAVE_16BIT_SP__=1 -D__GNUC_MINOR__=5 -D__UINTMAX_MAX__=18446744073709551615ULL -D__DEC32_MANT_DIG__=7 -D__DBL_MAX_10_EXP__=38 -D__LDBL_DENORM_MIN__=1.40129846e-45L -D__INT16_C\(c\)=c -D__PTRDIFF_TYPE__=int -D__UINT32_TYPE__=long\ unsigned\ int -D__UINTPTR_TYPE__=unsigned\ int -D__DEC64_SUBNORMAL_MIN__=0.000000000000001E-383DD -D__DEC128_MANT_DIG__=34 -D__LDBL_MIN_10_EXP__=\(-37\) -D__LDBL_DIG__=6 -D__UINT_FAST16_MAX__=65535U -D__GNUC_GNU_INLINE__=1 -D__UINT_FAST8_TYPE__=unsigned\ int -U_LP64 -U__ATOMIC_ACQUIRE -U__ATOMIC_ACQ_REL -U__ATOMIC_CONSUME -U__ATOMIC_RELAXED -U__ATOMIC_RELEASE -U__ATOMIC_SEQ_CST -U__BYTE_ORDER__ -U__CONSTANT_CFSTRINGS__ -U__ELF__ -U__GCC_ATOMIC_BOOL_LOCK_FREE -U__GCC_ATOMIC_CHAR16_T_LOCK_FREE -U__GCC_ATOMIC_CHAR32_T_LOCK_FREE -U__GCC_ATOMIC_CHAR_LOCK_FREE -U__GCC_ATOMIC_INT_LOCK_FREE -U__GCC_ATOMIC_LLONG_LOCK_FREE -U__GCC_ATOMIC_LONG_LOCK_FREE -U__GCC_ATOMIC_POINTER_LOCK_FREE -U__GCC_ATOMIC_SHORT_LOCK_FREE -U__GCC_ATOMIC_TEST_AND_SET_TRUEVAL -U__GCC_ATOMIC_WCHAR_T_LOCK_FREE -U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 -U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 -U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 -U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 -U__GNUC_STDC_INLINE__ -U__GXX_RTTI -U__INT64_C_SUFFIX__ -U__INTMAX_WIDTH__ -U__INTPTR_WIDTH__ -U__LITTLE_ENDIAN__ -U__LP64__ -U__MMX__ -U__NO_MATH_INLINES -U__ORDER_BIG_ENDIAN__ -U__ORDER_LITTLE_ENDIAN__ -U__ORDER_PDP_ENDIAN__ -U__POINTER_WIDTH__ -U__PTRDIFF_WIDTH__ -U__SIG_ATOMIC_WIDTH__ -U__SIZEOF_INT128__ -U__SIZE_WIDTH__ -U__SSE2_MATH__ -U__SSE2__ -U__SSE_MATH__ -U__SSE__ -U__STDC_UTF_16__ -U__STDC_UTF_32__ -U__STDC_VERSION__ -U__WCHAR_WIDTH__ -U__WINT_UNSIGNED__ -U__WINT_WIDTH__ -U__amd64 -U__amd64__ -U__clang__ -U__clang_major__ -U__clang_minor__ -U__clang_patchlevel__ -U__clang_version__ -U__gnu_linux__ -U__k8 -U__k8__ -U__linux -U__linux__ -U__llvm__ -U__tune_k8__ -U__unix -U__unix__ -U__x86_64 -U__x86_64__ -Ulinux -Uunix ' 37 | objcopy_flags: "-R .eeprom" 38 | size_flags: "" 39 | 40 | # The default name of the output file, which is created in /tmp/compiler.xxxx 41 | # by default. 42 | output: "output" 43 | 44 | -------------------------------------------------------------------------------- /Symfony/app/config/routing.yml: -------------------------------------------------------------------------------- 1 | codebender_compiler: 2 | resource: "@CodebenderCompilerBundle/Resources/config/routing.yml" 3 | prefix: / 4 | 5 | -------------------------------------------------------------------------------- /Symfony/app/config/routing_dev.yml: -------------------------------------------------------------------------------- 1 | _wdt: 2 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" 3 | prefix: /_wdt 4 | 5 | _profiler: 6 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" 7 | prefix: /_profiler 8 | 9 | _configurator: 10 | resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" 11 | prefix: /_configurator 12 | 13 | _main: 14 | resource: routing.yml 15 | -------------------------------------------------------------------------------- /Symfony/app/config/security.yml: -------------------------------------------------------------------------------- 1 | security: 2 | firewalls: 3 | anonymous: 4 | anonymous: ~ 5 | 6 | providers: 7 | in_memory: 8 | memory: 9 | -------------------------------------------------------------------------------- /Symfony/app/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); 19 | $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; 20 | 21 | if ($debug) { 22 | Debug::enable(); 23 | } 24 | 25 | $kernel = new AppKernel($env, $debug); 26 | $application = new Application($kernel); 27 | $application->run($input); 28 | -------------------------------------------------------------------------------- /Symfony/app/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | ../src/*/*Bundle/Tests 19 | ../src/*/Bundle/*Bundle/Tests 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | ../src 32 | 33 | ../src/*/*Bundle/Resources 34 | ../src/*/*Bundle/Tests 35 | ../src/*/Bundle/*Bundle/Resources 36 | ../src/*/Bundle/*Bundle/Tests 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Symfony/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symfony/framework-standard-edition", 3 | "license": "MIT", 4 | "type": "project", 5 | "description": "The \"Symfony Standard Edition\" distribution", 6 | "autoload": { 7 | "psr-0": { "": "src/" } 8 | }, 9 | "require": { 10 | "php": ">=5.3.3", 11 | "symfony/symfony": "2.3.*", 12 | "doctrine/orm": ">=2.2.3,<2.4-dev", 13 | "doctrine/doctrine-bundle": "1.2.*", 14 | "twig/extensions": "1.0.*", 15 | "symfony/assetic-bundle": "2.3.*", 16 | "symfony/swiftmailer-bundle": "2.3.*", 17 | "symfony/monolog-bundle": "2.3.*", 18 | "sensio/distribution-bundle": "2.3.*", 19 | "sensio/framework-extra-bundle": "2.3.*", 20 | "sensio/generator-bundle": "2.3.*", 21 | "incenteev/composer-parameter-handler": "~2.0" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "4.8.*", 25 | "satooshi/php-coveralls": "dev-master", 26 | "squizlabs/php_codesniffer": "1.*", 27 | "sebastian/phpcpd": "*", 28 | "phpmd/phpmd" : "2.0.*", 29 | "phpunit/php-code-coverage": "~2.1", 30 | "phpunit/php-token-stream": "~1.3", 31 | "phpunit/phpunit-mock-objects": "~2.3" 32 | }, 33 | "scripts": { 34 | "post-install-cmd": [ 35 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 36 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 37 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 38 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 39 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 40 | ], 41 | "post-update-cmd": [ 42 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 43 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 44 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache", 45 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets", 46 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 47 | ] 48 | }, 49 | "config": { 50 | "bin-dir": "bin" 51 | }, 52 | "minimum-stability": "stable", 53 | "extra": { 54 | "symfony-app-dir": "app", 55 | "symfony-web-dir": "web", 56 | "incenteev-parameters": { 57 | "file": "app/config/parameters.yml" 58 | }, 59 | "branch-alias": { 60 | "dev-master": "2.3-dev" 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Symfony/src/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all 2 | 3 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/CodebenderCompilerBundle.php: -------------------------------------------------------------------------------- 1 | true, 'status' => 'OK']); 26 | } 27 | 28 | public function testAction($authorizationKey) 29 | { 30 | $params = $this->generateParameters(); 31 | 32 | if ($authorizationKey !== $params["authorizationKey"]) { 33 | return new JsonResponse([ 34 | "success" => false, 35 | "step" => 0, 36 | "message" => "Invalid authorization key." 37 | ]); 38 | } 39 | 40 | set_time_limit(0); // make the script execution time unlimited (otherwise the request may time out) 41 | 42 | // change the current Symfony root dir 43 | chdir($this->get('kernel')->getRootDir()."/../"); 44 | 45 | //TODO: replace this with a less horrible way to handle phpunit 46 | exec("phpunit -c app --stderr 2>&1", $output, $return_val); 47 | 48 | return new JsonResponse([ 49 | "success" => (bool) !$return_val, 50 | "message" => implode("\n", $output) 51 | ]); 52 | } 53 | 54 | public function indexAction($authorizationKey, $version) 55 | { 56 | $params = $this->generateParameters(); 57 | 58 | if ($authorizationKey !== $params['authorizationKey']) { 59 | return new JsonResponse([ 60 | 'success' => false, 61 | 'step' => 0, 62 | 'message' => 'Invalid authorization key.' 63 | ]); 64 | } 65 | 66 | $requestObject = $this->getRequest(); 67 | $request = $requestObject->getContent(); 68 | if ($version == 'v1') { 69 | // Custom headers used during library tests. 70 | // They don't affect the compiler's response and make our life easier. 71 | if ($requestObject->headers->get('X-Set-Exec-Time') == 'true') { 72 | ini_set('max_execution_time', '30'); 73 | } 74 | $mongoProjectId = $requestObject->headers->get('X-Mongo-Id'); 75 | 76 | //Get the compiler service 77 | /** @var CompilerHandler $compiler */ 78 | $compiler = $this->get('compiler_handler'); 79 | 80 | $reply = $compiler->main($request, $params); 81 | if ($mongoProjectId != '') { 82 | $reply['mongo-id'] = $mongoProjectId; 83 | } 84 | 85 | return new JsonResponse($reply); 86 | } 87 | if ($version == 'v2') { 88 | /** @var CompilerV2Handler $compiler */ 89 | $compiler = $this->get('compiler_v2_handler'); 90 | 91 | $reply = $compiler->main($request, $params); 92 | 93 | return new JsonResponse($reply); 94 | } 95 | 96 | return new JsonResponse([ 97 | 'success' => false, 98 | 'step' => 0, 99 | 'message' => 'Invalid API version.' 100 | ]); 101 | } 102 | 103 | public function deleteAllObjectsAction($authorizationKey, $version) 104 | { 105 | if ($this->container->getParameter('authorizationKey') != $authorizationKey) { 106 | return new JsonResponse([ 107 | 'success' => false, 108 | 'step' => 0, 109 | 'message' => 'Invalid authorization key.' 110 | ]); 111 | } 112 | 113 | if (!in_array($version, ['v1', 'v2'])) { 114 | return new JsonResponse([ 115 | 'success' => false, 116 | 'step' => 0, 117 | 'message' => 'Invalid API version.' 118 | ]); 119 | } 120 | 121 | //Get the compiler service 122 | /** @var DeletionHandler $deleter */ 123 | $deleter = $this->get('deletion_handler'); 124 | 125 | $response = $deleter->deleteAllObjects(); 126 | 127 | if ($response['success'] !== true) { 128 | return new JsonResponse([ 129 | 'success' => false, 130 | 'step' => 0, 131 | 'message' => 'Failed to access object files directory.' 132 | ]); 133 | } 134 | 135 | return new JsonResponse(array_merge( 136 | [ 137 | 'success' => true, 138 | 'message' => 'Object files deletion complete. Found ' . $response['fileCount'] . ' files.' 139 | ], 140 | $response['deletionStats'], 141 | ["Files not deleted" => $response['notDeletedFiles']] 142 | )); 143 | } 144 | 145 | public function deleteSpecificObjectsAction($authorizationKey, $version, $option, $cachedObjectToDelete) 146 | { 147 | if ($this->container->getParameter('authorizationKey') != $authorizationKey) { 148 | return new JsonResponse([ 149 | 'success' => false, 'step' => 0, 150 | 'message' => 'Invalid authorization key.' 151 | ]); 152 | } 153 | 154 | if (!in_array($version, ['v1', 'v2'])) { 155 | return new JsonResponse([ 156 | 'success' => false, 157 | 'step' => 0, 158 | 'message' => 'Invalid API version.' 159 | ]); 160 | } 161 | 162 | //Get the compiler service 163 | /** @var DeletionHandler $deleter */ 164 | $deleter = $this->get('deletion_handler'); 165 | 166 | $response = $deleter->deleteSpecificObjects($option, $cachedObjectToDelete); 167 | 168 | if ($response['success'] !== true) { 169 | return new JsonResponse([ 170 | 'success' => false, 171 | 'step' => 0, 172 | 'message' => 'Failed to access object files directory.' 173 | ]); 174 | } 175 | 176 | if (!empty($response["notDeletedFiles"])) { 177 | $message = 'Failed to delete one or more of the specified core object files.'; 178 | if ($option == 'library') { 179 | $message = 'Failed to delete one or more of the specified library object files.'; 180 | } 181 | 182 | return new JsonResponse( 183 | array_merge( 184 | ['success' => false, 'step' => 0, 'message' => $message], 185 | $response 186 | ) 187 | ); 188 | } 189 | 190 | $message = 'Core object files deleted successfully.'; 191 | if ($option == 'library') { 192 | $message = 'Library deleted successfully.'; 193 | } 194 | 195 | return new JsonResponse( 196 | array_merge( 197 | ['success' => true, 'message' => $message], 198 | $response 199 | ) 200 | ); 201 | } 202 | 203 | /** 204 | * \brief Creates a list of the configuration parameters to be used in the compilation process. 205 | * 206 | * \return An array of the parameters. 207 | * 208 | * This function accesses the Symfony global configuration parameters, 209 | * and creates an array that our handlers (which don't have access to them) 210 | * can use them. 211 | */ 212 | private function generateParameters() 213 | { 214 | $parameters = array( 215 | "binutils", "python", "clang", "logdir", "temp_dir", 216 | "archive_dir", "autocompletion_dir", "autocompleter", 217 | "cflags", "cppflags", "asflags", "arflags", "ldflags", 218 | "ldflags_tail", "clang_flags", "objcopy_flags", "size_flags", 219 | "output", "arduino_cores_dir", "external_core_files", 220 | "authorizationKey"); 221 | 222 | $compiler_config = array(); 223 | 224 | foreach ($parameters as $parameter) { 225 | $compiler_config[$parameter] = $this->container->getParameter($parameter); 226 | } 227 | 228 | return $compiler_config; 229 | } 230 | 231 | } 232 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/DependencyInjection/CodebenderCompilerExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 24 | 25 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 26 | $loader->load('services.yml'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | root('codebender_compiler'); 22 | 23 | // Here you should define the parameters that are allowed to 24 | // configure your bundle. See the documentation linked above for 25 | // more information on that topic. 26 | 27 | return $treeBuilder; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/CompilerV2Handler.php: -------------------------------------------------------------------------------- 1 | requestValid($request); 32 | if ($isRequestValid['success'] !== true) { 33 | return $isRequestValid; 34 | } 35 | 36 | $this->setVariables($request, $libraries, $should_archive, $config); 37 | 38 | $incoming_files = array(); 39 | 40 | // Step 1(part 1): Extract the project files included in the request. 41 | $filesExtracted = $this->extractFiles($request['files'], $temporaryDirectory, $project_dir, $incoming_files, 'files'); 42 | if ($filesExtracted['success'] !== true) { 43 | return $filesExtracted; 44 | } 45 | 46 | // Add the compiler temp directory to the config struct. 47 | $config['project_dir'] = $project_dir; 48 | 49 | // Where compiled files go 50 | $config['output_dir'] = "$project_dir/output"; 51 | 52 | // Where the compiler and base libraries live 53 | $config['base_dir'] = $config['arduino_cores_dir'] . '/v' . $config['version']; 54 | 55 | // This is used, for example, to provide object files, and to provide output files. 56 | $config['project_name'] = str_replace($config['project_dir'] . '/files/', 57 | '', 58 | $incoming_files['ino'][0]) . '.ino'; 59 | 60 | // Set up a default library dir, but set it to empty so it won't be used by default. 61 | $config['lib_dir'] = ''; 62 | 63 | // Step 1(part 2): Extract the library files included in the request. 64 | $files['libs'] = []; 65 | foreach ($libraries as $library => $library_files) { 66 | $lib_dir = $config['lib_dir']; 67 | $libraryExtracted = $this->extractFiles($library_files, $temporaryDirectory, $lib_dir, 68 | $files['libs'][$library], $library, true); 69 | if ($libraryExtracted['success'] !== true) { 70 | return $libraryExtracted; 71 | } 72 | $config['lib_dir'] = $lib_dir; 73 | } 74 | 75 | $ARCHIVE_PATH = ''; 76 | if ($should_archive) { 77 | $archiveCreated = $this->createArchive($project_dir, $temporaryDirectory, $ARCHIVE_DIR, $ARCHIVE_PATH); 78 | if ($archiveCreated['success'] !== true) { 79 | return $archiveCreated; 80 | } 81 | } 82 | 83 | //Set logging to true if requested, and create the directory where logfiles are stored. 84 | $loggingSet = $this->setLoggingParams($request, $config, $temporaryDirectory, $project_dir); 85 | if ($loggingSet['success'] !== true) { 86 | return array_merge($loggingSet, ($should_archive) ? array("archive" => $ARCHIVE_PATH) : array()); 87 | } 88 | 89 | // Log the names of the project files and the libraries used in it. 90 | $this->makeLogEntry($request, $config, $should_archive, $ARCHIVE_PATH); 91 | 92 | // Step 4: Syntax-check and compile source files. 93 | $arduinoBuilderResult = $this->handleCompile("$project_dir/files", $incoming_files, $config); 94 | if (array_key_exists('builder_time', $arduinoBuilderResult)) { 95 | $config['builder_time'] = $arduinoBuilderResult['builder_time']; 96 | } 97 | 98 | // Step 4.5: Save the cache for future builds 99 | $this->saveCache($config); 100 | 101 | if ($config['logging'] === true && $arduinoBuilderResult['log']) { 102 | foreach ($arduinoBuilderResult['log'] as $line) { 103 | array_push($log, $line); 104 | } 105 | } 106 | 107 | if ($should_archive) { 108 | $archiveCreated = $this->createArchive($project_dir, $temporaryDirectory, $ARCHIVE_DIR, $ARCHIVE_PATH); 109 | $arduinoBuilderResult['archive'] = $ARCHIVE_PATH; 110 | if ($archiveCreated['success'] !== true) { 111 | $arduinoBuilderResult['archive'] = $archiveCreated['message']; 112 | } 113 | } 114 | 115 | if ($arduinoBuilderResult['success'] !== true) { 116 | return $arduinoBuilderResult; 117 | } 118 | 119 | // Step 8: Convert the output to hex and measure its size. 120 | $convertedOutput = $this->convertOutput($start_time, $config); 121 | 122 | if ($config['logging'] === true) { 123 | $convertedOutput['log'] =$log; 124 | } 125 | 126 | if ($should_archive) { 127 | $archiveCreated = $this->createArchive($project_dir, $temporaryDirectory, $ARCHIVE_DIR, $ARCHIVE_PATH); 128 | $convertedOutput['archive'] = $ARCHIVE_PATH; 129 | if ($archiveCreated['success'] !== true) { 130 | $convertedOutput['archive'] = $archiveCreated['message']; 131 | } 132 | } 133 | return $convertedOutput; 134 | } 135 | 136 | private function copyRecursive($src, $dst) 137 | { 138 | 139 | if (is_file($src)) { 140 | if (file_exists($dst) && is_dir($dst)) 141 | return array( 142 | "success" => false, 143 | "message" => "Destination exists already, and is a directory."); 144 | 145 | if (!copy($src, $dst)) 146 | return array( 147 | "success" => false, 148 | "message" => "Unable to copy $src to $dst."); 149 | return array("success" => true); 150 | } 151 | 152 | if (!is_dir($dst)) 153 | if (!mkdir($dst, 0775, true)) 154 | return array( 155 | "success" => false, 156 | "message" => "Unable to create directory $dst."); 157 | 158 | // The target directory exists. Copy all files over. 159 | $dirent = dir($src); 160 | if (!$dirent) 161 | return array( 162 | "success" => false, 163 | "message" => "Unable to open directory " . $src . " for copying files."); 164 | 165 | while (false !== ($filename = $dirent->read())) { 166 | if (($filename == '.') || ($filename == '..')) 167 | continue; 168 | 169 | $ret = $this->copyRecursive($src . "/" . $filename, $dst . "/" . $filename); 170 | if ($ret["success"] != true) { 171 | $dirent->close(); 172 | return $ret; 173 | } 174 | } 175 | $dirent->close(); 176 | 177 | return array("success" => true); 178 | } 179 | 180 | private function copyCaches($sourceDirectory, $destinationDirectory, $caches) 181 | { 182 | if (!file_exists($sourceDirectory)) 183 | return ['success' => null, 'message' => 'No existing cache found.']; 184 | 185 | // Ensure the target core directory exists 186 | if (!file_exists($destinationDirectory)) 187 | if (!mkdir($destinationDirectory, 0777, true)) 188 | return array( 189 | "success" => false, 190 | "message" => "Unable to create output dir."); 191 | 192 | // Go through each of the cache types and copy them, if they exist 193 | foreach ($caches as $dir) { 194 | if (!file_exists($sourceDirectory . "/" . $dir)) 195 | continue; 196 | 197 | $ret = $this->copyRecursive($sourceDirectory . "/" . $dir, $destinationDirectory . "/" . $dir); 198 | if ($ret["success"] != true) 199 | return $ret; 200 | } 201 | 202 | return array("success" => true); 203 | } 204 | 205 | private function updateAccessTimesRecursive($dir, $pattern) 206 | { 207 | // The target directory exists. Copy all files over. 208 | if (!file_exists($dir)) 209 | return array( 210 | "success" => true, 211 | "message" => "Cache directory " . $dir . " does not exist."); 212 | 213 | if (!is_dir($dir)) 214 | return array( 215 | "success" => false, 216 | "message" => "Cache directory " . $dir . " is not a directory."); 217 | 218 | $dirent = dir($dir); 219 | if (!$dirent) 220 | return array( 221 | "success" => false, 222 | "message" => "Unable to open directory " . $dir . " for updating access times."); 223 | 224 | while (false !== ($filename = $dirent->read())) { 225 | if (($filename == '.') || ($filename == '..')) 226 | continue; 227 | 228 | if ((substr($filename, strlen($filename) - strlen($pattern)) === $pattern) 229 | && file_exists($dir . "/" . $filename) 230 | ) { 231 | $ret = touch($dir . "/" . $filename); 232 | if (!$ret) { 233 | $dirent->close(); 234 | return array( 235 | "success" => false, 236 | "message" => "Unable to update " . $dir . "/" . $filename . " access time."); 237 | } 238 | } 239 | 240 | // Recurse into subdirectories, if we've encountered a subdir. 241 | if (is_dir($dir . "/" . $filename)) { 242 | $ret = $this->updateAccessTimesRecursive($dir . "/" . $filename, $pattern); 243 | if ($ret["success"] != true) { 244 | $dirent->close(); 245 | return $ret; 246 | } 247 | } 248 | } 249 | $dirent->close(); 250 | 251 | return array("success" => true); 252 | } 253 | 254 | private function updateDependencyPathsRecursive($dir, $old_dir, $new_dir) 255 | { 256 | $pattern = ".d"; 257 | 258 | // The target directory exists. Copy all files over. 259 | if (!file_exists($dir)) 260 | return array( 261 | "success" => true, 262 | "message" => "Cache directory " . $dir . " does not exist."); 263 | 264 | if (!is_dir($dir)) 265 | return array( 266 | "success" => false, 267 | "message" => "Cache directory " . $dir . " is not a directory."); 268 | 269 | $dirent = dir($dir); 270 | if (!$dirent) 271 | return array( 272 | "success" => false, 273 | "message" => "Unable to open directory " . $dir . " for updating access times."); 274 | 275 | while (false !== ($filename = $dirent->read())) { 276 | if (($filename == '.') || ($filename == '..')) 277 | continue; 278 | 279 | if ((substr($filename, strlen($filename) - strlen($pattern)) === $pattern) 280 | && file_exists($dir . "/" . $filename) 281 | ) { 282 | $ret = touch($dir . "/" . $filename); 283 | $content = file_get_contents($dir . "/" . $filename); 284 | $ret = file_put_contents($dir . "/" . $filename, str_replace($old_dir, $new_dir, $content)); 285 | if (!$ret) { 286 | $dirent->close(); 287 | return array( 288 | "success" => false, 289 | "message" => "Unable to update " . $dir . "/" . $filename . " paths."); 290 | } 291 | } 292 | 293 | // Recurse into subdirectories, if we've encountered a subdir. 294 | if (is_dir($dir . "/" . $filename)) { 295 | $ret = $this->updateDependencyPathsRecursive($dir . "/" . $filename, $old_dir, $new_dir); 296 | if ($ret["success"] != true) { 297 | $dirent->close(); 298 | return $ret; 299 | } 300 | } 301 | } 302 | $dirent->close(); 303 | 304 | return array("success" => true); 305 | } 306 | 307 | private function updateAccessTimes($base_dir, $sub_dirs, $pattern) 308 | { 309 | foreach ($sub_dirs as $sub_dir) { 310 | if (file_exists($base_dir . "/" . $sub_dir)) { 311 | $ret = touch($base_dir . "/" . $sub_dir); 312 | if (!$ret) 313 | return array( 314 | "success" => false, 315 | "message" => "Unable to update directory " . $base_dir . "/" . $sub_dir . " access time."); 316 | } 317 | 318 | $ret = $this->updateAccessTimesRecursive($base_dir . "/" . $sub_dir, $pattern); 319 | if ($ret["success"] != true) 320 | return $ret; 321 | } 322 | return array("success" => true); 323 | } 324 | 325 | private function updateDependencyPaths($output_dir, $sub_dirs, $old_dir, $new_dir) 326 | { 327 | foreach ($sub_dirs as $sub_dir) { 328 | $ret = $this->updateDependencyPathsRecursive($output_dir . "/" . $sub_dir, $old_dir, $new_dir); 329 | if ($ret["success"] != true) 330 | return $ret; 331 | } 332 | 333 | return array("success" => true); 334 | } 335 | 336 | private function cacheDirs() 337 | { 338 | return array("core", "libraries"); 339 | } 340 | 341 | private function restoreCache($config) 342 | { 343 | $cache_dir = $this->object_directory 344 | . "/" . $config["version"] 345 | . "/" . $config["fqbn"] 346 | . "/" . $config["vid"] 347 | . "/" . $config["pid"]; 348 | $output_dir = $config["output_dir"]; 349 | 350 | // Copy the files from the existing cache directory to the new project. 351 | $ret = $this->copyCaches($cache_dir, $output_dir, $this->cacheDirs()); 352 | 353 | // A success of "null" indicates it was not successful, but didn't fail, probably 354 | // due to the lack of an existing cache directory. That's fine, we just won't use 355 | // a cache. 356 | if ($ret["success"] == null) 357 | return array("success" => true); 358 | 359 | if ($ret["success"] != true) 360 | return $ret; 361 | 362 | // arduino-builder looks through dependency files. Update the paths 363 | // in the cached files we're copying back. 364 | $this->updateDependencyPaths($output_dir, $this->cacheDirs(), "::BUILD_DIR::", $output_dir); 365 | 366 | $suffixes = array(".d", ".o", ".a"); 367 | foreach ($suffixes as $suffix) { 368 | $ret = $this->updateAccessTimes($output_dir, $this->cacheDirs(), $suffix); 369 | if ($ret["success"] != true) 370 | return $ret; 371 | } 372 | 373 | return array("success" => true); 374 | } 375 | 376 | private function saveCache($config) 377 | { 378 | $cache_dir = $this->object_directory 379 | . "/" . $config["version"] 380 | . "/" . $config["fqbn"] 381 | . "/" . $config["vid"] 382 | . "/" . $config["pid"]; 383 | $output_dir = $config["output_dir"]; 384 | 385 | $this->copyCaches($output_dir, $cache_dir, $this->cacheDirs()); 386 | $this->updateDependencyPaths($cache_dir, $this->cacheDirs(), $output_dir, "::BUILD_DIR::"); 387 | 388 | return array("success" => true); 389 | } 390 | 391 | private function makeLogEntry($request, $config, $should_archive, $archive_path) 392 | { 393 | $user_id = $sketch_id = "null"; 394 | $req_elements = array("Files: "); 395 | 396 | if (isset($request['userId']) && $request['userId'] != 'null') { 397 | $user_id = $request['userId']; 398 | } 399 | if (isset($request['projectId']) && $request['projectId'] != 'null') { 400 | $sketch_id = $request['projectId']; 401 | } 402 | 403 | foreach ($request["files"] as $file) { 404 | $req_elements[] = $file["filename"]; 405 | } 406 | 407 | if ($request["libraries"]) { 408 | $req_elements[] = "Libraries: "; 409 | foreach ($request["libraries"] as $libname => $libfiles) { 410 | foreach ($libfiles as $libfile) 411 | $req_elements[] = $libname . "/" . $libfile["filename"]; 412 | } 413 | } 414 | 415 | $this->logger_id = microtime(true) . "_" . substr($config['project_dir'], -6) . "_user:$user_id" . "_project:$sketch_id"; 416 | 417 | $this->compiler_logger->addInfo($this->logger_id . " - " . implode(" ", $req_elements)); 418 | if ($should_archive) 419 | $this->compiler_logger->addInfo($this->logger_id . " - " . "Archive file: $archive_path"); 420 | } 421 | 422 | /** 423 | * \brief Determines whether a string contains unprintable chars. 424 | * 425 | * \param string $str String to check for binary-ness. 426 | * \return true if the stirng contains binary, false if it's printable. 427 | */ 428 | private function isBinaryObject($str) 429 | { 430 | 431 | for ($i = 0; $i < strlen($str); $i++) { 432 | $c = substr($str, $i, 1); 433 | if ($c > chr(127)) 434 | return true; 435 | } 436 | return false; 437 | } 438 | 439 | private function convertOutput($start_time, $config) 440 | { 441 | $builder_time = 0; 442 | if (array_key_exists('builder_time', $config)) { 443 | $builder_time = $config['builder_time']; 444 | } 445 | 446 | // Set the output file base path. All the product files (bin/hex/elf) have the same base name. 447 | $base_path = $config['output_dir'] . '/' . $config['project_name']; 448 | 449 | $content = ''; 450 | $content_path = $config['output_dir'] . '/' . $this->builderPref("recipe.output.tmp_file"); 451 | if (file_exists($content_path)) { 452 | $content = file_get_contents($content_path); 453 | } else { 454 | // TODO 455 | // Locate the correct objcopy (depends on AVR/SAM) and create the hex output from the .elf file. 456 | } 457 | 458 | // If content is still empty, something went wrong 459 | if ($content == '') { 460 | return [ 461 | 'success' => false, 462 | 'time' => microtime(true) - $start_time, 463 | 'builder_time' => $builder_time, 464 | 'step' => 8, 465 | 'message' => 'There was a problem while generating the your binary file from ' . $content_path . '.' 466 | ]; 467 | } 468 | 469 | // Get the size of the requested output file and return to the caller 470 | $size_cmd = $this->builderPref("recipe.size.pattern"); 471 | $size_regex = $this->builderPref("recipe.size.regex"); 472 | $data_regex = $this->builderPref("recipe.size.regex.data"); 473 | $eeprom_regex = $this->builderPref("recipe.size.regex.eeprom"); 474 | 475 | // Run the actual "size" command, and prepare to tally the results. 476 | exec($size_cmd, $size_output); 477 | 478 | // Go through each line of "size" output and execute the various size regexes. 479 | $full_size = 0; 480 | $data_size = 0; 481 | $eeprom_size = 0; 482 | foreach ($size_output as $size_line) { 483 | if ($size_regex && preg_match("/" . $size_regex . "/", $size_line, $matches)) 484 | $full_size += $matches[1]; 485 | 486 | if ($data_regex && preg_match("/" . $data_regex . "/", $size_line, $matches)) 487 | $data_size += $matches[1]; 488 | 489 | if ($eeprom_regex && preg_match("/" . $eeprom_regex . "/", $size_line, $matches)) 490 | $eeprom_size += $matches[1]; 491 | } 492 | 493 | $sizeValues = []; 494 | if ($data_size) { 495 | $sizeValues['data_size'] = $data_size; 496 | } 497 | if ($eeprom_size) { 498 | $sizeValues['eeprom_size'] = $eeprom_size; 499 | } 500 | return array_merge( 501 | [ 502 | 'success' => true, 503 | 'time' => microtime(true) - $start_time, 504 | 'builder_time' => $builder_time, 505 | 'size' => $full_size, 506 | 'tool' => $this->builderPref("upload.tool"), 507 | 'output' => base64_encode($content) 508 | ], 509 | $sizeValues 510 | ); 511 | } 512 | 513 | private function setVariables($request, &$libraries, &$should_archive, &$config) 514 | { 515 | // Extract the request options for easier access. 516 | $libraries = $request["libraries"]; 517 | $version = $request["version"]; 518 | 519 | if (!array_key_exists("archive", $request)) 520 | $should_archive = false; 521 | elseif ($request["archive"] !== false) 522 | $should_archive = false; 523 | else 524 | $should_archive = true; 525 | 526 | 527 | // Set the appropriate variables for USB vid and pid (Leonardo). 528 | $vid = (isset($request["vid"])) ? $request["vid"] : "null"; 529 | $pid = (isset($request["pid"])) ? $request["pid"] : "null"; 530 | 531 | $config["fqbn"] = $request["fqbn"]; 532 | $config["vid"] = $vid; 533 | $config["pid"] = $pid; 534 | $config["version"] = $version; 535 | } 536 | 537 | private function handleCompile($compile_directory, $files_array, $config, 538 | $caching = false, $name_params = null) 539 | { 540 | $base_dir = $config["base_dir"]; 541 | $core_dir = $config["external_core_files"]; 542 | $output_dir = $config["output_dir"]; 543 | $fqbn = $config["fqbn"]; 544 | $filename = $files_array["ino"][0] . ".ino"; 545 | $libraries = array(); 546 | 547 | // Set up a default library directory 548 | array_push($libraries, $base_dir . "/" . "libraries"); 549 | if ($config["lib_dir"]) 550 | array_push($libraries, $config["lib_dir"]); 551 | 552 | // Set the VID and PID, if they exist 553 | $vid_pid = ""; 554 | if (($config["vid"] != "null") && ($config["pid"] != "null")) { 555 | $vid = intval($config["vid"], 0); 556 | $pid = intval($config["pid"], 0); 557 | $vid_pid = sprintf(" -vid-pid=0X%1$04X_%2$04X", $vid, $pid); 558 | } 559 | 560 | if (!file_exists($output_dir)) 561 | if (!mkdir($output_dir, 0777, true)) 562 | return array( 563 | "success" => false, 564 | "step" => 4, 565 | "message" => "Unable to make output path.", 566 | "debug" => $output_dir 567 | ); 568 | 569 | if (!file_exists($base_dir)) 570 | return array( 571 | "success" => false, 572 | "step" => 4, 573 | "message" => "Base path does not exist.", 574 | "debug" => $base_dir 575 | ); 576 | 577 | if (!file_exists($filename)) 578 | return array( 579 | "success" => false, 580 | "step" => 4, 581 | "message" => "Source file does not exist.", 582 | "debug" => $filename 583 | ); 584 | 585 | $hardware_dirs = array( 586 | $base_dir . "/" . "hardware", 587 | $base_dir . "/" . "packages" 588 | ); 589 | $tools_dirs = array( 590 | $base_dir . "/" . "tools-builder", 591 | $base_dir . "/" . "hardware/tools/avr", 592 | $base_dir . "/" . "packages" 593 | ); 594 | 595 | // Create build.options.json, which is used for caching object files. 596 | // Also use it for passing parameters to the arduino-builder program. 597 | $build_options = 598 | "{\n" 599 | . " \"builtInLibrariesFolders\": \"\",\n" 600 | . " \"customBuildProperties\": \"\",\n" 601 | . " \"fqbn\": \"" . $fqbn . "\",\n" 602 | . " \"hardwareFolders\": \"" . implode(",", $hardware_dirs) . "\",\n" 603 | . " \"otherLibrariesFolders\": \"" . implode(",", $libraries) . "\",\n" 604 | . " \"runtime.ide.version\": \"" . ($config["version"] * 100) . "\",\n" 605 | . " \"sketchLocation\": \"" . $filename . "\",\n" 606 | . " \"toolsFolders\": \"" . implode(",", $tools_dirs) . "\"\n" 607 | . "}"; 608 | 609 | // Copy cached config files into directory (if they exist) 610 | file_put_contents($output_dir . "/" . "build.options.json", $build_options); 611 | $ret = $this->restoreCache($config); 612 | if ($ret["success"] != true) 613 | return $ret; 614 | 615 | $hardware_args = ""; 616 | foreach ($hardware_dirs as $hardware) 617 | $hardware_args .= " -hardware=\"" . $hardware . "\""; 618 | 619 | $tools_args = ""; 620 | foreach ($tools_dirs as $tools) 621 | $tools_args .= " -tools=\"" . $tools . "\""; 622 | 623 | $verbose_compile = ""; 624 | if (array_key_exists("verbose_compile", $config) && $config["verbose_compile"]) 625 | $verbose_compile = " -verbose"; 626 | 627 | // Ensure the lib_str lists the libraries in the same order as the build.options.json, in 628 | // order to allow arduino-builder to reuse files. 629 | $lib_str = ""; 630 | foreach ($libraries as $lib) 631 | $lib_str .= " -libraries=\"" . $lib . "\""; 632 | 633 | $cmd = $base_dir . "/arduino-builder" 634 | . " -logger=human" 635 | . " -compile" 636 | . $verbose_compile 637 | . " -ide-version=\"" . ($config["version"] * 100) . "\"" 638 | . " -warnings=all" 639 | . $hardware_args 640 | . $lib_str 641 | . " -build-path=" . $output_dir 642 | . $tools_args 643 | . " -fqbn=" . $fqbn 644 | . $vid_pid 645 | . " " . escapeshellarg($filename) 646 | . " 2>&1"; 647 | $arduino_builder_time_start = microtime(true); 648 | exec($cmd, $output, $ret_link); 649 | $arduino_builder_time_end = microtime(true); 650 | 651 | if ($config["logging"]) { 652 | file_put_contents($config['logFileName'], $cmd, FILE_APPEND); 653 | file_put_contents($config['logFileName'], implode(" ", $output), FILE_APPEND); 654 | } 655 | 656 | if ($ret_link) { 657 | return array( 658 | "success" => false, 659 | "retcode" => $ret_link, 660 | "message" => $this->pathRemover($output, $config), 661 | "log" => array($cmd, implode("\n", $output)) 662 | ); 663 | } 664 | 665 | // Pull out Arduino's internal build variables, useful for determining sizes and output files 666 | $cmd = $base_dir . "/arduino-builder" 667 | . " -logger=human" 668 | . " -compile" 669 | . " -dump-prefs=true" 670 | . " -ide-version=\"" . ($config["version"] * 100) . "\"" 671 | . $hardware_args 672 | . $lib_str 673 | . " -build-path=" . $output_dir 674 | . $tools_args 675 | . " -fqbn=" . $fqbn 676 | . $vid_pid 677 | . " " . escapeshellarg($filename) 678 | . " 2>&1"; 679 | exec($cmd, $this->builder_prefs_raw, $ret_link); 680 | 681 | if ($ret_link) { 682 | return array( 683 | "success" => false, 684 | "retcode" => $ret_link, 685 | "message" => $this->pathRemover($output, $config), 686 | "log" => array($cmd, implode("\n", $output)) 687 | ); 688 | } 689 | 690 | return array( 691 | "success" => true, 692 | "builder_time" => $arduino_builder_time_end - $arduino_builder_time_start, 693 | "log" => array($cmd, $output) 694 | ); 695 | } 696 | 697 | protected function builderPref($key) 698 | { 699 | // Ensure the builder prefs actually exists. 700 | if ($this->builder_prefs == null) { 701 | 702 | // If builder_prefs_raw does not exist, then the compile has not yet been run. 703 | if ($this->builder_prefs_raw == null) { 704 | return ""; 705 | } 706 | 707 | // Parse $builder_prefs_raw into an array. It comes in as 708 | // a bunch of lines of the format: 709 | // 710 | // key=val 711 | // 712 | // Additionally, val can contain values that need substitution with other keys. 713 | // This substitution will take place at a later time. 714 | $this->builder_prefs = array(); 715 | foreach ($this->builder_prefs_raw as $line) { 716 | $line = rtrim($line); 717 | $parts = explode("=", $line, 2); 718 | $this->builder_prefs[$parts[0]] = $parts[1]; 719 | } 720 | } 721 | 722 | if (!array_key_exists($key, $this->builder_prefs)) 723 | return ""; 724 | 725 | // Recursively expand the key. arduino-builder limits it to 10 recursion attempts. 726 | return $this->builderPrefExpand($this->builder_prefs[$key], 10); 727 | } 728 | 729 | private function builderPrefExpand($str, $recurse) 730 | { 731 | 732 | // Don't allow infinite recursion. 733 | if ($recurse <= 0) 734 | return $str; 735 | 736 | // Replace all keys in the string with their value. 737 | foreach ($this->builder_prefs as $key => $value) 738 | $str = str_replace("{" . $key . "}", $value, $str); 739 | 740 | // If there is more to expand, recurse. 741 | if (strpos($str, "{")) 742 | return $this->builderPrefExpand($str, $recurse - 1); 743 | 744 | return $str; 745 | } 746 | 747 | protected function pathRemover($output, $config) 748 | { 749 | // If the incoming output is still an array, implode it. 750 | $message = ""; 751 | if (!is_array($output)) 752 | $output = explode("\n", $output); 753 | 754 | foreach ($output as $modified) { 755 | 756 | // Remove the path of the project directory, add (sketch file) info text 757 | $modified = str_replace($config["project_dir"] . "/files/", '(sketch file) ', $modified); 758 | 759 | // Remove any remaining instance of the project directory name from the text. 760 | $modified = str_replace($config["project_dir"] . "/", '', $modified); 761 | 762 | // Replace userId_cb_personal_lib prefix from personal libraries errors with a (personal library file) info text. 763 | $modified = preg_replace('/libraries\/\d+_cb_personal_lib_/', '(personal library file) ', $modified); 764 | 765 | // Replace libraries/ prefix from personal libraries errors with a (personal library file) info text. 766 | $modified = str_replace('libraries/', '(library file) ', $modified); 767 | 768 | // Remove any instance of codebender arduino core files folder name from the text, add (arduino core file) info text 769 | $modified = str_replace($config["arduino_cores_dir"] . "/v167/", '(arduino core file) ', $modified); 770 | 771 | // Remove any instance of codebender external core file folder name from the text, , add (arduino core file) info text 772 | if (isset($config["external_core_files"]) && $config["external_core_files"] != "") { 773 | $modified = str_replace($config["external_core_files"], '(arduino core file) ', $modified); 774 | $modified = str_replace("/override_cores/", '(arduino core file) ', $modified); 775 | } 776 | 777 | // Remove column numbers from error messages 778 | $modified = preg_replace('/^([^:]+:\d+):\d+/', '$1', $modified); 779 | 780 | $message .= $modified . "\n"; 781 | } 782 | 783 | return $message; 784 | } 785 | } 786 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/DeletionHandler.php: -------------------------------------------------------------------------------- 1 | objectCacheDirectory = $objectFilesDirectory; 26 | } 27 | 28 | function deleteAllObjects() 29 | { 30 | $fileCount = 0; 31 | $notDeletedFiles = ''; 32 | $deletionStats = array('success_dot_a' => 0, 33 | 'failure_dot_a' => 0, 34 | 'success_dot_o' => 0, 35 | 'failure_dot_o' => 0, 36 | 'success_dot_d' => 0, 37 | 'failure_dot_d' => 0, 38 | 'success_dot_LOCK' => 0, 39 | 'failure_dot_LOCK' => 0); 40 | 41 | if ($handle = @opendir($this->objectCacheDirectory)) { 42 | 43 | while (false !== ($entry = readdir($handle))) { 44 | if ($entry == '.' || $entry == '..' || $entry == '.DS_Store') { 45 | continue; 46 | } 47 | $fileCount++; 48 | $extension = pathinfo($entry, PATHINFO_EXTENSION); 49 | 50 | if (!in_array($extension, array('a', 'o', 'd', 'LOCK'))) { 51 | continue; 52 | } 53 | 54 | if (@unlink($this->objectCacheDirectory . '/' . $entry) === false) { 55 | $deletionStats['failure_dot_$extension']++; 56 | $notDeletedFiles .= $entry . "\n"; 57 | continue; 58 | } 59 | 60 | $deletionStats['success_dot_' . $extension]++; 61 | } 62 | closedir($handle); 63 | 64 | return array( 65 | 'success' => true, 66 | 'fileCount' => $fileCount, 67 | 'notDeletedFiles' => $notDeletedFiles, 68 | 'deletionStats' => $deletionStats 69 | ); 70 | } 71 | 72 | return array('success' => false); 73 | } 74 | 75 | function deleteSpecificObjects($option, $cachedObjectToDelete) 76 | { 77 | if ($option == 'core') { 78 | $cachedObjectToDelete = str_replace(':', '_', $cachedObjectToDelete); 79 | } 80 | 81 | $deletedFiles = ''; 82 | $notDeletedFiles = ''; 83 | 84 | if ($handle = @opendir($this->objectCacheDirectory)) { 85 | 86 | while (false !== ($entry = readdir($handle))) { 87 | 88 | if ($entry == '.' || $entry == '..' || $entry == '.DS_Store') { 89 | continue; 90 | } 91 | 92 | if ($option == 'library' && strpos($entry, '______' . $cachedObjectToDelete . '_______') === false) { 93 | continue; 94 | } 95 | 96 | if ($option == 'core' && strpos($entry, '_' . $cachedObjectToDelete . '_') === false) { 97 | continue; 98 | } 99 | 100 | 101 | if (@unlink($this->objectCacheDirectory . '/' . $entry) === false) { 102 | $notDeletedFiles .= $entry."\n"; 103 | continue; 104 | } 105 | 106 | $deletedFiles .= $entry . "\n"; 107 | 108 | } 109 | closedir($handle); 110 | 111 | return array('success' => true, 'deletedFiles' => $deletedFiles, 'notDeletedFiles' => $notDeletedFiles); 112 | } 113 | 114 | return array('success' => false); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php: -------------------------------------------------------------------------------- 1 | . 12 | * 13 | * \author Dimitrios Christidis 14 | * \author Vasilis Georgitzikis 15 | * 16 | * \copyright (c) 2012, The Codebender Development Team 17 | * \copyright Licensed under the Simplified BSD License 18 | */ 19 | namespace Codebender\CompilerBundle\Handler; 20 | 21 | 22 | class MCUHandler 23 | { 24 | public static $MCU = array( 25 | "at90s1200" => "__AVR_AT90S1200__", 26 | "attiny11" => "__AVR_ATtiny11__", 27 | "attiny12" => "__AVR_ATtiny12__", 28 | "attiny15" => "__AVR_ATtiny15__", 29 | "attiny28" => "__AVR_ATtiny28__", 30 | "at90s2313" => "__AVR_AT90S2313__", 31 | "at90s2323" => "__AVR_AT90S2323__", 32 | "at90s2333" => "__AVR_AT90S2333__", 33 | "at90s2343" => "__AVR_AT90S2343__", 34 | "attiny22" => "__AVR_ATtiny22__", 35 | "attiny26" => "__AVR_ATtiny26__", 36 | "at90s4414" => "__AVR_AT90S4414__", 37 | "at90s4433" => "__AVR_AT90S4433__", 38 | "at90s4434" => "__AVR_AT90S4434__", 39 | "at90s8515" => "__AVR_AT90S8515__", 40 | "at90c8534" => "__AVR_AT90C8534__", 41 | "at90s8535" => "__AVR_AT90S8535__", 42 | "at86rf401" => "__AVR_AT86RF401__", 43 | "ata6289" => "__AVR_ATA6289__", 44 | "attiny13" => "__AVR_ATtiny13__", 45 | "attiny13a" => "__AVR_ATtiny13A__", 46 | "attiny2313" => "__AVR_ATtiny2313__", 47 | "attiny2313a" => "__AVR_ATtiny2313A__", 48 | "attiny24" => "__AVR_ATtiny24__", 49 | "attiny24a" => "__AVR_ATtiny24A__", 50 | "attiny25" => "__AVR_ATtiny25__", 51 | "attiny261" => "__AVR_ATtiny261__", 52 | "attiny261a" => "__AVR_ATtiny261A__", 53 | "attiny4313" => "__AVR_ATtiny4313__", 54 | "attiny43u" => "__AVR_ATtiny43U__", 55 | "attiny44" => "__AVR_ATtiny44__", 56 | "attiny44a" => "__AVR_ATtiny44A__", 57 | "attiny45" => "__AVR_ATtiny45__", 58 | "attiny461" => "__AVR_ATtiny461__", 59 | "attiny461a" => "__AVR_ATtiny461A__", 60 | "attiny48" => "__AVR_ATtiny48__", 61 | "attiny84" => "__AVR_ATtiny84__", 62 | "attiny84a" => "__AVR_ATtiny84A__", 63 | "attiny85" => "__AVR_ATtiny85__", 64 | "attiny861" => "__AVR_ATtiny861__", 65 | "attiny861a" => "__AVR_ATtiny861A__", 66 | "attiny87" => "__AVR_ATtiny87__", 67 | "attiny88" => "__AVR_ATtiny88__", 68 | "atmega603" => "__AVR_ATmega603__", 69 | "at43usb355" => "__AVR_AT43USB355__", 70 | "atmega103" => "__AVR_ATmega103__", 71 | "at43usb320" => "__AVR_AT43USB320__", 72 | "at90usb82" => "__AVR_AT90USB82__", 73 | "at90usb162" => "__AVR_AT90USB162__", 74 | "atmega8u2" => "__AVR_ATmega8U2__", 75 | "atmega16u2" => "__AVR_ATmega16U2__", 76 | "atmega32u2" => "__AVR_ATmega32U2__", 77 | "attiny167" => "__AVR_ATtiny167__", 78 | "at76c711" => "__AVR_AT76C711__", 79 | "atmega48" => "__AVR_ATmega48__", 80 | "atmega48a" => "__AVR_ATmega48A__", 81 | "atmega48p" => "__AVR_ATmega48P__", 82 | "atmega8" => "__AVR_ATmega8__", 83 | "atmega8515" => "__AVR_ATmega8515__", 84 | "atmega8535" => "__AVR_ATmega8535__", 85 | "atmega88" => "__AVR_ATmega88__", 86 | "atmega88a" => "__AVR_ATmega88A__", 87 | "atmega88p" => "__AVR_ATmega88P__", 88 | "atmega88pa" => "__AVR_ATmega88PA__", 89 | "atmega8hva" => "__AVR_ATmega8HVA__", 90 | "at90pwm1" => "__AVR_AT90PWM1__", 91 | "at90pwm2" => "__AVR_AT90PWM2__", 92 | "at90pwm2b" => "__AVR_AT90PWM2B__", 93 | "at90pwm3" => "__AVR_AT90PWM3__", 94 | "at90pwm3b" => "__AVR_AT90PWM3B__", 95 | "at90pwm81" => "__AVR_AT90PWM81__", 96 | "at90can32" => "__AVR_AT90CAN32__", 97 | "at90can64" => "__AVR_AT90CAN64__", 98 | "at90pwm216" => "__AVR_AT90PWM216__", 99 | "at90pwm316" => "__AVR_AT90PWM316__", 100 | "at90scr100" => "__AVR_AT90SCR100__", 101 | "at90usb646" => "__AVR_AT90USB646__", 102 | "at90usb647" => "__AVR_AT90USB647__", 103 | "at94k" => "__AVR_AT94K__", 104 | "atmega16" => "__AVR_ATmega16__", 105 | "atmega161" => "__AVR_ATmega161__", 106 | "atmega162" => "__AVR_ATmega162__", 107 | "atmega163" => "__AVR_ATmega163__", 108 | "atmega164a" => "__AVR_ATmega164A__", 109 | "atmega164p" => "__AVR_ATmega164P__", 110 | "atmega165" => "__AVR_ATmega165__", 111 | "atmega165a" => "__AVR_ATmega165A__", 112 | "atmega165p" => "__AVR_ATmega165P__", 113 | "atmega168" => "__AVR_ATmega168__", 114 | "atmega168a" => "__AVR_ATmega168A__", 115 | "atmega168p" => "__AVR_ATmega168P__", 116 | "atmega169" => "__AVR_ATmega169__", 117 | "atmega169a" => "__AVR_ATmega169A__", 118 | "atmega169p" => "__AVR_ATmega169P__", 119 | "atmega169pa" => "__AVR_ATmega169PA__", 120 | "atmega16a" => "__AVR_ATmega16A__", 121 | "atmega16hva" => "__AVR_ATmega16HVA__", 122 | "atmega16hva2" => "__AVR_ATmega16HVA2__", 123 | "atmega16hvb" => "__AVR_ATmega16HVB__", 124 | "atmega16hvbrevb" => "__AVR_ATmega16HVBREVB__", 125 | "atmega16m1" => "__AVR_ATmega16M1__", 126 | "atmega16u4" => "__AVR_ATmega16U4__", 127 | "atmega32" => "__AVR_ATmega32__", 128 | "atmega323" => "__AVR_ATmega323__", 129 | "atmega324a" => "__AVR_ATmega324A__", 130 | "atmega324p" => "__AVR_ATmega324P__", 131 | "atmega324pa" => "__AVR_ATmega324PA__", 132 | "atmega325" => "__AVR_ATmega325__", 133 | "atmega325a" => "__AVR_ATmega325A__", 134 | "atmega325p" => "__AVR_ATmega325P__", 135 | "atmega3250" => "__AVR_ATmega3250__", 136 | "atmega3250a" => "__AVR_ATmega3250A__", 137 | "atmega3250p" => "__AVR_ATmega3250P__", 138 | "atmega328" => "__AVR_ATmega328__", 139 | "atmega328p" => "__AVR_ATmega328P__", 140 | "atmega329" => "__AVR_ATmega329__", 141 | "atmega329a" => "__AVR_ATmega329A__", 142 | "atmega329p" => "__AVR_ATmega329P__", 143 | "atmega329pa" => "__AVR_ATmega329PA__", 144 | "atmega3290" => "__AVR_ATmega3290__", 145 | "atmega3290a" => "__AVR_ATmega3290A__", 146 | "atmega3290p" => "__AVR_ATmega3290P__", 147 | "atmega32c1" => "__AVR_ATmega32C1__", 148 | "atmega32hvb" => "__AVR_ATmega32HVB__", 149 | "atmega32hvbrevb" => "__AVR_ATmega32HVBREVB__", 150 | "atmega32m1" => "__AVR_ATmega32M1__", 151 | "atmega32u4" => "__AVR_ATmega32U4__", 152 | "atmega32u6" => "__AVR_ATmega32U6__", 153 | "atmega406" => "__AVR_ATmega406__", 154 | "atmega64" => "__AVR_ATmega64__", 155 | "atmega640" => "__AVR_ATmega640__", 156 | "atmega644" => "__AVR_ATmega644__", 157 | "atmega644a" => "__AVR_ATmega644A__", 158 | "atmega644p" => "__AVR_ATmega644P__", 159 | "atmega644pa" => "__AVR_ATmega644PA__", 160 | "atmega645" => "__AVR_ATmega645__", 161 | "atmega645a" => "__AVR_ATmega645A__", 162 | "atmega645p" => "__AVR_ATmega645P__", 163 | "atmega6450" => "__AVR_ATmega6450__", 164 | "atmega6450a" => "__AVR_ATmega6450A__", 165 | "atmega6450p" => "__AVR_ATmega6450P__", 166 | "atmega649" => "__AVR_ATmega649__", 167 | "atmega649a" => "__AVR_ATmega649A__", 168 | "atmega6490" => "__AVR_ATmega6490__", 169 | "atmega6490a" => "__AVR_ATmega6490A__", 170 | "atmega6490p" => "__AVR_ATmega6490P__", 171 | "atmega649p" => "__AVR_ATmega649P__", 172 | "atmega64c1" => "__AVR_ATmega64C1__", 173 | "atmega64hve" => "__AVR_ATmega64HVE__", 174 | "atmega64m1" => "__AVR_ATmega64M1__", 175 | "m3000" => "__AVR_M3000__", 176 | "at90can128" => "__AVR_AT90CAN128__", 177 | "at90usb1286" => "__AVR_AT90USB1286__", 178 | "at90usb1287" => "__AVR_AT90USB1287__", 179 | "atmega128" => "__AVR_ATmega128__", 180 | "atmega1280" => "__AVR_ATmega1280__", 181 | "atmega1281" => "__AVR_ATmega1281__", 182 | "atmega1284p" => "__AVR_ATmega1284P__", 183 | "atmega2560" => "__AVR_ATmega2560__", 184 | "atmega2561" => "__AVR_ATmega2561__", 185 | "atxmega16a4" => "__AVR_ATxmega16A4__", 186 | "atxmega16d4" => "__AVR_ATxmega16D4__", 187 | "atxmega32a4" => "__AVR_ATxmega32A4__", 188 | "atxmega32d4" => "__AVR_ATxmega32D4__", 189 | "atxmega64a3" => "__AVR_ATxmega64A3__", 190 | "atxmega64d3" => "__AVR_ATxmega64D3__", 191 | "atxmega64a1" => "__AVR_ATxmega64A1__", 192 | "atxmega64a1u" => "__AVR_ATxmega64A1U__", 193 | "atxmega128a3" => "__AVR_ATxmega128A3__", 194 | "atxmega128d3" => "__AVR_ATxmega128D3__", 195 | "atxmega192a3" => "__AVR_ATxmega192A3__", 196 | "atxmega192d3" => "__AVR_ATxmega192D3__", 197 | "atxmega256a3" => "__AVR_ATxmega256A3__", 198 | "atxmega256a3b" => "__AVR_ATxmega256A3B__", 199 | "atxmega256d3" => "__AVR_ATxmega256D3__", 200 | "atxmega128a1" => "__AVR_ATxmega128A1__", 201 | "atxmega128a1u" => "__AVR_ATxmega128A1U__", 202 | "attiny4" => "__AVR_ATtiny4__", 203 | "attiny5" => "__AVR_ATtiny5__", 204 | "attiny9" => "__AVR_ATtiny9__", 205 | "attiny10" => "__AVR_ATtiny10__", 206 | "attiny20" => "__AVR_ATtiny20__", 207 | "attiny40" => "__AVR_ATtiny40__"); 208 | 209 | } 210 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php: -------------------------------------------------------------------------------- 1 | ^[ (hex 0x1B) and 27 | * [, and ends with m. The color code is placed in between. Multiple 28 | * color codes can be included, separated by semicolon. 29 | */ 30 | function convertANSItoHTML($text) 31 | { 32 | $FORMAT = array( 33 | 0 => NULL, // reset modes to default 34 | 1 => "b", // bold 35 | 3 => "i", // italics 36 | 4 => "u", // underline 37 | 9 => "del", // strikethrough 38 | 30 => "black", // foreground colors 39 | 31 => "red", 40 | 32 => "green", 41 | 33 => "yellow", 42 | 34 => "blue", 43 | 35 => "purple", 44 | 36 => "cyan", 45 | 37 => "white", 46 | 40 => "black", // background colors 47 | 41 => "red", 48 | 42 => "green", 49 | 43 => "yellow", 50 | 44 => "blue", 51 | 45 => "purple", 52 | 46 => "cyan", 53 | 47 => "white"); 54 | // Matches ANSI escape sequences, starting with ^[[ and ending with m. 55 | // Valid characters inbetween are numbers and single semicolons. These 56 | // characters are stored in register 1. 57 | // 58 | // Examples: ^[[1;31m ^[[0m 59 | $REGEX = "/\x1B\[((?:\d+;?)*)m/"; 60 | 61 | $text = htmlspecialchars($text); 62 | $stack = array(); 63 | 64 | // ANSI escape sequences are located in the input text. Each color code 65 | // is replaced with the appropriate HTML tag. At the same time, the 66 | // corresponding closing tag is pushed on to the stack. When the reset 67 | // code '0' is found, it is replaced with all the closing tags in the 68 | // stack (LIFO order). 69 | while (preg_match($REGEX, $text, $matches)) 70 | { 71 | $replacement = ""; 72 | foreach (explode(";", $matches[1]) as $mode) 73 | { 74 | switch ($mode) 75 | { 76 | case 0: 77 | while ($stack) 78 | $replacement .= array_pop($stack); 79 | break; 80 | case 1: 81 | case 3: 82 | case 4: 83 | case 9: 84 | $replacement .= "<$FORMAT[$mode]>"; 85 | array_push($stack, ""); 86 | break; 87 | case 30: 88 | case 31: 89 | case 32: 90 | case 33: 91 | case 34: 92 | case 35: 93 | case 36: 94 | case 37: 95 | $replacement .= ""; 96 | array_push($stack, ""); 97 | break; 98 | case 40: 99 | case 41: 100 | case 42: 101 | case 43: 102 | case 44: 103 | case 45: 104 | case 46: 105 | case 47: 106 | $replacement .= ""; 107 | array_push($stack, ""); 108 | break; 109 | default: 110 | error_log(__FUNCTION__."(): Unhandled ANSI code '$mode'"); 111 | break; 112 | } 113 | } 114 | $text = preg_replace($REGEX, $replacement, $text, 1); 115 | } 116 | 117 | // Close any tags left in the stack, in case the input text didn't. 118 | while ($stack) 119 | $text .= array_pop($stack); 120 | 121 | return $text; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php: -------------------------------------------------------------------------------- 1 | main() function 22 | * - lack of function prototypes 23 | * 24 | * A skeleton file is provided in the Arduino core files that contains a 25 | * main() function. Its contents have to be linked to the output file later. 26 | * The prototypes of the functions defined in the input file should be added 27 | * above the code. This is required to avoid compiler errors regarding undefined 28 | * functions. 29 | * 30 | * The programmer is not aware of this modifications to his code. In case of a 31 | * compiler error, the line numbering would be wrong. To avoid this issue, a 32 | * \#line preprocessor directive is used. Thus it is ensured that the line 33 | * numbering in the output file will be the same as the input file. 34 | * 35 | * A regular expression is used to match function definitions in the input file. 36 | * Consequently this process will never be as sophisticated as a lexical analyzer. 37 | * Thus, some valid constructs cannot be matched. These include: 38 | * - definitions that are split across multiple lines 39 | * - definitions for variadic functions 40 | * - typedefs for the return value or the parameters 41 | * - pointers to functions 42 | * - arrays, structs, and unions 43 | */ 44 | 45 | /** 46 | * \param string $code The original code of the sketch 47 | * \return string A copy of the code with no comments, single- or double- quoted strings 48 | * or pre-processor directives 49 | */ 50 | function removeCommentsDirectivesQuotes($code) 51 | { 52 | // Use a copy of the code and strip comments, pre-processor directives, single- and double-quoted strings 53 | 54 | $regex = "/(\'.\')|(\"(?:[^\"\\\\]|\\\\.)*\")|(\/\/.*?$)|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(^\s*\#.*?$)/m"; 55 | 56 | // Replace every match of the regular expression with a whitespace 57 | 58 | $return_code = preg_replace($regex, " ", $code); 59 | 60 | return $return_code; 61 | } 62 | 63 | /** 64 | * \param string $code The code returned from removeCommentsDirectivesQuotes function 65 | * \return string The input code having all top level braces collapsed 66 | */ 67 | function emptyBraces($code) 68 | { 69 | // For every line of the code remove all the contents of top level braces 70 | 71 | $nesting = 0; 72 | $start = 0; 73 | $return_code = ""; 74 | // Use the code as an array of characters 75 | $length = strlen($code); 76 | for ($i = 0; $i < $length; $i++) { 77 | 78 | if ($code[$i] == "{") { 79 | if ($nesting == 0) { 80 | $return_code .= substr($code, $start, $i + 1 - $start); 81 | } 82 | $nesting++; 83 | continue; 84 | } 85 | if ($code[$i] == "}") { 86 | $nesting--; 87 | if ($nesting == 0) { 88 | $start = $i; 89 | } 90 | continue; 91 | 92 | } 93 | } 94 | $return_code .= substr($code, $start, $length - $start); 95 | 96 | return $return_code; 97 | } 98 | 99 | /** 100 | * \param string $code The code returned from empty_braces function 101 | * \return array An array including any prototypes found in the original code 102 | */ 103 | function findExistingPrototypes(&$code) 104 | { 105 | // In this case, the original code is used. Existing prototypes are matched, stored, and then removed from 106 | //the code, so that in the next step the compiler knows which prototypes should really be generated 107 | $existing_prototypes = array(); 108 | $regex = "/[\w\[\]\*]+\s+[&\[\]\*\w\s]+\([&,\[\]\*\w\s]*\)(?=\s*;)/m"; 109 | 110 | if (preg_match_all($regex, $code, $matches)) { 111 | $existing_prototypes = $matches[0]; 112 | } 113 | 114 | $code = preg_replace($regex, " ", $code); 115 | 116 | return $existing_prototypes; 117 | } 118 | 119 | /** 120 | * \param string $code The sketch code provided to the compiler 121 | * \param array $existing_prototypes Array of prototypes returned by findExistingPrototypes function 122 | * \return string The string including the function prototypes for the code 123 | */ 124 | function generatePrototypes($code, $existing_prototypes) 125 | { 126 | // This function uses a regular expression to match all function declarations, generate the 127 | // respective prototype and store all the prototypes in a string 128 | $regex = "/[\w\[\]\*]+\s+[&\[\]\*\w\s]+\([&,\[\]\*\w\s]*\)(?=\s*\{)/m"; 129 | 130 | $function_prototypes = ""; 131 | if (preg_match_all($regex, $code, $matches)) { 132 | 133 | foreach ($matches[0] as $match) { 134 | 135 | if (!empty($existing_prototypes)) { 136 | /* 137 | * If a prototype match has no parameters, two prototypes are generated, one with no parameters and 138 | * one with parameter void. Then the code searches if one of them already exists in the original code 139 | */ 140 | if (preg_match("/\(\s*\)/", $match)) { 141 | $match_void = preg_replace("/(\(\s*\))/", "(void)", $match); 142 | if (in_array($match_void, $existing_prototypes)) { 143 | continue; 144 | } 145 | } 146 | // If none of the above was true, check if the prototype exists 147 | if (in_array($match, $existing_prototypes)) { 148 | continue; 149 | } 150 | } 151 | // If everything is ok, add the prototype to the return value 152 | $function_prototypes .= $match . ";\n"; 153 | } 154 | } 155 | return $function_prototypes; 156 | } 157 | 158 | /** 159 | * \param string $code The sketch code 160 | * \return int The position where function prototypes should be placed 161 | */ 162 | function insertionPosition($code) 163 | { 164 | // Use the following regular expression to match whitespaces, single- and multiline comments and preprocessor directives 165 | $regex = "/(\s+|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(\/\/.*?$)|(\#(?:\\\\\\n|.)*))/m"; 166 | 167 | // Then find all the matches in the original code and count the offset of each one. 168 | preg_match_all($regex, $code, $matches, PREG_OFFSET_CAPTURE); 169 | 170 | $prev_position = 0; 171 | $position = 0; 172 | // The second offset of each matches[0] object contains the starting position (string index) of the match in the code 173 | // 174 | foreach ($matches[0] as $match) { 175 | // In case of a mismatch between prev_position and the beginning index of the current match, a non matching 176 | // expression exists between the last two matches. This is the position where the prototypes should be placed. 177 | // In other words, this is the first line of the code that is not a whitespace, comment, or preprocessor directive 178 | if ($match[1] != $prev_position) { 179 | $position = $prev_position - 1; 180 | break; 181 | } 182 | $prev_position += strlen($match[0]); 183 | } 184 | // If position is set to -1, there have been found no matches to the regular expression, so it must be set back to zero 185 | if ($position == -1) { 186 | $position = 0; 187 | } 188 | return $position; 189 | } 190 | 191 | /** 192 | * \param string $code The initial sketch code 193 | * \param $function_prototypes The function prototypes returned by generatePrototypes function 194 | * \param int $position The position to place the prototypes returned by insertion_position function 195 | * \return string Valid c++ code 196 | */ 197 | function buildCode($code, $function_prototypes, $position) 198 | { 199 | 200 | // To build the final code, the compiler starts adding every character of the original string, until the position 201 | // found by insertionPosition is reached. Then, the function prototypes are added, as well as a preprocessor 202 | //directive to fix the line numbering. 203 | $line = 1; 204 | $return_code = ""; 205 | if (!($position == 0)) { 206 | for ($i = 0; $i <= $position; $i++) { 207 | 208 | $return_code .= $code[$i]; 209 | if ($code[$i] == "\n") { 210 | $line++; 211 | } 212 | 213 | } 214 | } 215 | 216 | // Include the Arduino header file 217 | $return_code .= "#include \n"; 218 | // Then insert the prototypes, and finally the rest of the code 219 | $return_code .= $function_prototypes . "#line $line\n"; 220 | if ($position == 0) 221 | $next_pos = 0; 222 | else 223 | $next_pos = $position + 1; 224 | 225 | $length = strlen($code); 226 | for ($i = $next_pos; $i < $length; $i++) { 227 | $return_code .= $code[$i]; 228 | } 229 | 230 | return $return_code; 231 | } 232 | 233 | function convertInoToCpp($code, $filename = null) 234 | { 235 | // Remove comments, preprocessor directives, single- and double- quotes 236 | $no_comms_code = $this->removeCommentsDirectivesQuotes($code); 237 | // Remove any code between all top level braces 238 | $empty_braces_code = $this->emptyBraces($no_comms_code); 239 | // Find already existing prototypes 240 | $existing_prototypes = $this->findExistingPrototypes($empty_braces_code); 241 | // Generate prototypes that do not already exist 242 | $function_prototypes = $this->generatePrototypes($empty_braces_code, $existing_prototypes); 243 | // Find the right place to insert the function prototypes (after any preprocessor directives, comments, 244 | // before any function declaration) 245 | $insertion_position = $this->insertionPosition($code); 246 | 247 | $new_code = "#line 1\n"; 248 | // Add a preprocessor directive for line numbering. 249 | if ($filename) { 250 | $new_code .= "#line 1 \"$filename\"\n"; 251 | } 252 | 253 | // Build the new code for the cpp file that will eventually be compiled 254 | $new_code .= $this->buildCode($code, $function_prototypes, $insertion_position); 255 | 256 | return $new_code; 257 | 258 | } 259 | 260 | 261 | /** 262 | * \brief Decodes and performs validation checks on input data. 263 | * 264 | * \param string $request The JSON-encoded compile request. 265 | * \return The value encoded in JSON in appropriate PHP type or null. 266 | */ 267 | function validateInput($request) 268 | { 269 | $request = json_decode($request, true); 270 | 271 | // Request must be successfully decoded. 272 | if ($request === null) 273 | return null; 274 | // Request must contain certain entities. 275 | if (!(array_key_exists("format", $request) 276 | && array_key_exists("version", $request) 277 | && array_key_exists("files", $request) 278 | && array_key_exists("libraries", $request) 279 | && ((array_key_exists("build", $request) 280 | && is_array($request["build"]) 281 | && array_key_exists("mcu", $request["build"]) 282 | && array_key_exists("f_cpu", $request["build"]) 283 | && array_key_exists("core", $request["build"])) 284 | || array_key_exists("fqbn", $request)) 285 | && is_array($request["files"])) 286 | ) { 287 | return null; 288 | } 289 | 290 | if (array_key_exists("build", $request)) { 291 | 292 | // Leonardo-specific flags. 293 | if (array_key_exists("variant", $request["build"]) && $request["build"]["variant"] == "leonardo") 294 | if (!(array_key_exists("vid", $request["build"]) 295 | && array_key_exists("pid", $request["build"])) 296 | ) 297 | return null; 298 | 299 | // Values used as command-line arguments may not contain any special 300 | // characters. This is a serious security risk. 301 | $values = array("version", "mcu", "f_cpu", "core", "vid", "pid"); 302 | if (array_key_exists("variant", $request["build"])) { 303 | $values[] = "variant"; 304 | } 305 | foreach ($values as $i) { 306 | if (isset($request["build"][$i]) && escapeshellcmd($request["build"][$i]) != $request["build"][$i]) { 307 | return null; 308 | } 309 | } 310 | } 311 | 312 | $values = array("fqbn", "vid", "pid"); 313 | foreach ($values as $i) { 314 | if (isset($request[$i]) && escapeshellcmd($request[$i]) != $request[$i]) { 315 | return null; 316 | } 317 | } 318 | 319 | // Request is valid. 320 | return $request; 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php: -------------------------------------------------------------------------------- 1 | success 31 | * and contains the response to be sent back to the user. 32 | */ 33 | function extractFiles($directory, $request_files, $lib_extraction) 34 | { 35 | // File extensions used by Arduino projects. They are put in a string, 36 | // separated by "|" to be used in regular expressions. They are also 37 | // used as keys in an array that will contain the paths of all the 38 | // extracted files. 39 | $allowedExtensions = array("c", "cpp", "h", "inc", "ino", "o", "S"); 40 | $files = array(); 41 | foreach ($allowedExtensions as $ext) 42 | $files[$ext] = array(); 43 | $allowedExtensions = implode("|", $allowedExtensions); 44 | // Matches filename that end with an appropriate extension. The name 45 | // without the extension is stored in registerd 1, the extension itself 46 | // in register 2. 47 | // 48 | // Examples: foo.c bar.cpp 49 | $extensionsRegex = "/(.*)\.($allowedExtensions)$/"; 50 | 51 | if (!file_exists($directory)) 52 | mkdir($directory, 0777, true); 53 | 54 | foreach ($request_files as $file) 55 | { 56 | $filename = $file["filename"]; 57 | $content = $file["content"]; 58 | $ignore = false; 59 | 60 | $failureResponse = array( 61 | "success" => false, 62 | "step" => 1, 63 | "message" => "Failed to extract file '$filename'."); 64 | 65 | // Filenames may not use the special directory "..". This is a 66 | // serious security risk. 67 | $directories = explode("/", "$directory/$filename"); 68 | if (in_array("..", $directories)) 69 | return $failureResponse; 70 | 71 | if (strpos($filename, DIRECTORY_SEPARATOR)) 72 | { 73 | $new_directory = pathinfo($filename, PATHINFO_DIRNAME); 74 | 75 | if (($lib_extraction === true) && ($new_directory !== "utility")) 76 | $ignore = true; 77 | if (!file_exists("$directory/$new_directory")) 78 | mkdir("$directory/$new_directory", 0777, true); 79 | // There is no reason to check whether mkdir() 80 | // succeeded, given that the call to 81 | // file_put_contents() that follows would fail 82 | // as well. 83 | 84 | } 85 | 86 | if (file_put_contents("$directory/$filename", $content) === false) 87 | return $failureResponse; 88 | 89 | if ($ignore) 90 | continue; 91 | 92 | if (preg_match($extensionsRegex, $filename, $matches)) 93 | $files[$matches[2]][] = "$directory/$matches[1]"; 94 | else 95 | error_log(__FUNCTION__."(): Unhandled file extension '$filename'"); 96 | } 97 | 98 | // All files were extracted successfully. 99 | return array("success" => true, "files" => $files); 100 | } 101 | 102 | /** 103 | * \brief Searches for files with specific extensions in a directory. 104 | * 105 | * \param string $directory The directory to search for files. 106 | * \param mixed $extensions An array of strings, the extensions to look for. 107 | * \return A list of files that have the appropriate extension. 108 | */ 109 | function get_files_by_extension($directory, $extensions) 110 | { 111 | if (is_string($extensions)) 112 | $extensions = array($extensions); 113 | 114 | $files = array(); 115 | foreach (scandir($directory) as $entry) 116 | if (is_file("$directory/$entry") && in_array(pathinfo("$directory/$entry", PATHINFO_EXTENSION), $extensions)) 117 | $files[] = $entry; 118 | 119 | return $files; 120 | } 121 | 122 | /** 123 | * \brief Executes a command and displays the command itself and its output. 124 | * 125 | * \param string $command The command to be executed. 126 | * 127 | * Simplifies the creation and debugging of pages that rely on multiple external 128 | * programs by "emulating" the execution of the requested command in a terminal 129 | * emulator. Can be useful during early stages of development. Replace with 130 | * exec() afterwards. 131 | * 132 | * To perform the command execution, passthru() is used. The string 133 | * 2\>&1 is appended to the command to ensure messages sent to standard 134 | * error are not lost. 135 | * 136 | * \warning It is not possible to redirect the standard error output to a file. 137 | */ 138 | function execWithDebugging($command, /** @noinspection PhpUnusedParameterInspection */ 139 | &$output, /** @noinspection PhpUnusedParameterInspection */ 140 | &$retval) 141 | { 142 | echo "$ $command\n"; 143 | passthru("$command 2>&1"); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Resources/config/routing.yml: -------------------------------------------------------------------------------- 1 | codebender_compiler_status_check: 2 | pattern: /status 3 | defaults: { _controller: CodebenderCompilerBundle:Default:status } 4 | 5 | codebender_compiler_test: 6 | pattern: /{authorizationKey}/test/ 7 | defaults: { _controller: CodebenderCompilerBundle:Default:test } 8 | 9 | codebender_compiler_homepage: 10 | pattern: /{authorizationKey}/{version} 11 | defaults: { _controller: CodebenderCompilerBundle:Default:index } 12 | 13 | codebender_compiler_delete_all: 14 | pattern: /{authorizationKey}/{version}/delete/all/ 15 | defaults: { _controller: CodebenderCompilerBundle:Default:deleteAllObjects } 16 | 17 | codebender_compiler_delete_specific: 18 | pattern: /{authorizationKey}/{version}/delete/{option}/{cachedObjectToDelete} 19 | defaults: { _controller: CodebenderCompilerBundle:Default:deleteSpecificObjects } 20 | 21 | # redirecting the root 22 | root: 23 | path: / 24 | defaults: 25 | _controller: FrameworkBundle:Redirect:urlRedirect 26 | path: /status 27 | permanent: true 28 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | compiler_handler.class: Codebender\CompilerBundle\Handler\CompilerHandler 3 | compiler_v2_handler.class: Codebender\CompilerBundle\Handler\CompilerV2Handler 4 | utility_handler.class: Codebender\CompilerBundle\Handler\UtilityHandler 5 | preprocessing_handler.class: Codebender\CompilerBundle\Handler\PreprocessingHandler 6 | postprocessing_handler.class: Codebender\CompilerBundle\Handler\PostprocessingHandler 7 | deletion_handler.class: Codebender\CompilerBundle\Handler\DeletionHandler 8 | 9 | services: 10 | compiler_handler: 11 | class: "%compiler_handler.class%" 12 | arguments: ["@preprocessing_handler", "@postprocessing_handler", "@utility_handler", "@compiler_logger", "%temp_dir%/%objdir%"] 13 | compiler_v2_handler: 14 | class: "%compiler_v2_handler.class%" 15 | arguments: ["@preprocessing_handler", "@postprocessing_handler", "@utility_handler", "@compiler_logger", "%temp_dir%/%objdir%"] 16 | utility_handler: 17 | class: "%utility_handler.class%" 18 | preprocessing_handler: 19 | class: "%preprocessing_handler.class%" 20 | postprocessing_handler: 21 | class: "%postprocessing_handler.class%" 22 | deletion_handler: 23 | class: "%deletion_handler.class%" 24 | arguments: ["%temp_dir%/%objdir%"] 25 | compiler_logger: 26 | class: Symfony\Bridge\Monolog\Logger 27 | arguments: [cmplr_log] 28 | calls: 29 | - [pushHandler, [@compiler_log_handler]] 30 | compiler_log_handler: 31 | class: Monolog\Handler\StreamHandler 32 | arguments: [%kernel.logs_dir%/compiler.log] 33 | -------------------------------------------------------------------------------- /Symfony/src/Codebender/CompilerBundle/Tests/Controller/DefaultControllerFunctionalTest.php: -------------------------------------------------------------------------------- 1 | request('GET', '/status'); 14 | 15 | $this->assertEquals($client->getResponse()->getContent(), '{"success":true,"status":"OK"}'); 16 | 17 | } 18 | 19 | public function testInvalidKey() 20 | { 21 | $client = static::createClient(); 22 | 23 | $client->request('GET', '/inValidKey/v1'); 24 | 25 | $this->assertEquals($client->getResponse()->getContent(), '{"success":false,"step":0,"message":"Invalid authorization key."}'); 26 | 27 | } 28 | 29 | public function testInvalidAPI() 30 | { 31 | $client = static::createClient(); 32 | 33 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 34 | 35 | $client->request('GET', '/' . $authorizationKey . '/v666'); 36 | 37 | $this->assertEquals($client->getResponse()->getContent(), '{"success":false,"step":0,"message":"Invalid API version."}'); 38 | 39 | } 40 | 41 | public function testInvalidInput() 42 | { 43 | $client = static::createClient(); 44 | 45 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 46 | 47 | $client->request('GET', '/' . $authorizationKey . '/v1'); 48 | 49 | $this->assertEquals($client->getResponse()->getContent(), '{"success":false,"step":0,"message":"Invalid input."}'); 50 | 51 | } 52 | 53 | public function testBlinkUnoSyntaxCheck() 54 | { 55 | $files = array(array("filename" => "Blink.ino", "content" => "int led = 13;\nvoid setup() {pinMode(led, OUTPUT);}\nvoid loop() {\ndigitalWrite(led, HIGH);\ndelay(1000);\ndigitalWrite(led, LOW);\ndelay(1000);\n}\n")); 56 | $format = "syntax"; 57 | $version = "105"; 58 | $libraries = array(); 59 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 60 | 61 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 62 | 63 | $client = static::createClient(); 64 | 65 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 66 | 67 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 68 | 69 | $response = json_decode($client->getResponse()->getContent(), true); 70 | 71 | $this->assertEquals($response["success"], true); 72 | $this->assertTrue(is_numeric($response["time"])); 73 | 74 | } 75 | 76 | public function testBlinkUnoCompile() 77 | { 78 | $files = array(array("filename" => "Blink.ino", "content" => "\nint led = 13;\nvoid setup() {\npinMode(led, OUTPUT);\n}\nvoid loop() {\ndigitalWrite(led, HIGH);\ndelay(1000);\ndigitalWrite(led, LOW);\ndelay(1000);\n}\n")); 79 | $format = "binary"; 80 | $version = "105"; 81 | $libraries = array(); 82 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 83 | 84 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 85 | 86 | $client = static::createClient(); 87 | 88 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 89 | 90 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 91 | 92 | $response = json_decode($client->getResponse()->getContent(), true); 93 | 94 | $this->assertEquals($response["success"], true); 95 | $this->assertTrue(is_numeric($response["time"])); 96 | $this->assertTrue(is_numeric($response["size"])); 97 | 98 | $objectFilesPath = $client->getContainer()->getParameter('temp_dir') . '/' . $client->getContainer()->getParameter('objdir'); 99 | $coreObjectLibrary = glob("$objectFilesPath/*__v105__hardware__arduino__cores__arduino________atmega328p_16000000_arduino_standard_null_null_______core.a"); 100 | $this->assertTrue(count($coreObjectLibrary) > 0); 101 | } 102 | 103 | public function testBlinkUnoSyntaxCheckError() 104 | { 105 | $files = array(array("filename" => "Blink.ino", "content" => "\nint led = 13\nvoid setup() {\npinMode(led, OUTPUT);\npinMode(led);\n}\nvoid loop() {\ndigitalWrite(led, HIGH);\ndelay(1000);\ndigitalWrite(led, LOW);\ndelay(1000);\n}\n")); 106 | $format = "syntax"; 107 | $version = "105"; 108 | $libraries = array(); 109 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 110 | 111 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 112 | 113 | $client = static::createClient(); 114 | 115 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 116 | 117 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 118 | 119 | $response = json_decode($client->getResponse()->getContent(), true); 120 | 121 | $this->assertEquals($response["success"], false); 122 | $this->assertEquals($response["success"], false); 123 | $this->assertEquals($response["step"], 4); 124 | $this->assertContains("Blink.ino:2:13:", $response["message"]); 125 | $this->assertContains("expected ';' after top level declarator", $response["message"]); 126 | $this->assertContains("no matching function for call to 'pinMode'", $response["message"]); 127 | $this->assertContains("candidate function not viable: requires 2 arguments, but 1 was provided", $response["message"]); 128 | // $this->assertContains("2 errors generated.", $response["message"]); //unfortunately we no longer show how many errors were generated 129 | } 130 | 131 | public function testBlinkUnoCompileError() 132 | { 133 | $files = array(array("filename" => "Blink.ino", "content" => "\nint led = 13\nvoid setup() {\npinMode(led, OUTPUT);\npinMode(led);\n}\nvoid loop() {\ndigitalWrite(led, HIGH);\ndelay(1000);\ndigitalWrite(led, LOW);\n delay(1000);\n}\n")); 134 | $format = "binary"; 135 | $version = "105"; 136 | $libraries = array(); 137 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 138 | 139 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 140 | 141 | $client = static::createClient(); 142 | 143 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 144 | 145 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 146 | 147 | $response = json_decode($client->getResponse()->getContent(), true); 148 | 149 | $this->assertEquals($response["success"], false); 150 | $this->assertEquals($response["step"], 4); 151 | $this->assertContains("Blink.ino:2:13:", $response["message"]); 152 | $this->assertContains("expected ';' after top level declarator", $response["message"]); 153 | $this->assertContains("no matching function for call to 'pinMode'", $response["message"]); 154 | $this->assertContains("candidate function not viable: requires 2 arguments, but 1 was provided", $response["message"]); 155 | // $this->assertContains("2 errors generated.", $response["message"]); //unfortunately we no longer show how many errors were generated 156 | } 157 | 158 | public function testExternalVariant() 159 | { 160 | $files = array(array('filename' => 'Blink.ino', 'content' => "void setup(){}\nvoid loop(){}\n")); 161 | $format = 'binary'; 162 | $version = '105'; 163 | $libraries = array(); 164 | $build = array('mcu' => 'atmega32u4', 'f_cpu' => '8000000', 'core' => 'arduino', 'variant' => 'flora', 'pid' => '0x8004', 'vid' => '0x239A'); 165 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 166 | 167 | $client = static::createClient(); 168 | 169 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 170 | 171 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 172 | 173 | $response = json_decode($client->getResponse()->getContent(), true); 174 | 175 | $this->assertEquals($response['success'], true); 176 | $objectFilesPath = $client->getContainer()->getParameter('temp_dir') . '/' . $client->getContainer()->getParameter('objdir'); 177 | $coreObjectLibrary = glob("$objectFilesPath/*v105__hardware__arduino__cores__arduino________atmega32u4_8000000_arduino_flora_0x239A_0x8004_______core.a"); 178 | 179 | $this->assertTrue(count($coreObjectLibrary) > 0); 180 | } 181 | 182 | public function testExternalCore() 183 | { 184 | $files = array(array('filename' => 'Blink.ino', 'content' => "void setup(){}\nvoid loop(){}\n")); 185 | $format = 'binary'; 186 | $version = '105'; 187 | $libraries = array(); 188 | $build = array('mcu' => 'attiny85', 'f_cpu' => '8000000', 'core' => 'tiny'); 189 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 190 | 191 | $client = static::createClient(); 192 | 193 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 194 | 195 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 196 | 197 | $response = json_decode($client->getResponse()->getContent(), true); 198 | 199 | $this->assertEquals($response['success'], true); 200 | $objectFilesPath = $client->getContainer()->getParameter('temp_dir') . '/' . $client->getContainer()->getParameter('objdir'); 201 | $externalCoresPath = pathinfo($client->getContainer()->getParameter('external_core_files'), PATHINFO_BASENAME); 202 | $coreObjectLibrary = glob("$objectFilesPath/*__{$externalCoresPath}__tiny__cores__tiny________attiny85_8000000_tiny__null_null_______core.a"); 203 | 204 | $this->assertTrue(count($coreObjectLibrary) > 0); 205 | } 206 | 207 | public function testArchiveIsCreated() 208 | { 209 | $files = array(array('filename' => 'Blink.ino', 'content' => "void setup(){}\nvoid loop(){}\n")); 210 | $format = 'binary'; 211 | $version = '105'; 212 | $libraries = array(); 213 | $build = array('mcu' => 'atmega328p', 'f_cpu' => '16000000', 'core' => 'arduino', 'variant' => 'standard'); 214 | $data = json_encode(array('files' => $files, 'archive' => true, 'format' => $format, 'version' => $version, 'libraries' => $libraries, 'build' => $build)); 215 | 216 | $client = static::createClient(); 217 | 218 | $authorizationKey = $client->getContainer()->getParameter('authorizationKey'); 219 | 220 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 221 | 222 | $response = json_decode($client->getResponse()->getContent(), true); 223 | 224 | 225 | $this->assertTrue(file_exists($response['archive'])); 226 | } 227 | 228 | public function testCleanedUpLinkerError() 229 | { 230 | $files = array(array('filename' => 'Linker.ino', 'content' => 'void loop() { }')); 231 | $format = 'binary'; 232 | $version = '105'; 233 | $libraries = array(); 234 | $build = array('mcu' => 'atmega328p', 'f_cpu' => '16000000', 'core' => 'arduino', 'variant' => 'standard'); 235 | $data = json_encode(array('files' => $files, 'archive' => true, 'format' => $format, 'version' => $version, 'libraries' => $libraries, 'build' => $build)); 236 | 237 | $client = static::createClient(); 238 | 239 | $authorizationKey = $client->getContainer()->getParameter('authorizationKey'); 240 | 241 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 242 | 243 | $response = json_decode($client->getResponse()->getContent(), true); 244 | 245 | $expectedLinkerError = "core.a(main.o): In function `main': 246 | main.cpp:(.text.main+0x8): undefined reference to `setup'"; 247 | 248 | $this->assertFalse($response['success']); 249 | $this->assertEquals($expectedLinkerError, $response['message']); 250 | } 251 | 252 | public function testEthernetCompileErrorRemovedLibraryPaths() 253 | { 254 | $files = array(array("filename" => "Blink.ino", "content" => "#include \nvoid setup() {\n}\nvoid loop() {\n}\n")); 255 | $format = "binary"; 256 | $version = "105"; 257 | $libraries = array('PseudoEthernet' => array('files' => array('filename' => 'Ethernet.h', 'content' => "#include \"SPI.h\"\n"))); 258 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 259 | 260 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 261 | 262 | $client = static::createClient(); 263 | 264 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 265 | 266 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 267 | 268 | $response = json_decode($client->getResponse()->getContent(), true); 269 | 270 | $this->assertEquals($response["success"], false); 271 | $this->assertEquals($response["step"], 4); 272 | $this->assertContains('(library file) PseudoEthernet/Ethernet.h:1:10: fatal error: \'SPI.h\' file not found', $response['message']); 273 | } 274 | 275 | public function testEthernetCompileErrorRemovedPersonalLibraryPaths() 276 | { 277 | $files = array(array("filename" => "Blink.ino", "content" => "#include \nvoid setup() {\n}\nvoid loop() {\n}\n")); 278 | $format = "binary"; 279 | $version = "105"; 280 | $libraries = array('4096_cb_personal_lib_PseudoEthernet' => array('files' => array('filename' => 'Ethernet.h', 'content' => "#include \"SPI.h\"\n"))); 281 | $build = array("mcu" => "atmega328p", "f_cpu" => "16000000", "core" => "arduino", "variant" => "standard"); 282 | 283 | $data = json_encode(array("files" => $files, "format" => $format, "version" => $version, "libraries" => $libraries, "build" => $build)); 284 | 285 | $client = static::createClient(); 286 | 287 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 288 | 289 | $client->request('POST', '/' . $authorizationKey . '/v1', array(), array(), array(), $data); 290 | 291 | $response = json_decode($client->getResponse()->getContent(), true); 292 | 293 | $this->assertEquals($response["success"], false); 294 | $this->assertEquals($response["step"], 4); 295 | $this->assertContains('(personal library file) PseudoEthernet/Ethernet.h:1:10: fatal error: \'SPI.h\' file not found', $response['message']); 296 | } 297 | 298 | public function testDeleteTinyCoreFiles() 299 | { 300 | $client = static::createClient(); 301 | 302 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 303 | 304 | $client->request('POST', '/' . $authorizationKey . '/v1/delete/code/tiny'); 305 | 306 | $response = json_decode($client->getResponse()->getContent(), true); 307 | 308 | $this->assertTrue($response['success']); 309 | $this->assertContains('tiny__null_null_______core.a' . "\n", $response['deletedFiles']); 310 | $this->assertContains('tiny__null_null_______core.a.LOCK', $response['deletedFiles']); 311 | $this->assertEmpty($response['notDeletedFiles']); 312 | 313 | $tempDirectory = $client->getContainer()->getParameter('temp_dir'); 314 | $objectsDirectory = $client->getContainer()->getParameter('objdir'); 315 | $objectsPath = $tempDirectory . '/' . $objectsDirectory; 316 | 317 | $fileSystemIterator = new \FilesystemIterator($objectsPath); 318 | foreach ($fileSystemIterator as $file) { 319 | $this->assertNotContains('tiny__null_null_______core.a' . "\n", $file->getFilename()); 320 | $this->assertNotContains('tiny__null_null_______core.a.LOCK', $file->getFilename()); 321 | } 322 | } 323 | 324 | public function testDeleteAllCachedObjects() 325 | { 326 | $client = static::createClient(); 327 | 328 | $authorizationKey = $client->getContainer()->getParameter("authorizationKey"); 329 | 330 | $client->request('POST', '/' . $authorizationKey . '/v1/delete/all/'); 331 | 332 | $response = json_decode($client->getResponse()->getContent(), true); 333 | 334 | $this->assertTrue($response['success']); 335 | $this->assertEmpty($response['Files not deleted']); 336 | 337 | $tempDirectory = $client->getContainer()->getParameter('temp_dir'); 338 | $objectsDirectory = $client->getContainer()->getParameter('objdir'); 339 | $objectsPath = $tempDirectory . '/' . $objectsDirectory; 340 | 341 | $fileSystemIterator = new \FilesystemIterator($objectsPath); 342 | $this->assertEquals(0, iterator_count($fileSystemIterator)); 343 | } 344 | 345 | public function testAutocomplete() 346 | { 347 | $this->markTestIncomplete('No tests for the code completion feature yet.'); 348 | } 349 | 350 | public function testIncorrectInputs() 351 | { 352 | $this->markTestIncomplete('No tests for invalid inputs yet'); 353 | } 354 | } 355 | -------------------------------------------------------------------------------- /Symfony/web/.htaccess: -------------------------------------------------------------------------------- 1 | # Use the front controller as index file. It serves as fallback solution when 2 | # every other rewrite/redirect fails (e.g. in an aliased environment without 3 | # mod_rewrite). Additionally, this reduces the matching process for the 4 | # startpage (path "/") because otherwise Apache will apply the rewritting rules 5 | # to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). 6 | DirectoryIndex app.php 7 | 8 | 9 | RewriteEngine On 10 | 11 | # Determine the RewriteBase automatically and set it as environment variable. 12 | # If you are using Apache aliases to do mass virtual hosting or installed the 13 | # project in a subdirectory, the base path will be prepended to allow proper 14 | # resolution of the app.php file and to redirect to the correct URI. It will 15 | # work in environments without path prefix as well, providing a safe, one-size 16 | # fits all solution. But as you do not need it in this case, you can comment 17 | # the following 2 lines to eliminate the overhead. 18 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ 19 | RewriteRule ^(.*) - [E=BASE:%1] 20 | 21 | # Redirect to URI without front controller to prevent duplicate content 22 | # (with and without `/app.php`). Only do this redirect on the initial 23 | # rewrite by Apache and not on subsequent cycles. Otherwise we would get an 24 | # endless redirect loop (request -> rewrite to front controller -> 25 | # redirect -> request -> ...). 26 | # So in case you get a "too many redirects" error or you always get redirected 27 | # to the startpage because your Apache does not expose the REDIRECT_STATUS 28 | # environment variable, you have 2 choices: 29 | # - disable this feature by commenting the following 2 lines or 30 | # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the 31 | # following RewriteCond (best solution) 32 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 33 | RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] 34 | 35 | # If the requested filename exists, simply serve it. 36 | # We only want to let Apache serve files and not directories. 37 | RewriteCond %{REQUEST_FILENAME} -f 38 | RewriteRule .? - [L] 39 | 40 | # Rewrite all other queries to the front controller. 41 | RewriteRule .? %{ENV:BASE}/app.php [L] 42 | 43 | 44 | 45 | 46 | # When mod_rewrite is not available, we instruct a temporary redirect of 47 | # the startpage to the front controller explicitly so that the website 48 | # and the generated links can still be used. 49 | RedirectMatch 302 ^/$ /app.php/ 50 | # RedirectTemp cannot be used instead 51 | 52 | 53 | -------------------------------------------------------------------------------- /Symfony/web/app.php: -------------------------------------------------------------------------------- 1 | register(true); 14 | */ 15 | 16 | require_once __DIR__.'/../app/AppKernel.php'; 17 | //require_once __DIR__.'/../app/AppCache.php'; 18 | 19 | $kernel = new AppKernel('prod', false); 20 | $kernel->loadClassCache(); 21 | //$kernel = new AppCache($kernel); 22 | Request::enableHttpMethodParameterOverride(); 23 | $request = Request::createFromGlobals(); 24 | $response = $kernel->handle($request); 25 | $response->send(); 26 | $kernel->terminate($request, $response); 27 | -------------------------------------------------------------------------------- /Symfony/web/app_dev.php: -------------------------------------------------------------------------------- 1 | loadClassCache(); 27 | Request::enableHttpMethodParameterOverride(); 28 | $request = Request::createFromGlobals(); 29 | $response = $kernel->handle($request); 30 | $response->send(); 31 | $kernel->terminate($request, $response); 32 | -------------------------------------------------------------------------------- /Symfony/web/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebndr/compiler/7f01d36c128f2c4a62e98f165347f376d1335e40/Symfony/web/apple-touch-icon.png -------------------------------------------------------------------------------- /Symfony/web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebndr/compiler/7f01d36c128f2c4a62e98f165347f376d1335e40/Symfony/web/favicon.ico -------------------------------------------------------------------------------- /Symfony/web/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | -------------------------------------------------------------------------------- /apache-config: -------------------------------------------------------------------------------- 1 | 2 | DocumentRoot /opt/codebender/compiler/Symfony/web 3 | DirectoryIndex index.php 4 | SetEnv APPLICATION_ENV "production" 5 | 6 | Options -Indexes +FollowSymLinks +MultiViews 7 | Require all granted 8 | AllowOverride All 9 | 10 | -------------------------------------------------------------------------------- /scripts/clear_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Clearing the cache" 4 | php app/console cache:clear --env=dev 5 | php app/console cache:clear --env=prod 6 | php app/console cache:clear --env=test 7 | -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | set -e 4 | 5 | PACKAGENAME=compiler 6 | 7 | if [[ "$OSTYPE" == "linux-gnu" ]]; then 8 | echo "Configuring environment for Linux" 9 | sudo apt-get update 10 | if [[ ! $TRAVIS ]]; then 11 | # Ubuntu Server (on AWS?) lacks UTF-8 for some reason. Give it that 12 | sudo locale-gen en_US.UTF-8 13 | # Make sure we have up-to-date stuff 14 | sudo apt-get install -y php5-intl 15 | fi 16 | # Install dependencies 17 | sudo apt-get install -y apache2 libapache2-mod-php5 php-pear php5-xdebug php5-curl php5-sqlite acl curl git 18 | # Enable Apache configs 19 | sudo a2enmod rewrite 20 | sudo a2enmod alias 21 | # Restart Apache 22 | sudo service apache2 restart 23 | elif [[ "$OSTYPE" == "darwin"* ]]; then 24 | # is there something comparable to this on os x? perhaps Homebrew 25 | echo "Configuring environment for OS X" 26 | fi 27 | 28 | if [[ ! $TRAVIS ]]; then 29 | #### Set Max nesting lvl to something Symfony is happy with 30 | export ADDITIONAL_PATH=`php -i | grep -F --color=never 'Scan this dir for additional .ini files'` 31 | echo 'xdebug.max_nesting_level=256' | sudo tee ${ADDITIONAL_PATH:42}/symfony2.ini 32 | fi 33 | 34 | if [[ $TRAVIS ]]; then 35 | HTTPDUSER="root" 36 | else 37 | HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1` 38 | fi 39 | 40 | if [[ ${#HTTPDUSER} -eq 0 ]]; then 41 | echo "Failed to set HTTPDUSER" 42 | echo `ps aux` 43 | exit 1 44 | fi 45 | 46 | sudo mkdir -p /opt/codebender 47 | sudo cp -r . /opt/codebender/$PACKAGENAME 48 | sudo chown -R `whoami`:$HTTPDUSER /opt/codebender/$PACKAGENAME 49 | cd /opt/codebender/$PACKAGENAME 50 | 51 | #Set permissions for app/cache and app/logs 52 | 53 | rm -rf Symfony/app/cache/* 54 | rm -rf Symfony/app/logs/* 55 | 56 | if [[ "$OSTYPE" == "linux-gnu" ]]; then 57 | 58 | if [[ ! $TRAVIS ]]; then 59 | 60 | mkdir -p `pwd`/Symfony/app/cache/ 61 | mkdir -p `pwd`/Symfony/app/logs/ 62 | 63 | sudo rm -rf `pwd`/Symfony/app/cache/* 64 | sudo rm -rf `pwd`/Symfony/app/logs/* 65 | 66 | sudo setfacl -R -m u:www-data:rwX -m u:`whoami`:rwX `pwd`/Symfony/app/cache `pwd`/Symfony/app/logs 67 | sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx `pwd`/Symfony/app/cache `pwd`/Symfony/app/logs 68 | fi 69 | 70 | elif [[ "$OSTYPE" == "darwin"* ]]; then 71 | 72 | HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1` 73 | sudo chmod +a "$HTTPDUSER allow delete,write,append,file_inherit,directory_inherit" Symfony/app/cache Symfony/app/logs 74 | sudo chmod +a "`whoami` allow delete,write,append,file_inherit,directory_inherit" Symfony/app/cache Symfony/app/logs 75 | fi 76 | 77 | cd Symfony 78 | 79 | # TODO: generate parameters.yml file somehow 80 | cp app/config/parameters.yml.dist app/config/parameters.yml 81 | 82 | ../scripts/install_dependencies.sh 83 | 84 | ../scripts/install_composer.sh 85 | 86 | ../scripts/warmup_cache.sh 87 | 88 | # TODO: Fix this crap later on (Apache config), it's all hardcoded now 89 | if [[ "$OSTYPE" == "linux-gnu" ]]; then 90 | sudo cp /opt/codebender/$PACKAGENAME/apache-config /etc/apache2/sites-available/codebender-compiler 91 | cd /etc/apache2/sites-enabled 92 | sudo ln -s ../sites-available/codebender-compiler 00-codebender-compiler.conf 93 | sudo service apache2 restart 94 | fi 95 | -------------------------------------------------------------------------------- /scripts/install_composer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Installing Dependencies" 4 | curl -s http://getcomposer.org/installer | php 5 | php composer.phar install 6 | -------------------------------------------------------------------------------- /scripts/install_dependencies.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sudo apt-get install -y unzip 3 | cd ~ 4 | wget https://github.com/codebendercc/arduino-core-files/archive/master.zip 5 | unzip -q master.zip 6 | sudo cp -r arduino-core-files-master /opt/codebender/codebender-arduino-core-files 7 | rm master.zip 8 | wget https://github.com/codebendercc/external_cores/archive/master.zip 9 | unzip -q master.zip 10 | sudo cp -r external_cores-master /opt/codebender/external-core-files 11 | cd - -------------------------------------------------------------------------------- /scripts/run_local_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Left here to be commited on git, in case dirname doesn't work as expected 4 | #echo "The script you are running has basename `basename $0`, dirname `dirname $0`" 5 | #echo "The present working directory is `pwd`" 6 | 7 | 8 | #Ask user to make sure we want to run this 9 | echo "NEVER run this script in production. It will purge your database to a clean state" 10 | read -r -p "Are you sure you want to run this? [y/N] " response 11 | case $response in 12 | [yY][eE][sS]|[yY]) 13 | # User accepted 14 | ;; 15 | *) 16 | # Abort 17 | exit 18 | ;; 19 | esac 20 | 21 | #Changing directory to Symfony, regardless where we are 22 | cd `dirname $0`/../Symfony 23 | 24 | set -x 25 | pwd 26 | 27 | ../scripts/install_composer.sh 28 | 29 | ../scripts/clear_cache.sh 30 | 31 | ../scripts/warmup_cache.sh 32 | 33 | ../scripts/run_tests.sh 34 | -------------------------------------------------------------------------------- /scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -x 4 | 5 | echo "Running Tests" 6 | if [[ $TRAVIS ]]; then 7 | bin/phpunit -c app/ --coverage-clover build/logs/clover.xml --stderr 8 | #bin/phpcpd --log-pmd build/pmd-cpd.xml --exclude app --exclude vendor --names-exclude *Test.php -n . 9 | #bin/phpmd src/Codebender/ xml cleancode,codesize,design,naming,unusedcode --exclude *Test.php --reportfile build/pmd.xml 10 | else 11 | bin/phpunit -c app/ --stderr --coverage-html=coverage/ 12 | 13 | echo "Running Copy-Paste-Detector" 14 | bin/phpcpd --exclude app --exclude vendor --names-exclude *Test.php -n . 15 | bin/phpmd src/Codebender/ xml cleancode,codesize,design,naming,unusedcode --exclude *Test.php 16 | fi 17 | -------------------------------------------------------------------------------- /scripts/warmup_cache.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Warming up the cache" 4 | php app/console cache:warmup --env=dev 5 | php app/console cache:warmup --env=prod 6 | php app/console cache:warmup --env=test 7 | --------------------------------------------------------------------------------