<commit_before>#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include "boost/tokenizer.hpp"
#include "boost/algorithm/string.hpp"

using namespace std;

//Global used to keep track if the previous command executed successfully
//Used for the || and && connectors to see if they should execute
static bool *pass;

int main (int argc, char const *argv[])
{
    //Host name can only be 128 characters. If it's more than that, you need to reevaluate your naming choices
    char host[128];
    int h = gethostname(host, sizeof(host));
    if(h != 0) {
        perror("Error retrieving hostname.");
    }
    char * login = getlogin();
    if(!login) {
        perror("Error getting login name.");
    }

    //Input the user puts in
	string input;

    //mmap is used for preserving the variable (pass in this case) through the child processes
    pass = (bool *)mmap(NULL, sizeof *pass, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);

    //Setting the initial value to false since no command has run
    *pass = false;

    while(true)
	{
        //Terminal prompt display
        if(h == 0 && login)
            cout << login << "@" << host << " $ ";
        else
            cout << "$ ";
        cout.flush(); //Have to flush since no std::endl;

        //Grab user input for bash prompt
        getline(cin,input);
        boost::trim(input); //Remove trailing and leading space

        //Setting up a boost tokenizer.
        typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
        string separator1("");
        string separator2(" ");
        string separator3("\"\'"); //Used to count quoted text as a single token rather than delimit them separately
        boost::escaped_list_separator<char> sep(separator1,separator2,separator3);
        tokenizer tok(input, sep);

        //ls is a temp list for storing the tokenized value
        list<string> ls;
        //vector for storing a command and its arguments
        vector<char*> args;
        //vector for storing all of the commands that have been chained together
        vector<vector<char*> > commands;
        //vector for storing all of the connectors "AND" and "OR"
        vector<string> connectors;

        /*
        Check for # and immediatly end parsing since anything after it is a comment.
        Check for ; or || or && to know if a new command needs to be created.
        Put all of these new commands in the commands vector.
        */
        for(tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) {
            if( !it->empty() ) {
                if(*it == "#" || strncmp(&it->at(0),"#",1) == 0)
                    break;
                else if(strncmp(&it->back(), "#", 1) == 0) {
                    string temp = it->substr(0, it->size()-1);
                    if(temp.size() > 1) {
                        connectors.push_back(" ");
                        ls.push_back(temp);
                        args.push_back(const_cast<char*>(ls.back().c_str()));
                    }
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                    break;
                }
                else if (*it == "||" ) {
                    if(args.empty()) continue;
                    connectors.push_back("OR");
                    //Adds the connector to the vector and then terminates the current command
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                else if (*it == "&&") {
                    if(args.empty()) continue;
                    connectors.push_back("AND");
                    //Adds the connector to the vector and then terminates the current command
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                //Checks to see if the last character (or only character) on the token is a semicolon
                else if(strncmp(&it->back(), ";", 1) == 0) {
                    if(args.empty()) continue;
                    string temp = it->substr(0, it->size()-1);
                    if(temp.size() > 1) {
                        //We only want to count this is a command if there is actually some command being executed
                        //So we check if its size is larger then 1 to check if there's something else other than
                        //  just the semicolon itself.
                        connectors.push_back(" ");
                        ls.push_back(temp);
                        args.push_back(const_cast<char*>(ls.back().c_str()));
                    }
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                else {
                    //If the current token is not a comment, 'and', 'or', or a semicolon, add the token to the current command
                    ls.push_back(*it);
                    args.push_back(const_cast<char*>(ls.back().c_str()));
                }
            }
        }
        if(!args.empty()) {
            connectors.push_back(" ");
            args.push_back(0);
            commands.push_back(args);
        }

        //Go through all of the commands
        for(unsigned x = 0; x < commands.size(); x++) {

            //Get the current command
            vector<char*> com = commands.at(x);
            if(com.empty())
                continue;

            //Using string compare here since they're char * entries
            if(strncmp(com[0], "exit", 4) == 0) {
                exit(0);
            }

            //Main process thread
            pid_t i = fork();

            if(i < 0) { //Error
                perror("Failed to create child process");
                *pass = false;
                break;
            }
            else if(i == 0) { //Child process
                //Used for skipping the execution of commands in the event that they're conditional
                //based on the connector used by the user.
                if(x > 0 && connectors.size() > 1 && connectors.at(x-1) == "OR" && *pass)
                    exit(0);
                else if(x > 0 && connectors.size() > 1 && connectors.at(x-1) == "AND" && !*pass)
                    exit(0);
                else {
                    int result = execvp(com[0], &com[0]);
                    if(result < 0) {
                        *pass = false;
                        //This is just the standard format that bash outputs error notices
                        char result[100];
                        const char *error = "-rshell: ";
                        strcpy(result, error);
                        strcat(result, com[0]);
                        perror(result);
                        //Exiting with 1 since the command failed
                        exit(1);
                    }
                    else {
                        *pass = true;
                        exit(0);
                    }
                }
            }
            else { //Parent process
                int status;
				if(wait(&status) < 0) {
					perror("Error during child process");
                    *pass = false;
					exit(1);
				}
                else {
                    //Used to get the exit code of the child process
                    int estat = WEXITSTATUS(status);

                    if(estat == 0) {
                        *pass = true;
                    }
                    if(estat == 1) {
                        *pass = false;
                    }

                    //Check to see if the child terminated by a signal
                    else if (WIFSIGNALED(status)) {
                        printf("%ld terminated because it didn't catch signal number %d\n", (long)i, WTERMSIG(status));
                        *pass = false;
                    }
                }
            }
        }
	}
}
<commit_msg>Adding syscall for mmap<commit_after>#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include "errno.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <list>
#include <iterator>
#include "boost/tokenizer.hpp"
#include "boost/algorithm/string.hpp"

using namespace std;

//Global used to keep track if the previous command executed successfully
//Used for the || and && connectors to see if they should execute
static bool *pass;

int main (int argc, char const *argv[])
{
    //Host name can only be 128 characters. If it's more than that, you need to reevaluate your naming choices
    char host[128];
    int h = gethostname(host, sizeof(host));
    if(h != 0) {
        perror("Error retrieving hostname.");
    }
    char * login = getlogin();
    if(!login) {
        perror("Error getting login name.");
    }

    //Input the user puts in
	string input;

    //mmap is used for preserving the variable (pass in this case) through the child processes
    pass = (bool *)mmap(NULL, sizeof *pass, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
    if(pass == MAP_FAILED) {
        perror("Failed to save return state of process.");
    }

    //Setting the initial value to false since no command has run
    *pass = false;

    while(true)
	{
        //Terminal prompt display
        if(h == 0 && login)
            cout << login << "@" << host << " $ ";
        else
            cout << "$ ";
        cout.flush(); //Have to flush since no std::endl;

        //Grab user input for bash prompt
        getline(cin,input);
        boost::trim(input); //Remove trailing and leading space

        //Setting up a boost tokenizer.
        typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer;
        string separator1("");
        string separator2(" ");
        string separator3("\"\'"); //Used to count quoted text as a single token rather than delimit them separately
        boost::escaped_list_separator<char> sep(separator1,separator2,separator3);
        tokenizer tok(input, sep);

        //ls is a temp list for storing the tokenized value
        list<string> ls;
        //vector for storing a command and its arguments
        vector<char*> args;
        //vector for storing all of the commands that have been chained together
        vector<vector<char*> > commands;
        //vector for storing all of the connectors "AND" and "OR"
        vector<string> connectors;

        /*
        Check for # and immediatly end parsing since anything after it is a comment.
        Check for ; or || or && to know if a new command needs to be created.
        Put all of these new commands in the commands vector.
        */
        for(tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) {
            if( !it->empty() ) {
                if(*it == "#" || strncmp(&it->at(0),"#",1) == 0)
                    break;
                else if(strncmp(&it->back(), "#", 1) == 0) {
                    string temp = it->substr(0, it->size()-1);
                    if(temp.size() > 1) {
                        connectors.push_back(" ");
                        ls.push_back(temp);
                        args.push_back(const_cast<char*>(ls.back().c_str()));
                    }
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                    break;
                }
                else if (*it == "||" ) {
                    if(args.empty()) continue;
                    connectors.push_back("OR");
                    //Adds the connector to the vector and then terminates the current command
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                else if (*it == "&&") {
                    if(args.empty()) continue;
                    connectors.push_back("AND");
                    //Adds the connector to the vector and then terminates the current command
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                //Checks to see if the last character (or only character) on the token is a semicolon
                else if(strncmp(&it->back(), ";", 1) == 0) {
                    if(args.empty()) continue;
                    string temp = it->substr(0, it->size()-1);
                    if(temp.size() > 1) {
                        //We only want to count this is a command if there is actually some command being executed
                        //So we check if its size is larger then 1 to check if there's something else other than
                        //  just the semicolon itself.
                        connectors.push_back(" ");
                        ls.push_back(temp);
                        args.push_back(const_cast<char*>(ls.back().c_str()));
                    }
                    args.push_back(0);
                    commands.push_back(args);
                    args.clear();
                }
                else {
                    //If the current token is not a comment, 'and', 'or', or a semicolon, add the token to the current command
                    ls.push_back(*it);
                    args.push_back(const_cast<char*>(ls.back().c_str()));
                }
            }
        }
        if(!args.empty()) {
            connectors.push_back(" ");
            args.push_back(0);
            commands.push_back(args);
        }

        //Go through all of the commands
        for(unsigned x = 0; x < commands.size(); x++) {

            //Get the current command
            vector<char*> com = commands.at(x);
            if(com.empty())
                continue;

            //Using string compare here since they're char * entries
            if(strncmp(com[0], "exit", 4) == 0) {
                exit(0);
            }

            //Main process thread
            pid_t i = fork();

            if(i < 0) { //Error
                perror("Failed to create child process");
                *pass = false;
                break;
            }
            else if(i == 0) { //Child process
                //Used for skipping the execution of commands in the event that they're conditional
                //based on the connector used by the user.
                if(x > 0 && connectors.size() > 1 && connectors.at(x-1) == "OR" && *pass)
                    exit(0);
                else if(x > 0 && connectors.size() > 1 && connectors.at(x-1) == "AND" && !*pass)
                    exit(0);
                else {
                    int result = execvp(com[0], &com[0]);
                    if(result < 0) {
                        *pass = false;
                        //This is just the standard format that bash outputs error notices
                        char result[100];
                        const char *error = "-rshell: ";
                        strcpy(result, error);
                        strcat(result, com[0]);
                        perror(result);
                        //Exiting with 1 since the command failed
                        exit(1);
                    }
                    else {
                        *pass = true;
                        exit(0);
                    }
                }
            }
            else { //Parent process
                int status;
				if(wait(&status) < 0) {
					perror("Error during child process");
                    *pass = false;
					exit(1);
				}
                else {
                    //Used to get the exit code of the child process
                    int estat = WEXITSTATUS(status);

                    if(estat == 0) {
                        *pass = true;
                    }
                    if(estat == 1) {
                        *pass = false;
                    }

                    //Check to see if the child terminated by a signal
                    else if (WIFSIGNALED(status)) {
                        printf("%ld terminated because it didn't catch signal number %d\n", (long)i, WTERMSIG(status));
                        *pass = false;
                    }
                }
            }
        }
	}
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "CheckDeclarator.h"
#include "Semantic.h"
#include "AST.h"
#include "Control.h"
#include "TranslationUnit.h"
#include "Literals.h"
#include "CoreTypes.h"
#include "Symbols.h"

using namespace CPlusPlus;

CheckDeclarator::CheckDeclarator(Semantic *semantic)
    : SemanticCheck(semantic),
      _declarator(0),
      _scope(0),
      _name(0)
{ }

CheckDeclarator::~CheckDeclarator()
{ }

FullySpecifiedType CheckDeclarator::check(DeclaratorAST *declarator,
                                          const FullySpecifiedType &type,
                                          Scope *scope,
                                          const Name **name)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(type);
    Scope *previousScope = switchScope(scope);
    DeclaratorAST *previousDeclarator = switchDeclarator(declarator);
    const Name **previousName = switchName(name);
    accept(declarator);
    (void) switchName(previousName);
    (void) switchDeclarator(previousDeclarator);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

FullySpecifiedType CheckDeclarator::check(PtrOperatorListAST *ptrOperators,
                                          const FullySpecifiedType &type,
                                          Scope *scope)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(type);
    Scope *previousScope = switchScope(scope);
    accept(ptrOperators);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

FullySpecifiedType CheckDeclarator::check(ObjCMethodPrototypeAST *methodPrototype,
                                          Scope *scope)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(FullySpecifiedType());
    Scope *previousScope = switchScope(scope);
    accept(methodPrototype);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

DeclaratorAST *CheckDeclarator::switchDeclarator(DeclaratorAST *declarator)
{
    DeclaratorAST *previousDeclarator = _declarator;
    _declarator = declarator;
    return previousDeclarator;
}

FullySpecifiedType CheckDeclarator::switchFullySpecifiedType(const FullySpecifiedType &type)
{
    FullySpecifiedType previousType = _fullySpecifiedType;
    _fullySpecifiedType = type;
    return previousType;
}

Scope *CheckDeclarator::switchScope(Scope *scope)
{
    Scope *previousScope = _scope;
    _scope = scope;
    return previousScope;
}

const Name **CheckDeclarator::switchName(const Name **name)
{
    const Name **previousName = _name;
    _name = name;
    return previousName;
}

bool CheckDeclarator::visit(DeclaratorAST *ast)
{
    accept(ast->ptr_operator_list);
    accept(ast->postfix_declarator_list);
    accept(ast->core_declarator);

    if (ast->initializer) {
        FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);

        if (Function *funTy = _fullySpecifiedType->asFunctionType())
            funTy->setPureVirtual(true);
    }

    return false;
}

bool CheckDeclarator::visit(DeclaratorIdAST *ast)
{
    const Name *name = semantic()->check(ast->name, _scope);
    if (_name)
        *_name = name;
    return false;
}

bool CheckDeclarator::visit(NestedDeclaratorAST *ast)
{
    accept(ast->declarator);
    return false;
}

bool CheckDeclarator::visit(FunctionDeclaratorAST *ast)
{
    Function *fun = control()->newFunction(ast->firstToken());
    fun->setAmbiguous(ast->as_cpp_initializer != 0);
    ast->symbol = fun;
    fun->setReturnType(_fullySpecifiedType);

    if (_fullySpecifiedType.isVirtual())
        fun->setVirtual(true);

    if (ast->parameters) {
        DeclarationListAST *parameter_declarations = ast->parameters->parameter_declaration_list;
        for (DeclarationListAST *decl = parameter_declarations; decl; decl = decl->next) {
            semantic()->check(decl->value, fun->arguments());
        }

        if (ast->parameters->dot_dot_dot_token)
            fun->setVariadic(true);
    }

    // check the arguments
    bool hasDefaultArguments = false;
    for (unsigned i = 0; i < fun->argumentCount(); ++i) {
        Argument *arg = fun->argumentAt(i)->asArgument();
        if (hasDefaultArguments && ! arg->hasInitializer()) {
            translationUnit()->error(ast->firstToken(),
                "default argument missing for parameter at position %d", i + 1);
        } else if (! hasDefaultArguments) {
            hasDefaultArguments = arg->hasInitializer();
        }
    }

    FullySpecifiedType funTy(fun);
    _fullySpecifiedType = funTy;

    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
        SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it->value);
        const int k = tokenKind(cv->specifier_token);
        if (k == T_CONST)
            fun->setConst(true);
        else if (k == T_VOLATILE)
            fun->setVolatile(true);
    }

    return false;
}

bool CheckDeclarator::visit(ArrayDeclaratorAST *ast)
{
    ArrayType *ty = control()->arrayType(_fullySpecifiedType); // ### set the dimension
    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
    FullySpecifiedType arrTy(ty);
    _fullySpecifiedType = ty;
    return false;
}

bool CheckDeclarator::visit(PointerToMemberAST *ast)
{
    const Name *memberName = semantic()->check(ast->nested_name_specifier_list, _scope);
    PointerToMemberType *ptrTy = control()->pointerToMemberType(memberName, _fullySpecifiedType);
    FullySpecifiedType ty(ptrTy);
    _fullySpecifiedType = ty;
    applyCvQualifiers(ast->cv_qualifier_list);
    return false;
}

bool CheckDeclarator::visit(PointerAST *ast)
{
    PointerType *ptrTy = control()->pointerType(_fullySpecifiedType);
    FullySpecifiedType ty(ptrTy);
    _fullySpecifiedType = ty;
    applyCvQualifiers(ast->cv_qualifier_list);
    return false;
}

bool CheckDeclarator::visit(ReferenceAST *ast)
{
    const bool rvalueRef = (tokenKind(ast->reference_token) == T_AMPER_AMPER);

    ReferenceType *refTy = control()->referenceType(_fullySpecifiedType, rvalueRef);
    FullySpecifiedType ty(refTy);
    _fullySpecifiedType = ty;
    return false;
}

bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
{
    if (!ast)
        return false;

    if (!ast->selector) {
        // TODO: (EV) this currently happens when parsing:
        //   + (id<NSSomeProtocol>) zoo;
        // where the parser will start doing template magic. We'll need to disambiguate this case.
        return false;
    }

    FullySpecifiedType returnType = semantic()->check(ast->type_name, _scope);

    unsigned location = ast->selector->firstToken();

    semantic()->check(ast->selector, _scope);

    ObjCMethod *method = control()->newObjCMethod(location, ast->selector->name);
    ast->symbol = method;
    method->setScope(_scope);
    method->setVisibility(semantic()->currentVisibility());
    method->setReturnType(returnType);
    if (semantic()->isObjCClassMethod(tokenKind(ast->method_type_token)))
        method->setStorage(Symbol::Static);

    for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
        ObjCMessageArgumentDeclarationAST *argDecl = it->value;

        semantic()->check(argDecl, method->arguments());
    }

    if (ast->dot_dot_dot_token)
        method->setVariadic(true);

    _fullySpecifiedType = FullySpecifiedType(method);

    return false;
}

void CheckDeclarator::applyCvQualifiers(SpecifierListAST *it)
{
    for (; it; it = it->next) {
        SpecifierAST *cv = it->value;
        SimpleSpecifierAST *spec = static_cast<SimpleSpecifierAST *>(cv);
        switch (translationUnit()->tokenKind(spec->specifier_token)) {
        case T_VOLATILE:
            _fullySpecifiedType.setVolatile(true);
            break;
        case T_CONST:
            _fullySpecifiedType.setConst(true);
            break;
        default:
            break;
        } // switch
    }
}

<commit_msg>Warn for invalid references.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
// Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "CheckDeclarator.h"
#include "Semantic.h"
#include "AST.h"
#include "Control.h"
#include "TranslationUnit.h"
#include "Literals.h"
#include "CoreTypes.h"
#include "Symbols.h"

using namespace CPlusPlus;

CheckDeclarator::CheckDeclarator(Semantic *semantic)
    : SemanticCheck(semantic),
      _declarator(0),
      _scope(0),
      _name(0)
{ }

CheckDeclarator::~CheckDeclarator()
{ }

FullySpecifiedType CheckDeclarator::check(DeclaratorAST *declarator,
                                          const FullySpecifiedType &type,
                                          Scope *scope,
                                          const Name **name)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(type);
    Scope *previousScope = switchScope(scope);
    DeclaratorAST *previousDeclarator = switchDeclarator(declarator);
    const Name **previousName = switchName(name);
    accept(declarator);
    (void) switchName(previousName);
    (void) switchDeclarator(previousDeclarator);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

FullySpecifiedType CheckDeclarator::check(PtrOperatorListAST *ptrOperators,
                                          const FullySpecifiedType &type,
                                          Scope *scope)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(type);
    Scope *previousScope = switchScope(scope);
    accept(ptrOperators);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

FullySpecifiedType CheckDeclarator::check(ObjCMethodPrototypeAST *methodPrototype,
                                          Scope *scope)
{
    FullySpecifiedType previousType = switchFullySpecifiedType(FullySpecifiedType());
    Scope *previousScope = switchScope(scope);
    accept(methodPrototype);
    (void) switchScope(previousScope);
    return switchFullySpecifiedType(previousType);
}

DeclaratorAST *CheckDeclarator::switchDeclarator(DeclaratorAST *declarator)
{
    DeclaratorAST *previousDeclarator = _declarator;
    _declarator = declarator;
    return previousDeclarator;
}

FullySpecifiedType CheckDeclarator::switchFullySpecifiedType(const FullySpecifiedType &type)
{
    FullySpecifiedType previousType = _fullySpecifiedType;
    _fullySpecifiedType = type;
    return previousType;
}

Scope *CheckDeclarator::switchScope(Scope *scope)
{
    Scope *previousScope = _scope;
    _scope = scope;
    return previousScope;
}

const Name **CheckDeclarator::switchName(const Name **name)
{
    const Name **previousName = _name;
    _name = name;
    return previousName;
}

bool CheckDeclarator::visit(DeclaratorAST *ast)
{
    accept(ast->ptr_operator_list);
    accept(ast->postfix_declarator_list);
    accept(ast->core_declarator);

    if (ast->initializer) {
        FullySpecifiedType exprTy = semantic()->check(ast->initializer, _scope);

        if (Function *funTy = _fullySpecifiedType->asFunctionType())
            funTy->setPureVirtual(true);
    }

    return false;
}

bool CheckDeclarator::visit(DeclaratorIdAST *ast)
{
    const Name *name = semantic()->check(ast->name, _scope);
    if (_name)
        *_name = name;
    return false;
}

bool CheckDeclarator::visit(NestedDeclaratorAST *ast)
{
    accept(ast->declarator);
    return false;
}

bool CheckDeclarator::visit(FunctionDeclaratorAST *ast)
{
    Function *fun = control()->newFunction(ast->firstToken());
    fun->setAmbiguous(ast->as_cpp_initializer != 0);
    ast->symbol = fun;
    fun->setReturnType(_fullySpecifiedType);

    if (_fullySpecifiedType.isVirtual())
        fun->setVirtual(true);

    if (ast->parameters) {
        DeclarationListAST *parameter_declarations = ast->parameters->parameter_declaration_list;
        for (DeclarationListAST *decl = parameter_declarations; decl; decl = decl->next) {
            semantic()->check(decl->value, fun->arguments());
        }

        if (ast->parameters->dot_dot_dot_token)
            fun->setVariadic(true);
    }

    // check the arguments
    bool hasDefaultArguments = false;
    for (unsigned i = 0; i < fun->argumentCount(); ++i) {
        Argument *arg = fun->argumentAt(i)->asArgument();
        if (hasDefaultArguments && ! arg->hasInitializer()) {
            translationUnit()->error(ast->firstToken(),
                "default argument missing for parameter at position %d", i + 1);
        } else if (! hasDefaultArguments) {
            hasDefaultArguments = arg->hasInitializer();
        }
    }

    FullySpecifiedType funTy(fun);
    _fullySpecifiedType = funTy;

    for (SpecifierListAST *it = ast->cv_qualifier_list; it; it = it->next) {
        SimpleSpecifierAST *cv = static_cast<SimpleSpecifierAST *>(it->value);
        const int k = tokenKind(cv->specifier_token);
        if (k == T_CONST)
            fun->setConst(true);
        else if (k == T_VOLATILE)
            fun->setVolatile(true);
    }

    return false;
}

bool CheckDeclarator::visit(ArrayDeclaratorAST *ast)
{
    ArrayType *ty = control()->arrayType(_fullySpecifiedType); // ### set the dimension
    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
    FullySpecifiedType arrTy(ty);
    _fullySpecifiedType = ty;
    return false;
}

bool CheckDeclarator::visit(PointerToMemberAST *ast)
{
    const Name *memberName = semantic()->check(ast->nested_name_specifier_list, _scope);
    PointerToMemberType *ptrTy = control()->pointerToMemberType(memberName, _fullySpecifiedType);
    FullySpecifiedType ty(ptrTy);
    _fullySpecifiedType = ty;
    applyCvQualifiers(ast->cv_qualifier_list);
    return false;
}

bool CheckDeclarator::visit(PointerAST *ast)
{
    PointerType *ptrTy = control()->pointerType(_fullySpecifiedType);
    FullySpecifiedType ty(ptrTy);
    _fullySpecifiedType = ty;
    applyCvQualifiers(ast->cv_qualifier_list);
    return false;
}

bool CheckDeclarator::visit(ReferenceAST *ast)
{
    const bool rvalueRef = (tokenKind(ast->reference_token) == T_AMPER_AMPER);

    if (_fullySpecifiedType->isReferenceType())
        translationUnit()->error(ast->firstToken(), "cannot declare reference to a reference");

    ReferenceType *refTy = control()->referenceType(_fullySpecifiedType, rvalueRef);
    FullySpecifiedType ty(refTy);
    _fullySpecifiedType = ty;
    return false;
}

bool CheckDeclarator::visit(ObjCMethodPrototypeAST *ast)
{
    if (!ast)
        return false;

    if (!ast->selector) {
        // TODO: (EV) this currently happens when parsing:
        //   + (id<NSSomeProtocol>) zoo;
        // where the parser will start doing template magic. We'll need to disambiguate this case.
        return false;
    }

    FullySpecifiedType returnType = semantic()->check(ast->type_name, _scope);

    unsigned location = ast->selector->firstToken();

    semantic()->check(ast->selector, _scope);

    ObjCMethod *method = control()->newObjCMethod(location, ast->selector->name);
    ast->symbol = method;
    method->setScope(_scope);
    method->setVisibility(semantic()->currentVisibility());
    method->setReturnType(returnType);
    if (semantic()->isObjCClassMethod(tokenKind(ast->method_type_token)))
        method->setStorage(Symbol::Static);

    for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
        ObjCMessageArgumentDeclarationAST *argDecl = it->value;

        semantic()->check(argDecl, method->arguments());
    }

    if (ast->dot_dot_dot_token)
        method->setVariadic(true);

    _fullySpecifiedType = FullySpecifiedType(method);

    return false;
}

void CheckDeclarator::applyCvQualifiers(SpecifierListAST *it)
{
    for (; it; it = it->next) {
        SpecifierAST *cv = it->value;
        SimpleSpecifierAST *spec = static_cast<SimpleSpecifierAST *>(cv);
        switch (translationUnit()->tokenKind(spec->specifier_token)) {
        case T_VOLATILE:
            _fullySpecifiedType.setVolatile(true);
            break;
        case T_CONST:
            _fullySpecifiedType.setConst(true);
            break;
        default:
            break;
        } // switch
    }
}

<|endoftext|>


<commit_before>#include "RemovableDriveManager.hpp"
#include <iostream>
#include <stdio.h>
#include "boost/nowide/convert.hpp"

#if _WIN32
#include <windows.h>
#include <tchar.h>
#include <winioctl.h>
#include <shlwapi.h>
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
	0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#else
//linux includes
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <glob.h>
#include <libgen.h>
#endif

namespace Slic3r {
namespace GUI {

std::vector<DriveData>  RemovableDriveManager::m_current_drives;

#if _WIN32
void RemovableDriveManager::search_for_drives()
{
	m_current_drives.clear();
	m_current_drives.reserve(26);
	DWORD drivesMask = GetLogicalDrives();
	for (size_t i = 0; i < 26; i++)
	{
		if(drivesMask & (1 << i))
		{
			std::string path (1,(char)('A' + i));
			path+=":";
			UINT driveType = GetDriveTypeA(path.c_str());
			//std::cout << "found drive" << (char)('A' + i) << ": type:" <<driveType << "\n";
			if (driveType ==  DRIVE_REMOVABLE)
			{
				// get name of drive
				std::wstring wpath = std::wstring(path.begin(), path.end());
				std::wstring volumeName;
				volumeName.resize(1024);
				std::wstring fileSystemName;
				fileSystemName.resize(1024);
				LPWSTR  lpVolumeNameBuffer = new wchar_t;
				BOOL error = GetVolumeInformationW(wpath.c_str(), &volumeName[0], sizeof(volumeName), NULL, NULL, NULL, &fileSystemName[0], sizeof(fileSystemName));
				if(error != 0)
				{
					if (volumeName == L"")
					{
						volumeName = L"REMOVABLE DRIVE";
					}
					if (fileSystemName != L"")
					{
						ULARGE_INTEGER freeSpace;
						GetDiskFreeSpaceExA(path.c_str(), &freeSpace, NULL, NULL);
						//std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n";
						if (freeSpace.QuadPart > 0)
						{
							m_current_drives.push_back(DriveData(boost::nowide::narrow(volumeName), path));
						}
					}
				}
			}
			else if(driveType == 3)//disks and usb drives
			{
			}
		}
	}

}
void RemovableDriveManager::eject_drive(const std::string &path)
{

	//if (!update() || !is_drive_mounted(path))
	if(m_current_drives.empty())
		return;
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if ((*it).path == path)
		{
			std::string mpath = "\\\\.\\" + path;
			HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
			if (handle == INVALID_HANDLE_VALUE)
			{
				std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n";
				return;
			}
			DWORD deviceControlRetVal(0);
			BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
			CloseHandle(handle);
			if (error != 0)
				std::cout << "Ejected " << mpath << "\n";
			else
				std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";

			m_current_drives.erase(it);
			break;
		}
	}
}
#else
void RemovableDriveManager::search_for_drives()
{
    struct stat buf;
    std::string path(std::getenv("USER"));
	std::string pp(path);

	m_current_drives.clear();
	m_current_Drives.reserve(26);

    //search /media/* folder
    stat("/media/",&buf);
    std::cout << "/media ID: " <<buf.st_dev << "\n";
	search_path("/media/*", buf.st_dev);

	//search /media/USERNAME/* folder
	pp = "/media/"+pp;
	path = "/media/" + path + "/*";

	stat(pp.c_str() ,&buf);
    std::cout << pp <<" ID: " <<buf.st_dev << "\n";
	searchPath(path, buf.st_dev);

	//search /run/media/USERNAME/* folder
	path = "/run" + path;
	pp = "/run"+pp;
	stat(pp.c_str() ,&buf);
    std::cout << pp <<" ID: " <<buf.st_dev << "\n";
	searchPath(path, buf.st_dev);

	std::cout << "found drives:" <<newDrives.size() << "\n";
}
void RemovableDriveManager::search_path(const std::string &path,const dev_t &parentDevID)
{
    glob_t globbuf;
	globbuf.gl_offs = 2;
    std::cout<<"searching "<<path<<"\n";
	int error = glob(path.c_str(), GLOB_TILDE, NULL, &globbuf);
	if(error)
	{
		std::cerr<<"glob error "<< error<< "\n";
	}
	for(size_t i = 0; i < globbuf.gl_pathc; i++)
	{
		std::cout<<globbuf.gl_pathv[i]<<"\n";
		//TODO check if mounted
		std::string name = basename(globbuf.gl_pathv[i]);
        std::cout<<name<<"\n";
        struct stat buf;
		stat(globbuf.gl_pathv[i],&buf);
		std::cout << buf.st_dev << "\n";
		if(buf.st_dev != parentDevID)// not same file system
		{
            m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i]));
		}
	}
	globfree(&globbuf);
}
void RemovableDriveManager::eject_drive(const std::string &path)
{
	if (m_current_drives.empty())
		return;

	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if((*it).path == path)
		{
            std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n";
            int error = umount2(path.c_str(),MNT_DETACH);
            if(error)
            {
                int errsv = errno;
                std::cerr<<"Ejecting failed Error "<< errsv<<"\n";
            }
            m_current_drives.erase(it);
            break;
		}

	}

}
#endif
bool RemovableDriveManager::update()
{
	search_for_drives();
	return !m_current_drives.empty();
}

