From 6e07cd53473a6e84693eb7cbf2f469f500aec846 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:06:57 +0200 Subject: [PATCH 01/25] Removed in_memory Security Providers (unused) --- Symfony/app/config/security.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Symfony/app/config/security.yml b/Symfony/app/config/security.yml index 243aa71..375143e 100644 --- a/Symfony/app/config/security.yml +++ b/Symfony/app/config/security.yml @@ -8,10 +8,7 @@ security: providers: in_memory: - memory: - users: - user: { password: userpass, roles: [ 'ROLE_USER' ] } - admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] } + memory: ~ firewalls: dev: From 0f56ce53f00f7fe2d311dcf13c4fb1bca997ffde Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:21:19 +0200 Subject: [PATCH 02/25] Replaced OR operator with || & explicit precedence --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 653c5cd..bdb4ae4 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -933,7 +933,7 @@ private function setLoggingParams($request, &$compiler_config, $temp_dir, $compi file_put_contents($compiler_config['logFileName'], ''); } - elseif(!array_key_exists('logging', $request) or !$request['logging']) + elseif(!array_key_exists('logging', $request)|| (!$request['logging'])) $compiler_config['logging'] = false; return array("success"=>true); From 8a30ae37109bdf2b89aa48000e5186d6fb885f56 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:28:43 +0200 Subject: [PATCH 03/25] Removed unnecessary __FILE__ variables It is good practice not to use it with Symfony, and this project is small enought that it's unnecessary --- .../Codebender/CompilerBundle/Handler/PostprocessingHandler.php | 2 +- .../src/Codebender/CompilerBundle/Handler/UtilityHandler.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php index b64ab45..fcbf238 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php @@ -107,7 +107,7 @@ function ansi_to_html($text) array_push($stack, ""); break; default: - error_log(__FUNCTION__."(): Unhandled ANSI code '$mode' in ".__FILE__); + error_log(__FUNCTION__."(): Unhandled ANSI code '$mode'"); break; } } diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php index b539f31..4b2c444 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php @@ -92,7 +92,7 @@ function extract_files($directory, $request_files, $lib_extraction) if (preg_match($REGEX, $filename, $matches)) $files[$matches[2]][] = "$directory/$matches[1]"; else - error_log(__FUNCTION__."(): Unhandled file extension '$filename' in ".__FILE__); + error_log(__FUNCTION__."(): Unhandled file extension '$filename'"); } // All files were extracted successfully. From 9aeed6c8e3a8d91858f3de5c90b29abf99473a8b Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:33:19 +0200 Subject: [PATCH 04/25] Added codebender favicon --- Symfony/web/favicon.ico | Bin 1150 -> 1150 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Symfony/web/favicon.ico b/Symfony/web/favicon.ico index 864803618e0888f8463c0b30038633c018f939cc..41b8b6e97040085b07f46a22de6683c2c8f3d660 100644 GIT binary patch literal 1150 zcmaiz%`QVx5P(lZLSj>CLg<2EK}3XvAWA&~I}uzv2^%|0YlLlILszVHVZ#H^2M}v} zw7##sC%I`vr}^&8IWu#9W==!M@yq7}-|=wV8^TZsVH%iXrag}e0bgODO>6xBXC3!v zigq_C60it8Y2X3+Cq-M)XN<8~8D($>A8-zb@B-i98rsh3Go}jWL~+e`Xo5L)sK6=g z!6m$bK4XkECrS>(wHt5`D=BN}5zs#i4`7V3&SfQG@CtJ<2IUmjvL%W>V-ko`!mvKx z@fs#!1GZAVjP|UqF$~5SYmR-fN7l%@?ZZ5ny96_^3hp7Ubpl^tPVBF?`MWR(3ow!D zO>{ZM{mvkp?_50p6}D0U*U(qaU_C4F4DtM!ElK!V8|$oijw$f&uH*T4pbiOS#a`Hx z2G}F(Y`*k?{n&;_@UF&Y`{y3n_v2f+g(I*gH{ibBy9u4|$G2F8&iCtH((U~c()v$$ w4*w&H^@;h~iaukC4!TGQf9$XJpYlz2pLlT>R3lPjoRxkCHFl1EwK?Yg0wUUHpa1{> literal 1150 zcmaizUr1AN6vuy3^oL%AsH~?RBQobI=ccaNk~J)QQD?41%~lUl4?1&O#PTUgotA-9 zsDZB9Dx!CTsTlUUw?V5x4YK5>5M*n+r|-FL<1!X8KKK0Y+4-K|Ip_DgLX_ZFS}O27 zD6VZ4Vy_V55P%DwO+Snf_;2^FO_X=lLt9ZPzz)z@c~ldI{Q@#slCUp96W9qfs%tQ*oXL6(4`+eocJ>~>XTi!Tx6`NE0#k>{2Oo} ztK9}W2EBZ;)|i=(L{i>6UU}sHFa>93DOU?()OGNh>)?K^U==8P)fsB(g!Z`H)Oe2K zAL8V3c}P=UQK;p237iK()-qO$m3q1_)5Uf>)l?g3abZDzzr3uhc^8WX1k|b(vZuwUYd`2nOcXxJ?f6`A^uQ+Js>k0*)1Z4Ms zn^LJ1IeVQ{e)veSS*BUf_2AsdWHfQT>0~mg)MIP0(fZmtg+pPwU~40@=~Q74tpCV* z?ho@%#bU9aI76NxIeHwFNF*?aMWwIcY>?`WCUqU3p`BrU7P-H#KQlGy-*EQ!{qC?| zBHyTwqR}XwX|T}E>o*E#8G_CNzUOjq9hiOEpwp*$E~o3w^mcAenG2uk(7mCIUZ>~% zB=me1mhaCn;Cq#;BX2o}t+|y3?+$Lc6{R^^&pjZF^ From e25959fda1547654f592a6053376421bc12edc57 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:38:31 +0200 Subject: [PATCH 05/25] Added stricter checks for successful extractions --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index bdb4ae4..21f303e 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -73,7 +73,7 @@ function main($request, $compiler_config) $files = array(); $tmp = $this->extractFiles($request["files"], $TEMP_DIR, $compiler_dir, $files["sketch_files"], "files"); - if ($tmp["success"] == false) + if ($tmp["success"] === false) return $tmp; // Add the compiler temp directory to the compiler_config struct. @@ -84,7 +84,7 @@ function main($request, $compiler_config) foreach($libraries as $library => $library_files){ $tmp = $this->extractFiles($library_files, $TEMP_DIR, $compiler_dir, $files["libs"][$library], "libraries/$library", true); - if ($tmp["success"] == false) + if ($tmp["success"] === false) return $tmp; } From b332d4a45734095392be607a7358b6e56eafd4ef Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:40:06 +0200 Subject: [PATCH 06/25] Added stricter checks for successful preprocessing Made a strict boolean check for the return value of the Header Preprocessing function --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 21f303e..febd021 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -112,7 +112,7 @@ function main($request, $compiler_config) // Step 3: Preprocess Header includes and determine which core files directory(CORE_DIR) will be used. $tmp = $this->preprocessHeaders($libraries, $include_directories, $compiler_dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $CORE_DIR, $CORE_OVERRIDE_DIR, $version, $core, $variant); - if ($tmp["success"] == false) + if ($tmp["success"] === false) return array_merge($tmp, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); // Log the names of the project files and the libraries used in it. From 7aa2d68d1612fb7905781e620f5a2430d7e0c860 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 02:47:19 +0200 Subject: [PATCH 07/25] Deleted Acme Bundle (Symfony2 Demo) --- Symfony/app/config/routing_dev.yml | 4 - Symfony/app/config/security.yml | 38 +++---- .../src/Acme/DemoBundle/AcmeDemoBundle.php | 9 -- .../DemoBundle/Controller/DemoController.php | 57 ---------- .../Controller/SecuredController.php | 68 ------------ .../Controller/WelcomeController.php | 18 ---- .../DependencyInjection/AcmeDemoExtension.php | 22 ---- .../EventListener/ControllerListener.php | 24 ----- .../src/Acme/DemoBundle/Form/ContactType.php | 20 ---- .../DemoBundle/Resources/config/routing.yml | 12 --- .../DemoBundle/Resources/config/services.xml | 18 ---- .../DemoBundle/Resources/public/css/demo.css | 101 ------------------ .../Resources/public/images/blue-arrow.png | Bin 181 -> 0 bytes .../public/images/field-background.gif | Bin 63 -> 0 bytes .../Resources/public/images/logo.gif | Bin 1698 -> 0 bytes .../Resources/public/images/search.png | Bin 737 -> 0 bytes .../public/images/welcome-configure.gif | Bin 3530 -> 0 bytes .../Resources/public/images/welcome-demo.gif | Bin 4053 -> 0 bytes .../public/images/welcome-quick-tour.gif | Bin 4770 -> 0 bytes .../Resources/views/Demo/contact.html.twig | 15 --- .../Resources/views/Demo/hello.html.twig | 9 -- .../Resources/views/Demo/index.html.twig | 14 --- .../Resources/views/Secured/hello.html.twig | 11 -- .../views/Secured/helloadmin.html.twig | 9 -- .../Resources/views/Secured/layout.html.twig | 6 -- .../Resources/views/Secured/login.html.twig | 35 ------ .../Resources/views/Welcome/index.html.twig | 83 -------------- .../Resources/views/layout.html.twig | 37 ------- .../Tests/Controller/DemoControllerTest.php | 17 --- .../Twig/Extension/DemoExtension.php | 81 -------------- 30 files changed, 19 insertions(+), 689 deletions(-) delete mode 100644 Symfony/src/Acme/DemoBundle/AcmeDemoBundle.php delete mode 100644 Symfony/src/Acme/DemoBundle/Controller/DemoController.php delete mode 100644 Symfony/src/Acme/DemoBundle/Controller/SecuredController.php delete mode 100644 Symfony/src/Acme/DemoBundle/Controller/WelcomeController.php delete mode 100644 Symfony/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php delete mode 100644 Symfony/src/Acme/DemoBundle/EventListener/ControllerListener.php delete mode 100644 Symfony/src/Acme/DemoBundle/Form/ContactType.php delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/config/routing.yml delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/config/services.xml delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/css/demo.css delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/blue-arrow.png delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/field-background.gif delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/logo.gif delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/search.png delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-configure.gif delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Resources/views/layout.html.twig delete mode 100644 Symfony/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php delete mode 100644 Symfony/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php diff --git a/Symfony/app/config/routing_dev.yml b/Symfony/app/config/routing_dev.yml index c45f361..ff93a02 100644 --- a/Symfony/app/config/routing_dev.yml +++ b/Symfony/app/config/routing_dev.yml @@ -12,7 +12,3 @@ _configurator: _main: resource: routing.yml - -# AcmeDemoBundle routes (to be removed) -_acme_demo: - resource: "@AcmeDemoBundle/Resources/config/routing.yml" diff --git a/Symfony/app/config/security.yml b/Symfony/app/config/security.yml index 375143e..370c37a 100644 --- a/Symfony/app/config/security.yml +++ b/Symfony/app/config/security.yml @@ -15,22 +15,22 @@ security: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false - login: - pattern: ^/demo/secured/login$ - security: false - - secured_area: - pattern: ^/demo/secured/ - form_login: - check_path: _security_check - login_path: _demo_login - logout: - path: _demo_logout - target: _demo - #anonymous: ~ - #http_basic: - # realm: "Secured Demo Area" - - access_control: - - { path: ^/demo/secured/hello/admin/, roles: ROLE_ADMIN } - #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } +# login: +# pattern: ^/demo/secured/login$ +# security: false +# +# secured_area: +# pattern: ^/demo/secured/ +# form_login: +# check_path: _security_check +# login_path: _demo_login +# logout: +# path: _demo_logout +# target: _demo +# #anonymous: ~ +# #http_basic: +# # realm: "Secured Demo Area" +# +# access_control: +# - { path: ^/demo/secured/hello/admin/, roles: ROLE_ADMIN } +# #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } diff --git a/Symfony/src/Acme/DemoBundle/AcmeDemoBundle.php b/Symfony/src/Acme/DemoBundle/AcmeDemoBundle.php deleted file mode 100644 index 269fc1e..0000000 --- a/Symfony/src/Acme/DemoBundle/AcmeDemoBundle.php +++ /dev/null @@ -1,9 +0,0 @@ - $name); - } - - /** - * @Route("/contact", name="_demo_contact") - * @Template() - */ - public function contactAction() - { - $form = $this->get('form.factory')->create(new ContactType()); - - $request = $this->get('request'); - if ($request->isMethod('POST')) { - $form->submit($request); - if ($form->isValid()) { - $mailer = $this->get('mailer'); - // .. setup a message and send it - // http://symfony.com/doc/current/cookbook/email.html - - $this->get('session')->getFlashBag()->set('notice', 'Message sent!'); - - return new RedirectResponse($this->generateUrl('_demo')); - } - } - - return array('form' => $form->createView()); - } -} diff --git a/Symfony/src/Acme/DemoBundle/Controller/SecuredController.php b/Symfony/src/Acme/DemoBundle/Controller/SecuredController.php deleted file mode 100644 index f6d3005..0000000 --- a/Symfony/src/Acme/DemoBundle/Controller/SecuredController.php +++ /dev/null @@ -1,68 +0,0 @@ -attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { - $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR); - } else { - $error = $request->getSession()->get(SecurityContext::AUTHENTICATION_ERROR); - } - - return array( - 'last_username' => $request->getSession()->get(SecurityContext::LAST_USERNAME), - 'error' => $error, - ); - } - - /** - * @Route("/login_check", name="_security_check") - */ - public function securityCheckAction() - { - // The security layer will intercept this request - } - - /** - * @Route("/logout", name="_demo_logout") - */ - public function logoutAction() - { - // The security layer will intercept this request - } - - /** - * @Route("/hello", defaults={"name"="World"}), - * @Route("/hello/{name}", name="_demo_secured_hello") - * @Template() - */ - public function helloAction($name) - { - return array('name' => $name); - } - - /** - * @Route("/hello/admin/{name}", name="_demo_secured_hello_admin") - * @Template() - */ - public function helloadminAction($name) - { - return array('name' => $name); - } -} diff --git a/Symfony/src/Acme/DemoBundle/Controller/WelcomeController.php b/Symfony/src/Acme/DemoBundle/Controller/WelcomeController.php deleted file mode 100644 index acceedf..0000000 --- a/Symfony/src/Acme/DemoBundle/Controller/WelcomeController.php +++ /dev/null @@ -1,18 +0,0 @@ -render('AcmeDemoBundle:Welcome:index.html.twig'); - } -} diff --git a/Symfony/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php b/Symfony/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php deleted file mode 100644 index 6dfcc82..0000000 --- a/Symfony/src/Acme/DemoBundle/DependencyInjection/AcmeDemoExtension.php +++ /dev/null @@ -1,22 +0,0 @@ -load('services.xml'); - } - - public function getAlias() - { - return 'acme_demo'; - } -} diff --git a/Symfony/src/Acme/DemoBundle/EventListener/ControllerListener.php b/Symfony/src/Acme/DemoBundle/EventListener/ControllerListener.php deleted file mode 100644 index aa117d7..0000000 --- a/Symfony/src/Acme/DemoBundle/EventListener/ControllerListener.php +++ /dev/null @@ -1,24 +0,0 @@ -extension = $extension; - } - - public function onKernelController(FilterControllerEvent $event) - { - if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { - $this->extension->setController($event->getController()); - } - } -} diff --git a/Symfony/src/Acme/DemoBundle/Form/ContactType.php b/Symfony/src/Acme/DemoBundle/Form/ContactType.php deleted file mode 100644 index 2c76cdb..0000000 --- a/Symfony/src/Acme/DemoBundle/Form/ContactType.php +++ /dev/null @@ -1,20 +0,0 @@ -add('email', 'email'); - $builder->add('message', 'textarea'); - } - - public function getName() - { - return 'contact'; - } -} diff --git a/Symfony/src/Acme/DemoBundle/Resources/config/routing.yml b/Symfony/src/Acme/DemoBundle/Resources/config/routing.yml deleted file mode 100644 index 3402ca1..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/config/routing.yml +++ /dev/null @@ -1,12 +0,0 @@ -_welcome: - pattern: / - defaults: { _controller: AcmeDemoBundle:Welcome:index } - -_demo_secured: - resource: "@AcmeDemoBundle/Controller/SecuredController.php" - type: annotation - -_demo: - resource: "@AcmeDemoBundle/Controller/DemoController.php" - type: annotation - prefix: /demo \ No newline at end of file diff --git a/Symfony/src/Acme/DemoBundle/Resources/config/services.xml b/Symfony/src/Acme/DemoBundle/Resources/config/services.xml deleted file mode 100644 index d6274ce..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/config/services.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/Symfony/src/Acme/DemoBundle/Resources/public/css/demo.css b/Symfony/src/Acme/DemoBundle/Resources/public/css/demo.css deleted file mode 100644 index 4dd2f16..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/public/css/demo.css +++ /dev/null @@ -1,101 +0,0 @@ -body { - font-size: 14px; - font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; -} -h1.title { - font-size: 45px; - padding-bottom: 30px; -} -.sf-reset h2 { - font-weight: bold; - color: #FFFFFF; - /* Font is duplicated of body (sans-serif) */ - font-family: "Lucida Sans Unicode", "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; - - margin-bottom: 10px; - background-color: #aacd4e; - padding: 2px 4px; - display: inline-block; - text-transform: uppercase; - -} -p { - line-height: 20px; - padding-bottom: 20px; -} -ul#demo-list a { - background: url(../images/blue-arrow.png) no-repeat right 6px; - padding-right: 10px; - margin-right: 30px; -} -#symfony-header { - position: relative; - padding: 30px 30px 20px 30px; -} -.sf-reset .symfony-blocks-welcome { - overflow: hidden; -} -.sf-reset .symfony-blocks-welcome > div { - background-color: whitesmoke; - float: left; - width: 240px; - margin-right: 14px; - text-align: center; - padding: 26px 20px; -} -.sf-reset .symfony-blocks-welcome > div.block-demo { - margin-right: 0; -} -.sf-reset .symfony-blocks-welcome .illustration { - padding-bottom: 20px; -} -.sf-reset .symfony-blocks-help { - overflow: hidden; -} -.sf-reset .symfony-blocks-help { - margin-top: 30px; - padding: 18px; - border: 1px solid #E6E6E6; -} -.sf-reset .symfony-blocks-help > div { - width: 254px; - float: left; -} -.flash-message { - padding: 10px; - margin: 5px; - margin-top: 15px; - background-color: #ffe; -} -.sf-reset .error { - color: red; -} -#login label, #contact_form label { - display: block; - float: left; - width: 90px; -} -.sf-reset ul#menu { - float: right; - margin-bottom: 20px; - padding-left: 0; -} -.sf-reset #menu li { - padding-left: 0; - margin-right: 10px; - display: inline; -} -.sf-reset a, -.sf-reset li a { - color: #08C; - text-decoration: none; -} -.sf-reset a:hover, -.sf-reset li a:hover { - color: #08C; - text-decoration: underline; -} -.sf-reset .symfony-content pre { - white-space: pre; - font-family: monospace; -} diff --git a/Symfony/src/Acme/DemoBundle/Resources/public/images/blue-arrow.png b/Symfony/src/Acme/DemoBundle/Resources/public/images/blue-arrow.png deleted file mode 100644 index fa82d4b4fff6414062efb2a02049cfeb9e8e7cb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1c!3HD^Kbl$tDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md6+I= zhqi>4PnzMOuO)K~*(RkoSoCn7)R^#~T4CSujwM;<0=t>E&QEnQ(&y3G(9U?$#xX^m ckwt=G)hqGzYlDe*q4@=v9Pj!eSesj znO9X=ad2|Jy}yf!jHIKbv9Yp#e1F*3*>P`jS5;V~q@}*Tzl({C|Ns9mE;9fB{{R30 z000000000000000A^8LW000^QEC2ui0JZ==06+!*peBxFX^z0-1i_MJ3+p_pEh_&5dM^QH^o`2q?YC;|Y#eo6?SBFL~IkO9*W zUWrg(6a+6t1e9~gkzoUD0u)q?cL8IkHxMNMW_YDz4U&xn4G;-%fMrJwrreB*aD?3_ z1wa){Fo|t|jsdNTB$!ozNI7K6ROJ$p6pPVgF9`4wMB>|mt0D|wjG70m21m-KH6S4q zhKOfKG;JyM!j7010!F!0IkQPpts|OdaKxZQty_Z;XW06P@mIDOfgM&{!i#`0fD`e3 zQEdyS&0Nj2C9?Kr8lnz-R4p>0a~KE_K`S#&yS5Dk42ZH}fWWNn-@r{EpxZBi&EUv6 z8aN0#2?2n~qoYCA9N}^4*n51eZlv`Vo}$7KN0+^P4l3M z2>3zos9Q+@lo%19fEJ&v_eMl=Ver}i6~3L26fm|Wb=^(lB>@IXO1OprcmzanA$V+L zb^~<*z@))9>6GxyTD2hYPk$N-mINXQ^p_PtcqCwBVHzYQp9trqhK*03$jI3zp=`EL z4gk;<4l+DyFhEu)P)UL+z8NDzFH^jr%?TK>h?fa6iXfN(BusNv6&G%ik!z~7xy6*t zIl-j}Y9eFPWF!!y%L|M_g5H-VU{nL2eF8edifzfKN)iT20F<12yZv3FsjK z;Rr5efTm$DL^*<=i7qz6og;{q#A5}anraE7fn!1!py{+pbtXdbOp509;L?wY*qD(5 z06@@Q5uSu`O>_G}VTmEZ{vb*JgE&xUL1w2rpe-Fev@4h-90G~<(Y|8JzQl6785e#5UFuM(io2~!?FPxpW2UiiX#KE~* z@e34008|A3Hij{FaHUIu9SUF;&k<9N3>-uiQxHZ4U%WA%01CV85UvN?MKf#F{QQ#6 zwS{a20W27sMHohcl(Pv9{JSJU??&s;yP0%mi5&wxi^V4(W-tK+3tD074XPv%P67Jn zgWlPu)oR5^7&M*1$rz+WHy1@*`e+rU;lOHbgVTm}65KMKgaFOHA#`1H_0h5o&rIGb zE)5zmMj3GkP)KY67-azeT>((?w-JLB@U8#{nAQ0qC1>EkRbD)Is|#A0lK2~y79sN} zNG@y24sdXt_r~;iTHpx_=E*BaSP{$|$EWviZgdX{vBSluA zfC7ZqxHo|4cW)@0O6rG$hWUwSS3w4Z5G8{2&1zKz6h<&!@COo>P*Ep(L223&B{pG- z2y^&^Ds~qJqs^mjH~7XN@K6{!CC`PjdZDVeRKRC^iZLxrq7p~2JUof2D@uqT9E_kv z39)c17fSdz2oVk(|*9gP26mT@rLI(4sh?6#MCjsXOoCcz2gl2{9QVN>M zDBh=%)a0N50dPS1QV22^6&KcVi9jlXAybu*3hZqF zu;Jn-Qqr8K6@)kfNWj!GMXb&_vW`!zqp1P`D-sM~lX-ZeEsNm?6HFs{LTHX2-e5P0 zkjo5$5s}2!XM@Adqk=r!%(|SQh-ZjzVV3BW)ka{=J|u_>4l{-2o)9YhVN4aQ+W{Xl zVi%ZY#c|acCDCl7u_MR{1AEbx1k!1WaqiPJ^IWEzLb9vsZ1bQIlEVaoGL-Z@6r#YP s-o}b>F^nP~2bk%~rANzE00$7X3b6#@NZAEF2Ha}_46x5i%M$_sJDrx#NB{r; diff --git a/Symfony/src/Acme/DemoBundle/Resources/public/images/search.png b/Symfony/src/Acme/DemoBundle/Resources/public/images/search.png deleted file mode 100644 index 3c88b6a4234ef5bb048bcecdc210c603c629339d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 737 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 EJ3feF)c^nh diff --git a/Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif b/Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-demo.gif deleted file mode 100644 index 0623de54c9501be250cd0907bd09f6b452c53fe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4053 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 H0RaFzT>Bsn diff --git a/Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif b/Symfony/src/Acme/DemoBundle/Resources/public/images/welcome-quick-tour.gif deleted file mode 100644 index b9018b11dd21302f850984fe9b49e49828101a00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4770 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%0D3*BH}7=0?8k*0Vzrykq=6t~oIX@3Ybb_LZc-J4 zwg$N=q1>88;AoNU^#wW^zIjxX2j=5zB)0%{0VpH5B_cYF)9W!jR4bq^-g@+l9tGg~ zxCCem9vp!FsDY2m^EC(ZS1sm0W>Z#*X-Vd)3^s0?L>8$nFs{u%EK*X7q&=Od>xuIt z<>I9+h44rQi(QUaa0CMTLqc5YpX;AsqAWjo@d_n zuf6>|CSQsG*ro&El10oy{$|ooY zmEOc_ttc$V+%n zUq7kyi9=ztN&Ir+1+hFPg8qTY%3Q)F5jfn7!&^XF&Q1)x&Q1ZDCnCF=!W47DCENNH4#o+7}EL=wuI@Ghl?2N@x75it~Rwx zOb!!;;W5ZTLMmD!l`oRaP{>>ae$sXF0&xFjJB19(8}JD`F+3Xyo{v0L_&(2$c`8dn z#}M#=>`Afi$qouu{H~7$D1muaq1#W$=7G(l3yanS9W7H%u Pcp^k-X1orE1J?f^bf!^p diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig deleted file mode 100644 index e5b7523..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/contact.html.twig +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "AcmeDemoBundle::layout.html.twig" %} - -{% block title "Symfony - Contact form" %} - -{% block content %} -
- {{ form_errors(form) }} - - {{ form_row(form.email) }} - {{ form_row(form.message) }} - - {{ form_rest(form) }} - -
-{% endblock %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig deleted file mode 100644 index 3997ff6..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "AcmeDemoBundle::layout.html.twig" %} - -{% block title "Hello " ~ name %} - -{% block content %} -

