├── .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 |
4 |
5 |
6 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
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 | [](https://travis-ci.org/codebendercc/compiler)
4 | [](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, "$FORMAT[$mode]>");
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 |
--------------------------------------------------------------------------------