bool  RemovableDriveManager::is_drive_mounted(const std::string &path)
{
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if ((*it).path == path)
		{
			return true;
		}
	}
	return false;
}

std::string RemovableDriveManager::get_last_drive_path()
{
	if (!m_current_drives.empty())
	{
#if _WIN32
		return m_current_drives.back().path + "\\";
#else
		return m_current_drives.back().path;
#endif
	}
	return "";
}
std::vector<DriveData> RemovableDriveManager::get_all_drives()
{
	return m_current_drives;
}
#if _WIN32
bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path)
{
	if (m_current_drives.empty())
		return false;
	int letter = PathGetDriveNumberA(path.c_str());
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		char drive = (*it).path[0];
		if (drive == ('A' + letter))
			return true;
	}
	return false;
}
#else
bool RemovableDriveManager::is_path_on_removable_drive(const std::string& path, const std::string& drive)
{
	if (m_current_drives.empty())
		return false;

	return false;
}
#endif
}}//namespace Slicer::Gui::<commit_msg>prev commit linux part<commit_after>#include "RemovableDriveManager.hpp"
#include <iostream>
#include <stdio.h>
#include "boost/nowide/convert.hpp"

#if _WIN32
#include <windows.h>
#include <tchar.h>
#include <winioctl.h>
#include <shlwapi.h>
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
	0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#else