Hello {{ name }}!

-{% endblock %} - -{% set code = code(_self) %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig deleted file mode 100644 index 454a320..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Demo/index.html.twig +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "AcmeDemoBundle::layout.html.twig" %} - -{% block title "Symfony - Demos" %} - -{% block content_header '' %} - -{% block content %} -

Available demos

- -{% endblock %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig deleted file mode 100644 index faf95cf..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/hello.html.twig +++ /dev/null @@ -1,11 +0,0 @@ -{% extends "AcmeDemoBundle:Secured:layout.html.twig" %} - -{% block title "Hello " ~ name %} - -{% block content %} -

Hello {{ name }}!

- - Hello resource secured for admin only. -{% endblock %} - -{% set code = code(_self) %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig deleted file mode 100644 index 4e3649f..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/helloadmin.html.twig +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "AcmeDemoBundle:Secured:layout.html.twig" %} - -{% block title "Hello " ~ name %} - -{% block content %} -

Hello {{ name }} secured for Admins only!

-{% endblock %} - -{% set code = code(_self) %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig deleted file mode 100644 index aeea55c..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/layout.html.twig +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "AcmeDemoBundle::layout.html.twig" %} - -{% block content_header_more %} - {{ parent() }} -
  • logged in as {{ app.user ? app.user.username : 'Anonymous' }} - Logout
  • -{% endblock %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig deleted file mode 100644 index e74a5aa..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Secured/login.html.twig +++ /dev/null @@ -1,35 +0,0 @@ -{% extends 'AcmeDemoBundle::layout.html.twig' %} - -{% block content %} -

    Login

    - -

    - Choose between two default users: user/userpass (ROLE_USER) or admin/adminpass (ROLE_ADMIN) -

    - - {% if error %} -
    {{ error.message }}
    - {% endif %} - -
    -
    - - -
    - -
    - - -
    - - -
    -{% endblock %} - -{% set code = code(_self) %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig deleted file mode 100644 index ea3a729..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig +++ /dev/null @@ -1,83 +0,0 @@ -{% extends 'AcmeDemoBundle::layout.html.twig' %} - -{% block title %}Symfony - Welcome{% endblock %} - -{% block content_header '' %} - -{% block content %} - {% set version = constant('Symfony\\Component\\HttpKernel\\Kernel::MAJOR_VERSION') ~ '.' ~ constant('Symfony\\Component\\HttpKernel\\Kernel::MINOR_VERSION')%} - -

    Welcome!

    - -

    Congratulations! You have successfully installed a new Symfony application.

    - -
    - - {% if app.environment == 'dev' %} - - {% endif %} - -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -{% endblock %} diff --git a/Symfony/src/Acme/DemoBundle/Resources/views/layout.html.twig b/Symfony/src/Acme/DemoBundle/Resources/views/layout.html.twig deleted file mode 100644 index d7e97d5..0000000 --- a/Symfony/src/Acme/DemoBundle/Resources/views/layout.html.twig +++ /dev/null @@ -1,37 +0,0 @@ -{% extends "TwigBundle::layout.html.twig" %} - -{% block head %} - - -{% endblock %} - -{% block title 'Demo Bundle' %} - -{% block body %} - {% for flashMessage in app.session.flashbag.get('notice') %} -
    - Notice: {{ flashMessage }} -
    - {% endfor %} - - {% block content_header %} - - -
    - {% endblock %} - -
    - {% block content %}{% endblock %} -
    - - {% if code is defined %} -

    Code behind this page

    -
    -
    {{ code|raw }}
    -
    - {% endif %} -{% endblock %} diff --git a/Symfony/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php b/Symfony/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php deleted file mode 100644 index d720ce5..0000000 --- a/Symfony/src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php +++ /dev/null @@ -1,17 +0,0 @@ -request('GET', '/demo/hello/Fabien'); -// -// $this->assertGreaterThan(0, $crawler->filter('html:contains("Hello Fabien")')->count()); -// } -//} diff --git a/Symfony/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php b/Symfony/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php deleted file mode 100644 index a96a885..0000000 --- a/Symfony/src/Acme/DemoBundle/Twig/Extension/DemoExtension.php +++ /dev/null @@ -1,81 +0,0 @@ -loader = $loader; - } - - public function setController($controller) - { - $this->controller = $controller; - } - - /** - * {@inheritdoc} - */ - public function getFunctions() - { - return array( - 'code' => new \Twig_Function_Method($this, 'getCode', array('is_safe' => array('html'))), - ); - } - - public function getCode($template) - { - // highlight_string highlights php code only if 'getControllerCode(), true); - $controller = str_replace('<?php    ', '    ', $controller); - - $template = htmlspecialchars($this->getTemplateCode($template), ENT_QUOTES, 'UTF-8'); - - // remove the code block - $template = str_replace('{% set code = code(_self) %}', '', $template); - - return <<Controller Code

    -
    $controller
    - -

    Template Code

    -
    $template
    -EOF; - } - - protected function getControllerCode() - { - $class = get_class($this->controller[0]); - if (class_exists('CG\Core\ClassUtils')) { - $class = ClassUtils::getUserClass($class); - } - - $r = new \ReflectionClass($class); - $m = $r->getMethod($this->controller[1]); - - $code = file($r->getFilename()); - - return ' '.$m->getDocComment()."\n".implode('', array_slice($code, $m->getStartline() - 1, $m->getEndLine() - $m->getStartline() + 1)); - } - - protected function getTemplateCode($template) - { - return $this->loader->getSource($template->getTemplateName()); - } - - /** - * Returns the name of the extension. - * - * @return string The extension name - */ - public function getName() - { - return 'demo'; - } -} From cf132ddc2cdfdba9b9ff520fe8c6d15ca0e08cf7 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:00:15 +0200 Subject: [PATCH 08/25] Fixed Error due to removal of Acme Bundle --- Symfony/app/AppKernel.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Symfony/app/AppKernel.php b/Symfony/app/AppKernel.php index 914db81..b9ecdfb 100644 --- a/Symfony/app/AppKernel.php +++ b/Symfony/app/AppKernel.php @@ -20,7 +20,6 @@ public function registerBundles() ); if (in_array($this->getEnvironment(), array('dev', 'test'))) { - $bundles[] = new Acme\DemoBundle\AcmeDemoBundle(); $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); From 01ee5710e85fd5ee0bc5340992c8faceffb540f4 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:06:52 +0200 Subject: [PATCH 09/25] Fixed 2nd Error due to removal of Acme Bundle --- Symfony/app/config/security.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/app/config/security.yml b/Symfony/app/config/security.yml index 370c37a..ff75540 100644 --- a/Symfony/app/config/security.yml +++ b/Symfony/app/config/security.yml @@ -27,7 +27,7 @@ security: # logout: # path: _demo_logout # target: _demo -# #anonymous: ~ + anonymous: ~ # #http_basic: # # realm: "Secured Demo Area" # From 7057acc802939451bdca4349c6cbd987fc7f565d Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:11:46 +0200 Subject: [PATCH 10/25] This should fix the Acme deletion error --- Symfony/app/config/security.yml | 36 ++++----------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/Symfony/app/config/security.yml b/Symfony/app/config/security.yml index ff75540..e083cf3 100644 --- a/Symfony/app/config/security.yml +++ b/Symfony/app/config/security.yml @@ -1,36 +1,8 @@ security: - encoders: - Symfony\Component\Security\Core\User\User: plaintext - - role_hierarchy: - ROLE_ADMIN: ROLE_USER - ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] + firewalls: + anonymous: + anonymous: ~ providers: in_memory: - memory: ~ - - firewalls: - dev: - pattern: ^/(_(profiler|wdt)|css|images|js)/ - security: false - -# login: -# pattern: ^/demo/secured/login$ -# security: false -# -# secured_area: -# pattern: ^/demo/secured/ -# form_login: -# check_path: _security_check -# login_path: _demo_login -# logout: -# path: _demo_logout -# target: _demo - anonymous: ~ -# #http_basic: -# # realm: "Secured Demo Area" -# -# access_control: -# - { path: ^/demo/secured/hello/admin/, roles: ROLE_ADMIN } -# #- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } + memory: From ae8fab259f3b8aeb54a302345bd11768d371eee1 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:18:28 +0200 Subject: [PATCH 11/25] Removed dead code --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index febd021..59457d6 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -92,7 +92,7 @@ function main($request, $compiler_config) $ARCHIVE_OPTION = false; else $ARCHIVE_OPTION = $request["archive"]; - //return array("success" => false, "archive option" => $ARCHIVE_OPTION); + if ($ARCHIVE_OPTION === true){ $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); if ($arch_ret["success"] === false) From 885857c21a96a8189df824444b77e1b2587ef249 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:19:02 +0200 Subject: [PATCH 12/25] Added 1 more strict bool check --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 59457d6..861421d 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -107,7 +107,7 @@ function main($request, $compiler_config) // Step 2: Preprocess Arduino source files. $tmp = $this->preprocessIno($files["sketch_files"]); - if ($tmp["success"] == false) + if ($tmp["success"] === false) return array_merge($tmp, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); // Step 3: Preprocess Header includes and determine which core files directory(CORE_DIR) will be used. From 13f9500a4af94650598a3a97a07c16870408f657 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:26:54 +0200 Subject: [PATCH 13/25] Renamed a variable for readability --- .../Handler/CompilerHandler.php | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 861421d..11b3444 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -56,10 +56,9 @@ function main($request, $compiler_config) $start_time = microtime(true); // Step 0: Reject the request if the input data is not valid. - //TODO: Replace $tmp variable name - $tmp = $this->requestValid($request); - if($tmp["success"] === false) - return $tmp; + $tmpVar = $this->requestValid($request); + if($tmpVar["success"] === false) + return $tmpVar; $this->set_variables($request, $format, $libraries, $version, $mcu, $f_cpu, $core, $variant, $vid, $pid, $compiler_config); @@ -71,10 +70,10 @@ function main($request, $compiler_config) // Step 1(part 1): Extract the project files included in the request. $files = array(); - $tmp = $this->extractFiles($request["files"], $TEMP_DIR, $compiler_dir, $files["sketch_files"], "files"); + $tmpVar = $this->extractFiles($request["files"], $TEMP_DIR, $compiler_dir, $files["sketch_files"], "files"); - if ($tmp["success"] === false) - return $tmp; + if ($tmpVar["success"] === false) + return $tmpVar; // Add the compiler temp directory to the compiler_config struct. $compiler_config["compiler_dir"] = $compiler_dir; @@ -83,9 +82,9 @@ function main($request, $compiler_config) $files["libs"] = array(); foreach($libraries as $library => $library_files){ - $tmp = $this->extractFiles($library_files, $TEMP_DIR, $compiler_dir, $files["libs"][$library], "libraries/$library", true); - if ($tmp["success"] === false) - return $tmp; + $tmpVar = $this->extractFiles($library_files, $TEMP_DIR, $compiler_dir, $files["libs"][$library], "libraries/$library", true); + if ($tmpVar["success"] === false) + return $tmpVar; } if (!array_key_exists("archive", $request) || ($request["archive"] !== false && $request["archive"] !== true)) @@ -100,20 +99,19 @@ function main($request, $compiler_config) } //Set logging to true if requested, and create the directory where logfiles are stored. - //TODO: Replace $tmp variable name - $tmp = $this->setLoggingParams($request, $compiler_config, $TEMP_DIR, $compiler_dir); - if($tmp["success"] === false) - return array_merge($tmp, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); + $tmpVar = $this->setLoggingParams($request, $compiler_config, $TEMP_DIR, $compiler_dir); + if($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); // Step 2: Preprocess Arduino source files. - $tmp = $this->preprocessIno($files["sketch_files"]); - if ($tmp["success"] === false) - return array_merge($tmp, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); + $tmpVar = $this->preprocessIno($files["sketch_files"]); + if ($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); // Step 3: Preprocess Header includes and determine which core files directory(CORE_DIR) will be used. - $tmp = $this->preprocessHeaders($libraries, $include_directories, $compiler_dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $CORE_DIR, $CORE_OVERRIDE_DIR, $version, $core, $variant); - if ($tmp["success"] === false) - return array_merge($tmp, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); + $tmpVar = $this->preprocessHeaders($libraries, $include_directories, $compiler_dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $CORE_DIR, $CORE_OVERRIDE_DIR, $version, $core, $variant); + if ($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); // Log the names of the project files and the libraries used in it. if ($format != "autocomplete") { @@ -252,10 +250,10 @@ function main($request, $compiler_config) flock($lock, LOCK_EX); if (!file_exists($core_library)){ //makeCoresTmp scans the core files directory and return list including the urls of the files included there. - $tmp = $this->makeCoresTmp($CORE_DIR, $CORE_OVERRIDE_DIR, $TEMP_DIR, $compiler_dir, $files); + $tmpVar = $this->makeCoresTmp($CORE_DIR, $CORE_OVERRIDE_DIR, $TEMP_DIR, $compiler_dir, $files); - if(!$tmp["success"]){ - return array_merge($tmp, + if(!$tmpVar["success"]){ + return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); } @@ -382,26 +380,26 @@ function main($request, $compiler_config) // Step 8: Convert the output to the requested format and measure its // size. - $tmp = $this->convertOutput("$compiler_dir/files", $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config); + $tmpVar = $this->convertOutput("$compiler_dir/files", $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config); if ($compiler_config['logging'] === true) { $log_content = @file_get_contents($compiler_config['logFileName']); if (!$log_content) - $tmp["log"] = "Failed to access logfile."; + $tmpVar["log"] = "Failed to access logfile."; else { file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - $tmp["log"] = $log_content; + $tmpVar["log"] = $log_content; } } if ($ARCHIVE_OPTION === true){ $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); if ($arch_ret["success"] === false) - $tmp["archive"] = $arch_ret["message"]; + $tmpVar["archive"] = $arch_ret["message"]; else - $tmp["archive"] = $ARCHIVE_PATH; + $tmpVar["archive"] = $ARCHIVE_PATH; } - return $tmp; + return $tmpVar; } private function requestValid(&$request) From ec1d2b7a1b6000a4308cb2d736693076733103c2 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:34:32 +0200 Subject: [PATCH 14/25] This should fix all missing ending newlines --- Symfony/app/.htaccess | 3 ++- Symfony/src/.htaccess | 3 ++- Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php | 2 +- .../CompilerBundle/Handler/PostprocessingHandler.php | 2 +- .../Codebender/CompilerBundle/Handler/PreprocessingHandler.php | 2 +- .../src/Codebender/CompilerBundle/Handler/UtilityHandler.php | 2 +- .../src/Codebender/CompilerBundle/Resources/config/routing.yml | 2 +- .../Codebender/CompilerBundle/Resources/config/services.yml | 2 +- 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Symfony/app/.htaccess b/Symfony/app/.htaccess index 3418e55..c9c4d1b 100644 --- a/Symfony/app/.htaccess +++ b/Symfony/app/.htaccess @@ -1 +1,2 @@ -deny from all \ No newline at end of file +deny from all + diff --git a/Symfony/src/.htaccess b/Symfony/src/.htaccess index 3418e55..c9c4d1b 100644 --- a/Symfony/src/.htaccess +++ b/Symfony/src/.htaccess @@ -1 +1,2 @@ -deny from all \ No newline at end of file +deny from all + diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php index 297918f..e3b542a 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php @@ -206,4 +206,4 @@ class MCUHandler "attiny20" => "__AVR_ATtiny20__", "attiny40" => "__AVR_ATtiny40__"); -} \ No newline at end of file +} diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php index fcbf238..7203f92 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php @@ -120,4 +120,4 @@ function ansi_to_html($text) return $text; } -} \ No newline at end of file +} diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php index 720c2dd..a7d327d 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php @@ -293,4 +293,4 @@ function validate_input($request) // Request is valid. return $request; } -} \ No newline at end of file +} diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php index 4b2c444..000bb83 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php @@ -142,4 +142,4 @@ function debug_exec($command, /** @noinspection PhpUnusedParameterInspection */ echo "$ $command\n"; passthru("$command 2>&1"); } -} \ No newline at end of file +} diff --git a/Symfony/src/Codebender/CompilerBundle/Resources/config/routing.yml b/Symfony/src/Codebender/CompilerBundle/Resources/config/routing.yml index 2aa6eb0..0accf8d 100644 --- a/Symfony/src/Codebender/CompilerBundle/Resources/config/routing.yml +++ b/Symfony/src/Codebender/CompilerBundle/Resources/config/routing.yml @@ -16,4 +16,4 @@ codebender_compiler_delete_all: codebender_compiler_delete_specific: pattern: /{auth_key}/{version}/delete/{option}/{to_delete} - defaults: { _controller: CodebenderCompilerBundle:Default:deleteSpecificObjects } \ No newline at end of file + defaults: { _controller: CodebenderCompilerBundle:Default:deleteSpecificObjects } diff --git a/Symfony/src/Codebender/CompilerBundle/Resources/config/services.yml b/Symfony/src/Codebender/CompilerBundle/Resources/config/services.yml index 94a63ba..a529420 100644 --- a/Symfony/src/Codebender/CompilerBundle/Resources/config/services.yml +++ b/Symfony/src/Codebender/CompilerBundle/Resources/config/services.yml @@ -25,4 +25,4 @@ services: - [pushHandler, [@compiler_log_handler]] compiler_log_handler: class: Monolog\Handler\StreamHandler - arguments: [%kernel.logs_dir%/compiler.log] \ No newline at end of file + arguments: [%kernel.logs_dir%/compiler.log] From 29eab63a79fc73352b403440b0b64b920d0b75df Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:38:46 +0200 Subject: [PATCH 15/25] Auto-Formated PreprocessingHandler --- .../Handler/PreprocessingHandler.php | 491 +++++++++--------- 1 file changed, 259 insertions(+), 232 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php index a7d327d..9fb1680 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php @@ -13,245 +13,272 @@ class PreprocessingHandler { /** - \brief The following functions generate valid C++ code from Arduino source code. - - Arduino source code files are simplified C++ files. Thus, some preprocessing has - to be done to convert them to valid C++ code for the compiler to read. Some of - these "simplifications" include: - - lack of a main() function - - lack of function prototypes - - A skeleton file is provided in the Arduino core files that contains a - main() function. Its contents have to be linked to the output file later. - The prototypes of the functions defined in the input file should be added - above the code. This is required to avoid compiler errors regarding undefined - functions. - - The programmer is not aware of this modifications to his code. In case of a - compiler error, the line numbering would be wrong. To avoid this issue, a - \#line preprocessor directive is used. Thus it is ensured that the line - numbering in the output file will be the same as the input file. - - A regular expression is used to match function definitions in the input file. - Consequently this process will never be as sophisticated as a lexical analyzer. - Thus, some valid constructs cannot be matched. These include: - - definitions that are split across multiple lines - - definitions for variadic functions - - typedefs for the return value or the parameters - - pointers to functions - - arrays, structs, and unions + * \brief The following functions generate valid C++ code from Arduino source code. + * + * Arduino source code files are simplified C++ files. Thus, some preprocessing has + * to be done to convert them to valid C++ code for the compiler to read. Some of + * these "simplifications" include: + * - lack of a main() function + * - lack of function prototypes + * + * A skeleton file is provided in the Arduino core files that contains a + * main() function. Its contents have to be linked to the output file later. + * The prototypes of the functions defined in the input file should be added + * above the code. This is required to avoid compiler errors regarding undefined + * functions. + * + * The programmer is not aware of this modifications to his code. In case of a + * compiler error, the line numbering would be wrong. To avoid this issue, a + * \#line preprocessor directive is used. Thus it is ensured that the line + * numbering in the output file will be the same as the input file. + * + * A regular expression is used to match function definitions in the input file. + * Consequently this process will never be as sophisticated as a lexical analyzer. + * Thus, some valid constructs cannot be matched. These include: + * - definitions that are split across multiple lines + * - definitions for variadic functions + * - typedefs for the return value or the parameters + * - pointers to functions + * - arrays, structs, and unions */ - /** - \param string $code The original code of the sketch - \return string A copy of the code with no comments, single- or double- quoted strings - or pre-processor directives - */ - function remove_comments_directives_quotes($code) - { - // Use a copy of the code and strip comments, pre-processor directives, single- and double-quoted strings - - $regex = "/(\'.\')|(\"(?:[^\"\\\\]|\\\\.)*\")|(\/\/.*?$)|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(^\s*\#.*?$)/m"; - - // Replace every match of the regular expression with a whitespace - - $return_code = preg_replace($regex, " ", $code); - - return $return_code; - } - - /** - \param string $code The code returned from remove_comments_directives_quotes function - \return string The input code having all top level braces collapsed - */ - function empty_braces($code) - { - // For every line of the code remove all the contents of top level braces - - $nesting = 0; - $start = 0; - $return_code = ""; - // Use the code as an array of characters - for ($i=0; $iremove_comments_directives_quotes($code); - // Remove any code between all top level braces - $empty_braces_code = $this->empty_braces($no_comms_code); - // Find already existing prototypes - $existing_prototypes = $this->find_existing_prototypes($empty_braces_code); - // Generate prototypes that do not already exist - $function_prototypes = $this->generate_prototypes($empty_braces_code, $existing_prototypes); - // Find the right place to insert the function prototypes (after any preprocessor directives, comments, before any function declaration) - $insertion_position = $this->insertion_position($code); - - $new_code = ""; + /** + * \param string $code The original code of the sketch + * \return string A copy of the code with no comments, single- or double- quoted strings + * or pre-processor directives + */ + function remove_comments_directives_quotes($code) + { + // Use a copy of the code and strip comments, pre-processor directives, single- and double-quoted strings + + $regex = "/(\'.\')|(\"(?:[^\"\\\\]|\\\\.)*\")|(\/\/.*?$)|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(^\s*\#.*?$)/m"; + + // Replace every match of the regular expression with a whitespace + + $return_code = preg_replace($regex, " ", $code); + + return $return_code; + } + + /** + * \param string $code The code returned from remove_comments_directives_quotes function + * \return string The input code having all top level braces collapsed + */ + function empty_braces($code) + { + // For every line of the code remove all the contents of top level braces + + $nesting = 0; + $start = 0; + $return_code = ""; + // Use the code as an array of characters + for ($i = 0; $i < strlen($code); $i++) + { + + if ($code[$i] == "{") + { + if ($nesting == 0) + { + $return_code .= substr($code, $start, $i + 1 - $start); + } + $nesting++; + continue; + } + if ($code[$i] == "}") + { + $nesting--; + if ($nesting == 0) + { + $start = $i; + } + continue; + + } + } + $return_code .= substr($code, $start, strlen($code) - $start); + + return $return_code; + } + + /** + * \param string $code The code returned from empty_braces function + * \return array An array including any prototypes found in the original code + */ + function find_existing_prototypes(&$code) + { + // In this case, the original code is used. Existing prototypes are matched, stored, and then removed from + //the code, so that in the next step the compiler knows which prototypes should really be generated + $existing_prototypes = array(); + $regex = "/[\w\[\]\*]+\s+[&\[\]\*\w\s]+\([&,\[\]\*\w\s]*\)(?=\s*;)/m"; + + if (preg_match_all($regex, $code, $matches)) + { + $existing_prototypes = $matches[0]; + } + + $code = preg_replace($regex, " ", $code); + + return $existing_prototypes; + } + + /** + * \param string $code The sketch code provided to the compiler + * \param array $existing_prototypes Array of prototypes returned by find_existing_prototypes function + * \return string The string including the function prototypes for the code + */ + function generate_prototypes($code, $existing_prototypes) + { + // This function uses a regular expression to match all function declarations, generate the + // respective prototype and store all the prototypes in a string + $regex = "/[\w\[\]\*]+\s+[&\[\]\*\w\s]+\([&,\[\]\*\w\s]*\)(?=\s*\{)/m"; + + $function_prototypes = ""; + if (preg_match_all($regex, $code, $matches)) + { + + foreach ($matches[0] as $match) + { + + if (!empty($existing_prototypes)) + { + /* + * If a prototype match has no parameters, two prototypes are generated, one with no parameters and + * one with parameter void. Then the code searches if one of them already exists in the original code + */ + if (preg_match("/\(\s*\)/", $match)) + { + $match_void = preg_replace("/(\(\s*\))/", "(void)", $match); + if (in_array($match_void, $existing_prototypes)) + { + continue; + } + } + // If none of the above was true, check if the prototype exists + if (in_array($match, $existing_prototypes)) + { + continue; + } + } + // If everything is ok, add the prototype to the return value + $function_prototypes .= $match.";\n"; + } + } + return $function_prototypes; + } + + /** + * \param string $code The sketch code + * \return int The position where function prototypes should be placed + */ + function insertion_position($code) + { + // Use the following regular expression to match whitespaces, single- and multiline comments and preprocessor directives + $regex = "/(\s+|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(\/\/.*?$)|(\#(?:\\\\\\n|.)*))/m"; + + // Then find all the matches in the original code and count the offset of each one. + preg_match_all($regex, $code, $matches, PREG_OFFSET_CAPTURE); + + $prev_position = 0; + $position = 0; + // The second offset of each matches[0] object contains the starting position (string index) of the match in the code + // + foreach ($matches[0] as $match) + { + // In case of a mismatch between prev_position and the beginning index of the current match, a non matching + // expression exists between the last two matches. This is the position where the prototypes should be placed. + // In other words, this is the first line of the code that is not a whitespace, comment, or preprocessor directive + if ($match[1] != $prev_position) + { + $position = $prev_position - 1; + break; + } + $prev_position += strlen($match[0]); + } + // If position is set to -1, there have been found no matches to the regular expression, so it must be set back to zero + if ($position == -1) + { + $position = 0; + } + return $position; + } + + /** + * \param string $code The initial sketch code + * \param $function_prototypes The function prototypes returned by generate_prototypes function + * \param int $position The position to place the prototypes returned by insertion_position function + * \return string Valid c++ code + */ + function build_code($code, $function_prototypes, $position) + { + + // To build the final code, the compiler starts adding every character of the original string, until the position + // found by insertion_position is reached. Then, the function prototypes are added, as well as a preprocessor + //directive to fix the line numbering. + $line = 1; + $return_code = ""; + if (!($position == 0)) + { + for ($i = 0; $i <= $position; $i++) + { + + $return_code .= $code[$i]; + if ($code[$i] == "\n") + { + $line++; + } + + } + } + + // Include the Arduino header file + $return_code .= "#include \n"; + // Then insert the prototypes, and finally the rest of the code + $return_code .= $function_prototypes."#line $line\n"; + if ($position == 0) + $next_pos = 0; + else + $next_pos = $position + 1; + for ($i = $next_pos; $i < strlen($code); $i++) + { + $return_code .= $code[$i]; + } + + return $return_code; + } + + function ino_to_cpp($code, $filename = NULL) + { + // Remove comments, preprocessor directives, single- and double- quotes + $no_comms_code = $this->remove_comments_directives_quotes($code); + // Remove any code between all top level braces + $empty_braces_code = $this->empty_braces($no_comms_code); + // Find already existing prototypes + $existing_prototypes = $this->find_existing_prototypes($empty_braces_code); + // Generate prototypes that do not already exist + $function_prototypes = $this->generate_prototypes($empty_braces_code, $existing_prototypes); + // Find the right place to insert the function prototypes (after any preprocessor directives, comments, + // before any function declaration) + $insertion_position = $this->insertion_position($code); + + $new_code = ""; // Add a preprocessor directive for line numbering. if ($filename) - $new_code .= "#line 1 \"$filename\"\n"; - else - $new_code .= "#line 1\n"; - // Build the new code for the cpp file that will eventually be compiled - $new_code .= $this->build_code($code, $function_prototypes, $insertion_position); + $new_code .= "#line 1 \"$filename\"\n"; + else + $new_code .= "#line 1\n"; + // Build the new code for the cpp file that will eventually be compiled + $new_code .= $this->build_code($code, $function_prototypes, $insertion_position); return $new_code; - } - + } /** - \brief Decodes and performs validation checks on input data. - - \param string $request The JSON-encoded compile request. - \return The value encoded in JSON in appropriate PHP type or NULL. + * \brief Decodes and performs validation checks on input data. + * + * \param string $request The JSON-encoded compile request. + * \return The value encoded in JSON in appropriate PHP type or NULL. */ function validate_input($request) { @@ -283,9 +310,9 @@ function validate_input($request) // Values used as command-line arguments may not contain any special // characters. This is a serious security risk. - $values = array("version", "mcu", "f_cpu", "core", "vid", "pid"); - if (array_key_exists("variant", $request["build"])) - $values[] = "variant"; + $values = array("version", "mcu", "f_cpu", "core", "vid", "pid"); + if (array_key_exists("variant", $request["build"])) + $values[] = "variant"; foreach ($values as $i) if (isset($request["build"][$i]) && escapeshellcmd($request["build"][$i]) != $request["build"][$i]) return NULL; From 0ee45573d6f838c2229ed8a73ec359343bbd2fbb Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:40:15 +0200 Subject: [PATCH 16/25] Auto-Formated UtilityHandler --- .../CompilerBundle/Handler/UtilityHandler.php | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php index 000bb83..2ad398f 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php @@ -13,22 +13,22 @@ class UtilityHandler { /** - \brief Extracts the files included in a compile request. - - \param string $directory The directory to extract the files to. - \param array $request_files The files structure, as taken from the JSON request. - \return A list of files or a reply message in case of error. - - Takes the files structure from a compile request and creates each file in a - specified directory. If requested, it may create additional directories and - have the files placed inside them accordingly. - - Also creates a new structure where each key is the file extension and the - associated value is an array containing the absolute paths of the file, minus - the extension. - - In case of error, the return value is an array that has a key success - and contains the response to be sent back to the user. + * \brief Extracts the files included in a compile request. + * + * \param string $directory The directory to extract the files to. + * \param array $request_files The files structure, as taken from the JSON request. + * \return A list of files or a reply message in case of error. + * + * Takes the files structure from a compile request and creates each file in a + * specified directory. If requested, it may create additional directories and + * have the files placed inside them accordingly. + * + * Also creates a new structure where each key is the file extension and the + * associated value is an array containing the absolute paths of the file, minus + * the extension. + * + * In case of error, the return value is an array that has a key success + * and contains the response to be sent back to the user. */ function extract_files($directory, $request_files, $lib_extraction) { @@ -48,14 +48,14 @@ function extract_files($directory, $request_files, $lib_extraction) // Examples: foo.c bar.cpp $REGEX = "/(.*)\.($EXTENSIONS)$/"; - if(!file_exists($directory)) - mkdir($directory, 0777, true); + if (!file_exists($directory)) + mkdir($directory, 0777, true); foreach ($request_files as $file) { $filename = $file["filename"]; $content = $file["content"]; - $ignore = false; + $ignore = false; $failure_response = array( "success" => false, @@ -72,22 +72,22 @@ function extract_files($directory, $request_files, $lib_extraction) { $new_directory = pathinfo($filename, PATHINFO_DIRNAME); - if (($lib_extraction === true) && ($new_directory !== "utility")) - $ignore = true; - if (!file_exists("$directory/$new_directory")) - mkdir("$directory/$new_directory", 0777, true); - // There is no reason to check whether mkdir() - // succeeded, given that the call to - // file_put_contents() that follows would fail - // as well. + if (($lib_extraction === true) && ($new_directory !== "utility")) + $ignore = true; + if (!file_exists("$directory/$new_directory")) + mkdir("$directory/$new_directory", 0777, true); + // There is no reason to check whether mkdir() + // succeeded, given that the call to + // file_put_contents() that follows would fail + // as well. } if (file_put_contents("$directory/$filename", $content) === false) return $failure_response; - if ($ignore) - continue; + if ($ignore) + continue; if (preg_match($REGEX, $filename, $matches)) $files[$matches[2]][] = "$directory/$matches[1]"; @@ -100,11 +100,11 @@ function extract_files($directory, $request_files, $lib_extraction) } /** - \brief Searches for files with specific extensions in a directory. - - \param string $directory The directory to search for files. - \param mixed $extensions An array of strings, the extensions to look for. - \return A list of files that have the appropriate extension. + * \brief Searches for files with specific extensions in a directory. + * + * \param string $directory The directory to search for files. + * \param mixed $extensions An array of strings, the extensions to look for. + * \return A list of files that have the appropriate extension. */ function get_files_by_extension($directory, $extensions) { @@ -120,20 +120,20 @@ function get_files_by_extension($directory, $extensions) } /** - \brief Executes a command and displays the command itself and its output. - - \param string $command The command to be executed. - - Simplifies the creation and debugging of pages that rely on multiple external - programs by "emulating" the execution of the requested command in a terminal - emulator. Can be useful during early stages of development. Replace with - exec() afterwards. - - To perform the command execution, passthru() is used. The string - 2\>&1 is appended to the command to ensure messages sent to standard - error are not lost. - - \warning It is not possible to redirect the standard error output to a file. + * \brief Executes a command and displays the command itself and its output. + * + * \param string $command The command to be executed. + * + * Simplifies the creation and debugging of pages that rely on multiple external + * programs by "emulating" the execution of the requested command in a terminal + * emulator. Can be useful during early stages of development. Replace with + * exec() afterwards. + * + * To perform the command execution, passthru() is used. The string + * 2\>&1 is appended to the command to ensure messages sent to standard + * error are not lost. + * + * \warning It is not possible to redirect the standard error output to a file. */ function debug_exec($command, /** @noinspection PhpUnusedParameterInspection */ &$output, /** @noinspection PhpUnusedParameterInspection */ From 8c57183cd28db649005dc354747dad4932334656 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:44:01 +0200 Subject: [PATCH 17/25] Auto-Formated PostProcessingHandler --- .../Handler/PostprocessingHandler.php | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php index 7203f92..14f3a8b 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php @@ -13,19 +13,19 @@ class PostprocessingHandler { /** - \brief Converts text with ANSI color codes to HTML. - - \param string $text The string to convert. - \return A string with HTML tags. - - Takes a string with ANSI color codes and converts them to HTML tags. Can be - useful for displaying the output of terminal commands on a web page. Handles - codes that modify the color (foreground and background) as well as the format - (bold, italics, underline and strikethrough). Other codes are ignored. - - An ANSI escape sequence begins with the characters ^[ (hex 0x1B) and - [, and ends with m. The color code is placed in between. Multiple - color codes can be included, separated by semicolon. + * \brief Converts text with ANSI color codes to HTML. + * + * \param string $text The string to convert. + * \return A string with HTML tags. + * + * Takes a string with ANSI color codes and converts them to HTML tags. Can be + * useful for displaying the output of terminal commands on a web page. Handles + * codes that modify the color (foreground and background) as well as the format + * (bold, italics, underline and strikethrough). Other codes are ignored. + * + * An ANSI escape sequence begins with the characters ^[ (hex 0x1B) and + * [, and ends with m. The color code is placed in between. Multiple + * color codes can be included, separated by semicolon. */ function ansi_to_html($text) { From 21854c0ed758ea76d82e9296a6c602bcffb03ee7 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:44:43 +0200 Subject: [PATCH 18/25] Auto-Formated MCUHandler --- .../CompilerBundle/Handler/MCUHandler.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php index e3b542a..5fad6a8 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/MCUHandler.php @@ -1,20 +1,20 @@ . - -\author Dimitrios Christidis -\author Vasilis Georgitzikis - -\copyright (c) 2012, The Codebender Development Team -\copyright Licensed under the Simplified BSD License + * \file + * \brief MCU macros for Clang. + * + * When compiling source code for ATMEL AVR, one must specify the MCU type + * (avr-gcc's -mmcu flag). This defines a macro that is used for conditional + * compilation. Clang has no such flag, and thus the macro has to be predefined + * by hand. + * + * See . + * + * \author Dimitrios Christidis + * \author Vasilis Georgitzikis + * + * \copyright (c) 2012, The Codebender Development Team + * \copyright Licensed under the Simplified BSD License */ namespace Codebender\CompilerBundle\Handler; From d25ee5a54fbe0dcc9a0ac374b8820f55f8869391 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 03:50:53 +0200 Subject: [PATCH 19/25] Auto-Formated DefaultController --- .../Controller/DefaultController.php | 245 +++++++++--------- 1 file changed, 123 insertions(+), 122 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php b/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php index ab79309..2403fb7 100644 --- a/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php +++ b/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php @@ -1,13 +1,13 @@ getRequest()->getContent(); - //Get the compiler service + //Get the compiler service $compiler = $this->get('compiler_handler'); $reply = $compiler->main($request, $params); @@ -69,126 +69,127 @@ public function indexAction($auth_key, $version) } } - public function deleteAllObjectsAction($auth_key, $version) - { - if ($this->container->getParameter('auth_key') != $auth_key) - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid authorization key."))); - - if ($version != "v1") - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid API version."))); - - $tempDir = $this->container->getParameter('temp_dir'); - $objectFilesDir = $this->container->getParameter('objdir'); - $fileCount = 0; - $undeletedFiles = ""; - $deletionStats = array("success_dot_a" => 0, - "failure_dot_a" => 0, - "success_dot_o" => 0, - "failure_dot_o" => 0, - "success_dot_d" => 0, - "failure_dot_d" => 0, - "success_dot_LOCK" => 0, - "failure_dot_LOCK" => 0); - - if ($handle = opendir("$tempDir/$objectFilesDir")) - { - - while (false !== ($entry = readdir($handle))) - { - if ($entry != "." && $entry != ".." && $entry != ".DS_Store") - { - $fileCount++; - $extension = pathinfo($entry, PATHINFO_EXTENSION); - - if (!in_array($extension, array("a", "o", "d", "LOCK"))) - continue; - - if (@unlink("$tempDir/$objectFilesDir/$entry") === false) - { - $deletionStats["failure_dot_$extension"]++; - $undeletedFiles .= $entry . "\n"; - } - else - $deletionStats["success_dot_$extension"]++; - } - } - closedir($handle); - }else - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Failed to access object files directory."))); - - return new Response(json_encode(array_merge(array("success" => true, - "message" => "Object files deletion complete. Found $fileCount files."), - $deletionStats, - array("Files not deleted" => $undeletedFiles)))); - } - - public function deleteSpecificObjectsAction($auth_key, $version, $option, $to_delete) - { - if ($this->container->getParameter('auth_key') != $auth_key) - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid authorization key."))); - - if ($version != "v1") - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid API version."))); - - $tempDir = $this->container->getParameter('temp_dir'); - $objectFilesDir = $this->container->getParameter('objdir'); - - if ($option == "core") - $to_delete = str_replace(":", "_", $to_delete); - - $response = array(); - $response["deleted_files"] = ""; - $response["undeleted_files"] = ""; - - if ($handle = opendir("$tempDir/$objectFilesDir")) - { - while (false !== ($entry = readdir($handle))) - { - if ($entry == "." || $entry == ".." || $entry == ".DS_Store") - continue; - - if ($option == "library" && strpos($entry, "______" . $to_delete . "_______") === false) - continue; - - if ($option == "core" && strpos($entry, "_" . $to_delete . "_") === false) - continue; - - - if (@unlink("$tempDir/$objectFilesDir/$entry") === false) - $response["undeleted_files"] .= $entry . "\n"; - else - $response["deleted_files"] .= $entry . "\n"; - - } - closedir($handle); - } - else - { - return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Failed to access object files directory."))); - } - - if ($response["undeleted_files"] != "") - { - $message = ($option == "library") ? "Failed to delete one or more of the specified library object files.": "Failed to delete one or more of the specified core object files."; - return new Response(json_encode(array_merge(array("success" => false, "step" => 0, "message" => $message), $response))); - } - - $message = ($option == "library") ? "Library deleted successfully.": "Core object files deleted successfully."; - return new Response(json_encode(array_merge(array("success" => true, "message" => $message), $response))); - } + public function deleteAllObjectsAction($auth_key, $version) + { + if ($this->container->getParameter('auth_key') != $auth_key) + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid authorization key."))); - /** - \brief Creates a list of the configuration parameters to be used in the compilation process. + if ($version != "v1") + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid API version."))); + + $tempDir = $this->container->getParameter('temp_dir'); + $objectFilesDir = $this->container->getParameter('objdir'); + $fileCount = 0; + $undeletedFiles = ""; + $deletionStats = array("success_dot_a" => 0, + "failure_dot_a" => 0, + "success_dot_o" => 0, + "failure_dot_o" => 0, + "success_dot_d" => 0, + "failure_dot_d" => 0, + "success_dot_LOCK" => 0, + "failure_dot_LOCK" => 0); + + if ($handle = opendir("$tempDir/$objectFilesDir")) + { + + while (false !== ($entry = readdir($handle))) + { + if ($entry != "." && $entry != ".." && $entry != ".DS_Store") + { + $fileCount++; + $extension = pathinfo($entry, PATHINFO_EXTENSION); + + if (!in_array($extension, array("a", "o", "d", "LOCK"))) + continue; + + if (@unlink("$tempDir/$objectFilesDir/$entry") === false) + { + $deletionStats["failure_dot_$extension"]++; + $undeletedFiles .= $entry."\n"; + } + else + $deletionStats["success_dot_$extension"]++; + } + } + closedir($handle); + } + else + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Failed to access object files directory."))); + + return new Response(json_encode(array_merge(array("success" => true, + "message" => "Object files deletion complete. Found $fileCount files."), + $deletionStats, + array("Files not deleted" => $undeletedFiles)))); + } + + public function deleteSpecificObjectsAction($auth_key, $version, $option, $to_delete) + { + if ($this->container->getParameter('auth_key') != $auth_key) + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid authorization key."))); + + if ($version != "v1") + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Invalid API version."))); + + $tempDir = $this->container->getParameter('temp_dir'); + $objectFilesDir = $this->container->getParameter('objdir'); - \return An array of the parameters. + if ($option == "core") + $to_delete = str_replace(":", "_", $to_delete); - This function accesses the Symfony global configuration parameters, and creates an array that our handlers (which - don't have access to them) can use them. + $response = array(); + $response["deleted_files"] = ""; + $response["undeleted_files"] = ""; + + if ($handle = opendir("$tempDir/$objectFilesDir")) + { + while (false !== ($entry = readdir($handle))) + { + if ($entry == "." || $entry == ".." || $entry == ".DS_Store") + continue; + + if ($option == "library" && strpos($entry, "______".$to_delete."_______") === false) + continue; + + if ($option == "core" && strpos($entry, "_".$to_delete."_") === false) + continue; + + + if (@unlink("$tempDir/$objectFilesDir/$entry") === false) + $response["undeleted_files"] .= $entry."\n"; + else + $response["deleted_files"] .= $entry."\n"; + + } + closedir($handle); + } + else + { + return new Response(json_encode(array("success" => false, "step" => 0, "message" => "Failed to access object files directory."))); + } + + if ($response["undeleted_files"] != "") + { + $message = ($option == "library") ? "Failed to delete one or more of the specified library object files." : "Failed to delete one or more of the specified core object files."; + return new Response(json_encode(array_merge(array("success" => false, "step" => 0, "message" => $message), $response))); + } + + $message = ($option == "library") ? "Library deleted successfully." : "Core object files deleted successfully."; + return new Response(json_encode(array_merge(array("success" => true, "message" => $message), $response))); + } + + /** + * \brief Creates a list of the configuration parameters to be used in the compilation process. + * + * \return An array of the parameters. + * + * This function accesses the Symfony global configuration parameters, and creates an array that our handlers (which + * don't have access to them) can use them. */ private function generateParameters() { - $parameters = array("binutils", "python", "clang", "logdir", "temp_dir", "archive_dir", "autocompletion_dir", "autocompleter", "cflags", "cppflags", "asflags", "arflags", "ldflags", "ldflags_tail", "clang_flags", "objcopy_flags", "size_flags", "output", "arduino_cores_dir", "external_core_files", "auth_key"); + $parameters = array("binutils", "python", "clang", "logdir", "temp_dir", "archive_dir", "autocompletion_dir", "autocompleter", "cflags", "cppflags", "asflags", "arflags", "ldflags", "ldflags_tail", "clang_flags", "objcopy_flags", "size_flags", "output", "arduino_cores_dir", "external_core_files", "auth_key"); $compiler_config = array(); From 4260afd37d524a3f292e06a1a69664e70c6bb5b9 Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:05:53 +0200 Subject: [PATCH 20/25] Silenced PHPStorm Warning --- .../Codebender/CompilerBundle/Controller/DefaultController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php b/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php index 2403fb7..1070802 100644 --- a/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php +++ b/Symfony/src/Codebender/CompilerBundle/Controller/DefaultController.php @@ -57,6 +57,7 @@ public function indexAction($auth_key, $version) $request = $this->getRequest()->getContent(); //Get the compiler service + /** @var CompilerHandler $compiler */ $compiler = $this->get('compiler_handler'); $reply = $compiler->main($request, $params); From ff1375249b64943c72c39a3667658ea17bc7c8ad Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:07:00 +0200 Subject: [PATCH 21/25] Auto-Formated DefaultControllerTest --- .../CompilerBundle/Tests/Controller/DefaultControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Tests/Controller/DefaultControllerTest.php b/Symfony/src/Codebender/CompilerBundle/Tests/Controller/DefaultControllerTest.php index bd8fef8..01727a9 100644 --- a/Symfony/src/Codebender/CompilerBundle/Tests/Controller/DefaultControllerTest.php +++ b/Symfony/src/Codebender/CompilerBundle/Tests/Controller/DefaultControllerTest.php @@ -64,7 +64,7 @@ public function testBlinkUnoSyntaxCheck() $auth_key = $client->getContainer()->getParameter("auth_key"); - $client->request('POST', '/'.$auth_key.'/v1', array(),array(),array(),$data); + $client->request('POST', '/'.$auth_key.'/v1', array(), array(), array(), $data); $response = json_decode($client->getResponse()->getContent(), true); From 65d426ff8c866235c9d89cf9b4acbab89e1f871c Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:07:56 +0200 Subject: [PATCH 22/25] Removed unused Class --- .../src/Codebender/CompilerBundle/Handler/CompilerHandler.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 11b3444..660ea4f 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -15,7 +15,6 @@ // This file uses mktemp() to create a temporary directory where all the files // needed to process the compile request are stored. require_once "System.php"; -use Doctrine\Tests\ORM\Functional\ManyToManyBidirectionalAssociationTest; use System; use Codebender\CompilerBundle\Handler\MCUHandler; use Symfony\Bridge\Monolog\Logger; From 8b0faee709d7526298ba6f2565a09815a2f1b04e Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:11:58 +0200 Subject: [PATCH 23/25] Auto-Formated CompilerHandler --- .../Handler/CompilerHandler.php | 2380 +++++++++-------- 1 file changed, 1254 insertions(+), 1126 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index 660ea4f..c6615ee 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -1,13 +1,13 @@ preproc = $preprocHandl; - $this->postproc = $postprocHandl; - $this->utility = $utilHandl; - $this->compiler_logger = $logger; - $this->object_directory = $objdir; - } - - /** - \brief Processes a compile request. - - \param string $request The body of the POST request. - \return A message to be JSON-encoded and sent back to the requestor. - */ - function main($request, $compiler_config) - { - error_reporting(E_ALL & ~E_STRICT); - - $this->set_values($compiler_config, - $BINUTILS, $CLANG, $CFLAGS, $CPPFLAGS, $ASFLAGS, $ARFLAGS, $LDFLAGS, $LDFLAGS_TAIL, - $CLANG_FLAGS, $OBJCOPY_FLAGS, $SIZE_FLAGS, $OUTPUT, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, + private $preproc; + private $postproc; + private $utility; + private $compiler_logger; + private $object_directory; + private $logger_id; + + function __construct(PreprocessingHandler $preprocHandl, PostprocessingHandler $postprocHandl, UtilityHandler $utilHandl, Logger $logger, $objdir) + { + $this->preproc = $preprocHandl; + $this->postproc = $postprocHandl; + $this->utility = $utilHandl; + $this->compiler_logger = $logger; + $this->object_directory = $objdir; + } + + /** + * \brief Processes a compile request. + * + * \param string $request The body of the POST request. + * \return A message to be JSON-encoded and sent back to the requestor. + */ + function main($request, $compiler_config) + { + error_reporting(E_ALL & ~E_STRICT); + + $this->set_values($compiler_config, + $BINUTILS, $CLANG, $CFLAGS, $CPPFLAGS, $ASFLAGS, $ARFLAGS, $LDFLAGS, $LDFLAGS_TAIL, + $CLANG_FLAGS, $OBJCOPY_FLAGS, $SIZE_FLAGS, $OUTPUT, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $TEMP_DIR, $ARCHIVE_DIR, $AUTOCC_DIR, $PYTHON, $AUTOCOMPLETER); - $start_time = microtime(true); + $start_time = microtime(true); - // Step 0: Reject the request if the input data is not valid. - $tmpVar = $this->requestValid($request); - if($tmpVar["success"] === false) - return $tmpVar; + // Step 0: Reject the request if the input data is not valid. + $tmpVar = $this->requestValid($request); + if ($tmpVar["success"] === false) + return $tmpVar; - $this->set_variables($request, $format, $libraries, $version, $mcu, $f_cpu, $core, $variant, $vid, $pid, $compiler_config); + $this->set_variables($request, $format, $libraries, $version, $mcu, $f_cpu, $core, $variant, $vid, $pid, $compiler_config); - $this->set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, $CC, $CPP, $AS, $AR, $LD, $OBJCOPY, $SIZE); + $this->set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, $CC, $CPP, $AS, $AR, $LD, $OBJCOPY, $SIZE); - $target_arch = "-mmcu=$mcu -DARDUINO=$version -DF_CPU=$f_cpu -DUSB_VID=$vid -DUSB_PID=$pid"; - $clang_target_arch = "-D".MCUHandler::$MCU[$mcu]." -DARDUINO=$version -DF_CPU=$f_cpu"; + $target_arch = "-mmcu=$mcu -DARDUINO=$version -DF_CPU=$f_cpu -DUSB_VID=$vid -DUSB_PID=$pid"; + $clang_target_arch = "-D".MCUHandler::$MCU[$mcu]." -DARDUINO=$version -DF_CPU=$f_cpu"; $autocc_clang_target_arch = "-D".MCUHandler::$MCU[$mcu]." -DARDUINO=$version -DF_CPU=$f_cpu -DUSB_VID=$vid -DUSB_PID=$pid"; - // Step 1(part 1): Extract the project files included in the request. - $files = array(); - $tmpVar = $this->extractFiles($request["files"], $TEMP_DIR, $compiler_dir, $files["sketch_files"], "files"); - - if ($tmpVar["success"] === false) - return $tmpVar; - - // Add the compiler temp directory to the compiler_config struct. - $compiler_config["compiler_dir"] = $compiler_dir; - - // Step 1(part 2): Extract the library files included in the request. - $files["libs"] = array(); - foreach($libraries as $library => $library_files){ - - $tmpVar = $this->extractFiles($library_files, $TEMP_DIR, $compiler_dir, $files["libs"][$library], "libraries/$library", true); - if ($tmpVar["success"] === false) - return $tmpVar; - } - - if (!array_key_exists("archive", $request) || ($request["archive"] !== false && $request["archive"] !== true)) - $ARCHIVE_OPTION = false; - else - $ARCHIVE_OPTION = $request["archive"]; - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - return $arch_ret; - } - - //Set logging to true if requested, and create the directory where logfiles are stored. - $tmpVar = $this->setLoggingParams($request, $compiler_config, $TEMP_DIR, $compiler_dir); - if($tmpVar["success"] === false) - return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); - - // Step 2: Preprocess Arduino source files. - $tmpVar = $this->preprocessIno($files["sketch_files"]); - if ($tmpVar["success"] === false) - return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); - - // Step 3: Preprocess Header includes and determine which core files directory(CORE_DIR) will be used. - $tmpVar = $this->preprocessHeaders($libraries, $include_directories, $compiler_dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $CORE_DIR, $CORE_OVERRIDE_DIR, $version, $core, $variant); - if ($tmpVar["success"] === false) - return array_merge($tmpVar, ($ARCHIVE_OPTION ===true) ? array("archive" => $ARCHIVE_PATH) : array()); - - // Log the names of the project files and the libraries used in it. - if ($format != "autocomplete") { - $user_id = $sketch_id = "null"; - $req_elements = array("Files: "); - - foreach ($request["files"] as $file) { - $req_elements[] = $file["filename"]; - if (strpos($file["filename"], ".txt") !== false) { - if (preg_match('/(?<=user_)[\d]+/', $file['filename'], $match)) $user_id = $match[0]; - if (preg_match('/(?<=project_)[\d]+/', $file['filename'], $match)) $sketch_id = $match[0]; - - } - } - - if ($request["libraries"]) { - $req_elements[] = "Libraries: "; - foreach ($request["libraries"] as $libname => $libfiles) { - foreach ($libfiles as $libfile) - $req_elements[] = $libname . "/" . $libfile["filename"]; - } - } - - $this->logger_id = microtime(true) . "_" . substr($compiler_config['compiler_dir'], -6) . "_user:$user_id" . "_project:$sketch_id"; - - $this->compiler_logger->addInfo($this->logger_id . " - " . implode(" ", $req_elements)); - if ($ARCHIVE_OPTION === true) - $this->compiler_logger->addInfo($this->logger_id . " - " . "Archive file: $ARCHIVE_PATH"); - } - - // Step 4: Syntax-check and compile source files. - //Use the include paths for the AVR headers that are bundled with each Arduino SDK version - //These may differ between linux and MAC OS versions of the Arduino core files, so check before including - $core_includes = ""; - if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include")) - $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include"; - if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include-fixed")) - $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include-fixed"; - if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/avr/include")) - $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/avr/include "; - elseif (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/avr/include")) - $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/avr/include "; - - if ($format == "autocomplete"){ + // Step 1(part 1): Extract the project files included in the request. + $files = array(); + $tmpVar = $this->extractFiles($request["files"], $TEMP_DIR, $compiler_dir, $files["sketch_files"], "files"); + + if ($tmpVar["success"] === false) + return $tmpVar; + + // Add the compiler temp directory to the compiler_config struct. + $compiler_config["compiler_dir"] = $compiler_dir; + + // Step 1(part 2): Extract the library files included in the request. + $files["libs"] = array(); + foreach ($libraries as $library => $library_files) + { + + $tmpVar = $this->extractFiles($library_files, $TEMP_DIR, $compiler_dir, $files["libs"][$library], "libraries/$library", true); + if ($tmpVar["success"] === false) + return $tmpVar; + } + + if (!array_key_exists("archive", $request) || ($request["archive"] !== false && $request["archive"] !== true)) + $ARCHIVE_OPTION = false; + else + $ARCHIVE_OPTION = $request["archive"]; + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + return $arch_ret; + } + + //Set logging to true if requested, and create the directory where logfiles are stored. + $tmpVar = $this->setLoggingParams($request, $compiler_config, $TEMP_DIR, $compiler_dir); + if ($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION === true) ? array("archive" => $ARCHIVE_PATH) : array()); + + // Step 2: Preprocess Arduino source files. + $tmpVar = $this->preprocessIno($files["sketch_files"]); + if ($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION === true) ? array("archive" => $ARCHIVE_PATH) : array()); + + // Step 3: Preprocess Header includes and determine which core files directory(CORE_DIR) will be used. + $tmpVar = $this->preprocessHeaders($libraries, $include_directories, $compiler_dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $CORE_DIR, $CORE_OVERRIDE_DIR, $version, $core, $variant); + if ($tmpVar["success"] === false) + return array_merge($tmpVar, ($ARCHIVE_OPTION === true) ? array("archive" => $ARCHIVE_PATH) : array()); + + // Log the names of the project files and the libraries used in it. + if ($format != "autocomplete") + { + $user_id = $sketch_id = "null"; + $req_elements = array("Files: "); + + foreach ($request["files"] as $file) + { + $req_elements[] = $file["filename"]; + if (strpos($file["filename"], ".txt") !== false) + { + if (preg_match('/(?<=user_)[\d]+/', $file['filename'], $match)) $user_id = $match[0]; + if (preg_match('/(?<=project_)[\d]+/', $file['filename'], $match)) $sketch_id = $match[0]; + + } + } + + if ($request["libraries"]) + { + $req_elements[] = "Libraries: "; + foreach ($request["libraries"] as $libname => $libfiles) + { + foreach ($libfiles as $libfile) + $req_elements[] = $libname."/".$libfile["filename"]; + } + } + + $this->logger_id = microtime(true)."_".substr($compiler_config['compiler_dir'], -6)."_user:$user_id"."_project:$sketch_id"; + + $this->compiler_logger->addInfo($this->logger_id." - ".implode(" ", $req_elements)); + if ($ARCHIVE_OPTION === true) + $this->compiler_logger->addInfo($this->logger_id." - "."Archive file: $ARCHIVE_PATH"); + } + + // Step 4: Syntax-check and compile source files. + //Use the include paths for the AVR headers that are bundled with each Arduino SDK version + //These may differ between linux and MAC OS versions of the Arduino core files, so check before including + $core_includes = ""; + if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include")) + $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include"; + if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include-fixed")) + $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/gcc/avr/4.3.2/include-fixed"; + if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/avr/include")) + $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/avr/include "; + elseif (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/avr/include")) + $core_includes .= " -I$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/lib/avr/include "; + + if ($format == "autocomplete") + { $autocompleteRet = $this->handleAutocompletion($ARDUINO_CORES_DIR, "$compiler_dir/files", $include_directories["main"], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $core_includes, $autocc_clang_target_arch, $TEMP_DIR, $AUTOCC_DIR, $PYTHON, $AUTOCOMPLETER); - if ($ARCHIVE_OPTION === true){ + if ($ARCHIVE_OPTION === true) + { $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); if ($arch_ret["success"] === false) return $arch_ret; @@ -165,718 +174,785 @@ function main($request, $compiler_config) return array_merge($autocompleteRet, array("total_compiler_exec_time" => microtime(true) - $start_time)); } - //handleCompile sets any include directories needed and calls the doCompile function, which does the actual compilation - $ret = $this->handleCompile("$compiler_dir/files", $files["sketch_files"], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["main"], $format); - - $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); - if ($compiler_config['logging'] === true){ - if ($log_content !== false) { - $ret["log"] = $log_content; - file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - } - else - $ret["log"] = "Failed to access logfile."; - } - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - $ret["archive"] = $arch_ret["message"]; - else - $ret["archive"] = $ARCHIVE_PATH; - } - - if (!$ret["success"]) - return $ret; - - if ($format == "syntax") - return array_merge(array( - "success" => true, - "time" => microtime(true) - $start_time), - ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), - ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); - - //Keep all object files urls needed for linking. - $objects_to_link = $files["sketch_files"]["o"]; - - //TODO: return objects if more than one file?? - if ($format == "object") - { - $content = base64_encode(file_get_contents($files["sketch_files"]["o"][0].".o")); - if (count($files["sketch_files"]["o"]) != 1 || !$content){ - return array_merge(array( - "success" => false, - "step" => -1, //TODO: Fix this step? - "message" => ""), - ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), - ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); - } - else - return array_merge(array( - "success" => true, - "time" => microtime(true) - $start_time, - "output" => $content), - ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), - ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); - } - - // Step 5: Create objects for core files (if core file does not already exist) - //Link all core object files to a core.a library. - - //TODO: Figure out why Symfony needs "@" to suppress mkdir wanring - if(!file_exists($this->object_directory)){ - //The code below was added to ensure that no error will be returned because of multithreaded execution. - $make_dir_success = @mkdir($this->object_directory, 0777, true); - if (!$make_dir_success && !is_dir($this->object_directory)) { - usleep(rand( 5000 , 10000 )); - $make_dir_success = @mkdir($this->object_directory, 0777, true); - } - if(!$make_dir_success){ - return array_merge(array( - "success" => false, - "step" => 5, - "message" => "Could not create object files directory."), - ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), - ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); - } - } - - //Generate full pathname of the cores library and then check if the library exists. - $core_library = $this->object_directory ."/". pathinfo(str_replace("/", "__", $CORE_DIR."_"), PATHINFO_FILENAME)."_______"."${mcu}_${f_cpu}_${core}_${variant}_${vid}_${pid}_______"."core.a"; - - $lock = fopen("$core_library.LOCK", "w"); - - flock($lock, LOCK_EX); - if (!file_exists($core_library)){ - //makeCoresTmp scans the core files directory and return list including the urls of the files included there. - $tmpVar = $this->makeCoresTmp($CORE_DIR, $CORE_OVERRIDE_DIR, $TEMP_DIR, $compiler_dir, $files); - - if(!$tmpVar["success"]){ - return array_merge($tmpVar, - ($ARCHIVE_OPTION ===true) ? array("archive" => $ret["archive"]) : array(), - ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); - } - - $ret = $this->handleCompile("$compiler_dir/core", $files["core"], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["core"], "object"); - - $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); - - if ($compiler_config['logging'] === true){ - if ($log_content !== false){ - $ret["log"] = $log_content; - file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - } - else - $ret["log"] = "Failed to access logfile."; - } - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - $ret["archive"] = $arch_ret["message"]; - else - $ret["archive"] = $ARCHIVE_PATH; - } - - if (!$ret["success"]) - return $ret; - - foreach ($files["core"]["o"] as $core_object){ - //Link object file to library. - exec("$AR $ARFLAGS $core_library $core_object.o", $output); - - if ($compiler_config['logging']) - file_put_contents($compiler_config['logFileName'], "$AR $ARFLAGS $core_library $core_object.o"."\n", FILE_APPEND); - } - flock($lock, LOCK_UN); - fclose($lock); - } - else{ - flock($lock, LOCK_UN); - fclose($lock); - if($compiler_config['logging']) - file_put_contents($compiler_config['logFileName'],"\nUsing previously compiled version of $core_library\n", FILE_APPEND); - } - - // Step 6: Create objects for libraries. - // The elements of the "build" array are needed to build the unique name of every library object file. - $lib_object_naming_params = $request["build"]; - if (!array_key_exists("variant", $request["build"])) - $lib_object_naming_params["variant"] = ""; - $lib_object_naming_params["vid"] = $vid; - $lib_object_naming_params["pid"] = $pid; - - foreach ($files["libs"] as $library_name => $library_files){ - - $lib_object_naming_params["library"] = $library_name; - - $ret = $this->handleCompile("$compiler_dir/libraries/$library_name", $files["libs"][$library_name], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["main"], $format, true, $lib_object_naming_params); - - $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); - if ($compiler_config['logging'] === true){ - if ($log_content !== false) { - $ret["log"] = $log_content; - file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - } - else - $ret["log"] = "Failed to access logfile."; - } - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - $ret["archive"] = $arch_ret["message"]; - else - $ret["archive"] = $ARCHIVE_PATH; - } - - if(!$ret["success"]) - return $ret; - - $objects_to_link = array_merge($objects_to_link, $files["libs"][$library_name]["o"]); - } - - // Step 7: Link all object files and create executable. - $object_files = ""; - foreach ($objects_to_link as $object) - $object_files .= " ".escapeshellarg("$object.o"); - - //Link core.a and every other object file to a .elf binary file - exec("$LD $LDFLAGS $target_arch $object_files $core_library -o $compiler_dir/files/$OUTPUT.elf $LDFLAGS_TAIL 2>&1", $output, $ret_link); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'], "$LD $LDFLAGS $target_arch $object_files $core_library -o $compiler_dir/files/$OUTPUT.elf $LDFLAGS_TAIL\n", FILE_APPEND); - } - - if ($ret_link){ - - // Log the fact that an error occurred during linking - $this->compiler_logger->addInfo($this->logger_id . " - An error occurred during linking: " . json_encode(implode("\n", $output))); - - $returner = array( - "success" => false, - "step" => 7, - "message" => implode("\n", $output)); - - if ($compiler_config['logging'] === true) { - $log_content = @file_get_contents($compiler_config['logFileName']); - if (!$log_content) - $returner["log"] = "Failed to access logfile."; - else { - file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - $returner["log"] = $log_content; - } - } - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - $returner["archive"] = $arch_ret["message"]; - else - $returner["archive"] = $ARCHIVE_PATH; - } - return $returner; - } - - // Step 8: Convert the output to the requested format and measure its - // size. - $tmpVar = $this->convertOutput("$compiler_dir/files", $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config); - - if ($compiler_config['logging'] === true) { - $log_content = @file_get_contents($compiler_config['logFileName']); - if (!$log_content) - $tmpVar["log"] = "Failed to access logfile."; - else { - file_put_contents($compiler_config["compiler_dir"] . "/log", $log_content); - $tmpVar["log"] = $log_content; - } - } - - if ($ARCHIVE_OPTION === true){ - $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); - if ($arch_ret["success"] === false) - $tmpVar["archive"] = $arch_ret["message"]; - else - $tmpVar["archive"] = $ARCHIVE_PATH; - } - return $tmpVar; - } - - private function requestValid(&$request) - { - $request = $this->preproc->validate_input($request); - if (!$request) - return array( - "success" => false, - "step" => 0, - "message" => "Invalid input."); - else return array("success" => true); - } - - private function createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, &$ARCHIVE_PATH) - { - if (!file_exists($ARCHIVE_PATH)){ - // Create a directory in tmp folder and store archive files there - if (!file_exists("$TEMP_DIR/$ARCHIVE_DIR")){ - //The code below was added to ensure that no error will be returned because of multithreaded execution. - $make_dir_success = @mkdir("$TEMP_DIR/$ARCHIVE_DIR", 0777, true); - if (!$make_dir_success && !is_dir("$TEMP_DIR/$ARCHIVE_DIR")) { - usleep(rand( 5000 , 10000 )); - $make_dir_success = @mkdir("$TEMP_DIR/$ARCHIVE_DIR", 0777, true); - } - if (!$make_dir_success) - return array("success" => false, "message" => "Failed to create archive directory."); - } - - do{ - $tar_random_name = uniqid(rand(), true) . '.tar.gz'; - }while (file_exists("$TEMP_DIR/$ARCHIVE_DIR/$tar_random_name")); - $ARCHIVE_PATH = "$TEMP_DIR/$ARCHIVE_DIR/$tar_random_name"; - } - - // The archive files include all the files of the project and the libraries needed to compile it - exec("tar -zcvf $ARCHIVE_PATH -C $TEMP_DIR/ ". pathinfo($compiler_dir, PATHINFO_BASENAME), $output, $ret_var); - - if ($ret_var !=0) - return array("success" => false, "message" => "Failed to archive project files."); - return array("success" => true); - } - - private function extractFiles($request, $temp_dir, &$dir, &$files, $suffix, $lib_extraction = false) - { - // Create a temporary directory to place all the files needed to process - // the compile request. This directory is created in $TMPDIR or /tmp by - // default and is automatically removed upon execution completion. - $cnt = 0; - if (!$dir) - do { - $dir = @System::mktemp("-t $temp_dir/ -d compiler."); - $cnt++; - } while (!$dir && $cnt <= 2); - - if (!$dir) - return array( - "success" => false, - "step" => 1, - "message" => "Failed to create temporary directory."); - - $response = $this->utility->extract_files("$dir/$suffix", $request, $lib_extraction); - - if ($response["success"] === false) - return $response; - $files = $response["files"]; - - return array("success" => true); - } - - private function preprocessIno(&$files) - { - foreach ($files["ino"] as $file) - { - $code = file_get_contents("$file.ino"); - $new_code = $this->preproc->ino_to_cpp($code, "$file.ino"); - $ret = file_put_contents("$file.cpp", $new_code); - - if ($code === false || !$new_code || !$ret) - return array( - "success" => false, - "step" => 2, - "message" => "Failed to preprocess file '$file.ino'."); - - $files["cpp"][] = array_shift($files["ino"]); - } - - return array("success" => true); - } - - public function preprocessHeaders($libraries, &$include_directories, $dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, &$CORE_DIR, &$CORE_OVERRIDE_DIR, $version, &$core, &$variant) - { - try - { - // Create command-line arguments for header search paths. Note that the - // current directory is added to eliminate the difference between <> - // and "" in include preprocessor directives. - - // Check if the core or variant contains a semicolon. - // When a semicolon exists both the core folder and the core itself are specified. - // The same applies to the variant specification. - - $core_specs = array('folder' => "arduino", 'name' => $core, 'modified' => false); - $variant_specs = array('folder' => "arduino", 'name' => $variant, 'modified' => false); - - $tmp = explode(":", $core); - if (count($tmp) == 2){ - $core_specs = array('folder' => $tmp[0], 'name' => $tmp[1], 'modified' => true); - $core = str_replace(":", "_", $core); //core name is used for object file naming, so it shouldn't contain any semicolons - } - elseif (count($tmp) != 1) - return array("success" => false, "step" => 3, "message" => "Invalid core specifier."); - - $tmp = explode(":", $variant); - if (count($tmp) == 2){ - $variant_specs = array('folder' => $tmp[0], 'name' => $tmp[1], 'modified' => true); - $variant = str_replace(":", "_", $variant); //variant name is used for object file naming, so it shouldn't contain any semicolons - } - elseif (count($tmp) != 1) - return array("success" => false, "step" => 3, "message" => "Invalid variant specifier."); - - - - $include_directories = array(); - - // Try to locate the core files - if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/".$core_specs['folder']."/cores/".$core_specs['name'])){ - $CORE_DIR = "$ARDUINO_CORES_DIR/v$version/hardware/".$core_specs['folder']."/cores/".$core_specs['name']; - } - elseif (is_dir($EXTERNAL_CORES_DIR)){ - if ($core_specs['modified'] === true){ - if (file_exists("$EXTERNAL_CORES_DIR/".$core_specs['folder']."/cores/".$core_specs['name'])) - $CORE_DIR = "$EXTERNAL_CORES_DIR/".$core_specs['folder']."/cores/".$core_specs['name']; - } - elseif (false !== ($externals = @scandir($EXTERNAL_CORES_DIR))){ - foreach ($externals as $dirname) - if (is_dir("$EXTERNAL_CORES_DIR/$dirname/") && $dirname != "." && $dirname != ".." && file_exists("$EXTERNAL_CORES_DIR/$dirname/cores/".$core_specs['name'])){ - $CORE_DIR = "$EXTERNAL_CORES_DIR/$dirname/cores/".$core_specs['name']; - break; - } - } - } - - if (empty($CORE_DIR)) - return array("success" => false, "step" => 3, "message" => "Failed to detect core files."); - - // Try to locate the variant - if ($variant != ""){ - if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/".$variant_specs['folder']."/variants/".$variant_specs['name'])) - $variant_dir = "$ARDUINO_CORES_DIR/v$version/hardware/".$variant_specs['folder']."/variants/".$variant_specs['name']; - else { - if (is_dir($EXTERNAL_CORES_DIR)){ - if ($variant_specs['modified'] === true){ - if (file_exists("$EXTERNAL_CORES_DIR/".$variant_specs['folder']."/variants/".$variant_specs['name'])) - $variant_dir = "$EXTERNAL_CORES_DIR/".$variant_specs['folder']."/variants/".$variant_specs['name']; - } - elseif (false !== ($externals = @scandir($EXTERNAL_CORES_DIR))){ - foreach ($externals as $dirname) - if (is_dir("$EXTERNAL_CORES_DIR/$dirname") && $dirname != "." && $dirname != "..") - if ($variant != "" && file_exists("$EXTERNAL_CORES_DIR/$dirname/variants/".$variant_specs['name'])){ - $variant_dir = "$EXTERNAL_CORES_DIR/$dirname/variants/".$variant_specs['name']; - break; - } - } - } - } - } - - if (!empty($variant) && empty($variant_dir)) - return array("success" => false, "step" => 3, "message" => "Failed to detect variant."); + //handleCompile sets any include directories needed and calls the doCompile function, which does the actual compilation + $ret = $this->handleCompile("$compiler_dir/files", $files["sketch_files"], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["main"], $format); + + $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); + if ($compiler_config['logging'] === true) + { + if ($log_content !== false) + { + $ret["log"] = $log_content; + file_put_contents($compiler_config["compiler_dir"]."/log", $log_content); + } + else + $ret["log"] = "Failed to access logfile."; + } + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + $ret["archive"] = $arch_ret["message"]; + else + $ret["archive"] = $ARCHIVE_PATH; + } + + if (!$ret["success"]) + return $ret; + + if ($format == "syntax") + return array_merge(array( + "success" => true, + "time" => microtime(true) - $start_time), + ($ARCHIVE_OPTION === true) ? array("archive" => $ret["archive"]) : array(), + ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); + + //Keep all object files urls needed for linking. + $objects_to_link = $files["sketch_files"]["o"]; + + //TODO: return objects if more than one file?? + if ($format == "object") + { + $content = base64_encode(file_get_contents($files["sketch_files"]["o"][0].".o")); + if (count($files["sketch_files"]["o"]) != 1 || !$content) + { + return array_merge(array( + "success" => false, + "step" => -1, //TODO: Fix this step? + "message" => ""), + ($ARCHIVE_OPTION === true) ? array("archive" => $ret["archive"]) : array(), + ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); + } + else + return array_merge(array( + "success" => true, + "time" => microtime(true) - $start_time, + "output" => $content), + ($ARCHIVE_OPTION === true) ? array("archive" => $ret["archive"]) : array(), + ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); + } + + // Step 5: Create objects for core files (if core file does not already exist) + //Link all core object files to a core.a library. + + //TODO: Figure out why Symfony needs "@" to suppress mkdir wanring + if (!file_exists($this->object_directory)) + { + //The code below was added to ensure that no error will be returned because of multithreaded execution. + $make_dir_success = @mkdir($this->object_directory, 0777, true); + if (!$make_dir_success && !is_dir($this->object_directory)) + { + usleep(rand(5000, 10000)); + $make_dir_success = @mkdir($this->object_directory, 0777, true); + } + if (!$make_dir_success) + { + return array_merge(array( + "success" => false, + "step" => 5, + "message" => "Could not create object files directory."), + ($ARCHIVE_OPTION === true) ? array("archive" => $ret["archive"]) : array(), + ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); + } + } + + //Generate full pathname of the cores library and then check if the library exists. + $core_library = $this->object_directory."/".pathinfo(str_replace("/", "__", $CORE_DIR."_"), PATHINFO_FILENAME)."_______"."${mcu}_${f_cpu}_${core}_${variant}_${vid}_${pid}_______"."core.a"; + + $lock = fopen("$core_library.LOCK", "w"); + + flock($lock, LOCK_EX); + if (!file_exists($core_library)) + { + //makeCoresTmp scans the core files directory and return list including the urls of the files included there. + $tmpVar = $this->makeCoresTmp($CORE_DIR, $CORE_OVERRIDE_DIR, $TEMP_DIR, $compiler_dir, $files); + + if (!$tmpVar["success"]) + { + return array_merge($tmpVar, + ($ARCHIVE_OPTION === true) ? array("archive" => $ret["archive"]) : array(), + ($compiler_config['logging'] === true) ? array("log" => $ret["log"]) : array()); + } + + $ret = $this->handleCompile("$compiler_dir/core", $files["core"], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["core"], "object"); + + $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); + + if ($compiler_config['logging'] === true) + { + if ($log_content !== false) + { + $ret["log"] = $log_content; + file_put_contents($compiler_config["compiler_dir"]."/log", $log_content); + } + else + $ret["log"] = "Failed to access logfile."; + } + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + $ret["archive"] = $arch_ret["message"]; + else + $ret["archive"] = $ARCHIVE_PATH; + } + + if (!$ret["success"]) + return $ret; + + foreach ($files["core"]["o"] as $core_object) + { + //Link object file to library. + exec("$AR $ARFLAGS $core_library $core_object.o", $output); + + if ($compiler_config['logging']) + file_put_contents($compiler_config['logFileName'], "$AR $ARFLAGS $core_library $core_object.o"."\n", FILE_APPEND); + } + flock($lock, LOCK_UN); + fclose($lock); + } + else + { + flock($lock, LOCK_UN); + fclose($lock); + if ($compiler_config['logging']) + file_put_contents($compiler_config['logFileName'], "\nUsing previously compiled version of $core_library\n", FILE_APPEND); + } + + // Step 6: Create objects for libraries. + // The elements of the "build" array are needed to build the unique name of every library object file. + $lib_object_naming_params = $request["build"]; + if (!array_key_exists("variant", $request["build"])) + $lib_object_naming_params["variant"] = ""; + $lib_object_naming_params["vid"] = $vid; + $lib_object_naming_params["pid"] = $pid; + + foreach ($files["libs"] as $library_name => $library_files) + { + + $lib_object_naming_params["library"] = $library_name; + + $ret = $this->handleCompile("$compiler_dir/libraries/$library_name", $files["libs"][$library_name], $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories["main"], $format, true, $lib_object_naming_params); + + $log_content = (($compiler_config['logging'] === true) ? @file_get_contents($compiler_config['logFileName']) : ""); + if ($compiler_config['logging'] === true) + { + if ($log_content !== false) + { + $ret["log"] = $log_content; + file_put_contents($compiler_config["compiler_dir"]."/log", $log_content); + } + else + $ret["log"] = "Failed to access logfile."; + } + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + $ret["archive"] = $arch_ret["message"]; + else + $ret["archive"] = $ARCHIVE_PATH; + } + + if (!$ret["success"]) + return $ret; + + $objects_to_link = array_merge($objects_to_link, $files["libs"][$library_name]["o"]); + } + + // Step 7: Link all object files and create executable. + $object_files = ""; + foreach ($objects_to_link as $object) + $object_files .= " ".escapeshellarg("$object.o"); + + //Link core.a and every other object file to a .elf binary file + exec("$LD $LDFLAGS $target_arch $object_files $core_library -o $compiler_dir/files/$OUTPUT.elf $LDFLAGS_TAIL 2>&1", $output, $ret_link); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$LD $LDFLAGS $target_arch $object_files $core_library -o $compiler_dir/files/$OUTPUT.elf $LDFLAGS_TAIL\n", FILE_APPEND); + } + + if ($ret_link) + { + + // Log the fact that an error occurred during linking + $this->compiler_logger->addInfo($this->logger_id." - An error occurred during linking: ".json_encode(implode("\n", $output))); + + $returner = array( + "success" => false, + "step" => 7, + "message" => implode("\n", $output)); + + if ($compiler_config['logging'] === true) + { + $log_content = @file_get_contents($compiler_config['logFileName']); + if (!$log_content) + $returner["log"] = "Failed to access logfile."; + else + { + file_put_contents($compiler_config["compiler_dir"]."/log", $log_content); + $returner["log"] = $log_content; + } + } + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + $returner["archive"] = $arch_ret["message"]; + else + $returner["archive"] = $ARCHIVE_PATH; + } + return $returner; + } + + // Step 8: Convert the output to the requested format and measure its + // size. + $tmpVar = $this->convertOutput("$compiler_dir/files", $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config); + + if ($compiler_config['logging'] === true) + { + $log_content = @file_get_contents($compiler_config['logFileName']); + if (!$log_content) + $tmpVar["log"] = "Failed to access logfile."; + else + { + file_put_contents($compiler_config["compiler_dir"]."/log", $log_content); + $tmpVar["log"] = $log_content; + } + } + + if ($ARCHIVE_OPTION === true) + { + $arch_ret = $this->createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, $ARCHIVE_PATH); + if ($arch_ret["success"] === false) + $tmpVar["archive"] = $arch_ret["message"]; + else + $tmpVar["archive"] = $ARCHIVE_PATH; + } + return $tmpVar; + } + + private function requestValid(&$request) + { + $request = $this->preproc->validate_input($request); + if (!$request) + return array( + "success" => false, + "step" => 0, + "message" => "Invalid input."); + else return array("success" => true); + } + + private function createArchive($compiler_dir, $TEMP_DIR, $ARCHIVE_DIR, &$ARCHIVE_PATH) + { + if (!file_exists($ARCHIVE_PATH)) + { + // Create a directory in tmp folder and store archive files there + if (!file_exists("$TEMP_DIR/$ARCHIVE_DIR")) + { + //The code below was added to ensure that no error will be returned because of multithreaded execution. + $make_dir_success = @mkdir("$TEMP_DIR/$ARCHIVE_DIR", 0777, true); + if (!$make_dir_success && !is_dir("$TEMP_DIR/$ARCHIVE_DIR")) + { + usleep(rand(5000, 10000)); + $make_dir_success = @mkdir("$TEMP_DIR/$ARCHIVE_DIR", 0777, true); + } + if (!$make_dir_success) + return array("success" => false, "message" => "Failed to create archive directory."); + } + + do + { + $tar_random_name = uniqid(rand(), true).'.tar.gz'; + } while (file_exists("$TEMP_DIR/$ARCHIVE_DIR/$tar_random_name")); + $ARCHIVE_PATH = "$TEMP_DIR/$ARCHIVE_DIR/$tar_random_name"; + } + + // The archive files include all the files of the project and the libraries needed to compile it + exec("tar -zcvf $ARCHIVE_PATH -C $TEMP_DIR/ ".pathinfo($compiler_dir, PATHINFO_BASENAME), $output, $ret_var); + + if ($ret_var != 0) + return array("success" => false, "message" => "Failed to archive project files."); + return array("success" => true); + } + + private function extractFiles($request, $temp_dir, &$dir, &$files, $suffix, $lib_extraction = false) + { + // Create a temporary directory to place all the files needed to process + // the compile request. This directory is created in $TMPDIR or /tmp by + // default and is automatically removed upon execution completion. + $cnt = 0; + if (!$dir) + do + { + $dir = @System::mktemp("-t $temp_dir/ -d compiler."); + $cnt++; + } while (!$dir && $cnt <= 2); + + if (!$dir) + return array( + "success" => false, + "step" => 1, + "message" => "Failed to create temporary directory."); + + $response = $this->utility->extract_files("$dir/$suffix", $request, $lib_extraction); + + if ($response["success"] === false) + return $response; + $files = $response["files"]; + + return array("success" => true); + } + + private function preprocessIno(&$files) + { + foreach ($files["ino"] as $file) + { + $code = file_get_contents("$file.ino"); + $new_code = $this->preproc->ino_to_cpp($code, "$file.ino"); + $ret = file_put_contents("$file.cpp", $new_code); + + if ($code === false || !$new_code || !$ret) + return array( + "success" => false, + "step" => 2, + "message" => "Failed to preprocess file '$file.ino'."); + + $files["cpp"][] = array_shift($files["ino"]); + } + + return array("success" => true); + } + + public function preprocessHeaders($libraries, &$include_directories, $dir, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, &$CORE_DIR, &$CORE_OVERRIDE_DIR, $version, &$core, &$variant) + { + try + { + // Create command-line arguments for header search paths. Note that the + // current directory is added to eliminate the difference between <> + // and "" in include preprocessor directives. + + // Check if the core or variant contains a semicolon. + // When a semicolon exists both the core folder and the core itself are specified. + // The same applies to the variant specification. + + $core_specs = array('folder' => "arduino", 'name' => $core, 'modified' => false); + $variant_specs = array('folder' => "arduino", 'name' => $variant, 'modified' => false); + + $tmp = explode(":", $core); + if (count($tmp) == 2) + { + $core_specs = array('folder' => $tmp[0], 'name' => $tmp[1], 'modified' => true); + $core = str_replace(":", "_", $core); //core name is used for object file naming, so it shouldn't contain any semicolons + } + elseif (count($tmp) != 1) + return array("success" => false, "step" => 3, "message" => "Invalid core specifier."); + + $tmp = explode(":", $variant); + if (count($tmp) == 2) + { + $variant_specs = array('folder' => $tmp[0], 'name' => $tmp[1], 'modified' => true); + $variant = str_replace(":", "_", $variant); //variant name is used for object file naming, so it shouldn't contain any semicolons + } + elseif (count($tmp) != 1) + return array("success" => false, "step" => 3, "message" => "Invalid variant specifier."); + + + $include_directories = array(); + + // Try to locate the core files + if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/".$core_specs['folder']."/cores/".$core_specs['name'])) + { + $CORE_DIR = "$ARDUINO_CORES_DIR/v$version/hardware/".$core_specs['folder']."/cores/".$core_specs['name']; + } + elseif (is_dir($EXTERNAL_CORES_DIR)) + { + if ($core_specs['modified'] === true) + { + if (file_exists("$EXTERNAL_CORES_DIR/".$core_specs['folder']."/cores/".$core_specs['name'])) + $CORE_DIR = "$EXTERNAL_CORES_DIR/".$core_specs['folder']."/cores/".$core_specs['name']; + } + elseif (false !== ($externals = @scandir($EXTERNAL_CORES_DIR))) + { + foreach ($externals as $dirname) + if (is_dir("$EXTERNAL_CORES_DIR/$dirname/") && $dirname != "." && $dirname != ".." && file_exists("$EXTERNAL_CORES_DIR/$dirname/cores/".$core_specs['name'])) + { + $CORE_DIR = "$EXTERNAL_CORES_DIR/$dirname/cores/".$core_specs['name']; + break; + } + } + } + + if (empty($CORE_DIR)) + return array("success" => false, "step" => 3, "message" => "Failed to detect core files."); + + // Try to locate the variant + if ($variant != "") + { + if (file_exists("$ARDUINO_CORES_DIR/v$version/hardware/".$variant_specs['folder']."/variants/".$variant_specs['name'])) + $variant_dir = "$ARDUINO_CORES_DIR/v$version/hardware/".$variant_specs['folder']."/variants/".$variant_specs['name']; + else + { + if (is_dir($EXTERNAL_CORES_DIR)) + { + if ($variant_specs['modified'] === true) + { + if (file_exists("$EXTERNAL_CORES_DIR/".$variant_specs['folder']."/variants/".$variant_specs['name'])) + $variant_dir = "$EXTERNAL_CORES_DIR/".$variant_specs['folder']."/variants/".$variant_specs['name']; + } + elseif (false !== ($externals = @scandir($EXTERNAL_CORES_DIR))) + { + foreach ($externals as $dirname) + if (is_dir("$EXTERNAL_CORES_DIR/$dirname") && $dirname != "." && $dirname != "..") + if ($variant != "" && file_exists("$EXTERNAL_CORES_DIR/$dirname/variants/".$variant_specs['name'])) + { + $variant_dir = "$EXTERNAL_CORES_DIR/$dirname/variants/".$variant_specs['name']; + break; + } + } + } + } + } + + if (!empty($variant) && empty($variant_dir)) + return array("success" => false, "step" => 3, "message" => "Failed to detect variant."); // Check the override file directories for files that override the requested cores - if (is_dir("$EXTERNAL_CORES_DIR/override_cores/".$core_specs['name']."/") ) + if (is_dir("$EXTERNAL_CORES_DIR/override_cores/".$core_specs['name']."/")) $CORE_OVERRIDE_DIR = "$EXTERNAL_CORES_DIR/override_cores/".$core_specs['name']."/"; else $CORE_OVERRIDE_DIR = ""; $include_directories["core"] = ((!empty($CORE_OVERRIDE_DIR)) && ($CORE_OVERRIDE_DIR != "")) ? " -I$CORE_OVERRIDE_DIR" : ""; - $include_directories["core"] .= " -I$CORE_DIR"; + $include_directories["core"] .= " -I$CORE_DIR"; $include_directories["core"] .= (!empty($variant_dir)) ? " -I$variant_dir" : ""; - $include_directories["main"] = $include_directories["core"]; - foreach ($libraries as $library_name => $library_files) - $include_directories["main"] .= " -I$dir/libraries/$library_name"; - } - catch(\Exception $e) - { - return array("success" => false, "step" => 3, "message" => "Unknown Error:\n".$e->getMessage()); - } - - return array("success" => true); - } - - private function doCompile($compiler_config, &$files, $dir, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching = false, $name_params = null) - { - if ($format == "syntax") - { - $CFLAGS .= " -fsyntax-only"; - $CPPFLAGS .= " -fsyntax-only"; - } - - foreach (array("c", "cpp", "S") as $ext) - { - foreach ($files[$ext] as $file) - { - if($caching){ - $name_params['core'] = str_replace(":", "_", $name_params['core']); - $name_params['variant'] = str_replace(":", "_", $name_params['variant']); - $object_filename = "$this->object_directory/${name_params['mcu']}_${name_params['f_cpu']}_${name_params['core']}_${name_params['variant']}_${name_params['vid']}_${name_params['pid']}______${name_params['library']}_______".((pathinfo(pathinfo($file, PATHINFO_DIRNAME), PATHINFO_FILENAME) == "utility") ? "utility_______" : "") .pathinfo($file, PATHINFO_FILENAME); - $object_file = $object_filename; - //Lock the file so that only one compiler instance (thread) will compile every library object file - $lock = fopen("$object_file.o.LOCK", "w"); - $lock_check = flock($lock, LOCK_EX); - } - else - $object_file = $file; - - if(!file_exists("$object_file.o")){ - // From hereon, $file is shell escaped and thus should only be used in calls - // to exec(). - $file = escapeshellarg($file); - $object_file = escapeshellarg($object_file); - - //replace exec() calls with $this->utility->debug_exec() for debugging - if ($ext == "c") - { - exec("$CC $CFLAGS $core_includes $target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$CC $CFLAGS $core_includes $target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); - } - } - elseif ($ext == "cpp") - { - exec("$CPP $CPPFLAGS $core_includes $target_arch -MMD $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$CPP $CPPFLAGS $core_includes $target_arch -MMD $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); - } - } - elseif ($ext == "S") - { - exec("$AS $ASFLAGS $target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$AS $ASFLAGS $target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); - } - } - if (isset($ret_compile) && $ret_compile) - { - $avr_output = implode("\n", $output); - unset($output); - exec("$CLANG $CLANG_FLAGS $core_includes $clang_target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$CLANG $CLANG_FLAGS $core_includes $clang_target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); - } - - $output = $this->postproc->ansi_to_html(implode("\n", $output)); - - $resp = array( - "success" => false, - "step" => 4, - "debug" => $avr_output); - - /** - * When an error occurs, compare the output of both avr-gcc and clang - * and if significant differences are detected, return a modified version of the clang output. - */ - $clangElements = $this->getClangErrorFileList ($output); - $this->compiler_logger->addInfo($this->logger_id . " - Clang reported files: " . implode(" | ", array_keys($clangElements))); - $gccElements = $this->getGccErrorFileList ($avr_output); - $this->compiler_logger->addInfo($this->logger_id . " - Gcc reported files: " . implode(" | ", array_keys($gccElements))); - - if (array_diff(array_keys($clangElements), array_keys($gccElements))) { - - $resp["old_message"] = $output; - $this->compiler_logger->addInfo($this->logger_id . " - Mismatch between clang and gcc output found."); - - $next_clang_output = $this->cleanUpClangOutput ($output, $compiler_config, "asm"); - - $clangElements = $this->getClangErrorFileList ($next_clang_output); - $this->compiler_logger->addInfo($this->logger_id . " - Clang reported files after removing asm: " . implode(" | ", array_keys($clangElements))); - - if (array_diff(array_keys($clangElements), array_keys($gccElements))) { - $this->compiler_logger->addInfo($this->logger_id . " - Mismatch between clang and gcc output found after removing assembly messages."); - $final_clang_output = $this->cleanUpClangOutput ($next_clang_output, $compiler_config, "non_asm"); - - $clangElements = $this->getClangErrorFileList ($final_clang_output); - if (array_diff(array_keys($clangElements), array_keys($gccElements))) { - $this->compiler_logger->addInfo($this->logger_id . " - Mismatch between clang and gcc output found after removing assembly/library/core messages."); - }else { - $this->compiler_logger->addInfo($this->logger_id . " - Clang and gcc issue solved. Both report same files with errors."); - } - $this->compiler_logger->addInfo($this->logger_id . " - Gcc output: " . json_encode($avr_output)); - $this->compiler_logger->addInfo($this->logger_id . " - Clang initial output: " . json_encode($output)); - $this->compiler_logger->addInfo($this->logger_id . " - Clang reformated output: " . json_encode($final_clang_output)); - $final_clang_output = $this->pathRemover ($final_clang_output, $compiler_config); - $resp["message"] = $final_clang_output; - if ($resp["message"] == "") - $resp["message"] = $this->pathRemover ($output, $compiler_config); - return $resp; - }else { - $this->compiler_logger->addInfo($this->logger_id . " - Gcc output: " . json_encode($avr_output)); - $this->compiler_logger->addInfo($this->logger_id . " - Clang initial output: " . json_encode($output)); - $this->compiler_logger->addInfo($this->logger_id . " - Clang reformated output: " . json_encode($next_clang_output)); - $next_clang_output = $this->pathRemover ($next_clang_output, $compiler_config); - $resp["message"] = $next_clang_output; - if ($resp["message"] == "") - $resp["message"] = $this->pathRemover ($output, $compiler_config); - return $resp; - } - } - - $resp["message"] = $this->pathRemover ($output, $compiler_config); - if ($resp["message"] == "") - $resp["message"] = $this->pathRemover($avr_output, $compiler_config); - return $resp; - } - unset($output); - if ($caching && $lock_check){ - flock($lock, LOCK_UN); - fclose($lock); - } - } - elseif ($caching && $lock_check){ - if($compiler_config['logging']) - file_put_contents($compiler_config['logFileName'],"Using previously compiled version of $object_file.o\n", FILE_APPEND); - flock($lock, LOCK_UN); - fclose($lock); - } - - if(!$caching){ - $files["o"][] = array_shift($files[$ext]); - } - else{ - $files["o"][] = $object_filename; - array_shift($files[$ext]); - } - } - } - - return array("success" => true); - } - - private function convertOutput($dir, $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config) - { - if ($format == "elf") - { - $ret_objcopy = false; - exec("$SIZE $SIZE_FLAGS --target=elf32-avr $dir/$OUTPUT.elf | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME - - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$SIZE $SIZE_FLAGS --target=elf32-avr $dir/$OUTPUT.elf | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); - } - $content = base64_encode(file_get_contents("$dir/$OUTPUT.elf")); - } - elseif ($format == "binary") - { - exec("$OBJCOPY $OBJCOPY_FLAGS -O binary $dir/$OUTPUT.elf $dir/$OUTPUT.bin", $dummy, $ret_objcopy); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$OBJCOPY $OBJCOPY_FLAGS -O binary $dir/$OUTPUT.elf $dir/$OUTPUT.bin\n", FILE_APPEND); - } - - exec("$SIZE $SIZE_FLAGS --target=binary $dir/$OUTPUT.bin | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$SIZE $SIZE_FLAGS --target=binary $dir/$OUTPUT.bin | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); - } - $content = base64_encode(file_get_contents("$dir/$OUTPUT.bin")); - } - elseif ($format == "hex") - { - exec("$OBJCOPY $OBJCOPY_FLAGS -O ihex $dir/$OUTPUT.elf $dir/$OUTPUT.hex", $dummy, $ret_objcopy); - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$OBJCOPY $OBJCOPY_FLAGS -O ihex $dir/$OUTPUT.elf $dir/$OUTPUT.hex\n", FILE_APPEND); - } - - exec("$SIZE $SIZE_FLAGS --target=ihex $dir/$OUTPUT.hex | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME - if($compiler_config['logging']){ - file_put_contents($compiler_config['logFileName'],"$SIZE $SIZE_FLAGS --target=ihex $dir/$OUTPUT.hex | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); - } - - $content = file_get_contents("$dir/$OUTPUT.hex"); - } - - // If everything went well, return the reply to the caller. - if ($ret_objcopy || $ret_size || $content === false) - return array( - "success" => false, - "step" => 8, - "message" => "There was a problem while generating the your binary file"); - else - return array( - "success" => true, - "time" => microtime(true) - $start_time, - "size" => $size[0], - "output" => $content); - - } - - private function set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, &$CC, &$CPP, &$AS, &$AR, &$LD, &$OBJCOPY, &$SIZE) - { - // External binaries. - $binaries = array("cc" => "-gcc", "cpp" => "-g++", "as" => "-gcc", "ar" => "-ar", "ld" => "-gcc", "objcopy" => "-objcopy", "size" => "-size"); - - $binpaths = array(); - foreach ($binaries as $key => $value){ - if (!file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/bin/avr$value")) - $binpaths[$key] = "$BINUTILS/avr$value"; - else - $binpaths[$key] = "$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/bin/avr$value"; - } - - $CC = $binpaths["cc"]; - $CPP = $binpaths["cpp"]; - $AS = $binpaths["as"]; - $AR = $binpaths["ar"]; - $LD = $binpaths["ld"]; - $OBJCOPY = $binpaths["objcopy"]; - $SIZE = $binpaths["size"]; - - } - private function set_values($compiler_config, - &$BINUTILS, &$CLANG, &$CFLAGS, &$CPPFLAGS, - &$ASFLAGS, &$ARFLAGS, &$LDFLAGS, &$LDFLAGS_TAIL, &$CLANG_FLAGS, &$OBJCOPY_FLAGS, &$SIZE_FLAGS, - &$OUTPUT, &$ARDUINO_CORES_DIR, &$EXTERNAL_CORES_DIR, &$TEMP_DIR, &$ARCHIVE_DIR, &$AUTOCC_DIR, &$PYTHON, &$AUTOCOMPLETER) - { - // External binaries. - //If the current version of the core files does not include its own binaries, then use the default - //ones included in the binutils parameter - $BINUTILS = $compiler_config["binutils"]; - //Clang is used to return the output in case of an error, it's version independent, so its - //value is set by set_values function. - - $LDLIBRARYPATH="LD_LIBRARY_PATH=" . $compiler_config["arduino_cores_dir"] . "/clang/v3_5/lib:\$LD_LIBRARY_PATH"; - $CLANG = $LDLIBRARYPATH . " " . $compiler_config["clang"]; + $include_directories["main"] = $include_directories["core"]; + foreach ($libraries as $library_name => $library_files) + $include_directories["main"] .= " -I$dir/libraries/$library_name"; + } catch (\Exception $e) + { + return array("success" => false, "step" => 3, "message" => "Unknown Error:\n".$e->getMessage()); + } + + return array("success" => true); + } + + private function doCompile($compiler_config, &$files, $dir, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching = false, $name_params = null) + { + if ($format == "syntax") + { + $CFLAGS .= " -fsyntax-only"; + $CPPFLAGS .= " -fsyntax-only"; + } + + foreach (array("c", "cpp", "S") as $ext) + { + foreach ($files[$ext] as $file) + { + if ($caching) + { + $name_params['core'] = str_replace(":", "_", $name_params['core']); + $name_params['variant'] = str_replace(":", "_", $name_params['variant']); + $object_filename = "$this->object_directory/${name_params['mcu']}_${name_params['f_cpu']}_${name_params['core']}_${name_params['variant']}_${name_params['vid']}_${name_params['pid']}______${name_params['library']}_______".((pathinfo(pathinfo($file, PATHINFO_DIRNAME), PATHINFO_FILENAME) == "utility") ? "utility_______" : "").pathinfo($file, PATHINFO_FILENAME); + $object_file = $object_filename; + //Lock the file so that only one compiler instance (thread) will compile every library object file + $lock = fopen("$object_file.o.LOCK", "w"); + $lock_check = flock($lock, LOCK_EX); + } + else + $object_file = $file; + + if (!file_exists("$object_file.o")) + { + // From hereon, $file is shell escaped and thus should only be used in calls + // to exec(). + $file = escapeshellarg($file); + $object_file = escapeshellarg($object_file); + + //replace exec() calls with $this->utility->debug_exec() for debugging + if ($ext == "c") + { + exec("$CC $CFLAGS $core_includes $target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$CC $CFLAGS $core_includes $target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); + } + } + elseif ($ext == "cpp") + { + exec("$CPP $CPPFLAGS $core_includes $target_arch -MMD $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$CPP $CPPFLAGS $core_includes $target_arch -MMD $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); + } + } + elseif ($ext == "S") + { + exec("$AS $ASFLAGS $target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$AS $ASFLAGS $target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); + } + } + if (isset($ret_compile) && $ret_compile) + { + $avr_output = implode("\n", $output); + unset($output); + exec("$CLANG $CLANG_FLAGS $core_includes $clang_target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$CLANG $CLANG_FLAGS $core_includes $clang_target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); + } + + $output = $this->postproc->ansi_to_html(implode("\n", $output)); + + $resp = array( + "success" => false, + "step" => 4, + "debug" => $avr_output); + + /** + * When an error occurs, compare the output of both avr-gcc and clang + * and if significant differences are detected, return a modified version of the clang output. + */ + $clangElements = $this->getClangErrorFileList($output); + $this->compiler_logger->addInfo($this->logger_id." - Clang reported files: ".implode(" | ", array_keys($clangElements))); + $gccElements = $this->getGccErrorFileList($avr_output); + $this->compiler_logger->addInfo($this->logger_id." - Gcc reported files: ".implode(" | ", array_keys($gccElements))); + + if (array_diff(array_keys($clangElements), array_keys($gccElements))) + { + + $resp["old_message"] = $output; + $this->compiler_logger->addInfo($this->logger_id." - Mismatch between clang and gcc output found."); + + $next_clang_output = $this->cleanUpClangOutput($output, $compiler_config, "asm"); + + $clangElements = $this->getClangErrorFileList($next_clang_output); + $this->compiler_logger->addInfo($this->logger_id." - Clang reported files after removing asm: ".implode(" | ", array_keys($clangElements))); + + if (array_diff(array_keys($clangElements), array_keys($gccElements))) + { + $this->compiler_logger->addInfo($this->logger_id." - Mismatch between clang and gcc output found after removing assembly messages."); + $final_clang_output = $this->cleanUpClangOutput($next_clang_output, $compiler_config, "non_asm"); + + $clangElements = $this->getClangErrorFileList($final_clang_output); + if (array_diff(array_keys($clangElements), array_keys($gccElements))) + { + $this->compiler_logger->addInfo($this->logger_id." - Mismatch between clang and gcc output found after removing assembly/library/core messages."); + } + else + { + $this->compiler_logger->addInfo($this->logger_id." - Clang and gcc issue solved. Both report same files with errors."); + } + $this->compiler_logger->addInfo($this->logger_id." - Gcc output: ".json_encode($avr_output)); + $this->compiler_logger->addInfo($this->logger_id." - Clang initial output: ".json_encode($output)); + $this->compiler_logger->addInfo($this->logger_id." - Clang reformated output: ".json_encode($final_clang_output)); + $final_clang_output = $this->pathRemover($final_clang_output, $compiler_config); + $resp["message"] = $final_clang_output; + if ($resp["message"] == "") + $resp["message"] = $this->pathRemover($output, $compiler_config); + return $resp; + } + else + { + $this->compiler_logger->addInfo($this->logger_id." - Gcc output: ".json_encode($avr_output)); + $this->compiler_logger->addInfo($this->logger_id." - Clang initial output: ".json_encode($output)); + $this->compiler_logger->addInfo($this->logger_id." - Clang reformated output: ".json_encode($next_clang_output)); + $next_clang_output = $this->pathRemover($next_clang_output, $compiler_config); + $resp["message"] = $next_clang_output; + if ($resp["message"] == "") + $resp["message"] = $this->pathRemover($output, $compiler_config); + return $resp; + } + } + + $resp["message"] = $this->pathRemover($output, $compiler_config); + if ($resp["message"] == "") + $resp["message"] = $this->pathRemover($avr_output, $compiler_config); + return $resp; + } + unset($output); + if ($caching && $lock_check) + { + flock($lock, LOCK_UN); + fclose($lock); + } + } + elseif ($caching && $lock_check) + { + if ($compiler_config['logging']) + file_put_contents($compiler_config['logFileName'], "Using previously compiled version of $object_file.o\n", FILE_APPEND); + flock($lock, LOCK_UN); + fclose($lock); + } + + if (!$caching) + { + $files["o"][] = array_shift($files[$ext]); + } + else + { + $files["o"][] = $object_filename; + array_shift($files[$ext]); + } + } + } + + return array("success" => true); + } + + private function convertOutput($dir, $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJCOPY_FLAGS, $OUTPUT, $start_time, $compiler_config) + { + if ($format == "elf") + { + $ret_objcopy = false; + exec("$SIZE $SIZE_FLAGS --target=elf32-avr $dir/$OUTPUT.elf | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME + + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$SIZE $SIZE_FLAGS --target=elf32-avr $dir/$OUTPUT.elf | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); + } + $content = base64_encode(file_get_contents("$dir/$OUTPUT.elf")); + } + elseif ($format == "binary") + { + exec("$OBJCOPY $OBJCOPY_FLAGS -O binary $dir/$OUTPUT.elf $dir/$OUTPUT.bin", $dummy, $ret_objcopy); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$OBJCOPY $OBJCOPY_FLAGS -O binary $dir/$OUTPUT.elf $dir/$OUTPUT.bin\n", FILE_APPEND); + } + + exec("$SIZE $SIZE_FLAGS --target=binary $dir/$OUTPUT.bin | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$SIZE $SIZE_FLAGS --target=binary $dir/$OUTPUT.bin | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); + } + $content = base64_encode(file_get_contents("$dir/$OUTPUT.bin")); + } + elseif ($format == "hex") + { + exec("$OBJCOPY $OBJCOPY_FLAGS -O ihex $dir/$OUTPUT.elf $dir/$OUTPUT.hex", $dummy, $ret_objcopy); + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$OBJCOPY $OBJCOPY_FLAGS -O ihex $dir/$OUTPUT.elf $dir/$OUTPUT.hex\n", FILE_APPEND); + } + + exec("$SIZE $SIZE_FLAGS --target=ihex $dir/$OUTPUT.hex | awk 'FNR == 2 {print $1+$2}'", $size, $ret_size); // FIXME + if ($compiler_config['logging']) + { + file_put_contents($compiler_config['logFileName'], "$SIZE $SIZE_FLAGS --target=ihex $dir/$OUTPUT.hex | awk 'FNR == 2 {print $1+$2}'\n", FILE_APPEND); + } + + $content = file_get_contents("$dir/$OUTPUT.hex"); + } + + // If everything went well, return the reply to the caller. + if ($ret_objcopy || $ret_size || $content === false) + return array( + "success" => false, + "step" => 8, + "message" => "There was a problem while generating the your binary file"); + else + return array( + "success" => true, + "time" => microtime(true) - $start_time, + "size" => $size[0], + "output" => $content); + + } + + private function set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, &$CC, &$CPP, &$AS, &$AR, &$LD, &$OBJCOPY, &$SIZE) + { + // External binaries. + $binaries = array("cc" => "-gcc", "cpp" => "-g++", "as" => "-gcc", "ar" => "-ar", "ld" => "-gcc", "objcopy" => "-objcopy", "size" => "-size"); + + $binpaths = array(); + foreach ($binaries as $key => $value) + { + if (!file_exists("$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/bin/avr$value")) + $binpaths[$key] = "$BINUTILS/avr$value"; + else + $binpaths[$key] = "$ARDUINO_CORES_DIR/v$version/hardware/tools/avr/bin/avr$value"; + } + + $CC = $binpaths["cc"]; + $CPP = $binpaths["cpp"]; + $AS = $binpaths["as"]; + $AR = $binpaths["ar"]; + $LD = $binpaths["ld"]; + $OBJCOPY = $binpaths["objcopy"]; + $SIZE = $binpaths["size"]; + + } + + private function set_values($compiler_config, + &$BINUTILS, &$CLANG, &$CFLAGS, &$CPPFLAGS, + &$ASFLAGS, &$ARFLAGS, &$LDFLAGS, &$LDFLAGS_TAIL, &$CLANG_FLAGS, &$OBJCOPY_FLAGS, &$SIZE_FLAGS, + &$OUTPUT, &$ARDUINO_CORES_DIR, &$EXTERNAL_CORES_DIR, &$TEMP_DIR, &$ARCHIVE_DIR, &$AUTOCC_DIR, &$PYTHON, &$AUTOCOMPLETER) + { + // External binaries. + //If the current version of the core files does not include its own binaries, then use the default + //ones included in the binutils parameter + $BINUTILS = $compiler_config["binutils"]; + //Clang is used to return the output in case of an error, it's version independent, so its + //value is set by set_values function. + + $LDLIBRARYPATH = "LD_LIBRARY_PATH=".$compiler_config["arduino_cores_dir"]."/clang/v3_5/lib:\$LD_LIBRARY_PATH"; + $CLANG = $LDLIBRARYPATH." ".$compiler_config["clang"]; //Path to Python binaries, needed for the execution of the autocompletion script. - $PYTHONPATH="PYTHONPATH=" . $compiler_config["arduino_cores_dir"] . "/clang/v3_5/bindings/python:\$PYTHONPATH"; - $PYTHON = $LDLIBRARYPATH . " " . $PYTHONPATH . " " . $compiler_config["python"]; - - // Standard command-line arguments used by the binaries. - $CFLAGS = $compiler_config["cflags"]; - $CPPFLAGS = $compiler_config["cppflags"]; - $ASFLAGS = $compiler_config["asflags"]; - $ARFLAGS = $compiler_config["arflags"]; - $LDFLAGS = $compiler_config["ldflags"]; - $LDFLAGS_TAIL = $compiler_config["ldflags_tail"]; - $CLANG_FLAGS = $compiler_config["clang_flags"]; - $OBJCOPY_FLAGS = $compiler_config["objcopy_flags"]; - $SIZE_FLAGS = $compiler_config["size_flags"]; - // The default name of the output file. - $OUTPUT = $compiler_config["output"]; - // The tmp folder where logfiles and object files are placed - $TEMP_DIR = $compiler_config["temp_dir"]; - // The directory name where archive files are stored in $TEMP_DIR - $ARCHIVE_DIR = $compiler_config["archive_dir"]; + $PYTHONPATH = "PYTHONPATH=".$compiler_config["arduino_cores_dir"]."/clang/v3_5/bindings/python:\$PYTHONPATH"; + $PYTHON = $LDLIBRARYPATH." ".$PYTHONPATH." ".$compiler_config["python"]; + + // Standard command-line arguments used by the binaries. + $CFLAGS = $compiler_config["cflags"]; + $CPPFLAGS = $compiler_config["cppflags"]; + $ASFLAGS = $compiler_config["asflags"]; + $ARFLAGS = $compiler_config["arflags"]; + $LDFLAGS = $compiler_config["ldflags"]; + $LDFLAGS_TAIL = $compiler_config["ldflags_tail"]; + $CLANG_FLAGS = $compiler_config["clang_flags"]; + $OBJCOPY_FLAGS = $compiler_config["objcopy_flags"]; + $SIZE_FLAGS = $compiler_config["size_flags"]; + // The default name of the output file. + $OUTPUT = $compiler_config["output"]; + // The tmp folder where logfiles and object files are placed + $TEMP_DIR = $compiler_config["temp_dir"]; + // The directory name where archive files are stored in $TEMP_DIR + $ARCHIVE_DIR = $compiler_config["archive_dir"]; // The directory where autocompletion files are stored. $AUTOCC_DIR = $compiler_config["autocompletion_dir"]; // The name of the python script that will be executed for autocompletion. $AUTOCOMPLETER = $compiler_config["autocompleter"]; - // Path to arduino-core-files repository. - $ARDUINO_CORES_DIR = $compiler_config["arduino_cores_dir"]; - // Path to external core files (for example arduino ATtiny) - $EXTERNAL_CORES_DIR = $compiler_config["external_core_files"]; - } - - private function set_variables($request, &$format, &$libraries, &$version, &$mcu, &$f_cpu, &$core, &$variant, &$vid, &$pid, &$compiler_config) - { - // Extract the request options for easier access. - $format = $request["format"]; - $libraries = $request["libraries"]; - $version = $request["version"]; - $mcu = $request["build"]["mcu"]; - $f_cpu = $request["build"]["f_cpu"]; - $core = $request["build"]["core"]; - // Some cores do not specify any variants. In this case, set variant to be an empty string - if (!array_key_exists("variant", $request["build"])) - $variant = ""; - else - $variant = $request["build"]["variant"]; - - if ($format == "autocomplete") { + // Path to arduino-core-files repository. + $ARDUINO_CORES_DIR = $compiler_config["arduino_cores_dir"]; + // Path to external core files (for example arduino ATtiny) + $EXTERNAL_CORES_DIR = $compiler_config["external_core_files"]; + } + + private function set_variables($request, &$format, &$libraries, &$version, &$mcu, &$f_cpu, &$core, &$variant, &$vid, &$pid, &$compiler_config) + { + // Extract the request options for easier access. + $format = $request["format"]; + $libraries = $request["libraries"]; + $version = $request["version"]; + $mcu = $request["build"]["mcu"]; + $f_cpu = $request["build"]["f_cpu"]; + $core = $request["build"]["core"]; + // Some cores do not specify any variants. In this case, set variant to be an empty string + if (!array_key_exists("variant", $request["build"])) + $variant = ""; + else + $variant = $request["build"]["variant"]; + + if ($format == "autocomplete") + { $compiler_config["autocmpfile"] = $request["position"]["file"]; $compiler_config["autocmprow"] = $request["position"]["row"]; $compiler_config["autocmpcol"] = $request["position"]["column"]; @@ -884,136 +960,152 @@ private function set_variables($request, &$format, &$libraries, &$version, &$mcu $compiler_config["autocmpprefix"] = $request["prefix"]; } - // Set the appropriate variables for vid and pid (Leonardo). - - $vid = (isset($request["build"]["vid"])) ? $request["build"]["vid"] : "null"; - $pid = (isset($request["build"]["pid"])) ? $request["build"]["pid"] : "null"; - } - - private function setLoggingParams($request, &$compiler_config, $temp_dir, $compiler_dir) - { - //Check if $request['logging'] exists and is true, then make the logfile, otherwise set - //$compiler_config['logdir'] to false and return to caller - if(array_key_exists('logging', $request) && $request['logging']) - { - /* - Generate a random part for the log name based on current date and time, - in order to avoid naming different Blink projects for which we need logfiles - */ - $randPart = date('YmdHis'); - /* - Then find the name of the arduino file which usually is the project name itself - and mix them all together - */ - - foreach($request['files'] as $file){ - if(strcmp(pathinfo($file['filename'], PATHINFO_EXTENSION), "ino") == 0){$basename = pathinfo($file['filename'], PATHINFO_FILENAME);} - } - if(!isset($basename)){$basename="logfile";} - - $compiler_config['logging'] = true; - $directory = $temp_dir."/".$compiler_config['logdir']; - //The code below was added to ensure that no error will be returned because of multithreaded execution. - if(!file_exists($directory)){ - $make_dir_success = @mkdir($directory, 0777, true); - if (!$make_dir_success && !is_dir($directory)) { - usleep(rand( 5000 , 10000 )); - $make_dir_success = @mkdir($directory, 0777, true); - } - if(!$make_dir_success) - return array("success"=>false, "message"=>"Failed to create logfiles directory."); - } - - $compiler_part = str_replace(".", "_", substr($compiler_dir, strpos($compiler_dir, "compiler"))); - - $compiler_config['logFileName'] = $directory ."/". $basename ."_".$compiler_part."_". $randPart .".txt"; - - file_put_contents($compiler_config['logFileName'], ''); - } - elseif(!array_key_exists('logging', $request)|| (!$request['logging'])) - $compiler_config['logging'] = false; - - return array("success"=>true); - } - - - /** - \brief Reads all core files from the respective directory and passes their contents to extractFiles function - which then writes them to the compiler temp directory - - \param string $core_files_directory The directory containing the core files. - \param string $tmp_compiler The tmp directory where the actual compilation process takes place. - \return array An array containing the function results. - */ - private function makeCoresTmp($core_files_directory, $core_overrd_directory, $temp_directory, $tmp_compiler, &$files){ - - $core = array(); - if(false === ($scanned_files = @scandir($core_files_directory))) - return array( "success"=>false, "step"=>5, "message"=>"Failed to read core files." ); - - // Get the contents of the core files - foreach ($scanned_files as $core_file) - if(!is_dir("$core_files_directory/$core_file")){ - if (!empty($core_overrd_directory) && $core_overrd_directory !="" && file_exists("$core_overrd_directory/$core_file")) + // Set the appropriate variables for vid and pid (Leonardo). + + $vid = (isset($request["build"]["vid"])) ? $request["build"]["vid"] : "null"; + $pid = (isset($request["build"]["pid"])) ? $request["build"]["pid"] : "null"; + } + + private function setLoggingParams($request, &$compiler_config, $temp_dir, $compiler_dir) + { + //Check if $request['logging'] exists and is true, then make the logfile, otherwise set + //$compiler_config['logdir'] to false and return to caller + if (array_key_exists('logging', $request) && $request['logging']) + { + /* + Generate a random part for the log name based on current date and time, + in order to avoid naming different Blink projects for which we need logfiles + */ + $randPart = date('YmdHis'); + /* + Then find the name of the arduino file which usually is the project name itself + and mix them all together + */ + + foreach ($request['files'] as $file) + { + if (strcmp(pathinfo($file['filename'], PATHINFO_EXTENSION), "ino") == 0) + { + $basename = pathinfo($file['filename'], PATHINFO_FILENAME); + } + } + if (!isset($basename)) + { + $basename = "logfile"; + } + + $compiler_config['logging'] = true; + $directory = $temp_dir."/".$compiler_config['logdir']; + //The code below was added to ensure that no error will be returned because of multithreaded execution. + if (!file_exists($directory)) + { + $make_dir_success = @mkdir($directory, 0777, true); + if (!$make_dir_success && !is_dir($directory)) + { + usleep(rand(5000, 10000)); + $make_dir_success = @mkdir($directory, 0777, true); + } + if (!$make_dir_success) + return array("success" => false, "message" => "Failed to create logfiles directory."); + } + + $compiler_part = str_replace(".", "_", substr($compiler_dir, strpos($compiler_dir, "compiler"))); + + $compiler_config['logFileName'] = $directory."/".$basename."_".$compiler_part."_".$randPart.".txt"; + + file_put_contents($compiler_config['logFileName'], ''); + } + elseif (!array_key_exists('logging', $request) || (!$request['logging'])) + $compiler_config['logging'] = false; + + return array("success" => true); + } + + + /** + * \brief Reads all core files from the respective directory and passes their contents to extractFiles function + * which then writes them to the compiler temp directory + * + * \param string $core_files_directory The directory containing the core files. + * \param string $tmp_compiler The tmp directory where the actual compilation process takes place. + * \return array An array containing the function results. + */ + private function makeCoresTmp($core_files_directory, $core_overrd_directory, $temp_directory, $tmp_compiler, &$files) + { + + $core = array(); + if (false === ($scanned_files = @scandir($core_files_directory))) + return array("success" => false, "step" => 5, "message" => "Failed to read core files."); + + // Get the contents of the core files + foreach ($scanned_files as $core_file) + if (!is_dir("$core_files_directory/$core_file")) + { + if (!empty($core_overrd_directory) && $core_overrd_directory != "" && file_exists("$core_overrd_directory/$core_file")) $core[] = array("filename" => $core_file, "content" => file_get_contents("$core_overrd_directory/$core_file"), "filepath" => "$core_overrd_directory/$core_file"); else $core[] = array("filename" => $core_file, "content" => file_get_contents("$core_files_directory/$core_file"), "filepath" => "$core_files_directory/$core_file"); } - // Check if the version of the core files includes an avr-libc directory and scan - if(file_exists("$core_files_directory/avr-libc")){ - if(false === ($scanned_avr_files = @scandir("$core_files_directory/avr-libc"))) - return array( "success"=>false, "step"=>5, "message"=>"Failed to read core files." ); - foreach($scanned_avr_files as $avr_file) - if(!is_dir("$core_files_directory/avr-libc/$avr_file")){ - if (!empty($core_overrd_directory) && $core_overrd_directory !="" && file_exists("$core_overrd_directory/avr-libc/$avr_file")) + // Check if the version of the core files includes an avr-libc directory and scan + if (file_exists("$core_files_directory/avr-libc")) + { + if (false === ($scanned_avr_files = @scandir("$core_files_directory/avr-libc"))) + return array("success" => false, "step" => 5, "message" => "Failed to read core files."); + foreach ($scanned_avr_files as $avr_file) + if (!is_dir("$core_files_directory/avr-libc/$avr_file")) + { + if (!empty($core_overrd_directory) && $core_overrd_directory != "" && file_exists("$core_overrd_directory/avr-libc/$avr_file")) $core[] = array("filename" => "avr-libc/$avr_file", "content" => file_get_contents("$core_overrd_directory/avr-libc/$avr_file"), "filepath" => "$core_overrd_directory/avr-libc/$avr_file"); else $core[] = array("filename" => "avr-libc/$avr_file", "content" => file_get_contents("$core_files_directory/avr-libc/$avr_file"), "filepath" => "$core_files_directory/avr-libc/$avr_file"); } - } + } - $tmp = $this->extractFiles($core, $temp_directory, $tmp_compiler, $files["core"], "core"); - if($tmp["success"] === false) - return array( "success"=>false, "step"=>5, "message"=>$tmp["message"] ); + $tmp = $this->extractFiles($core, $temp_directory, $tmp_compiler, $files["core"], "core"); + if ($tmp["success"] === false) + return array("success" => false, "step" => 5, "message" => $tmp["message"]); - return array('success' => true); - } + return array('success' => true); + } - private function handleCompile($compile_directory, &$files_array, $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching = false, $name_params = null){ + private function handleCompile($compile_directory, &$files_array, $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching = false, $name_params = null) + { - //Add any include directories needed - if (pathinfo($compile_directory, PATHINFO_BASENAME) !== "files") - $include_directories .= " -I$compile_directory "; + //Add any include directories needed + if (pathinfo($compile_directory, PATHINFO_BASENAME) !== "files") + $include_directories .= " -I$compile_directory "; - if(file_exists("$compile_directory/utility")) - $include_directories .= " -I$compile_directory/utility "; + if (file_exists("$compile_directory/utility")) + $include_directories .= " -I$compile_directory/utility "; - if (file_exists("$compile_directory/avr-libc")) - $include_directories .= " -I$compile_directory/avr-libc "; + if (file_exists("$compile_directory/avr-libc")) + $include_directories .= " -I$compile_directory/avr-libc "; - //Call doCompile, which will do the actual compilation. - $compile_res = $this->doCompile($compiler_config, $files_array, $compile_directory, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching, $name_params); + //Call doCompile, which will do the actual compilation. + $compile_res = $this->doCompile($compiler_config, $files_array, $compile_directory, $CC, $CFLAGS, $CPP, $CPPFLAGS, $AS, $ASFLAGS, $CLANG, $CLANG_FLAGS, $core_includes, $target_arch, $clang_target_arch, $include_directories, $format, $caching, $name_params); - if($compile_res['success']) - return array("success" => true); + if ($compile_res['success']) + return array("success" => true); - return $compile_res; - } + return $compile_res; + } - private function doAutocomplete($ARDUINO_CORES_DIR, $compiler_config, $compile_directory, $CC, $CFLAGS, $CPP, $CPPFLAGS, $core_includes, $target_arch, $include_directories, $autocompletionDir, $PYTHON, $AUTOCOMPLETER){ + private function doAutocomplete($ARDUINO_CORES_DIR, $compiler_config, $compile_directory, $CC, $CFLAGS, $CPP, $CPPFLAGS, $core_includes, $target_arch, $include_directories, $autocompletionDir, $PYTHON, $AUTOCOMPLETER) + { - $file = $compile_directory . "/" . $compiler_config["autocmpfile"]; + $file = $compile_directory."/".$compiler_config["autocmpfile"]; - $filename = pathinfo($file, PATHINFO_DIRNAME) . "/" . pathinfo($file, PATHINFO_FILENAME); + $filename = pathinfo($file, PATHINFO_DIRNAME)."/".pathinfo($file, PATHINFO_FILENAME); $ext = pathinfo($file, PATHINFO_EXTENSION); if (!in_array($ext, array("ino", "c", "cpp", "h", "hpp"))) return array("success" => false, "message" => "Sorry, autocompletion is only supported for .ino, .c, .cpp or .h files."); - if ($ext == "ino"){ + if ($ext == "ino") + { $ext = "cpp"; } $compiler_config["autocmpfile"] = "$filename.$ext"; @@ -1042,7 +1134,7 @@ private function doAutocomplete($ARDUINO_CORES_DIR, $compiler_config, $compile_d // Set the PYTHONPATH environment variable here, instead of setting a global variable in // every machine the compiler runs on. $SET_PYTHONPATH = "export PYTHONPATH=\"$ARDUINO_CORES_DIR/clang/v3_5/bindings/python:\$PYTHONPATH\""; - $result = exec("$SET_PYTHONPATH && $PYTHON $AUTOCOMPLETER " . $compiler_config["autocmpmaxresults"] . " $compile_directory/autocc.json", $output, $retval); + $result = exec("$SET_PYTHONPATH && $PYTHON $AUTOCOMPLETER ".$compiler_config["autocmpmaxresults"]." $compile_directory/autocc.json", $output, $retval); $exec_time = microtime(true) - $time; @@ -1056,11 +1148,13 @@ private function doAutocomplete($ARDUINO_CORES_DIR, $compiler_config, $compile_d return array("success" => true, "retval" => $retval, "message" => "Autocompletion was successful!", "autocomplete" => $command_output, "autocc_exec_time" => $exec_time); } - private function handleAutocompletion($ARDUINO_CORES_DIR, $compile_directory, $include_directories, $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $core_includes, $target_arch, $tmpDir, $autoccDir, $PYTHON, $AUTOCOMPLETER){ + private function handleAutocompletion($ARDUINO_CORES_DIR, $compile_directory, $include_directories, $compiler_config, $CC, $CFLAGS, $CPP, $CPPFLAGS, $core_includes, $target_arch, $tmpDir, $autoccDir, $PYTHON, $AUTOCOMPLETER) + { $make_dir_success = @mkdir("$tmpDir/$autoccDir", 0777, true); - if (!$make_dir_success && !is_dir("$tmpDir/$autoccDir")) { - usleep(rand( 5000 , 10000 )); + if (!$make_dir_success && !is_dir("$tmpDir/$autoccDir")) + { + usleep(rand(5000, 10000)); $make_dir_success = @mkdir("$tmpDir/$autoccDir", 0777, true); } if (!$make_dir_success && !is_dir("$tmpDir/$autoccDir")) @@ -1073,193 +1167,227 @@ private function handleAutocompletion($ARDUINO_CORES_DIR, $compile_directory, $i return $compile_res; } - private function getClangErrorFileList ($clang_output) { - /** - * Clang's output processing - */ - // Get all the 'filename.extension:line' elements. Include only those followed by an 'error' statement. - $tag_free_content = strip_tags($clang_output); // Remove color tags (as many as possible). - - $clang_matches = preg_split('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $tag_free_content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); - - $elements = array(); - foreach ($clang_matches as $key => $val ) { - if (preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $val) - && array_key_exists($key + 1, $clang_matches) - && (strpos($clang_matches[$key +1 ],"error:") !== false - || strpos($clang_matches[$key +1 ],"note:") !== false - || strpos($clang_matches[$key +1 ],"in asm") !== false - || strpos($clang_matches[$key],"in asm") !== false)) { - if (strpos($val, "In file included from ") !== false) - $val = str_replace("In file included from ", "", $val); - $val = str_replace("In file included from ", "", $val); - $elements[] = $val; - } - } - - // Split the elements from above and get an associative array structure of [filename => lines] - $clang_elements = array(); - foreach ($elements as $element) { - - // The first part is filename.extension, the second represents the line, - // and the third one is the column number (not used for now). - $split = explode(':', $element); - - if (!array_key_exists($split[0], $clang_elements)) { - $clang_elements[$split[0]] = array(); - $clang_elements[$split[0]][] = $split[1]; - continue; - } - $clang_elements[$split[0]][] = $split[1]; - } - return $clang_elements; - } - - private function getGccErrorFileList ($avr_output) { - /** - * Avr gcc's output processing - */ - // Get all 'filename.extension:line' elements. - // Note that avr-gcc output only includes filenames and lines in error reporting, not collumns. - preg_match_all('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $avr_output, $gcc_matches, PREG_PATTERN_ORDER); - - $gcc_elements = array(); - foreach ($gcc_matches[0] as $element) { - - // The first part is filename.extension, the second represents the line. - $split = explode(':', $element); - if (!array_key_exists($split[0], $gcc_elements)) { - $gcc_elements[$split[0]] = array(); - $gcc_elements[$split[0]][] = $split[1]; - continue; - } - $gcc_elements[$split[0]][] = $split[1]; - } - return $gcc_elements; - } - - private function cleanUpClangOutput ($clang_output, $compiler_config, $option) { - - $content_line_array = explode("\n", $clang_output); - - $header = ""; - $body = ""; - $final = ""; - $header_found = false; - $libFound = false; - $coreFound = false; - $asmFound = false; - - foreach ($content_line_array as $key => $line) { - - if ((strpos($line, "In file included from") !== false - && preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $line)) - || (preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $line) - && strpos($line, "error:") !== false)) { - - if ($header_found === false) { - if (($option == "non_asm" && preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) - || strpos($header, $compiler_config["arduino_cores_dir"]) !== false - || (array_key_exists("external_core_files", $compiler_config) - && strpos($header, $compiler_config["external_core_files"]) !== false)) - || ($option == "asm" - && (strpos($header, "in asm") !== false - || strpos($body, "in asm") !== false))) { - - if (preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) && $libFound === false && $option != "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports library issue."); - $libFound = true; - } - if ((strpos($header, $compiler_config["arduino_cores_dir"]) !== false - || (array_key_exists("external_core_files", $compiler_config) - && strpos($header, $compiler_config["external_core_files"]) !== false)) - && $coreFound === false && $option != "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports core issue."); - $coreFound = true; - } - if ((strpos($header, "in asm") !== false || strpos($body, "in asm") !== false) && $asmFound === false && $option == "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports assembly issue."); - $asmFound = true; - } - $header = ""; - $body = ""; - } - - if ($header != "") { - if (strpos($header, "") == 0) - $header = substr_replace($header, '', 0, 11); - if (array_key_exists($key + 1, $content_line_array) - && strpos($content_line_array[$key + 1], "") == 0) - $body = $body . ""; - $final .= $header ."\n"; - $final .= $body . "\n"; - $header = ""; - $body = ""; - } - } - - $header .= $line . "\n"; - $header_found = true; - continue; - } - - if (!array_key_exists($key + 1, $content_line_array)) { - if ((!preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) - && strpos($header, $compiler_config["arduino_cores_dir"]) === false - && (array_key_exists("external_core_files", $compiler_config) - && strpos($header, $compiler_config["external_core_files"]) === false) - && $option == "non_asm") - || ($option == "asm" - && strpos($header, "in asm") === false - && strpos($body, "in asm") === false)) { - if ($header != "") { - if (strpos($header, "") == 0) - $header = substr_replace($header, '', 0, 11); - $final .= $header ."\n"; - $final .= $body . "\n"; - } - }else { - if (preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) && $libFound === false && $option != "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports library issue."); - } - if ((strpos($header, $compiler_config["arduino_cores_dir"]) !== false - || (array_key_exists("external_core_files", $compiler_config) - && strpos($header, $compiler_config["external_core_files"]) !== false)) - && $coreFound === false && $option != "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports core issue."); - } - if ((strpos($header, "in asm") !== false || strpos($body, "in asm") !== false) && $asmFound === false && $option == "asm") { - $this->compiler_logger->addInfo($this->logger_id . " - Clang reports assembly issue."); - } - } - } - - $header_found = false; - $body .= $line . "\n"; - - } - - return $final; - } - - private function pathRemover ($output, $compiler_config) { - - // Remove any instance of "compiler.RANDOM/files/" folder name from the text - $modified = str_replace($compiler_config["compiler_dir"] . "/files/", '', $output); - - // Remove any remaining instance of "compiler.RANDOM/" folder name from the text. - $modified = str_replace($compiler_config["compiler_dir"] . "/", '', $modified); - - // Remove any instance of codebender arduino core files folder name from the text - $modified = str_replace($compiler_config["arduino_cores_dir"] . "/v105/", '', $modified); - - // Remove any instance of codebender external core file folder name from the text - if (isset($compiler_config["external_core_files"]) && $compiler_config["external_core_files"] != "") { - $modified = str_replace($compiler_config["external_core_files"], '', $modified); - $modified = str_replace("/override_cores/", '', $modified); - } - - return $modified; - } + private function getClangErrorFileList($clang_output) + { + /** + * Clang's output processing + */ + // Get all the 'filename.extension:line' elements. Include only those followed by an 'error' statement. + $tag_free_content = strip_tags($clang_output); // Remove color tags (as many as possible). + + $clang_matches = preg_split('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $tag_free_content, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + + $elements = array(); + foreach ($clang_matches as $key => $val) + { + if (preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $val) + && array_key_exists($key + 1, $clang_matches) + && (strpos($clang_matches[$key + 1], "error:") !== false + || strpos($clang_matches[$key + 1], "note:") !== false + || strpos($clang_matches[$key + 1], "in asm") !== false + || strpos($clang_matches[$key], "in asm") !== false) + ) + { + if (strpos($val, "In file included from ") !== false) + $val = str_replace("In file included from ", "", $val); + $val = str_replace("In file included from ", "", $val); + $elements[] = $val; + } + } + + // Split the elements from above and get an associative array structure of [filename => lines] + $clang_elements = array(); + foreach ($elements as $element) + { + + // The first part is filename.extension, the second represents the line, + // and the third one is the column number (not used for now). + $split = explode(':', $element); + + if (!array_key_exists($split[0], $clang_elements)) + { + $clang_elements[$split[0]] = array(); + $clang_elements[$split[0]][] = $split[1]; + continue; + } + $clang_elements[$split[0]][] = $split[1]; + } + return $clang_elements; + } + + private function getGccErrorFileList($avr_output) + { + /** + * Avr gcc's output processing + */ + // Get all 'filename.extension:line' elements. + // Note that avr-gcc output only includes filenames and lines in error reporting, not collumns. + preg_match_all('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $avr_output, $gcc_matches, PREG_PATTERN_ORDER); + + $gcc_elements = array(); + foreach ($gcc_matches[0] as $element) + { + + // The first part is filename.extension, the second represents the line. + $split = explode(':', $element); + if (!array_key_exists($split[0], $gcc_elements)) + { + $gcc_elements[$split[0]] = array(); + $gcc_elements[$split[0]][] = $split[1]; + continue; + } + $gcc_elements[$split[0]][] = $split[1]; + } + return $gcc_elements; + } + + private function cleanUpClangOutput($clang_output, $compiler_config, $option) + { + + $content_line_array = explode("\n", $clang_output); + + $header = ""; + $body = ""; + $final = ""; + $header_found = false; + $libFound = false; + $coreFound = false; + $asmFound = false; + + foreach ($content_line_array as $key => $line) + { + + if ((strpos($line, "In file included from") !== false + && preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $line)) + || (preg_match('/([\w*\s*(!@#$%^&*()-+;\'{}\[\])*]+\.\w+:\d+:[\d+:]?)/', $line) + && strpos($line, "error:") !== false) + ) + { + + if ($header_found === false) + { + if (($option == "non_asm" && preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) + || strpos($header, $compiler_config["arduino_cores_dir"]) !== false + || (array_key_exists("external_core_files", $compiler_config) + && strpos($header, $compiler_config["external_core_files"]) !== false)) + || ($option == "asm" + && (strpos($header, "in asm") !== false + || strpos($body, "in asm") !== false)) + ) + { + + if (preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) && $libFound === false && $option != "asm") + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports library issue."); + $libFound = true; + } + if ((strpos($header, $compiler_config["arduino_cores_dir"]) !== false + || (array_key_exists("external_core_files", $compiler_config) + && strpos($header, $compiler_config["external_core_files"]) !== false)) + && $coreFound === false && $option != "asm" + ) + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports core issue."); + $coreFound = true; + } + if ((strpos($header, "in asm") !== false || strpos($body, "in asm") !== false) && $asmFound === false && $option == "asm") + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports assembly issue."); + $asmFound = true; + } + $header = ""; + $body = ""; + } + + if ($header != "") + { + if (strpos($header, "") == 0) + $header = substr_replace($header, '', 0, 11); + if (array_key_exists($key + 1, $content_line_array) + && strpos($content_line_array[$key + 1], "") == 0 + ) + $body = $body.""; + $final .= $header."\n"; + $final .= $body."\n"; + $header = ""; + $body = ""; + } + } + + $header .= $line."\n"; + $header_found = true; + continue; + } + + if (!array_key_exists($key + 1, $content_line_array)) + { + if ((!preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) + && strpos($header, $compiler_config["arduino_cores_dir"]) === false + && (array_key_exists("external_core_files", $compiler_config) + && strpos($header, $compiler_config["external_core_files"]) === false) + && $option == "non_asm") + || ($option == "asm" + && strpos($header, "in asm") === false + && strpos($body, "in asm") === false) + ) + { + if ($header != "") + { + if (strpos($header, "") == 0) + $header = substr_replace($header, '', 0, 11); + $final .= $header."\n"; + $final .= $body."\n"; + } + } + else + { + if (preg_match('/(\/compiler\.\w+\/libraries\/)/', $header) && $libFound === false && $option != "asm") + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports library issue."); + } + if ((strpos($header, $compiler_config["arduino_cores_dir"]) !== false + || (array_key_exists("external_core_files", $compiler_config) + && strpos($header, $compiler_config["external_core_files"]) !== false)) + && $coreFound === false && $option != "asm" + ) + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports core issue."); + } + if ((strpos($header, "in asm") !== false || strpos($body, "in asm") !== false) && $asmFound === false && $option == "asm") + { + $this->compiler_logger->addInfo($this->logger_id." - Clang reports assembly issue."); + } + } + } + + $header_found = false; + $body .= $line."\n"; + + } + + return $final; + } + + private function pathRemover($output, $compiler_config) + { + + // Remove any instance of "compiler.RANDOM/files/" folder name from the text + $modified = str_replace($compiler_config["compiler_dir"]."/files/", '', $output); + + // Remove any remaining instance of "compiler.RANDOM/" folder name from the text. + $modified = str_replace($compiler_config["compiler_dir"]."/", '', $modified); + + // Remove any instance of codebender arduino core files folder name from the text + $modified = str_replace($compiler_config["arduino_cores_dir"]."/v105/", '', $modified); + + // Remove any instance of codebender external core file folder name from the text + if (isset($compiler_config["external_core_files"]) && $compiler_config["external_core_files"] != "") + { + $modified = str_replace($compiler_config["external_core_files"], '', $modified); + $modified = str_replace("/override_cores/", '', $modified); + } + + return $modified; + } } From b52fc76f2f6b631912afa731e95087fb394b8fea Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:15:20 +0200 Subject: [PATCH 24/25] Avoiding using functions in for loop --- .../CompilerBundle/Handler/PreprocessingHandler.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php index 9fb1680..f67dc93 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php @@ -72,7 +72,8 @@ function empty_braces($code) $start = 0; $return_code = ""; // Use the code as an array of characters - for ($i = 0; $i < strlen($code); $i++) + $length = strlen($code); + for ($i = 0; $i < $length; $i++) { if ($code[$i] == "{") @@ -95,7 +96,7 @@ function empty_braces($code) } } - $return_code .= substr($code, $start, strlen($code) - $start); + $return_code .= substr($code, $start, $length - $start); return $return_code; } @@ -238,7 +239,9 @@ function build_code($code, $function_prototypes, $position) $next_pos = 0; else $next_pos = $position + 1; - for ($i = $next_pos; $i < strlen($code); $i++) + + $length = strlen($code); + for ($i = $next_pos; $i < $length; $i++) { $return_code .= $code[$i]; } From c1b415403a3e82217c7edfedaafb17c6ee6c9cee Mon Sep 17 00:00:00 2001 From: Vasileios Georgitzikis Date: Fri, 9 Jan 2015 04:38:59 +0200 Subject: [PATCH 25/25] Fixed all PSR-1 Method Naming warnings (hopefuly) --- .../Handler/CompilerHandler.php | 24 ++++++------- .../Handler/PostprocessingHandler.php | 2 +- .../Handler/PreprocessingHandler.php | 36 +++++++++---------- .../CompilerBundle/Handler/UtilityHandler.php | 4 +-- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php index c6615ee..3498fc3 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/CompilerHandler.php @@ -47,7 +47,7 @@ function main($request, $compiler_config) { error_reporting(E_ALL & ~E_STRICT); - $this->set_values($compiler_config, + $this->setValues($compiler_config, $BINUTILS, $CLANG, $CFLAGS, $CPPFLAGS, $ASFLAGS, $ARFLAGS, $LDFLAGS, $LDFLAGS_TAIL, $CLANG_FLAGS, $OBJCOPY_FLAGS, $SIZE_FLAGS, $OUTPUT, $ARDUINO_CORES_DIR, $EXTERNAL_CORES_DIR, $TEMP_DIR, $ARCHIVE_DIR, $AUTOCC_DIR, $PYTHON, $AUTOCOMPLETER); @@ -59,9 +59,9 @@ function main($request, $compiler_config) if ($tmpVar["success"] === false) return $tmpVar; - $this->set_variables($request, $format, $libraries, $version, $mcu, $f_cpu, $core, $variant, $vid, $pid, $compiler_config); + $this->setVariables($request, $format, $libraries, $version, $mcu, $f_cpu, $core, $variant, $vid, $pid, $compiler_config); - $this->set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, $CC, $CPP, $AS, $AR, $LD, $OBJCOPY, $SIZE); + $this->setAVR($version, $ARDUINO_CORES_DIR, $BINUTILS, $CC, $CPP, $AS, $AR, $LD, $OBJCOPY, $SIZE); $target_arch = "-mmcu=$mcu -DARDUINO=$version -DF_CPU=$f_cpu -DUSB_VID=$vid -DUSB_PID=$pid"; $clang_target_arch = "-D".MCUHandler::$MCU[$mcu]." -DARDUINO=$version -DF_CPU=$f_cpu"; @@ -438,7 +438,7 @@ function main($request, $compiler_config) private function requestValid(&$request) { - $request = $this->preproc->validate_input($request); + $request = $this->preproc->validateInput($request); if (!$request) return array( "success" => false, @@ -499,7 +499,7 @@ private function extractFiles($request, $temp_dir, &$dir, &$files, $suffix, $lib "step" => 1, "message" => "Failed to create temporary directory."); - $response = $this->utility->extract_files("$dir/$suffix", $request, $lib_extraction); + $response = $this->utility->extractFiles("$dir/$suffix", $request, $lib_extraction); if ($response["success"] === false) return $response; @@ -513,7 +513,7 @@ private function preprocessIno(&$files) foreach ($files["ino"] as $file) { $code = file_get_contents("$file.ino"); - $new_code = $this->preproc->ino_to_cpp($code, "$file.ino"); + $new_code = $this->preproc->convertInoToCpp($code, "$file.ino"); $ret = file_put_contents("$file.cpp", $new_code); if ($code === false || !$new_code || !$ret) @@ -675,7 +675,7 @@ private function doCompile($compiler_config, &$files, $dir, $CC, $CFLAGS, $CPP, $file = escapeshellarg($file); $object_file = escapeshellarg($object_file); - //replace exec() calls with $this->utility->debug_exec() for debugging + //replace exec() calls with $this->utility->execWithDebugging() for debugging if ($ext == "c") { exec("$CC $CFLAGS $core_includes $target_arch $include_directories -c -o $object_file.o $file.$ext 2>&1", $output, $ret_compile); @@ -710,7 +710,7 @@ private function doCompile($compiler_config, &$files, $dir, $CC, $CFLAGS, $CPP, file_put_contents($compiler_config['logFileName'], "$CLANG $CLANG_FLAGS $core_includes $clang_target_arch $include_directories -c -o $object_file.o $file.$ext\n", FILE_APPEND); } - $output = $this->postproc->ansi_to_html(implode("\n", $output)); + $output = $this->postproc->convertANSItoHTML(implode("\n", $output)); $resp = array( "success" => false, @@ -868,7 +868,7 @@ private function convertOutput($dir, $format, $SIZE, $SIZE_FLAGS, $OBJCOPY, $OBJ } - private function set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, &$CC, &$CPP, &$AS, &$AR, &$LD, &$OBJCOPY, &$SIZE) + private function setAVR($version, $ARDUINO_CORES_DIR, $BINUTILS, &$CC, &$CPP, &$AS, &$AR, &$LD, &$OBJCOPY, &$SIZE) { // External binaries. $binaries = array("cc" => "-gcc", "cpp" => "-g++", "as" => "-gcc", "ar" => "-ar", "ld" => "-gcc", "objcopy" => "-objcopy", "size" => "-size"); @@ -892,7 +892,7 @@ private function set_avr($version, $ARDUINO_CORES_DIR, $BINUTILS, &$CC, &$CPP, & } - private function set_values($compiler_config, + private function setValues($compiler_config, &$BINUTILS, &$CLANG, &$CFLAGS, &$CPPFLAGS, &$ASFLAGS, &$ARFLAGS, &$LDFLAGS, &$LDFLAGS_TAIL, &$CLANG_FLAGS, &$OBJCOPY_FLAGS, &$SIZE_FLAGS, &$OUTPUT, &$ARDUINO_CORES_DIR, &$EXTERNAL_CORES_DIR, &$TEMP_DIR, &$ARCHIVE_DIR, &$AUTOCC_DIR, &$PYTHON, &$AUTOCOMPLETER) @@ -902,7 +902,7 @@ private function set_values($compiler_config, //ones included in the binutils parameter $BINUTILS = $compiler_config["binutils"]; //Clang is used to return the output in case of an error, it's version independent, so its - //value is set by set_values function. + //value is set by setValues function. $LDLIBRARYPATH = "LD_LIBRARY_PATH=".$compiler_config["arduino_cores_dir"]."/clang/v3_5/lib:\$LD_LIBRARY_PATH"; $CLANG = $LDLIBRARYPATH." ".$compiler_config["clang"]; @@ -936,7 +936,7 @@ private function set_values($compiler_config, $EXTERNAL_CORES_DIR = $compiler_config["external_core_files"]; } - private function set_variables($request, &$format, &$libraries, &$version, &$mcu, &$f_cpu, &$core, &$variant, &$vid, &$pid, &$compiler_config) + private function setVariables($request, &$format, &$libraries, &$version, &$mcu, &$f_cpu, &$core, &$variant, &$vid, &$pid, &$compiler_config) { // Extract the request options for easier access. $format = $request["format"]; diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php index 14f3a8b..afbe798 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PostprocessingHandler.php @@ -27,7 +27,7 @@ class PostprocessingHandler * [, and ends with m. The color code is placed in between. Multiple * color codes can be included, separated by semicolon. */ - function ansi_to_html($text) + function convertANSItoHTML($text) { $FORMAT = array( 0 => NULL, // reset modes to default diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php index f67dc93..1dac789 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/PreprocessingHandler.php @@ -47,7 +47,7 @@ class PreprocessingHandler * \return string A copy of the code with no comments, single- or double- quoted strings * or pre-processor directives */ - function remove_comments_directives_quotes($code) + function removeCommentsDirectivesQuotes($code) { // Use a copy of the code and strip comments, pre-processor directives, single- and double-quoted strings @@ -61,10 +61,10 @@ function remove_comments_directives_quotes($code) } /** - * \param string $code The code returned from remove_comments_directives_quotes function + * \param string $code The code returned from removeCommentsDirectivesQuotes function * \return string The input code having all top level braces collapsed */ - function empty_braces($code) + function emptyBraces($code) { // For every line of the code remove all the contents of top level braces @@ -105,7 +105,7 @@ function empty_braces($code) * \param string $code The code returned from empty_braces function * \return array An array including any prototypes found in the original code */ - function find_existing_prototypes(&$code) + function findExistingPrototypes(&$code) { // In this case, the original code is used. Existing prototypes are matched, stored, and then removed from //the code, so that in the next step the compiler knows which prototypes should really be generated @@ -124,10 +124,10 @@ function find_existing_prototypes(&$code) /** * \param string $code The sketch code provided to the compiler - * \param array $existing_prototypes Array of prototypes returned by find_existing_prototypes function + * \param array $existing_prototypes Array of prototypes returned by findExistingPrototypes function * \return string The string including the function prototypes for the code */ - function generate_prototypes($code, $existing_prototypes) + function generatePrototypes($code, $existing_prototypes) { // This function uses a regular expression to match all function declarations, generate the // respective prototype and store all the prototypes in a string @@ -171,7 +171,7 @@ function generate_prototypes($code, $existing_prototypes) * \param string $code The sketch code * \return int The position where function prototypes should be placed */ - function insertion_position($code) + function insertionPosition($code) { // Use the following regular expression to match whitespaces, single- and multiline comments and preprocessor directives $regex = "/(\s+|(\/\*[^*]*(?:\*(?!\/)[^*]*)*\*\/)|(\/\/.*?$)|(\#(?:\\\\\\n|.)*))/m"; @@ -205,15 +205,15 @@ function insertion_position($code) /** * \param string $code The initial sketch code - * \param $function_prototypes The function prototypes returned by generate_prototypes function + * \param $function_prototypes The function prototypes returned by generatePrototypes function * \param int $position The position to place the prototypes returned by insertion_position function * \return string Valid c++ code */ - function build_code($code, $function_prototypes, $position) + function buildCode($code, $function_prototypes, $position) { // To build the final code, the compiler starts adding every character of the original string, until the position - // found by insertion_position is reached. Then, the function prototypes are added, as well as a preprocessor + // found by insertionPosition is reached. Then, the function prototypes are added, as well as a preprocessor //directive to fix the line numbering. $line = 1; $return_code = ""; @@ -249,19 +249,19 @@ function build_code($code, $function_prototypes, $position) return $return_code; } - function ino_to_cpp($code, $filename = NULL) + function convertInoToCpp($code, $filename = NULL) { // Remove comments, preprocessor directives, single- and double- quotes - $no_comms_code = $this->remove_comments_directives_quotes($code); + $no_comms_code = $this->removeCommentsDirectivesQuotes($code); // Remove any code between all top level braces - $empty_braces_code = $this->empty_braces($no_comms_code); + $empty_braces_code = $this->emptyBraces($no_comms_code); // Find already existing prototypes - $existing_prototypes = $this->find_existing_prototypes($empty_braces_code); + $existing_prototypes = $this->findExistingPrototypes($empty_braces_code); // Generate prototypes that do not already exist - $function_prototypes = $this->generate_prototypes($empty_braces_code, $existing_prototypes); + $function_prototypes = $this->generatePrototypes($empty_braces_code, $existing_prototypes); // Find the right place to insert the function prototypes (after any preprocessor directives, comments, // before any function declaration) - $insertion_position = $this->insertion_position($code); + $insertion_position = $this->insertionPosition($code); $new_code = ""; // Add a preprocessor directive for line numbering. @@ -270,7 +270,7 @@ function ino_to_cpp($code, $filename = NULL) else $new_code .= "#line 1\n"; // Build the new code for the cpp file that will eventually be compiled - $new_code .= $this->build_code($code, $function_prototypes, $insertion_position); + $new_code .= $this->buildCode($code, $function_prototypes, $insertion_position); return $new_code; @@ -283,7 +283,7 @@ function ino_to_cpp($code, $filename = NULL) * \param string $request The JSON-encoded compile request. * \return The value encoded in JSON in appropriate PHP type or NULL. */ - function validate_input($request) + function validateInput($request) { $request = json_decode($request, true); diff --git a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php index 2ad398f..33ba5ed 100644 --- a/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php +++ b/Symfony/src/Codebender/CompilerBundle/Handler/UtilityHandler.php @@ -30,7 +30,7 @@ class UtilityHandler * In case of error, the return value is an array that has a key success * and contains the response to be sent back to the user. */ - function extract_files($directory, $request_files, $lib_extraction) + function extractFiles($directory, $request_files, $lib_extraction) { // File extensions used by Arduino projects. They are put in a string, // separated by "|" to be used in regular expressions. They are also @@ -135,7 +135,7 @@ function get_files_by_extension($directory, $extensions) * * \warning It is not possible to redirect the standard error output to a file. */ - function debug_exec($command, /** @noinspection PhpUnusedParameterInspection */ + function execWithDebugging($command, /** @noinspection PhpUnusedParameterInspection */ &$output, /** @noinspection PhpUnusedParameterInspection */ &$retval) {