//linux includes
#include <errno.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <glob.h>
#include <libgen.h>
#endif

namespace Slic3r {
namespace GUI {

std::vector<DriveData>  RemovableDriveManager::m_current_drives;

#if _WIN32
void RemovableDriveManager::search_for_drives()
{
	m_current_drives.clear();
	m_current_drives.reserve(26);
	DWORD drives_mask = GetLogicalDrives();
	for (size_t i = 0; i < 26; i++)
	{
		if(drives_mask & (1 << i))
		{
			std::string path (1,(char)('A' + i));
			path+=":";
			UINT drive_type = GetDriveTypeA(path.c_str());
			//std::cout << "found drive" << (char)('A' + i) << ": type:" <<driveType << "\n";
			if (drive_type ==  DRIVE_REMOVABLE)
			{
				// get name of drive
				std::wstring wpath = std::wstring(path.begin(), path.end());
				std::wstring volume_name;
				volume_name.resize(1024);
				std::wstring file_system_name;
				file_system_name.resize(1024);
				LPWSTR  lp_volume_name_buffer = new wchar_t;
				BOOL error = GetVolumeInformationW(wpath.c_str(), &volume_name[0], sizeof(volume_name), NULL, NULL, NULL, &file_system_name[0], sizeof(file_system_name));
				if(error != 0)
				{
					if (volume_name == L"")
					{
						volume_name = L"REMOVABLE DRIVE";
					}
					if (file_system_name != L"")
					{
						ULARGE_INTEGER free_space;
						GetDiskFreeSpaceExA(path.c_str(), &free_space, NULL, NULL);
						//std::cout << std::string(volumeName.begin(), volumeName.end()) << " " << std::string(fileSystemName.begin(), fileSystemName.end()) << " " << freeSpace.QuadPart << "\n";
						if (free_space.QuadPart > 0)
						{
							m_current_drives.push_back(DriveData(boost::nowide::narrow(volume_name), path));
						}
					}
				}
			}
		}
	}

}
void RemovableDriveManager::eject_drive(const std::string &path)
{

	//if (!update() || !is_drive_mounted(path))
	if(m_current_drives.empty())
		return;
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if ((*it).path == path)
		{
			std::string mpath = "\\\\.\\" + path;
			HANDLE handle = CreateFileA(mpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
			if (handle == INVALID_HANDLE_VALUE)
			{
				std::cerr << "Ejecting " << mpath << " failed " << GetLastError() << " \n";
				return;
			}
			DWORD deviceControlRetVal(0);
			BOOL error = DeviceIoControl(handle, IOCTL_STORAGE_EJECT_MEDIA, nullptr, 0, nullptr, 0, &deviceControlRetVal, nullptr);
			CloseHandle(handle);
			if (error == 0)
			{
				std::cerr << "Ejecting " << mpath << " failed " << deviceControlRetVal << " " << GetLastError() << " \n";
			}

			m_current_drives.erase(it);
			break;
		}
	}
}
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
{
	if (m_current_drives.empty())
		return false;
	int letter = PathGetDriveNumberA(path.c_str());
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		char drive = (*it).path[0];
		if (drive == ('A' + letter))
			return true;
	}
	return false;
}
#else
void RemovableDriveManager::search_for_drives()
{
    struct stat buf;
    std::string path(std::getenv("USER"));
	std::string pp(path);

	m_current_drives.clear();
	m_current_drives.reserve(26);

    //search /media/* folder
    stat("/media/",&buf);
    //std::cout << "/media ID: " <<buf.st_dev << "\n";
	search_path("/media/*", buf.st_dev);

	//search /media/USERNAME/* folder
	pp = "/media/"+pp;
	path = "/media/" + path + "/*";

	stat(pp.c_str() ,&buf);
    //std::cout << pp <<" ID: " <<buf.st_dev << "\n";
	search_path(path, buf.st_dev);

	//search /run/media/USERNAME/* folder
	path = "/run" + path;
	pp = "/run"+pp;
	stat(pp.c_str() ,&buf);
    //std::cout << pp <<" ID: " <<buf.st_dev << "\n";
	search_path(path, buf.st_dev);

	//std::cout << "found drives:" <<m_current_drives.size() << "\n";
}
void RemovableDriveManager::search_path(const std::string &path,const dev_t &parentDevID)
{
    glob_t globbuf;
	globbuf.gl_offs = 2;
    //std::cout<<"searching "<<path<<"\n";
	int error = glob(path.c_str(), GLOB_TILDE, NULL, &globbuf);
	if(error)
	{
		//std::cout<<"glob error "<< error<< "\n";
	}else
	{
		for(size_t i = 0; i < globbuf.gl_pathc; i++)
		{
			//std::cout<<globbuf.gl_pathv[i]<<"\n";
			//TODO check if mounted
			std::string name = basename(globbuf.gl_pathv[i]);
	        //std::cout<<name<<"\n";
	        struct stat buf;
			stat(globbuf.gl_pathv[i],&buf);
			//std::cout << buf.st_dev << "\n";
			if(buf.st_dev != parentDevID)// not same file system
			{
	            m_current_drives.push_back(DriveData(name,globbuf.gl_pathv[i]));
			}
		}
	}

	globfree(&globbuf);
}

void RemovableDriveManager::eject_drive(const std::string &path)
{
	if (m_current_drives.empty())
		return;

	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if((*it).path == path)
		{
            //std::cout<<"Ejecting "<<(*it).name<<" from "<< (*it).path<<"\n";
            int error = umount2(path.c_str(),MNT_DETACH);
            if(error)
            {
                int errsv = errno;
                std::cerr<<"Ejecting failed Error "<< errsv<<"\n";
            }
            m_current_drives.erase(it);
            break;
		}

	}

}
bool RemovableDriveManager::is_path_on_removable_drive(const std::string &path)
{
	if (m_current_drives.empty())
		return false;
	struct stat path_buf;
	stat(path.c_str(), &path_buf);
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		struct stat drive_buf;
		stat((*it).path.c_str(), &drive_buf);
		if(drive_buf.st_dev == path_buf.st_dev)
			return true;
	}
	return false;
}
#endif
bool RemovableDriveManager::update()
{
	search_for_drives();
	return !m_current_drives.empty();
}

bool  RemovableDriveManager::is_drive_mounted(const std::string &path)
{
	for (auto it = m_current_drives.begin(); it != m_current_drives.end(); ++it)
	{
		if ((*it).path == path)
		{
			return true;
		}
	}
	return false;
}

std::string RemovableDriveManager::get_last_drive_path()
{
	if (!m_current_drives.empty())
	{
#if _WIN32
		return m_current_drives.back().path + "\\";
#else
		return m_current_drives.back().path;
#endif
	}
	return "";
}
std::vector<DriveData> RemovableDriveManager::get_all_drives()
{
	return m_current_drives;
}
#if _WIN32

#else

#endif
}}//namespace Slicer::Gui::<|endoftext|>


<commit_before>#ifndef STAN__AGRAD__FWD__FUNCTIONS__OWENS_T_HPP
#define STAN__AGRAD__FWD__FUNCTIONS__OWENS_T_HPP

#include <math.h>
#include <stan/agrad/fwd/fvar.hpp>
#include <stan/meta/traits.hpp>
#include <stan/math/constants.hpp>
#include <stan/math/functions/owens_t.hpp>

namespace stan {
  namespace agrad {

    template <typename T>
    inline
    fvar<T>
    owens_t(const fvar<T>& x1, const fvar<T>& x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::INV_SQRT_2;
      using stan::math::INV_SQRT_TWO_PI;
      using stan::math::square;
      using std::exp;
      using ::erf;

      T neg_x1_sq_div_2 = -square(x1.val_) * 0.5;
      T one_p_x2_sq = 1.0 + square(x2.val_);

      return fvar<T>(owens_t(x1.val_, x2.val_),
                     - x1.d_
                     * (erf(x2.val_ * x1.val_ * INV_SQRT_2)
                        * exp(neg_x1_sq_div_2) * INV_SQRT_TWO_PI * 0.5)
                     + x2.d_ * exp(neg_x1_sq_div_2 * one_p_x2_sq)
                     / (one_p_x2_sq * 2.0 * pi()));
    }

    template <typename T>
    inline
    fvar<T>
    owens_t(const double x1, const fvar<T>& x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::square;
      using std::exp;

      T neg_x1_sq_div_2 = -square(x1) * 0.5;
      T one_p_x2_sq = 1.0 + square(x2.val_);

      return fvar<T>(owens_t(x1, x2.val_),
                     x2.d_ * exp(neg_x1_sq_div_2 * one_p_x2_sq)
                     / (one_p_x2_sq * 2.0 * pi()));
    }

    template <typename T>
    inline
    fvar<T>
    owens_t(const fvar<T>& x1, const double x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::square;
      using stan::math::INV_SQRT_2;
      using stan::math::INV_SQRT_TWO_PI;
      using std::exp;
      using ::erf;

      T neg_x1_sq_div_2 = -square(x1.val_) * 0.5;

      return fvar<T>(owens_t(x1.val_, x2),
                     -x1.d_  * (erf(x2 * x1.val_ * INV_SQRT_2)
                                * exp(neg_x1_sq_div_2)
                                * INV_SQRT_TWO_PI * 0.5));
    }

  }
}
#endif
<commit_msg>updating includes<commit_after>#ifndef STAN__AGRAD__FWD__FUNCTIONS__OWENS_T_HPP
#define STAN__AGRAD__FWD__FUNCTIONS__OWENS_T_HPP

#include <math.h>
#include <stan/agrad/fwd/fvar.hpp>
#include <stan/meta/traits.hpp>
#include <stan/math/constants.hpp>
#include <stan/math/functions/owens_t.hpp>
#include <stan/math/functions/square.hpp>

namespace stan {
  namespace agrad {

    template <typename T>
    inline
    fvar<T>
    owens_t(const fvar<T>& x1, const fvar<T>& x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::INV_SQRT_2;
      using stan::math::INV_SQRT_TWO_PI;
      using stan::math::square;
      using std::exp;
      using ::erf;

      T neg_x1_sq_div_2 = -square(x1.val_) * 0.5;
      T one_p_x2_sq = 1.0 + square(x2.val_);

      return fvar<T>(owens_t(x1.val_, x2.val_),
                     - x1.d_
                     * (erf(x2.val_ * x1.val_ * INV_SQRT_2)
                        * exp(neg_x1_sq_div_2) * INV_SQRT_TWO_PI * 0.5)
                     + x2.d_ * exp(neg_x1_sq_div_2 * one_p_x2_sq)
                     / (one_p_x2_sq * 2.0 * pi()));
    }

    template <typename T>
    inline
    fvar<T>
    owens_t(const double x1, const fvar<T>& x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::square;
      using std::exp;

      T neg_x1_sq_div_2 = -square(x1) * 0.5;
      T one_p_x2_sq = 1.0 + square(x2.val_);

      return fvar<T>(owens_t(x1, x2.val_),
                     x2.d_ * exp(neg_x1_sq_div_2 * one_p_x2_sq)
                     / (one_p_x2_sq * 2.0 * pi()));
    }

    template <typename T>
    inline
    fvar<T>
    owens_t(const fvar<T>& x1, const double x2) {
      using stan::math::owens_t;
      using stan::math::pi;
      using stan::math::square;
      using stan::math::INV_SQRT_2;
      using stan::math::INV_SQRT_TWO_PI;
      using std::exp;
      using ::erf;

      T neg_x1_sq_div_2 = -square(x1.val_) * 0.5;

      return fvar<T>(owens_t(x1.val_, x2),
                     -x1.d_  * (erf(x2 * x1.val_ * INV_SQRT_2)
                                * exp(neg_x1_sq_div_2)
                                * INV_SQRT_TWO_PI * 0.5));
    }

  }
}
#endif
<|endoftext|>


<commit_before>//*******************************************************************
//
// License: MIT
//
// See LICENSE.txt file in the top level directory for more details.
//
// Author: Garrett Potts
//
// Description: Nitf support class
//
//********************************************************************
// $Id$

#include <ossim/support_data/ossimNitfFileHeader.h>
#include <ossim/base/ossimContainerProperty.h>
#include <iostream>

static const char* TAGS_KW = "tags";

RTTI_DEF2(ossimNitfFileHeader, "ossimNitfFileHeader", ossimObject, ossimPropertyInterface);

std::ostream& ossimNitfImageOffsetInformation::print(std::ostream& out) const
{
   return out << "theImageHeaderOffset:          "
              << theImageHeaderOffset << std::endl
              << "theImageDataOffset:            "
              << theImageDataOffset;
}

ossimNitfFileHeader::ossimNitfFileHeader()
{
}

ossimNitfFileHeader::~ossimNitfFileHeader()
{
}

bool ossimNitfFileHeader::getTag(ossimNitfTagInformation& tagInfo,
                                 const ossimString& tagName)const
{
   if(theTagList.size())
   {
      for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
      {
         if(theTagList[i].getTagName() == tagName)
         {
            tagInfo = theTagList[i];
            return true;
         }
      }
   }

   return false;
}
bool ossimNitfFileHeader::getDesInformation(ossimNitfDesInformation &desInfo,
                                            const ossimString &desId,
                                            bool exactMatch)
{
   if (theDesList.size())
   {
      for (ossim_uint32 i = 0; i < theDesList.size(); ++i)
      {
         if(exactMatch)
         {
            if (theDesList[i].getDesId() == desId)
            {
               desInfo = theDesList[i];
               return true;
            }
         }
         else
         {
            if(theDesList[i].getDesId().contains(desId))
            {
               desInfo = theDesList[i];
               return true;
            }
         }
      }
   }
}

bool  ossimNitfFileHeader::hasImages()const
{
   return (getNumberOfImages() > 0);
}

bool  ossimNitfFileHeader::hasSymbols()const
{
   return (getNumberOfSymbols() > 0);
}

bool  ossimNitfFileHeader::hasGraphics()const
{
   return (getNumberOfGraphics() > 0);
}

bool  ossimNitfFileHeader::hasText()const
{
   return (getNumberOfTextSegments() > 0);
}

bool  ossimNitfFileHeader::hasLabels()const
{
   return (getNumberOfLabels() > 0);
}
bool ossimNitfFileHeader::hasDataExtSegments()const
{
   return (getNumberOfDataExtSegments() > 0);
}

void ossimNitfFileHeader::removeTag(const ossimString& tagName)
{
   ossim_uint32 idx = 0;
   for(idx = 0; idx < theTagList.size(); ++idx)
   {
      if(theTagList[idx].getTagName() == tagName)
      {
         theTagList.erase(theTagList.begin() + idx);
         return;
      }
   }
}
void ossimNitfFileHeader::addTag(const ossimNitfTagInformation& tag, bool unique)
{
   if(unique)
   {
      removeTag(tag.getTagName());
   }
   theTagList.push_back(tag);
}

bool ossimNitfFileHeader::getTagInformation(ossimNitfTagInformation& tag,
                                            int idx) const
{
   bool result = false;

   if(static_cast<ossim_uint32>(idx) < theTagList.size())
   {
      tag = theTagList[idx];
      result = true;
   }

   return result;
}

int ossimNitfFileHeader::getNumberOfTags()const
{
   return (int)theTagList.size();
}

const std::vector<ossimNitfDesInformation> &ossimNitfFileHeader::getDesInfoList() const
{
    return theDesList;
}

ossim_uint32 ossimNitfFileHeader::getTotalTagLength() const
{
   ossim_uint32 tagLength = 0;

   for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
   {
      tagLength += theTagList[i].getTotalTagLength();
   }

   return tagLength;
}

void ossimNitfFileHeader::setProperty(ossimRefPtr<ossimProperty> /* property */)
{
}

ossimRefPtr<ossimProperty> ossimNitfFileHeader::getProperty(const ossimString& name)const
{
   ossimRefPtr<ossimProperty> result = 0;

   if(name == TAGS_KW)
   {
      ossim_uint32 idxMax = (ossim_uint32)theTagList.size();
      if(idxMax > 0)
      {
         ossimContainerProperty* containerProperty = new ossimContainerProperty;
         containerProperty->setName(name);
         ossim_uint32 idx = 0;

         result = containerProperty;
         for(idx = 0; idx < idxMax; ++idx)
         {
            ossimNitfTagInformation tagInfo;
            getTagInformation(tagInfo, idx);

            const ossimRefPtr<ossimNitfRegisteredTag> tagData = tagInfo.getTagData();
            if(tagData.valid())
            {
               ossimContainerProperty* containerPropertyTag = new ossimContainerProperty;
               containerPropertyTag->setName(tagInfo.getTagName());
               std::vector<ossimRefPtr<ossimProperty> > propertyList;
               tagData->getPropertyList(propertyList);

               containerPropertyTag->addChildren(propertyList);
               containerProperty->addChild(containerPropertyTag);
            }
            else
            {
               containerProperty->addStringProperty(tagInfo.getTagName(), "", true);
            }
         }
      }
   }

   return result;
}

void ossimNitfFileHeader::getPropertyNames(std::vector<ossimString>& propertyNames)const
{
   propertyNames.push_back(TAGS_KW);
}

bool ossimNitfFileHeader::saveState(ossimKeywordlist& kwl, const ossimString& prefix)const
{
   ossimObject::saveState(kwl, prefix);

   bool result = true;
   ossimString tagsPrefix = prefix;
   ossim_uint32 i = 0;
   for(; i < theTagList.size(); ++i)
   {
      ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
      if (tag.valid())
      {
         // we eventually need to do our own prefix for this object and not let the calling object do any prefix definitions
//         ossimString newPrefix = tagsPrefix + tag->getRegisterTagName() + ".";

         tag->saveState(kwl, tagsPrefix);
      }
   }
   i = 0;
   ossimString desPrefix = prefix + "des";
   for (auto des : theDesList)
   {
      des.saveState(kwl, desPrefix+ossimString(i) + ".");
   }
   return result;
}

std::ostream& ossimNitfFileHeader::print(std::ostream& out,
                                         const std::string& prefix ) const
{
   return printTags(out, prefix);
}

std::ostream& ossimNitfFileHeader::printTags(std::ostream& out,
                                             const std::string& prefix) const
{
   ossim_uint32 i = 0;
   for (; i < theTagList.size(); ++i)
   {
      ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
      if (tag.valid())
      {
         tag->print(out, prefix);
      }
   }
   ossimString desPrefix = prefix + "des";
   for (i = 0; i < theDesList.size(); ++i)
   {
      theDesList[i].print(out, desPrefix + ossimString::toString(i) + ".");
   }

   return out;
}
<commit_msg>Needed a return at the end of the method<commit_after>//*******************************************************************
//
// License: MIT
//
// See LICENSE.txt file in the top level directory for more details.
//
// Author: Garrett Potts
//
// Description: Nitf support class
//
//********************************************************************
// $Id$

#include <ossim/support_data/ossimNitfFileHeader.h>
#include <ossim/base/ossimContainerProperty.h>
#include <iostream>

static const char* TAGS_KW = "tags";

RTTI_DEF2(ossimNitfFileHeader, "ossimNitfFileHeader", ossimObject, ossimPropertyInterface);

std::ostream& ossimNitfImageOffsetInformation::print(std::ostream& out) const
{
   return out << "theImageHeaderOffset:          "
              << theImageHeaderOffset << std::endl
              << "theImageDataOffset:            "
              << theImageDataOffset;
}

ossimNitfFileHeader::ossimNitfFileHeader()
{
}

ossimNitfFileHeader::~ossimNitfFileHeader()
{
}

bool ossimNitfFileHeader::getTag(ossimNitfTagInformation& tagInfo,
                                 const ossimString& tagName)const
{
   if(theTagList.size())
   {
      for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
      {
         if(theTagList[i].getTagName() == tagName)
         {
            tagInfo = theTagList[i];
            return true;
         }
      }
   }

   return false;
}
bool ossimNitfFileHeader::getDesInformation(ossimNitfDesInformation &desInfo,
                                            const ossimString &desId,
                                            bool exactMatch)
{
   if (theDesList.size())
   {
      for (ossim_uint32 i = 0; i < theDesList.size(); ++i)
      {
         if(exactMatch)
         {
            if (theDesList[i].getDesId() == desId)
            {
               desInfo = theDesList[i];
               return true;
            }
         }
         else
         {
            if(theDesList[i].getDesId().contains(desId))
            {
               desInfo = theDesList[i];
               return true;
            }
         }
      }
   }
   return false
}

bool  ossimNitfFileHeader::hasImages()const
{
   return (getNumberOfImages() > 0);
}

bool  ossimNitfFileHeader::hasSymbols()const
{
   return (getNumberOfSymbols() > 0);
}

bool  ossimNitfFileHeader::hasGraphics()const
{
   return (getNumberOfGraphics() > 0);
}

bool  ossimNitfFileHeader::hasText()const
{
   return (getNumberOfTextSegments() > 0);
}

bool  ossimNitfFileHeader::hasLabels()const
{
   return (getNumberOfLabels() > 0);
}
bool ossimNitfFileHeader::hasDataExtSegments()const
{
   return (getNumberOfDataExtSegments() > 0);
}

void ossimNitfFileHeader::removeTag(const ossimString& tagName)
{
   ossim_uint32 idx = 0;
   for(idx = 0; idx < theTagList.size(); ++idx)
   {
      if(theTagList[idx].getTagName() == tagName)
      {
         theTagList.erase(theTagList.begin() + idx);
         return;
      }
   }
}
void ossimNitfFileHeader::addTag(const ossimNitfTagInformation& tag, bool unique)
{
   if(unique)
   {
      removeTag(tag.getTagName());
   }
   theTagList.push_back(tag);
}

bool ossimNitfFileHeader::getTagInformation(ossimNitfTagInformation& tag,
                                            int idx) const
{
   bool result = false;

   if(static_cast<ossim_uint32>(idx) < theTagList.size())
   {
      tag = theTagList[idx];
      result = true;
   }

   return result;
}

int ossimNitfFileHeader::getNumberOfTags()const
{
   return (int)theTagList.size();
}

const std::vector<ossimNitfDesInformation> &ossimNitfFileHeader::getDesInfoList() const
{
    return theDesList;
}

ossim_uint32 ossimNitfFileHeader::getTotalTagLength() const
{
   ossim_uint32 tagLength = 0;

   for(ossim_uint32 i = 0; i < theTagList.size(); ++i)
   {
      tagLength += theTagList[i].getTotalTagLength();
   }

   return tagLength;
}

void ossimNitfFileHeader::setProperty(ossimRefPtr<ossimProperty> /* property */)
{
}

ossimRefPtr<ossimProperty> ossimNitfFileHeader::getProperty(const ossimString& name)const
{
   ossimRefPtr<ossimProperty> result = 0;

   if(name == TAGS_KW)
   {
      ossim_uint32 idxMax = (ossim_uint32)theTagList.size();
      if(idxMax > 0)
      {
         ossimContainerProperty* containerProperty = new ossimContainerProperty;
         containerProperty->setName(name);
         ossim_uint32 idx = 0;

         result = containerProperty;
         for(idx = 0; idx < idxMax; ++idx)
         {
            ossimNitfTagInformation tagInfo;
            getTagInformation(tagInfo, idx);

            const ossimRefPtr<ossimNitfRegisteredTag> tagData = tagInfo.getTagData();
            if(tagData.valid())
            {
               ossimContainerProperty* containerPropertyTag = new ossimContainerProperty;
               containerPropertyTag->setName(tagInfo.getTagName());
               std::vector<ossimRefPtr<ossimProperty> > propertyList;
               tagData->getPropertyList(propertyList);

               containerPropertyTag->addChildren(propertyList);
               containerProperty->addChild(containerPropertyTag);
            }
            else
            {
               containerProperty->addStringProperty(tagInfo.getTagName(), "", true);
            }
         }
      }
   }

   return result;
}

void ossimNitfFileHeader::getPropertyNames(std::vector<ossimString>& propertyNames)const
{
   propertyNames.push_back(TAGS_KW);
}

bool ossimNitfFileHeader::saveState(ossimKeywordlist& kwl, const ossimString& prefix)const
{
   ossimObject::saveState(kwl, prefix);

   bool result = true;
   ossimString tagsPrefix = prefix;
   ossim_uint32 i = 0;
   for(; i < theTagList.size(); ++i)
   {
      ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
      if (tag.valid())
      {
         // we eventually need to do our own prefix for this object and not let the calling object do any prefix definitions
//         ossimString newPrefix = tagsPrefix + tag->getRegisterTagName() + ".";

         tag->saveState(kwl, tagsPrefix);
      }
   }
   i = 0;
   ossimString desPrefix = prefix + "des";
   for (auto des : theDesList)
   {
      des.saveState(kwl, desPrefix+ossimString(i) + ".");
   }
   return result;
}

std::ostream& ossimNitfFileHeader::print(std::ostream& out,
                                         const std::string& prefix ) const
{
   return printTags(out, prefix);
}

std::ostream& ossimNitfFileHeader::printTags(std::ostream& out,
                                             const std::string& prefix) const
{
   ossim_uint32 i = 0;
   for (; i < theTagList.size(); ++i)
   {
      ossimRefPtr<ossimNitfRegisteredTag> tag = theTagList[i].getTagData();
      if (tag.valid())
      {
         tag->print(out, prefix);
      }
   }
   ossimString desPrefix = prefix + "des";
   for (i = 0; i < theDesList.size(); ++i)
   {
      theDesList[i].print(out, desPrefix + ossimString::toString(i) + ".");
   }

   return out;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2008 James Molloy, James Pritchett, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <processor/types.h>
#include "cppsupport.h"

// Required for G++ to link static init/destructors.
void *__dso_handle;

// Defined in the linker.
uintptr_t start_ctors;
uintptr_t end_ctors;

/// Calls the constructors for all global objects.
/// Call this before using any global objects.
void initialiseConstructors()
{
  // Constructor list is defined in the linker script.
  // The .ctors section is just an array of function pointers.
  // iterate through, calling each in turn.
  uintptr_t *iterator = reinterpret_cast<uintptr_t*>(&start_ctors);
  while (iterator < reinterpret_cast<uintptr_t*>(&end_ctors))
  {
    void (*fp)(void) = reinterpret_cast<void (*)(void)>(*iterator);
    fp();
    iterator++;
  }
}

/// Required for G++ to compile code.
extern "C" void __cxa_atexit(void (*f)(void *), void *p, void *d)
{
}

/// Called by G++ if a pure virtual function is called. Bad Thing, should never happen!
extern "C" void __cxa_pure_virtual()
{
}

/// Called by G++ if function local statics are initialised for the first time
extern "C" void __cxa_guard_acquire()
{
  // TODO
}
extern "C" void __cxa_guard_release()
{
  // TODO
}

#include "dlmalloc.h"
void *operator new (size_t size) throw()
{
#ifdef X86_COMMON
  return malloc(size);
#else
  return 0;
#endif
}
void *operator new[] (size_t size) throw()
{
#ifdef X86_COMMON
  return malloc(size);
#else
  return 0;
#endif
}
void *operator new (size_t size, void* memory) throw()
{
  return memory;
}
void *operator new[] (size_t size, void* memory) throw()
{
  return memory;
}
void operator delete (void * p)
{
#ifdef X86_COMMON
  free(p);
#endif
}
void operator delete[] (void * p)
{
#ifdef X86_COMMON
  free(p);
#endif
}
void operator delete (void *p, void *q)
{
  // TODO
}
void operator delete[] (void *p, void *q)
{
  // TODO
}
<commit_msg>I think/hope I fixed and issue with static object creation.<commit_after>/*
 * Copyright (c) 2008 James Molloy, James Pritchett, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
#include <processor/types.h>
#include "cppsupport.h"

// Required for G++ to link static init/destructors.
void *__dso_handle;

// Defined in the linker.
uintptr_t start_ctors;
uintptr_t end_ctors;

/// Calls the constructors for all global objects.
/// Call this before using any global objects.
void initialiseConstructors()
{
  // Constructor list is defined in the linker script.
  // The .ctors section is just an array of function pointers.
  // iterate through, calling each in turn.
  uintptr_t *iterator = reinterpret_cast<uintptr_t*>(&start_ctors);
  while (iterator < reinterpret_cast<uintptr_t*>(&end_ctors))
  {
    void (*fp)(void) = reinterpret_cast<void (*)(void)>(*iterator);
    fp();
    iterator++;
  }
}

/// Required for G++ to compile code.
extern "C" void __cxa_atexit(void (*f)(void *), void *p, void *d)
{
}

/// Called by G++ if a pure virtual function is called. Bad Thing, should never happen!
extern "C" void __cxa_pure_virtual()
{
}

/// Called by G++ if function local statics are initialised for the first time
extern "C" int __cxa_guard_acquire()
{
  return 1;
}
extern "C" void __cxa_guard_release()
{
  // TODO
}

#include "dlmalloc.h"
void *operator new (size_t size) throw()
{
#ifdef X86_COMMON
  return malloc(size);
#else
  return 0;
#endif
}
void *operator new[] (size_t size) throw()
{
#ifdef X86_COMMON
  return malloc(size);
#else
  return 0;
#endif
}
void *operator new (size_t size, void* memory) throw()
{
  return memory;
}
void *operator new[] (size_t size, void* memory) throw()
{
  return memory;
}
void operator delete (void * p)
{
#ifdef X86_COMMON
  free(p);
#endif
}
void operator delete[] (void * p)
{
#ifdef X86_COMMON
  free(p);
#endif
}
void operator delete (void *p, void *q)
{
  // TODO
}
void operator delete[] (void *p, void *q)
{
  // TODO
}
<|endoftext|>


<commit_before>/*	____________________________________________________________________________

	                 Scanner Component for the Micro A Compiler

	                                mscan.h

	                              Version 2007 - 2016

	                           James L. Richards
	                     Last Update: August 28, 2007
	                      	   Nelson A Castillo
	                     Last Update: January 31, 2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by Charles N. Fischer and Richard J. LeBlanc, Jr.,
	Benjamin Cummings Publishing Co. (1991).

	See Section 2.2, pp. 25-29.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"

// *******************
// **  Constructor  **
// *******************

Scanner::Scanner()
{
	tokenBuffer = "";
	lineBuffer = "";
	lineNumber = 0;
}

// ********************************
// **  Private Member Functions  **
// ********************************

void Scanner::BufferChar(char c)
{
	if (tokenBuffer.length() < ID_STRING_LEN){
		tokenBuffer += c;
	}
	//cerr << tokenBuffer << endl;
}
void Scanner::BufferString(char c)
{
	stringBuffer += c;
	//cerr << tokenBuffer << endl;
}

Token Scanner::CheckReserved()
{
	/* Convert the string to lower case */
	transform(tokenBuffer.begin(), tokenBuffer.end(), \
				tokenBuffer.begin(), ::tolower);
	/* Check the converted words */
	if ((tokenBuffer) == "bool") return BOOL_SYM;
	if ((tokenBuffer) == "break") return BREAK_SYM;
	if ((tokenBuffer) == "case") return CASE_SYM;
	if ((tokenBuffer) == "cheese") return CHEESE_SYM;
	if ((tokenBuffer) == "decs") return DECS_SYM;
	if ((tokenBuffer) == "do") return DO_SYM;
	if ((tokenBuffer) == "else") return ELSE_SYM;
	if ((tokenBuffer) == "end") return END_SYM;
	if ((tokenBuffer) == "false") return FALSE_SYM;
	if ((tokenBuffer) == "float") return FLOAT_SYM;
	if ((tokenBuffer) == "for") return FOR_SYM;
	if ((tokenBuffer) == "hiphip") return HIPHIP_SYM;
	if ((tokenBuffer) == "if") return IF_SYM;
	if ((tokenBuffer) == "int") return INT_SYM;
	if ((tokenBuffer) == "listen") return LISTEN_SYM;
	if ((tokenBuffer) == "otherwise") return OTHERWISE_SYM;
	if ((tokenBuffer) == "select") return SELECT_SYM;
	if ((tokenBuffer) == "shout") return SHOUT_SYM;
	if ((tokenBuffer) == "then") return THEN_SYM;
	if ((tokenBuffer) == "true") return TRUE_SYM;
	if ((tokenBuffer) == "while") return WHILE_SYM;

	return ID;
}

void Scanner::ClearBuffer()
{
	tokenBuffer = "";
	stringBuffer = "";
}

void Scanner::LexicalError(char& c)/* TODO: , string& errorExp = "") */
{
	cout << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << endl;
	listFile << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << endl;

	c = NextChar();
}
void Scanner::LexicalError(char& c, const string& errorExp)/* TODO: , string& errorExp = "") */
{
	cout << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << '\n'
		<< errorExp << endl;
	listFile << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << '\n'
		<< errorExp << endl;

	c = NextChar();
}

char Scanner::NextChar()
{
	char c;

	sourceFile.get(c);
	if (c == '\n')
	{
		listFile.width(6);
		listFile << ++lineNumber << "  " << lineBuffer << endl;
		lineBuffer = "";
	} else{
		lineBuffer += c;
	}
	return c;
}

// *******************************
// **  Public Member Functions  **
// *******************************

Token Scanner::GetNextToken()
{
	char currentChar, c;

	ClearBuffer();
	currentChar = NextChar();
	while (!sourceFile.eof())
	{
		if (isspace(currentChar)) {
			/* do nothing */
			currentChar = NextChar();
		} else if (isalpha(currentChar)) {
			/* identifier */
			BufferChar(currentChar);
			c = sourceFile.peek();
			while (isalnum(c) || c == '_') {
				currentChar = NextChar();
				BufferChar(currentChar);
				c = sourceFile.peek();
			}
			return CheckReserved();
		} else if (isdigit(currentChar)) {
			/* integer or float literals */
			BufferChar(currentChar);
			c = sourceFile.peek();
			while (isdigit(c)) {
				currentChar = NextChar();
				BufferChar(currentChar);
				c = sourceFile.peek();
			}
			/* check if it is a float */
			if (c == '.') {
				currentChar = NextChar();
				c = sourceFile.peek();
				/* check for a digit after the '.' */
				if (!isdigit(c))
					LexicalError(currentChar, to_string(c)+" Boolean needs a digit after the '.'");
				BufferChar(currentChar);
				while (isdigit(c)) {
					currentChar = NextChar();
					BufferChar(currentChar);
					c = sourceFile.peek();
				}
				/* check for power of 10 multipliers */
				if (c == 'e' || c == 'E') {
					currentChar = NextChar();
					c = sourceFile.peek();
					if (c != '+' && c!= '-') {
						LexicalError(currentChar, to_string(c)+" Boolean needs a '+' or a '-' after 'E' ");
					}
					BufferChar(currentChar);
					currentChar = NextChar();
					c = sourceFile.peek();
					if (!isdigit(c))
						LexicalError(currentChar, to_string(c)+"Boolean needs a  digit after '+' or '-'");
					BufferChar(currentChar);
					while (isdigit(c)) {
						currentChar = NextChar();
						BufferChar(currentChar);
						c = sourceFile.peek();
					}
				}
				return FLOAT_LIT;
			}
			return INT_LIT;
		} else if (currentChar == '"') {
			// string literal
			// BufferString(currentChar);
			do {
				currentChar = NextChar();
				// cout << currentChar <<endl;
				if (currentChar == '"' \
						& sourceFile.peek() != '"') {
					// BufferString(currentChar);
					// cout << "________________________" <<endl;
					// cout << stringBuffer <<endl;
					// cout << "________________________" <<endl;
					return CHEESE_LIT;
				} else if (currentChar == '"' \
						& sourceFile.peek() == '"') {
					currentChar = NextChar();
				}
				BufferString(currentChar);
			} while (sourceFile.peek()!='\n');
			return CHEESE_LIT;
		} else if (currentChar == '(') {
			BufferString(currentChar);
			return LBANANA;
		} else if (currentChar == ')') {
			BufferString(currentChar);
			return RBANANA;
		} else if (currentChar == '[') {
			BufferString(currentChar);
			return LSTAPLE;
		} else if (currentChar == ']') {
			BufferString(currentChar);
			return RSTAPLE;
		} else if (currentChar == '{') {
			BufferString(currentChar);
			return LMUSTACHE;
		} else if (currentChar == '}') {
			BufferString(currentChar);
			return RMUSTACHE;
		} else if (currentChar == ';') {
			BufferString(currentChar);
			return SEMICOLON;
		} else if (currentChar == ':') {
			BufferString(currentChar);
			return COLON;
		} else if (currentChar == ',') {
			BufferString(currentChar);
			return COMMA;
		} else if (currentChar == '+') {
			BufferChar(currentChar);
			return PLUS_OP;
		} else if (currentChar == '*') {
			BufferChar(currentChar);
			return MULT_OP;
		} else if (currentChar == '/') {
			/* check if it is a multiline comment */
			if (sourceFile.peek() == ':') {
				do { /* skip comment */
					currentChar = NextChar();
					if (currentChar == ':') {
						currentChar = NextChar();
						if (currentChar == '/') {
							break;
						}
					}
				} while (!sourceFile.eof());
			}
			BufferChar(currentChar);
			return DIV_OP;
		} else if (currentChar == '=') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return EQ_OP1;
			}
			currentChar = NextChar();
			return ASSIGN_OP;
		} else if (currentChar == '!') {
			if (sourceFile.peek() == '!') {
				currentChar = NextChar();
				return EQ_OP2;
			} else if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return NE_OP;
			}
		} else if (currentChar == '<') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return LE_OP;
			}
			currentChar = NextChar();
			return LT_OP;
		} else if (currentChar == '>') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return GE_OP;
			}
			currentChar = NextChar();
			return GT_OP;
		} else if (currentChar == '-') {
			/* check if it is a comment or a minus symbol */
			if (sourceFile.peek() == '-') { /* comment */
				do { /* skip comment */
					currentChar = NextChar();
				} while (currentChar != '\n');
			} else { /* minus operator */
				BufferChar(currentChar);
				return MINUS_OP;
			}
		} else {
			/* Unrecognized character */
			LexicalError(currentChar, to_string(c)+" Unrecognized character");
		}
	} /* end while */

	return EOF_SYM;
}
<commit_msg>Remove old comments.<commit_after>/*	____________________________________________________________________________

	                 Scanner Component for the Micro A Compiler

	                                mscan.h

	                              Version 2007 - 2016

	                           James L. Richards
	                     Last Update: August 28, 2007
	                      	   Nelson A Castillo
	                     Last Update: January 31, 2016

	The routines in this unit are based on those provided in the book
	"Crafting A Compiler" by Charles N. Fischer and Richard J. LeBlanc, Jr.,
	Benjamin Cummings Publishing Co. (1991).

	See Section 2.2, pp. 25-29.
	____________________________________________________________________________
*/

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

extern ifstream sourceFile;
extern ofstream outFile, listFile;

#include "mscan.h"

// *******************
// **  Constructor  **
// *******************

Scanner::Scanner()
{
	tokenBuffer = "";
	lineBuffer = "";
	lineNumber = 0;
}

// ********************************
// **  Private Member Functions  **
// ********************************

void Scanner::BufferChar(char c)
{
	if (tokenBuffer.length() < ID_STRING_LEN){
		tokenBuffer += c;
	}
	//cerr << tokenBuffer << endl;
}
void Scanner::BufferString(char c)
{
	stringBuffer += c;
	//cerr << tokenBuffer << endl;
}

Token Scanner::CheckReserved()
{
	/* Convert the string to lower case */
	transform(tokenBuffer.begin(), tokenBuffer.end(), \
				tokenBuffer.begin(), ::tolower);
	/* Check the converted words */
	if ((tokenBuffer) == "bool") return BOOL_SYM;
	if ((tokenBuffer) == "break") return BREAK_SYM;
	if ((tokenBuffer) == "case") return CASE_SYM;
	if ((tokenBuffer) == "cheese") return CHEESE_SYM;
	if ((tokenBuffer) == "decs") return DECS_SYM;
	if ((tokenBuffer) == "do") return DO_SYM;
	if ((tokenBuffer) == "else") return ELSE_SYM;
	if ((tokenBuffer) == "end") return END_SYM;
	if ((tokenBuffer) == "false") return FALSE_SYM;
	if ((tokenBuffer) == "float") return FLOAT_SYM;
	if ((tokenBuffer) == "for") return FOR_SYM;
	if ((tokenBuffer) == "hiphip") return HIPHIP_SYM;
	if ((tokenBuffer) == "if") return IF_SYM;
	if ((tokenBuffer) == "int") return INT_SYM;
	if ((tokenBuffer) == "listen") return LISTEN_SYM;
	if ((tokenBuffer) == "otherwise") return OTHERWISE_SYM;
	if ((tokenBuffer) == "select") return SELECT_SYM;
	if ((tokenBuffer) == "shout") return SHOUT_SYM;
	if ((tokenBuffer) == "then") return THEN_SYM;
	if ((tokenBuffer) == "true") return TRUE_SYM;
	if ((tokenBuffer) == "while") return WHILE_SYM;

	return ID;
}

void Scanner::ClearBuffer()
{
	tokenBuffer = "";
	stringBuffer = "";
}

void Scanner::LexicalError(char& c)
{
	cout << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << endl;
	listFile << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << endl;

	c = NextChar();
}
void Scanner::LexicalError(char& c, const string& errorExp)
{
	cout << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << '\n'
		<< errorExp << endl;
	listFile << " *** Lexical Error: '" << c
		<< "' ignored at position " << int(lineBuffer.size())
		<< " on line #" << lineNumber + 1 << '.' << '\n'
		<< errorExp << endl;

	c = NextChar();
}

char Scanner::NextChar()
{
	char c;

	sourceFile.get(c);
	if (c == '\n')
	{
		listFile.width(6);
		listFile << ++lineNumber << "  " << lineBuffer << endl;
		lineBuffer = "";
	} else{
		lineBuffer += c;
	}
	return c;
}

// *******************************
// **  Public Member Functions  **
// *******************************

Token Scanner::GetNextToken()
{
	char currentChar, c;

	ClearBuffer();
	currentChar = NextChar();
	while (!sourceFile.eof())
	{
		if (isspace(currentChar)) {
			/* do nothing */
			currentChar = NextChar();
		} else if (isalpha(currentChar)) {
			/* identifier */
			BufferChar(currentChar);
			c = sourceFile.peek();
			while (isalnum(c) || c == '_') {
				currentChar = NextChar();
				BufferChar(currentChar);
				c = sourceFile.peek();
			}
			return CheckReserved();
		} else if (isdigit(currentChar)) {
			/* integer or float literals */
			BufferChar(currentChar);
			c = sourceFile.peek();
			while (isdigit(c)) {
				currentChar = NextChar();
				BufferChar(currentChar);
				c = sourceFile.peek();
			}
			/* check if it is a float */
			if (c == '.') {
				currentChar = NextChar();
				c = sourceFile.peek();
				/* check for a digit after the '.' */
				if (!isdigit(c))
					LexicalError(currentChar, to_string(c)+" Boolean needs a digit after the '.'");
				BufferChar(currentChar);
				while (isdigit(c)) {
					currentChar = NextChar();
					BufferChar(currentChar);
					c = sourceFile.peek();
				}
				/* check for power of 10 multipliers */
				if (c == 'e' || c == 'E') {
					currentChar = NextChar();
					c = sourceFile.peek();
					if (c != '+' && c!= '-') {
						LexicalError(currentChar, to_string(c)+" Boolean needs a '+' or a '-' after 'E' ");
					}
					BufferChar(currentChar);
					currentChar = NextChar();
					c = sourceFile.peek();
					if (!isdigit(c))
						LexicalError(currentChar, to_string(c)+"Boolean needs a  digit after '+' or '-'");
					BufferChar(currentChar);
					while (isdigit(c)) {
						currentChar = NextChar();
						BufferChar(currentChar);
						c = sourceFile.peek();
					}
				}
				return FLOAT_LIT;
			}
			return INT_LIT;
		} else if (currentChar == '"') {
			// string literal
			// BufferString(currentChar);
			do {
				currentChar = NextChar();
				// cout << currentChar <<endl;
				if (currentChar == '"' \
						& sourceFile.peek() != '"') {
					// BufferString(currentChar);
					// cout << "________________________" <<endl;
					// cout << stringBuffer <<endl;
					// cout << "________________________" <<endl;
					return CHEESE_LIT;
				} else if (currentChar == '"' \
						& sourceFile.peek() == '"') {
					currentChar = NextChar();
				}
				BufferString(currentChar);
			} while (sourceFile.peek()!='\n');
			return CHEESE_LIT;
		} else if (currentChar == '(') {
			BufferString(currentChar);
			return LBANANA;
		} else if (currentChar == ')') {
			BufferString(currentChar);
			return RBANANA;
		} else if (currentChar == '[') {
			BufferString(currentChar);
			return LSTAPLE;
		} else if (currentChar == ']') {
			BufferString(currentChar);
			return RSTAPLE;
		} else if (currentChar == '{') {
			BufferString(currentChar);
			return LMUSTACHE;
		} else if (currentChar == '}') {
			BufferString(currentChar);
			return RMUSTACHE;
		} else if (currentChar == ';') {
			BufferString(currentChar);
			return SEMICOLON;
		} else if (currentChar == ':') {
			BufferString(currentChar);
			return COLON;
		} else if (currentChar == ',') {
			BufferString(currentChar);
			return COMMA;
		} else if (currentChar == '+') {
			BufferChar(currentChar);
			return PLUS_OP;
		} else if (currentChar == '*') {
			BufferChar(currentChar);
			return MULT_OP;
		} else if (currentChar == '/') {
			/* check if it is a multiline comment */
			if (sourceFile.peek() == ':') {
				do { /* skip comment */
					currentChar = NextChar();
					if (currentChar == ':') {
						currentChar = NextChar();
						if (currentChar == '/') {
							break;
						}
					}
				} while (!sourceFile.eof());
			}
			BufferChar(currentChar);
			return DIV_OP;
		} else if (currentChar == '=') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return EQ_OP1;
			}
			currentChar = NextChar();
			return ASSIGN_OP;
		} else if (currentChar == '!') {
			if (sourceFile.peek() == '!') {
				currentChar = NextChar();
				return EQ_OP2;
			} else if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return NE_OP;
			}
		} else if (currentChar == '<') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return LE_OP;
			}
			currentChar = NextChar();
			return LT_OP;
		} else if (currentChar == '>') {
			if (sourceFile.peek() == '=') {
				currentChar = NextChar();
				return GE_OP;
			}
			currentChar = NextChar();
			return GT_OP;
		} else if (currentChar == '-') {
			/* check if it is a comment or a minus symbol */
			if (sourceFile.peek() == '-') { /* comment */
				do { /* skip comment */
					currentChar = NextChar();
				} while (currentChar != '\n');
			} else { /* minus operator */
				BufferChar(currentChar);
				return MINUS_OP;
			}
		} else {
			/* Unrecognized character */
			LexicalError(currentChar, to_string(c)+" Unrecognized character");
		}
	} /* end while */

	return EOF_SYM;
}
<|endoftext|>


<commit_before>#include "major.hpp"
using namespace std;

void Major::copy(const Major &c) {
	name = c.name;
	department = c.department;
	requirements = c.requirements;
	specialRequirements = c.specialRequirements;
}

Major::Major() {
	cout << "Called Major constructor with nothing." << endl;
	name = "None";
	department = Department("NONE");
}

Major::Major(string str) {
	// cout << "Called Major constructor with string '" << str << "'" << endl;
	string s = removeStartingText(str, " ");
	department = Department(str);
	name = department.getFullName();
}

Major::Major(const Major &c) {
	copy(c);
}

Major& Major::operator= (const Major &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

ostream& Major::getData(ostream &os) {
	os << name;
	return os;
}

ostream &operator<<(ostream &os, Major &item) {
	return item.getData(os);
}

void Major::display() {
	cout << *this << endl;
}
<commit_msg>Begin alterations of Major()<commit_after>#include "major.hpp"
using namespace std;

void Major::copy(const Major &c) {
	name = c.name;
	department = c.department;
	requirements = c.requirements;
	specialRequirements = c.specialRequirements;
}

Major::Major() {
	cout << "Called Major constructor with nothing." << endl;
	name = "None";
	department = Department("NONE");
}

Major::Major(string str) {
	// cout << "Called Major constructor with string '" << str << "'" << endl;
	string s = removeStartingText(str, " ");
	department = Department(str);
	name = department.getFullName();

	string contentsOfFile = getFileContents("majors/" + department.getName() + ".txt");
	vector<string> record = split(contentsOfFile, '\n');
	for (vector<string>::iterator i=record.begin(); i != record.end(); ++i) {
//		*i = removeAllQuotes(*i);
//		*i = removeTrailingSlashes(*i);
		cout << *i << endl;
	}

	record.clear();
}

Major::Major(const Major &c) {
	copy(c);
}

Major& Major::operator= (const Major &c) {
	if (this == &c) return *this;
	copy(c);
	return *this;
}

ostream& Major::getData(ostream &os) {
	os << name;
	return os;
}

ostream &operator<<(ostream &os, Major &item) {
	return item.getData(os);
}

void Major::display() {
	cout << *this << endl;
}
<|endoftext|>