<commit_before>/**
 * @file file.cpp
 * @brief Classes for transferring files
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega/file.h"
#include "mega/transfer.h"
#include "mega/transferslot.h"
#include "mega/megaclient.h"
#include "mega/sync.h"
#include "mega/command.h"

namespace mega {
File::File()
{
    transfer = NULL;
    hprivate = true;
    syncxfer = false;
}

File::~File()
{
    // if transfer currently running, stop
    if (transfer)
    {
        transfer->client->stopxfer(this);
    }
}

void File::prepare()
{
    transfer->localfilename = localname;
}

void File::start()
{
}

void File::progress()
{
}

void File::completed(Transfer* t, LocalNode* l)
{
    if (t->type == PUT)
    {
        NewNode* newnode = new NewNode[1];

        // build new node
        newnode->source = NEW_UPLOAD;

        // upload handle required to retrieve/include pending file attributes
        newnode->uploadhandle = t->uploadhandle;

        // reference to uploaded file
        memcpy(newnode->uploadtoken, t->ultoken, sizeof newnode->uploadtoken);

        // file's crypto key
        newnode->nodekey.assign((char*)t->filekey, FILENODEKEYLENGTH);
        newnode->type = FILENODE;
        newnode->parenthandle = UNDEF;
#ifdef ENABLE_SYNC
        if ((newnode->localnode = l))
        {
            l->newnode = newnode;
            newnode->syncid = l->syncid;
        }
#endif
        AttrMap attrs;

        // store filename
        attrs.map['n'] = name;

        // store fingerprint
        t->serializefingerprint(&attrs.map['c']);

        string tattrstring;

        attrs.getjson(&tattrstring);

        newnode->attrstring = new string;
        t->client->makeattr(&t->key, newnode->attrstring, tattrstring.c_str());

        if (targetuser.size())
        {
            // drop file into targetuser's inbox
            t->client->reqtag = t->tag;
            t->client->putnodes(targetuser.c_str(), newnode, 1);
        }
        else
        {
            handle th = h;

            // inaccessible target folder - use / instead
            if (!t->client->nodebyhandle(th))
            {
                th = t->client->rootnodes[0];
            }
#ifdef ENABLE_SYNC
            if (l)
            {
                t->client->syncadding++;
            }
#endif
            t->client->reqs[t->client->r].add(new CommandPutNodes(t->client,
                                                                  th, NULL,
                                                                  newnode, 1,
                                                                  t->tag,
#ifdef ENABLE_SYNC
                                                                  l ? PUTNODES_SYNC : PUTNODES_APP));
#else
                                                                  PUTNODES_APP));
#endif
        }
    }
}

void File::terminated()
{

}

// do not retry crypto errors or administrative takedowns; retry other types of
// failuresup to 16 times
bool File::failed(error e)
{
    return e != API_EKEY && e != API_EBLOCKED && transfer->failcount < 16;
}

void File::displayname(string* dname)
{
    if (name.size())
    {
        *dname = name;
    }
    else
    {
        Node* n;

        if ((n = transfer->client->nodebyhandle(h)))
        {
            *dname = n->displayname();
        }
        else
        {
            *dname = "DELETED/UNAVAILABLE";
        }
    }
}

#ifdef ENABLE_SYNC
SyncFileGet::SyncFileGet(Sync* csync, Node* cn, string* clocalname)
{
    sync = csync;

    n = cn;
    h = n->nodehandle;
    *(FileFingerprint*)this = *n;
    localname = *clocalname;

    syncxfer = true;
    n->syncget = this;
}

SyncFileGet::~SyncFileGet()
{
    n->syncget = NULL;
}

// create sync-specific temp download directory and set unique filename
void SyncFileGet::prepare()
{
    if (!transfer->localfilename.size())
    {
        int i;
        string tmpname, lockname;

        tmpname = "tmp";
        sync->client->fsaccess->name2local(&tmpname);

        if (!sync->tmpfa)
        {
            sync->tmpfa = sync->client->fsaccess->newfileaccess();

            for (i = 3; i--;)
            {
                transfer->localfilename = sync->localdebris;
                sync->client->fsaccess->mkdirlocal(&transfer->localfilename, true);

                transfer->localfilename.append(sync->client->fsaccess->localseparator);
                transfer->localfilename.append(tmpname);
                sync->client->fsaccess->mkdirlocal(&transfer->localfilename);

                // lock it
                transfer->localfilename.append(sync->client->fsaccess->localseparator);
                lockname = "lock";
                sync->client->fsaccess->name2local(&lockname);
                transfer->localfilename.append(lockname);

                if (sync->tmpfa->fopen(&transfer->localfilename, false, true))
                {
                    break;
                }
            }

            // if we failed to create the tmp dir three times in a row, fall
            // back to the sync's root
            if (i < 0)
            {
                delete sync->tmpfa;
                sync->tmpfa = NULL;
            }
        }

        if (sync->tmpfa)
        {
            transfer->localfilename = sync->localdebris;
            transfer->localfilename.append(sync->client->fsaccess->localseparator);
            transfer->localfilename.append(tmpname);
        }
        else
        {
            transfer->localfilename = sync->localroot.localname;
        }

        sync->client->fsaccess->tmpnamelocal(&tmpname);
        transfer->localfilename.append(sync->client->fsaccess->localseparator);
        transfer->localfilename.append(tmpname);
    }

    if (n->parent && n->parent->localnode)
    {
        n->parent->localnode->treestate(TREESTATE_SYNCING);
    }
}

bool SyncFileGet::failed(error e)
{
    if (n->parent && n->parent->localnode)
    {
        n->parent->localnode->treestate(TREESTATE_PENDING);
    }

    return File::failed(e);
}

// update localname (parent's localnode)
void SyncFileGet::updatelocalname()
{
    attr_map::iterator ait;

    if ((ait = n->attrs.map.find('n')) != n->attrs.map.end())
    {
        if (n->parent && n->parent->localnode)
        {
            string tmpname = ait->second;

            sync->client->fsaccess->name2local(&tmpname);
            n->parent->localnode->getlocalpath(&localname);

            localname.append(sync->client->fsaccess->localseparator);
            localname.append(tmpname);
        }
    }
}

// add corresponding LocalNode (by path), then self-destruct
void SyncFileGet::completed(Transfer* t, LocalNode* n)
{
    sync->checkpath(NULL, &localname);
    delete this;
}

void SyncFileGet::terminated()
{
    delete this;
}
#endif
} // namespace
<commit_msg>API_EOVERQUOTA finishes the transfer.<commit_after>/**
 * @file file.cpp
 * @brief Classes for transferring files
 *
 * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega/file.h"
#include "mega/transfer.h"
#include "mega/transferslot.h"
#include "mega/megaclient.h"
#include "mega/sync.h"
#include "mega/command.h"

namespace mega {
File::File()
{
    transfer = NULL;
    hprivate = true;
    syncxfer = false;
}

File::~File()
{
    // if transfer currently running, stop
    if (transfer)
    {
        transfer->client->stopxfer(this);
    }
}

void File::prepare()
{
    transfer->localfilename = localname;
}

void File::start()
{
}

void File::progress()
{
}

void File::completed(Transfer* t, LocalNode* l)
{
    if (t->type == PUT)
    {
        NewNode* newnode = new NewNode[1];

        // build new node
        newnode->source = NEW_UPLOAD;

        // upload handle required to retrieve/include pending file attributes
        newnode->uploadhandle = t->uploadhandle;

        // reference to uploaded file
        memcpy(newnode->uploadtoken, t->ultoken, sizeof newnode->uploadtoken);

        // file's crypto key
        newnode->nodekey.assign((char*)t->filekey, FILENODEKEYLENGTH);
        newnode->type = FILENODE;
        newnode->parenthandle = UNDEF;
#ifdef ENABLE_SYNC
        if ((newnode->localnode = l))
        {
            l->newnode = newnode;
            newnode->syncid = l->syncid;
        }
#endif
        AttrMap attrs;

        // store filename
        attrs.map['n'] = name;

        // store fingerprint
        t->serializefingerprint(&attrs.map['c']);

        string tattrstring;

        attrs.getjson(&tattrstring);

        newnode->attrstring = new string;
        t->client->makeattr(&t->key, newnode->attrstring, tattrstring.c_str());

        if (targetuser.size())
        {
            // drop file into targetuser's inbox
            t->client->reqtag = t->tag;
            t->client->putnodes(targetuser.c_str(), newnode, 1);
        }
        else
        {
            handle th = h;

            // inaccessible target folder - use / instead
            if (!t->client->nodebyhandle(th))
            {
                th = t->client->rootnodes[0];
            }
#ifdef ENABLE_SYNC
            if (l)
            {
                t->client->syncadding++;
            }
#endif
            t->client->reqs[t->client->r].add(new CommandPutNodes(t->client,
                                                                  th, NULL,
                                                                  newnode, 1,
                                                                  t->tag,
#ifdef ENABLE_SYNC
                                                                  l ? PUTNODES_SYNC : PUTNODES_APP));
#else
                                                                  PUTNODES_APP));
#endif
        }
    }
}

void File::terminated()
{

}

// do not retry crypto errors or administrative takedowns; retry other types of
// failuresup to 16 times
bool File::failed(error e)
{
    return e != API_EKEY && e != API_EBLOCKED && e != API_EOVERQUOTA && transfer->failcount < 16;
}

void File::displayname(string* dname)
{
    if (name.size())
    {
        *dname = name;
    }
    else
    {
        Node* n;

        if ((n = transfer->client->nodebyhandle(h)))
        {
            *dname = n->displayname();
        }
        else
        {
            *dname = "DELETED/UNAVAILABLE";
        }
    }
}

#ifdef ENABLE_SYNC
SyncFileGet::SyncFileGet(Sync* csync, Node* cn, string* clocalname)
{
    sync = csync;

    n = cn;
    h = n->nodehandle;
    *(FileFingerprint*)this = *n;
    localname = *clocalname;

    syncxfer = true;
    n->syncget = this;
}

SyncFileGet::~SyncFileGet()
{
    n->syncget = NULL;
}

// create sync-specific temp download directory and set unique filename
void SyncFileGet::prepare()
{
    if (!transfer->localfilename.size())
    {
        int i;
        string tmpname, lockname;

        tmpname = "tmp";
        sync->client->fsaccess->name2local(&tmpname);

        if (!sync->tmpfa)
        {
            sync->tmpfa = sync->client->fsaccess->newfileaccess();

            for (i = 3; i--;)
            {
                transfer->localfilename = sync->localdebris;
                sync->client->fsaccess->mkdirlocal(&transfer->localfilename, true);

                transfer->localfilename.append(sync->client->fsaccess->localseparator);
                transfer->localfilename.append(tmpname);
                sync->client->fsaccess->mkdirlocal(&transfer->localfilename);

                // lock it
                transfer->localfilename.append(sync->client->fsaccess->localseparator);
                lockname = "lock";
                sync->client->fsaccess->name2local(&lockname);
                transfer->localfilename.append(lockname);

                if (sync->tmpfa->fopen(&transfer->localfilename, false, true))
                {
                    break;
                }
            }

            // if we failed to create the tmp dir three times in a row, fall
            // back to the sync's root
            if (i < 0)
            {
                delete sync->tmpfa;
                sync->tmpfa = NULL;
            }
        }

        if (sync->tmpfa)
        {
            transfer->localfilename = sync->localdebris;
            transfer->localfilename.append(sync->client->fsaccess->localseparator);
            transfer->localfilename.append(tmpname);
        }
        else
        {
            transfer->localfilename = sync->localroot.localname;
        }

        sync->client->fsaccess->tmpnamelocal(&tmpname);
        transfer->localfilename.append(sync->client->fsaccess->localseparator);
        transfer->localfilename.append(tmpname);
    }

    if (n->parent && n->parent->localnode)
    {
        n->parent->localnode->treestate(TREESTATE_SYNCING);
    }
}

bool SyncFileGet::failed(error e)
{
    if (n->parent && n->parent->localnode)
    {
        n->parent->localnode->treestate(TREESTATE_PENDING);
    }

    return File::failed(e);
}

// update localname (parent's localnode)
void SyncFileGet::updatelocalname()
{
    attr_map::iterator ait;

    if ((ait = n->attrs.map.find('n')) != n->attrs.map.end())
    {
        if (n->parent && n->parent->localnode)
        {
            string tmpname = ait->second;

            sync->client->fsaccess->name2local(&tmpname);
            n->parent->localnode->getlocalpath(&localname);

            localname.append(sync->client->fsaccess->localseparator);
            localname.append(tmpname);
        }
    }
}

// add corresponding LocalNode (by path), then self-destruct
void SyncFileGet::completed(Transfer* t, LocalNode* n)
{
    sync->checkpath(NULL, &localname);
    delete this;
}

void SyncFileGet::terminated()
{
    delete this;
}
#endif
} // namespace
<|endoftext|>


<commit_before>#include "p3DFFT_to_iR.hpp"
#include "Morton_shuffler.hpp"
#include <iostream>

int myrank, nprocs;

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    int n, N, nfiles;
    if (argc == 4)
    {
        n = atoi(argv[1]);
        N = atoi(argv[2]);
        nfiles = atoi(argv[3]);
    }
    else
    {
        std::cerr <<
            "not enough (or too many) parameters.\naborting." <<
            std::endl;
        MPI_Finalize();
        return EXIT_SUCCESS;
    }
    p3DFFT_to_iR *r = new p3DFFT_to_iR(
            (n/2+1), n, n,
            N, N, N,
            2);

    // initialize file names
    char* ifile[2];
    for (int i=0; i<2; i++)
    {
        ifile[i] = (char*)malloc(100*sizeof(char));
        sprintf(ifile[i], "Kdata%d", i);
    }

    //read
    r->read(ifile);
    for (int i = 0; i<2; i++)
        free(ifile[i]);

    Morton_shuffler *s = new Morton_shuffler(
            N, N, N, 2, nfiles);
    s->shuffle(r->r3, "Rdata");

    delete s;
    delete r;

    // clean up
    fftwf_mpi_cleanup();
    MPI_Finalize();
    return EXIT_SUCCESS;
}

<commit_msg>use 3 fields in full test<commit_after>#include "p3DFFT_to_iR.hpp"
#include "Morton_shuffler.hpp"
#include <iostream>

int myrank, nprocs;

int main(int argc, char *argv[])
{
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    int n, N, nfiles, nfields;
    if (argc == 5)
    {
        n = atoi(argv[1]);
        N = atoi(argv[2]);
        nfiles = atoi(argv[3]);
        nfields = atoi(argv[4]);
    }
    else
    {
        std::cerr <<
            "not enough (or too many) parameters.\naborting." <<
            std::endl;
        MPI_Finalize();
        return EXIT_SUCCESS;
    }
    p3DFFT_to_iR *r = new p3DFFT_to_iR(
            (n/2+1), n, n,
            N, N, N,
            nfields);

    // initialize file names
    char* ifile[nfields];
    for (int i=0; i<nfields; i++)
    {
        ifile[i] = (char*)malloc(100*sizeof(char));
        sprintf(ifile[i], "Kdata%d", i);
    }

    //read
    r->read(ifile);
    for (int i = 0; i<nfields; i++)
        free(ifile[i]);

    Morton_shuffler *s = new Morton_shuffler(
            N, N, N, nfields, nfiles);
    s->shuffle(r->r3, "Rdata");

    delete s;
    delete r;

    // clean up
    fftwf_mpi_cleanup();
    MPI_Finalize();
    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>#ifndef __NODE_GDAL_GLOBAL_H__
#define __NODE_GDAL_GLOBAL_H__

// v8
#include <v8.h>

// node
#include <node.h>

// ogr
#include <ogr_api.h>
#include <ogrsf_frmts.h>

// gdal
#include "gdal_common.hpp"
#include "gdal_driver.hpp"
#include "gdal_dataset.hpp"

using namespace v8;
using namespace node;

namespace node_gdal {

	static Handle<Value> open(const Arguments &args)
	{
		HandleScope scope;

		std::string path;
		std::string mode = "r";
		GDALAccess access = GA_ReadOnly;

		NODE_ARG_STR(0, "path", path);
		NODE_ARG_OPT_STR(1, "update", mode);

		if (mode == "r+") {
			access = GA_Update;
		} else if (mode != "r") {
			return NODE_THROW("Invalid open mode. Must be \"r\" or \"r+\"");
		}

		OGRDataSource *ogr_ds = OGRSFDriverRegistrar::Open(path.c_str(), static_cast<int>(access));
		if(ogr_ds) {
			return scope.Close(Dataset::New(ogr_ds));
		}

		GDALDataset *gdal_ds = (GDALDataset*) GDALOpen(path.c_str(), access);
		if(gdal_ds) {
			return scope.Close(Dataset::New(gdal_ds));
		}

		return NODE_THROW("Error opening dataset");
	}

	static Handle<Value> setConfigOption(const Arguments &args)
	{
		HandleScope scope;

		std::string name;
		std::string val;

		NODE_ARG_STR(0, "name", name);

		if (args.Length() < 2) {
			return NODE_THROW("string or null value must be provided");
		}
		if(args[1]->IsString()){
			val = TOSTR(args[1]);
			CPLSetConfigOption(name.c_str(), val.c_str());
		} else if(args[1]->IsNull() || args[1]->IsUndefined()) {
			CPLSetConfigOption(name.c_str(), NULL);
		} else {
			return NODE_THROW("value must be a string or null");
		}

		return Undefined();
	}

	static Handle<Value> getConfigOption(const Arguments &args)
	{
		HandleScope scope;

		std::string name;
		NODE_ARG_STR(0, "name", name);

		return scope.Close(SafeString::New(CPLGetConfigOption(name.c_str(), NULL)));
	}

	static Handle<Value> decToDMS(const Arguments &args){
		HandleScope scope;

		double angle;
		std::string axis;
		int precision = 2;
		NODE_ARG_DOUBLE(0, "angle", angle);
		NODE_ARG_STR(1, "axis", axis);
		NODE_ARG_INT_OPT(2, "precision", precision);

		if (axis.length() > 0) {
			axis[0] = std::toupper(axis[0]);
		}
		if (axis != "Lat" && axis != "Long") {
			return NODE_THROW("Axis must be 'lat' or 'long'");
		}

		return scope.Close(SafeString::New(GDALDecToDMS(angle, axis.c_str(), precision)));
	}
}

#endif
<commit_msg>toupper, not std::toupper<commit_after>#ifndef __NODE_GDAL_GLOBAL_H__
#define __NODE_GDAL_GLOBAL_H__

// v8
#include <v8.h>

// node
#include <node.h>

// ogr
#include <ogr_api.h>
#include <ogrsf_frmts.h>

// gdal
#include "gdal_common.hpp"
#include "gdal_driver.hpp"
#include "gdal_dataset.hpp"

using namespace v8;
using namespace node;

namespace node_gdal {

	static Handle<Value> open(const Arguments &args)
	{
		HandleScope scope;

		std::string path;
		std::string mode = "r";
		GDALAccess access = GA_ReadOnly;

		NODE_ARG_STR(0, "path", path);
		NODE_ARG_OPT_STR(1, "update", mode);

		if (mode == "r+") {
			access = GA_Update;
		} else if (mode != "r") {
			return NODE_THROW("Invalid open mode. Must be \"r\" or \"r+\"");
		}

		OGRDataSource *ogr_ds = OGRSFDriverRegistrar::Open(path.c_str(), static_cast<int>(access));
		if(ogr_ds) {
			return scope.Close(Dataset::New(ogr_ds));
		}

		GDALDataset *gdal_ds = (GDALDataset*) GDALOpen(path.c_str(), access);
		if(gdal_ds) {
			return scope.Close(Dataset::New(gdal_ds));
		}

		return NODE_THROW("Error opening dataset");
	}

	static Handle<Value> setConfigOption(const Arguments &args)
	{
		HandleScope scope;

		std::string name;
		std::string val;

		NODE_ARG_STR(0, "name", name);

		if (args.Length() < 2) {
			return NODE_THROW("string or null value must be provided");
		}
		if(args[1]->IsString()){
			val = TOSTR(args[1]);
			CPLSetConfigOption(name.c_str(), val.c_str());
		} else if(args[1]->IsNull() || args[1]->IsUndefined()) {
			CPLSetConfigOption(name.c_str(), NULL);
		} else {
			return NODE_THROW("value must be a string or null");
		}

		return Undefined();
	}

	static Handle<Value> getConfigOption(const Arguments &args)
	{
		HandleScope scope;

		std::string name;
		NODE_ARG_STR(0, "name", name);

		return scope.Close(SafeString::New(CPLGetConfigOption(name.c_str(), NULL)));
	}

	static Handle<Value> decToDMS(const Arguments &args){
		HandleScope scope;

		double angle;
		std::string axis;
		int precision = 2;
		NODE_ARG_DOUBLE(0, "angle", angle);
		NODE_ARG_STR(1, "axis", axis);
		NODE_ARG_INT_OPT(2, "precision", precision);

		if (axis.length() > 0) {
			axis[0] = toupper(axis[0]);
		}
		if (axis != "Lat" && axis != "Long") {
			return NODE_THROW("Axis must be 'lat' or 'long'");
		}

		return scope.Close(SafeString::New(GDALDecToDMS(angle, axis.c_str(), precision)));
	}
}

#endif
<|endoftext|>


<commit_before>// Scintilla source code edit control
// @file LexAU3.cxx
// Lexer for AutoIt3  http://www.hiddensoft.com/autoit3
// by Jos van der Zande, jvdzande@yahoo.com
//
// Changes:
//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static inline bool IsTypeCharacter(const int ch)
{
    return ch == '$';
}
static inline bool IsAWordChar(const int ch)
{
    return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '-');
}

static inline bool IsAWordStart(const int ch)
{
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '{' || ch == '+' || ch == '!' || ch == '#' || ch == '^');
}

static void ColouriseAU3Doc(unsigned int startPos,
							int length, int initStyle,
							WordList *keywordlists[],
							Accessor &styler) {

    WordList &keywords = *keywordlists[0];
    WordList &keywords2 = *keywordlists[1];
    WordList &keywords3 = *keywordlists[2];
    WordList &keywords4 = *keywordlists[3];
    styler.StartAt(startPos);

    StyleContext sc(startPos, length, initStyle, styler);
	char si,sk;
	si=0;
	sk=0;
    for (; sc.More(); sc.Forward()) {
		char s[100];
		sc.GetCurrentLowered(s, sizeof(s));
		switch (sc.state)
        {
            case SCE_AU3_COMMENTBLOCK:
            {
                if (sc.ch == '#') {sc.SetState(SCE_AU3_DEFAULT);}
				break;
			}
            case SCE_AU3_COMMENT:
            {
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_OPERATOR:
            {
                sc.SetState(SCE_AU3_DEFAULT);
                break;
            }
            case SCE_AU3_KEYWORD:
            {
                if (!IsAWordChar(sc.ch))
                {
                    if (!IsTypeCharacter(sc.ch))
                    {
						if (strcmp(s, "#cs")==0 || strcmp(s, "#comments_start")==0)
						{
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
							sc.SetState(SCE_AU3_COMMENTBLOCK);
						}
						else if (strcmp(s, "#ce")==0 || strcmp(s, "#comments_end")==0)
						{
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords.InList(s)) {
							sc.ChangeState(SCE_AU3_KEYWORD);
							sc.SetState(SCE_AU3_DEFAULT);
							//sc.SetState(SCE_AU3_KEYWORD);
						}
						else if (keywords2.InList(s)) {
							sc.ChangeState(SCE_AU3_FUNCTION);
							sc.SetState(SCE_AU3_DEFAULT);
							//sc.SetState(SCE_AU3_FUNCTION);
						}
						else if (keywords3.InList(s)) {
							sc.ChangeState(SCE_AU3_MACRO);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (!IsAWordChar(sc.ch)) {
							sc.ChangeState(SCE_AU3_DEFAULT);
							sc.SetState(SCE_AU3_DEFAULT);
						}
					}
				}
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_NUMBER:
            {
                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_VARIABLE:
            {
                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_STRING:
            {
				sk = 0;
				// check for " in and single qouted string
	            if (si == 1){
					if (sc.ch == '\"'){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				// check for ' in and double qouted string
                if (si == 2){
					if (sc.ch == '\''){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
				// find Sendkeys in an STRING
				if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '#' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				break;
            }

            case SCE_AU3_SENT:
            {
				// Sent key string ended
				if (sk == 1)
				{
					// set color to SENTKEY when valid sentkey .. else set to comment to show its wrong
					if (keywords4.InList(s))
					{
						sc.ChangeState(SCE_AU3_SENT);
					}
					else
					{
						sc.ChangeState(SCE_AU3_STRING);
					}
					sc.SetState(SCE_AU3_STRING);
					sk=0;
				}
				// check if next portion is again a sentkey
				if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
				if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '#' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				// check to see if the string ended...
				// check for " in and single qouted string
	            if (si == 1){
					if (sc.ch == '\"'){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				// check for ' in and double qouted string
                if (si == 2){
					if (sc.ch == '\''){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				break;
            }
        }  //switch (sc.state)

        // Determine if a new state should be entered:
        if (sc.state == SCE_AU3_SENT)
        {
			if (sc.ch == '}' && sc.chNext != '}')
			{
				sk = 1;
			}
		}
		if (sc.state == SCE_AU3_DEFAULT)
        {
            if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
            else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '\"') {
				sc.SetState(SCE_AU3_STRING);
				si = 1;	}
            else if (sc.ch == '\'') {
				sc.SetState(SCE_AU3_STRING);
				si = 2;	}
            else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_AU3_NUMBER);}
            //else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
            else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {sc.SetState(SCE_AU3_OPERATOR);}
			else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
        }
    }      //for (; sc.More(); sc.Forward())
    sc.Complete();
}

//

static const char * const AU3WordLists[] = {
    "#autoit keywords",
    "#autoit functions",
    "#autoit macros",
    "#autoit Sent keys",
    0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", NULL , AU3WordLists);
<commit_msg>Folder added by Jos.<commit_after>// Scintilla source code edit control
// @file LexAU3.cxx
// Lexer for AutoIt3  http://www.hiddensoft.com/autoit3
// by Jos van der Zande, jvdzande@yahoo.com
//
// Changes:
//
// Copyright for Scintilla: 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
// Scintilla source code edit control

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static bool IsAU3Comment(Accessor &styler, int pos, int len) {
	return len>0 && styler[pos]==';';
}

static inline bool IsTypeCharacter(const int ch)
{
    return ch == '$';
}
static inline bool IsAWordChar(const int ch)
{
    return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '-');
}

static inline bool IsAWordStart(const int ch)
{
    return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '@' || ch == '#' || ch == '{' || ch == '+' || ch == '!' || ch == '#' || ch == '^');
}

static void ColouriseAU3Doc(unsigned int startPos,
							int length, int initStyle,
							WordList *keywordlists[],
							Accessor &styler) {

    WordList &keywords = *keywordlists[0];
    WordList &keywords2 = *keywordlists[1];
    WordList &keywords3 = *keywordlists[2];
    WordList &keywords4 = *keywordlists[3];
    styler.StartAt(startPos);

    StyleContext sc(startPos, length, initStyle, styler);
	char si,sk;
	si=0;
	sk=0;
    for (; sc.More(); sc.Forward()) {
		char s[100];
		sc.GetCurrentLowered(s, sizeof(s));
		switch (sc.state)
        {
            case SCE_AU3_COMMENTBLOCK:
            {
                if (sc.ch == '#') {sc.SetState(SCE_AU3_DEFAULT);}
				break;
			}
            case SCE_AU3_COMMENT:
            {
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_OPERATOR:
            {
                sc.SetState(SCE_AU3_DEFAULT);
                break;
            }
            case SCE_AU3_KEYWORD:
            {
                if (!IsAWordChar(sc.ch))
                {
                    if (!IsTypeCharacter(sc.ch))
                    {
						if (strcmp(s, "#cs")==0 || strcmp(s, "#comments_start")==0)
						{
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
							sc.SetState(SCE_AU3_COMMENTBLOCK);
						}
						else if (strcmp(s, "#ce")==0 || strcmp(s, "#comments_end")==0)
						{
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords.InList(s)) {
							sc.ChangeState(SCE_AU3_KEYWORD);
							sc.SetState(SCE_AU3_DEFAULT);
							//sc.SetState(SCE_AU3_KEYWORD);
						}
						else if (keywords2.InList(s)) {
							sc.ChangeState(SCE_AU3_FUNCTION);
							sc.SetState(SCE_AU3_DEFAULT);
							//sc.SetState(SCE_AU3_FUNCTION);
						}
						else if (keywords3.InList(s)) {
							sc.ChangeState(SCE_AU3_MACRO);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (!IsAWordChar(sc.ch)) {
							sc.ChangeState(SCE_AU3_DEFAULT);
							sc.SetState(SCE_AU3_DEFAULT);
						}
					}
				}
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_NUMBER:
            {
                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_VARIABLE:
            {
                if (!IsAWordChar(sc.ch)) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_STRING:
            {
				sk = 0;
				// check for " in and single qouted string
	            if (si == 1){
					if (sc.ch == '\"'){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				// check for ' in and double qouted string
                if (si == 2){
					if (sc.ch == '\''){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
				// find Sendkeys in an STRING
				if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '#' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				break;
            }

            case SCE_AU3_SENT:
            {
				// Sent key string ended
				if (sk == 1)
				{
					// set color to SENTKEY when valid sentkey .. else set to comment to show its wrong
					if (keywords4.InList(s))
					{
						sc.ChangeState(SCE_AU3_SENT);
					}
					else
					{
						sc.ChangeState(SCE_AU3_STRING);
					}
					sc.SetState(SCE_AU3_STRING);
					sk=0;
				}
				// check if next portion is again a sentkey
				if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
				if (sc.ch == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '+' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '!' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '^' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				if (sc.ch == '#' && sc.chNext == '{') {sc.SetState(SCE_AU3_SENT);}
				// check to see if the string ended...
				// check for " in and single qouted string
	            if (si == 1){
					if (sc.ch == '\"'){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				// check for ' in and double qouted string
                if (si == 2){
					if (sc.ch == '\''){sc.ForwardSetState(SCE_AU3_DEFAULT);}}
				break;
            }
        }  //switch (sc.state)

        // Determine if a new state should be entered:
        if (sc.state == SCE_AU3_SENT)
        {
			if (sc.ch == '}' && sc.chNext != '}')
			{
				sk = 1;
			}
		}
		if (sc.state == SCE_AU3_DEFAULT)
        {
            if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
            else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '\"') {
				sc.SetState(SCE_AU3_STRING);
				si = 1;	}
            else if (sc.ch == '\'') {
				sc.SetState(SCE_AU3_STRING);
				si = 2;	}
            else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {sc.SetState(SCE_AU3_NUMBER);}
            //else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
            else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {sc.SetState(SCE_AU3_OPERATOR);}
			else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
        }
    }      //for (; sc.More(); sc.Forward())
    sc.Complete();
}

//
//
static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
		int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its fold status
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent);
		}
	}
	int spaceFlags = 0;
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsAU3Comment);
	char chNext = styler[startPos];
	for (int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			int lev = indentCurrent;
			int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsAU3Comment);
			if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
				// Only non whitespace lines can be headers
				if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
					lev |= SC_FOLDLEVELHEADERFLAG;
				} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
					// Line after is blank so check the next - maybe should continue further?
					int spaceFlags2 = 0;
					int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsAU3Comment);
					if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
						lev |= SC_FOLDLEVELHEADERFLAG;
					}
				}
			}
			indentCurrent = indentNext;
			styler.SetLevel(lineCurrent, lev);
			lineCurrent++;
		}
	}

}

//

static const char * const AU3WordLists[] = {
    "#autoit keywords",
    "#autoit functions",
    "#autoit macros",
    "#autoit Sent keys",
    0
};
LexerModule lmAU3(SCLEX_AU3, ColouriseAU3Doc, "au3", FoldAU3Doc , AU3WordLists);
<|endoftext|>


<commit_before>#include "common.th"
#include "errno.th"

#define RANK_0_LOG 4
#define RANK_0_SIZE (1 << RANK_0_LOG)
#define RANKS 3

// NOTE there are some assumptions in the below code that NPER * BPER = 32,
// notably in DIFF()
#define NPERBITS 4
#define BPERBITS 1

#define NPER (1 << NPERBITS)
#define BPER (1 << BPERBITS)

#define TN rel(nodes)

// TODO size `nodes' appropriately
nodes:
    .word 0

// TODO initialise counts appropriately
counts:
    .word 0, 0, 1

// Type `SZ' is a word-wide unsigned integer (some places used as a boolean).
// Type `NP' is a word-wide struct, where the word is split into a 28-bit word
// pointer and a 4-bit index into the word pointed to. The word pointer must
// have bit 27-31 the same (i.e. we must be able to sign-extend the 28-pointer
// to get the original 32-bit pointer).

// NODE gets SZ index in C, returns NP node in B, clobbers C
#define NODE(B,C)               \
    B   <- C << BPERBITS      ; \
    B   <- B + TN             ; \
    C   <- C & (BPER - 1)     ; \
    B   <- B | C              ; \
    //

// IRANK gets SZ rank in C, returns SZ inverted-rank in B
#define IRANK(B,C)              \
    B   <- - C + (RANKS - 1)  ; \
    //

// DIFF gets NP a in C, NP b in D, returns SZ distance in B
#define DIFF(B,C,D)             \
    B   <- C - D              ; \
    //

// INDEX gets NP n in C, returns SZ distance from TN in B
#define INDEX(B,C)              \
    B   <- TN                 ; \
    B   <- B << BPERBITS      ; \
    DIFF(B,C,B)               ; \
    //

// LLINK gets NP n in C, returns NP left-child in B, clobbers C
#define LLINK(B,C)              \
    INDEX(B,C)                ; \
    C   <- B << 1             ; \
    C   <- C +  1             ; \
    NODE(B,C)                 ; \
    //

// RLINK gets NP n in C, returns NP right-child in B, clobbers C
#define RLINK(B,C)              \
    INDEX(B,C)                ; \
    C   <- B << 1             ; \
    C   <- C +  2             ; \
    NODE(B,C)                 ; \
    //

// ISLEFT gets NP n in C, returns SZ leftness in B
#define ISLEFT(B,C)             \
    INDEX(B,C)                ; \
    B   <- B & 1              ; \
    B   <- B == 1             ; \
    //

// ISRIGHT gets NP n in C, returns SZ rightness in B
#define ISRIGHT(B,C)            \
    INDEX(B,C)                ; \
    B   <- B & 1              ; \
    B   <- B == 0             ; \
    //

// PARENT gets NP n in C, returns NP parent in B, clobbers C
#define PARENT(B,C)             \
    INDEX(B,C)                ; \
    C   <- B -  1             ; \
    C   <- C >> 1             ; \
    NODE(B,C)                 ; \
    //

// TODO check SIBLING logic, not very certain of it
// SIBLING gets NP n in C, returns NP sibling in B, clobbers C
#define SIBLING(B,C)            \
    INDEX(B,C)                ; \
    ISLEFT(C,B)               ; \
    B   <- B - C              ; \
    C   <- ~ C                ; \
    B   <- B + C              ; \
    //

// TODO NODE2RANK
// TODO SIZE2RANK
#define SIZE2RANK(B,C) \
    //

// RANK2WORDS gets SZ rank in C, returns SZ word-count in B, clobbers C
#define RANK2WORDS(B,C)         \
    C   <- C + RANK_0_LOG     ; \
    B   <- 1                  ; \
    B   <- B << C             ; \
    //

// GET_COUNT gets SZ rank in C, returns SZ free-count in B
#define GET_COUNT(B,C)          \
    B   <- [C + rel(counts)]  ; \
    //

// SET_COUNT gets SZ rank in C, SZ free-count in D, returns nothing
#define SET_COUNT(C,D)          \
    D   -> [C + rel(counts)]  ; \
    //

// GET_NODE gets NP n in C, returns SZ shifted-word in B, clobbers C
#define GET_NODE(B,C)           \
    B   <- C >> BPERBITS      ; \
    C   <- C & (BPER - 1)     ; \
    B   <- [B]                ; \
    B   <- B >> C             ; \
    //

// GET_LEAF gets NP n in C, returns SZ leafiness in B, clobbers C
#define GET_LEAF(B,C)           \
    GET_NODE(B,C)             ; \
    B   <- B &  1             ; \
    B   <- B == 0             ; \
    //

// GET_FULL gets NP n in C, returns SZ fullness in B, clobbers C
#define GET_FULL(B,C)           \
    GET_NODE(B,C)             ; \
    B   <- B &  2             ; \
    B   <- B == 2             ; \
    //

// GET_VALID gets NP n in C, returns SZ validity in B
#define GET_VALID(B,C,T0)       \
    T0  <- C                  ; \
    INDEX(B,C)                ; \
    PARENT(C,T0)              ; \
    GET_LEAF(T0,C)            ; \
    B   <- B &~ T0            ; \
    //

// TODO SET_LEAF
// TODO SET_FULL
#define SET_FULL(C,D) \
    //
// TODO NODE2ADDR
// TODO ADDR2NODE
ADDR2NODE:
    // TODO
    ret

.global buddy_malloc
buddy_malloc:
    goto(buddy_alloc)

.global buddy_calloc
buddy_calloc:
    C   <- C * D
    push(C)
    call(buddy_alloc)
    C   <- B
    D   <- 0
    pop(E)
    call(memset)
    ret

.global buddy_free
buddy_free:
    // TODO
    ret

.global buddy_realloc
buddy_realloc:
    // TODO
    ret

// -----------------------------------------------------------------------------

buddy_splitnode:
    // TODO
    ret

buddy_autosplit:
    // TODO
    ret

// TODO check for clobbering
// buddy_alloc gets SZ size in C, returns address or 0 in B
buddy_alloc:
    pushall(D,E,F,G)
    SIZE2RANK(B,C)
    D   <- B < RANKS
    jzrel(D,L_buddy_alloc_error)
    D   <- B
    GET_COUNT(E,D)
    D   <- E == 0
    jnzrel(D,L_buddy_alloc_do_split)
    // here is the main body, where we have a nonzero count of the needed
    // rank. B is rank, D is scratch, E is scratch and currently count
    D   <- B
    IRANK(E,D)
    F   <- 1
    F   <- F << E       // F is loop bound
    D   <- F - 1        // D is first index to check
    F   <- F + D        // F is loop bound adjust for `first'
L_buddy_alloc_loop_top:
    NODE(E,D)           // E is NODE(D)
    GET_VALID(C,E,G)    // C is validity
    jzrel(C,L_buddy_alloc_loop_bottom)
    GET_LEAF(C,E)       // C is leafiness
    jzrel(C,L_buddy_alloc_loop_bottom)
    GET_FULL(C,E)       // C is fullness
    jnzrel(C,L_buddy_alloc_loop_bottom)
    SET_FULL(E,-1)
    GET_COUNT(C,B)
    C   <- C - 1
    SET_COUNT(E,C)
    C   <- E
    call(ADDR2NODE)
    goto(L_buddy_alloc_done)

L_buddy_alloc_loop_bottom:
    D   <- D + 1    // D is loop index
    goto(L_buddy_alloc_loop_top)

L_buddy_alloc_do_split:
    D   <- E
    call(buddy_autosplit)
    goto(L_buddy_alloc_done)

L_buddy_alloc_error:
    D   <- ENOMEM
    D   -> errno
    B   <- 0
L_buddy_alloc_done:
    popall(D,E,F,G)
    ret

<commit_msg>Add some macro implementations<commit_after>#include "common.th"
#include "errno.th"

#define RANK_0_LOG 4
#define RANK_0_SIZE (1 << RANK_0_LOG)
#define RANKS 3

// NOTE there are some assumptions in the below code that NPER * BPER = 32,
// notably in DIFF()
#define NPERBITS 4
#define BPERBITS 1

#define NPER (1 << NPERBITS)
#define BPER (1 << BPERBITS)

#define TN rel(nodes)

// TODO size `nodes' appropriately
// TODO implement .lcomm and use it for this
nodes:
    .word 0

// TODO initialise counts appropriately
counts:
    .word 0, 0, 1

// Type `SZ' is a word-wide unsigned integer (some places used as a boolean).
// Type `NP' is a word-wide struct, where the word is split into a 28-bit word
// index into `nodes` and a 4-bit index into the word indexed.

ilog2:
    B   <- 0
    push(D)
L_ilog2_top:
    C   <- C >> 1
    D   <- C == 0
    jnzrel(D, L_ilog2_done)
    B   <- B + 1
    goto(L_ilog2_top)
L_ilog2_done:
    pop(D)
    ret

// NODE gets SZ index in C, returns NP node in B, clobbers C
#define NODE(B,C)               \
    B   <- C << BPERBITS      ; \
    B   <- B + TN             ; \
    C   <- C & (BPER - 1)     ; \
    B   <- B | C              ; \
    //

// IRANK gets SZ rank in C, returns SZ inverted-rank in B
#define IRANK(B,C)              \
    B   <- - C + (RANKS - 1)  ; \
    //

// DIFF gets NP a in C, NP b in D, returns SZ distance in B
#define DIFF(B,C,D)             \
    B   <- C - D              ; \
    //

// INDEX gets NP n in C, returns SZ distance from TN in B
#define INDEX(B,C)              \
    DIFF(B,C,0)               ; \
    //

// LLINK gets NP n in C, returns NP left-child in B, clobbers C
#define LLINK(B,C)              \
    INDEX(B,C)                ; \
    C   <- B << 1             ; \
    C   <- C +  1             ; \
    NODE(B,C)                 ; \
    //

// RLINK gets NP n in C, returns NP right-child in B, clobbers C
#define RLINK(B,C)              \
    INDEX(B,C)                ; \
    C   <- B << 1             ; \
    C   <- C +  2             ; \
    NODE(B,C)                 ; \
    //

// ISLEFT gets NP n in C, returns SZ leftness in B
#define ISLEFT(B,C)             \
    INDEX(B,C)                ; \
    B   <- B & 1              ; \
    B   <- B == 1             ; \
    //

// ISRIGHT gets NP n in C, returns SZ rightness in B
#define ISRIGHT(B,C)            \
    INDEX(B,C)                ; \
    B   <- B & 1              ; \
    B   <- B == 0             ; \
    //

// PARENT gets NP n in C, returns NP parent in B, clobbers C
#define PARENT(B,C)             \
    INDEX(B,C)                ; \
    C   <- B -  1             ; \
    C   <- C >> 1             ; \
    NODE(B,C)                 ; \
    //

// SIBLING gets NP n in C, returns NP sibling in B, clobbers C
#define SIBLING(B,C)            \
    INDEX(B,C)                ; \
    ISLEFT(C,B)               ; \
    B   <- B - C              ; \
    C   <- ~ C                ; \
    B   <- B + C              ; \
    //

// NODE2RANK gets NP n in C, returns SZ rank in B
#define NODE2RANK(B,C)          \
    call(NODE2RANK_func)      ; \
    //

NODE2RANK_func:
    push(D)
    D   <- 0
L_NODE2RANK_top:
    INDEX(B,C)
    B   <- B == 0
    jnzrel(B, L_NODE2RANK_done)
    D   <- D + 1
    B   <- C
    PARENT(C,B)
    goto(L_NODE2RANK_top)
L_NODE2RANK_done:
    B   <- - D + (RANKS - 1)
    pop(D)
    ret

#define SIZE2RANK(B,C) \
    call(SIZE2RANK_func)
    //

SIZE2RANK_func:
    B   <- C <> 0
    jzrel(B, L_SIZE2RANK_zero)
    C   <- C - 1
    C   <- C >> RANK_0_LOG
    call(ilog2)
    B   <- B + 1
L_SIZE2RANK_zero:
    ret

// RANK2WORDS gets SZ rank in C, returns SZ word-count in B, clobbers C
#define RANK2WORDS(B,C)         \
    C   <- C + RANK_0_LOG     ; \
    B   <- 1                  ; \
    B   <- B << C             ; \
    //

// GET_COUNT gets SZ rank in C, returns SZ free-count in B
#define GET_COUNT(B,C)          \
    B   <- [C + rel(counts)]  ; \
    //

// SET_COUNT gets SZ rank in C, SZ free-count in D, returns nothing
#define SET_COUNT(C,D)          \
    D   -> [C + rel(counts)]  ; \
    //

// GET_NODE gets NP n in C, returns SZ shifted-word in B, clobbers C
#define GET_NODE(B,C)           \
    B   <- C >> BPERBITS      ; \
    C   <- C & (BPER - 1)     ; \
    B   <- [B]                ; \
    B   <- B >> C             ; \
    //

// GET_LEAF gets NP n in C, returns SZ leafiness in B, clobbers C
#define GET_LEAF(B,C)           \
    GET_NODE(B,C)             ; \
    B   <- B &  1             ; \
    B   <- B == 0             ; \
    //

// GET_FULL gets NP n in C, returns SZ fullness in B, clobbers C
#define GET_FULL(B,C)           \
    GET_NODE(B,C)             ; \
    B   <- B &  2             ; \
    B   <- B == 2             ; \
    //

// GET_VALID gets NP n in C, returns SZ validity in B
#define GET_VALID(B,C,T0)       \
    T0  <- C                  ; \
    INDEX(B,C)                ; \
    PARENT(C,T0)              ; \
    GET_LEAF(T0,C)            ; \
    B   <- B &~ T0            ; \
    //

// TODO SET_LEAF
// TODO SET_FULL
#define SET_FULL(C,D) \
    //
// TODO NODE2ADDR
// TODO ADDR2NODE
ADDR2NODE:
    // TODO
    ret

.global buddy_malloc
buddy_malloc:
    goto(buddy_alloc)

.global buddy_calloc
buddy_calloc:
    C   <- C * D
    push(C)
    call(buddy_alloc)
    C   <- B
    D   <- 0
    pop(E)
    call(memset)
    ret

.global buddy_free
buddy_free:
    // TODO
    ret

.global buddy_realloc
buddy_realloc:
    // TODO
    ret

// -----------------------------------------------------------------------------

buddy_splitnode:
    // TODO
    ret

buddy_autosplit:
    // TODO
    ret

// TODO check for clobbering
// buddy_alloc gets SZ size in C, returns address or 0 in B
buddy_alloc:
    pushall(D,E,F,G)
    SIZE2RANK(B,C)
    D   <- B < RANKS
    jzrel(D,L_buddy_alloc_error)
    D   <- B
    GET_COUNT(E,D)
    D   <- E == 0
    jnzrel(D,L_buddy_alloc_do_split)
    // here is the main body, where we have a nonzero count of the needed
    // rank. B is rank, D is scratch, E is scratch and currently count
    D   <- B
    IRANK(E,D)
    F   <- 1
    F   <- F << E       // F is loop bound
    D   <- F - 1        // D is first index to check
    F   <- F + D        // F is loop bound adjust for `first'
L_buddy_alloc_loop_top:
    NODE(E,D)           // E is NODE(D)
    GET_VALID(C,E,G)    // C is validity
    jzrel(C,L_buddy_alloc_loop_bottom)
    GET_LEAF(C,E)       // C is leafiness
    jzrel(C,L_buddy_alloc_loop_bottom)
    GET_FULL(C,E)       // C is fullness
    jnzrel(C,L_buddy_alloc_loop_bottom)
    SET_FULL(E,-1)
    GET_COUNT(C,B)
    C   <- C - 1
    SET_COUNT(E,C)
    C   <- E
    call(ADDR2NODE)
    goto(L_buddy_alloc_done)

L_buddy_alloc_loop_bottom:
    D   <- D + 1    // D is loop index
    goto(L_buddy_alloc_loop_top)

L_buddy_alloc_do_split:
    D   <- E
    call(buddy_autosplit)
    goto(L_buddy_alloc_done)

L_buddy_alloc_error:
    D   <- ENOMEM
    D   -> errno
    B   <- 0
L_buddy_alloc_done:
    popall(D,E,F,G)
    ret

<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file LexGAP.cxx
 ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
 ** http://www.gap-system.org
 **/
// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static inline bool IsGAPOperator(char ch) {
	if (isalnum(ch)) return false;
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
		ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
		ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
		ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
		ch == '{' || ch == '}' || ch == ':' )
		return true;
	return false;
}

static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) {
	unsigned int i = 0;
	while ((i < end - start + 1) && (i < len-1)) {
		s[i] = static_cast<char>(styler[start + i]);
		i++;
	}
	s[i] = '\0';
}

static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords1 = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];
	WordList &keywords4 = *keywordlists[3];

	// Do not leak onto next line
	if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// Prevent SCE_GAP_STRINGEOL from leaking back to previous line
		if ( sc.atLineStart ) {
			if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
			if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
		}

		// Handle line continuation generically
		if (sc.ch == '\\' ) {
			if (sc.chNext == '\n' || sc.chNext == '\r') {
				sc.Forward();
				if (sc.ch == '\r' && sc.chNext == '\n') {
					sc.Forward();
				}
				continue;
			}
		}

		// Determine if the current state should terminate
		switch (sc.state) {
			case SCE_GAP_OPERATOR :
				sc.SetState(SCE_GAP_DEFAULT);
				break;

			case SCE_GAP_NUMBER :
				if (!IsADigit(sc.ch)) {
					if (sc.ch == '\\') {
						if (!sc.atLineEnd) {
							if (!IsADigit(sc.chNext)) {
								sc.Forward();
								sc.ChangeState(SCE_GAP_IDENTIFIER);
							}
						}
					} else if (isalpha(sc.ch) || sc.ch == '_') {
						sc.ChangeState(SCE_GAP_IDENTIFIER);
					}
					else sc.SetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_IDENTIFIER :
				if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
					if (sc.ch == '\\') sc.Forward();
					else {
						char s[1000];
						sc.GetCurrent(s, sizeof(s));
						if (keywords1.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD);
						} else if (keywords2.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD2);
						} else if (keywords3.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD3);
						} else if (keywords4.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD4);
						}
						sc.SetState(SCE_GAP_DEFAULT);
					}
				}
				break;

			case SCE_GAP_COMMENT :
				if (sc.atLineEnd) {
					sc.SetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_STRING:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_GAP_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\"') {
						sc.Forward();
					}
				} else if (sc.ch == '\"') {
					sc.ForwardSetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_CHAR:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_GAP_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\'') {
						sc.Forward();
					}
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_STRINGEOL:
				if (sc.atLineStart) {
					sc.SetState(SCE_GAP_DEFAULT);
				}
				break;
		}

		// Determine if a new state should be entered
		if (sc.state == SCE_GAP_DEFAULT) {
			if (IsGAPOperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_GAP_OPERATOR);
			}
			else if (IsADigit(sc.ch)) {
				sc.SetState(SCE_GAP_NUMBER);
			} else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
				sc.SetState(SCE_GAP_IDENTIFIER);
				if (sc.ch == '\\') sc.Forward();
			} else if (sc.ch == '#') {
				sc.SetState(SCE_GAP_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_GAP_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_GAP_CHAR);
			}
		}

	}
	sc.Complete();
}

static int ClassifyFoldPointGAP(const char* s) {
	int level = 0;
	if (strcmp(s, "function") == 0 ||
		strcmp(s, "do") == 0 ||
		strcmp(s, "if") == 0 ||
		strcmp(s, "repeat") == 0 ) {
		level = 1;
	} else if (strcmp(s, "end") == 0 ||
			strcmp(s, "od") == 0 ||
			strcmp(s, "fi") == 0 ||
			strcmp(s, "until") == 0 ) {
		level = -1;
	}
	return level;
}

static void FoldGAPDoc( unsigned int startPos, int length, int initStyle,   WordList** , Accessor &styler) {
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;

	int lastStart = 0;

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

		if (stylePrev == SCE_GAP_DEFAULT && style == SCE_GAP_KEYWORD) {
			// Store last word start point.
			lastStart = i;
		}

		if (stylePrev == SCE_GAP_KEYWORD) {
			if(iswordchar(ch) && !iswordchar(chNext)) {
				char s[100];
				GetRange(lastStart, i, styler, s, sizeof(s));
				levelCurrent += ClassifyFoldPointGAP(s);
			}
		}

		if (atEOL) {
			int lev = levelPrev;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}

		if (!isspacechar(ch))
			visibleChars++;
	}

	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const GAPWordListDesc[] = {
	"Keywords 1",
	"Keywords 2",
	"Keywords 3 (unused)",
	"Keywords 4 (unused)",
	0
};

LexerModule lmGAP(
   SCLEX_GAP,
   ColouriseGAPDoc,
   "gap",
   FoldGAPDoc,
   GAPWordListDesc);
<commit_msg>Bug 1704800 fixed dealing with strings and chars like "something\\".<commit_after>// Scintilla source code edit control
/** @file LexGAP.cxx
 ** Lexer for the GAP language. (The GAP System for Computational Discrete Algebra)
 ** http://www.gap-system.org
 **/
// Copyright 2007 by Istvan Szollosi ( szteven <at> gmail <dot> com )
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static inline bool IsGAPOperator(char ch) {
	if (isalnum(ch)) return false;
	if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
		ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
		ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
		ch == ')' || ch == ';' || ch == '[' || ch == ']' ||
		ch == '{' || ch == '}' || ch == ':' )
		return true;
	return false;
}

static void GetRange(unsigned int start, unsigned int end, Accessor &styler, char *s, unsigned int len) {
	unsigned int i = 0;
	while ((i < end - start + 1) && (i < len-1)) {
		s[i] = static_cast<char>(styler[start + i]);
		i++;
	}
	s[i] = '\0';
}

static void ColouriseGAPDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) {

	WordList &keywords1 = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];
	WordList &keywords4 = *keywordlists[3];

	// Do not leak onto next line
	if (initStyle == SCE_GAP_STRINGEOL) initStyle = SCE_GAP_DEFAULT;

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// Prevent SCE_GAP_STRINGEOL from leaking back to previous line
		if ( sc.atLineStart ) {
			if (sc.state == SCE_GAP_STRING) sc.SetState(SCE_GAP_STRING);
			if (sc.state == SCE_GAP_CHAR) sc.SetState(SCE_GAP_CHAR);
		}

		// Handle line continuation generically
		if (sc.ch == '\\' ) {
			if (sc.chNext == '\n' || sc.chNext == '\r') {
				sc.Forward();
				if (sc.ch == '\r' && sc.chNext == '\n') {
					sc.Forward();
				}
				continue;
			}
		}

		// Determine if the current state should terminate
		switch (sc.state) {
			case SCE_GAP_OPERATOR :
				sc.SetState(SCE_GAP_DEFAULT);
				break;

			case SCE_GAP_NUMBER :
				if (!IsADigit(sc.ch)) {
					if (sc.ch == '\\') {
						if (!sc.atLineEnd) {
							if (!IsADigit(sc.chNext)) {
								sc.Forward();
								sc.ChangeState(SCE_GAP_IDENTIFIER);
							}
						}
					} else if (isalpha(sc.ch) || sc.ch == '_') {
						sc.ChangeState(SCE_GAP_IDENTIFIER);
					}
					else sc.SetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_IDENTIFIER :
				if (!(iswordstart(static_cast<char>(sc.ch)) || sc.ch == '$')) {
					if (sc.ch == '\\') sc.Forward();
					else {
						char s[1000];
						sc.GetCurrent(s, sizeof(s));
						if (keywords1.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD);
						} else if (keywords2.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD2);
						} else if (keywords3.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD3);
						} else if (keywords4.InList(s)) {
							sc.ChangeState(SCE_GAP_KEYWORD4);
						}
						sc.SetState(SCE_GAP_DEFAULT);
					}
				}
				break;

			case SCE_GAP_COMMENT :
				if (sc.atLineEnd) {
					sc.SetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_STRING:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_GAP_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
						sc.Forward();
					}
				} else if (sc.ch == '\"') {
					sc.ForwardSetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_CHAR:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_GAP_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
						sc.Forward();
					}
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_GAP_DEFAULT);
				}
				break;

			case SCE_GAP_STRINGEOL:
				if (sc.atLineStart) {
					sc.SetState(SCE_GAP_DEFAULT);
				}
				break;
		}

		// Determine if a new state should be entered
		if (sc.state == SCE_GAP_DEFAULT) {
			if (IsGAPOperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_GAP_OPERATOR);
			}
			else if (IsADigit(sc.ch)) {
				sc.SetState(SCE_GAP_NUMBER);
			} else if (isalpha(sc.ch) || sc.ch == '_' || sc.ch == '\\' || sc.ch == '$' || sc.ch == '~') {
				sc.SetState(SCE_GAP_IDENTIFIER);
				if (sc.ch == '\\') sc.Forward();
			} else if (sc.ch == '#') {
				sc.SetState(SCE_GAP_COMMENT);
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_GAP_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_GAP_CHAR);
			}
		}

	}
	sc.Complete();
}

static int ClassifyFoldPointGAP(const char* s) {
	int level = 0;
	if (strcmp(s, "function") == 0 ||
		strcmp(s, "do") == 0 ||
		strcmp(s, "if") == 0 ||
		strcmp(s, "repeat") == 0 ) {
		level = 1;
	} else if (strcmp(s, "end") == 0 ||
			strcmp(s, "od") == 0 ||
			strcmp(s, "fi") == 0 ||
			strcmp(s, "until") == 0 ) {
		level = -1;
	}
	return level;
}

static void FoldGAPDoc( unsigned int startPos, int length, int initStyle,   WordList** , Accessor &styler) {
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;

	int lastStart = 0;

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

		if (stylePrev == SCE_GAP_DEFAULT && style == SCE_GAP_KEYWORD) {
			// Store last word start point.
			lastStart = i;
		}

		if (stylePrev == SCE_GAP_KEYWORD) {
			if(iswordchar(ch) && !iswordchar(chNext)) {
				char s[100];
				GetRange(lastStart, i, styler, s, sizeof(s));
				levelCurrent += ClassifyFoldPointGAP(s);
			}
		}

		if (atEOL) {
			int lev = levelPrev;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}

		if (!isspacechar(ch))
			visibleChars++;
	}

	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}

static const char * const GAPWordListDesc[] = {
	"Keywords 1",
	"Keywords 2",
	"Keywords 3 (unused)",
	"Keywords 4 (unused)",
	0
};

LexerModule lmGAP(
   SCLEX_GAP,
   ColouriseGAPDoc,
   "gap",
   FoldGAPDoc,
   GAPWordListDesc);
<|endoftext|>


<commit_before>#pragma once

#include <string>
#include <cryptopp/sha3.h>

#include "Arguments.hpp"

namespace Ethereum{namespace ABI{

class Method
{
    public:
        static std::string Encode(const std::string &method);
        static std::string Encode(const char *method);
        static std::string Encode(const char *method, size_t size);
        static std::string Encode(const char *method, const Arguments &args);
        static std::string Encode(const std::string &method, const Arguments &args);
        static std::string Encode(const char *method, size_t size, const Arguments &args);
};

}}
<commit_msg>prefer local cryptopp<commit_after>#pragma once

#include <string>
#include "cryptopp/sha3.h"

#include "Arguments.hpp"

namespace Ethereum{namespace ABI{

class Method
{
    public:
        static std::string Encode(const std::string &method);
        static std::string Encode(const char *method);
        static std::string Encode(const char *method, size_t size);
        static std::string Encode(const char *method, const Arguments &args);
        static std::string Encode(const std::string &method, const Arguments &args);
        static std::string Encode(const char *method, size_t size, const Arguments &args);
};

}}
<|endoftext|>


<commit_before>/*
 * Module
 *
 * let you manage your code into modules
 *
 * writen by ImagicTheCat for Tsux
 * https://github.com/ImagicTheCat/Tsux
 */

#ifndef H_MODULE
#define H_MODULE

#include <iostream>
#include "Tsux.hpp"

class Module{
  public:
    //the name need to be unique
    Module(Tsux& tsux, const std::string& name);
    ~Module();

    /* Interface to tsux */
    //time in seconds
    void createCookie(const std::string& name, const std::string& data, int time){
      tsux.createCookie(name, data, time);
    }

    //generate html : 404, etc
    void generate(int code){ tsux.generate(code); }
    void generate(ParamSet set){ tsux.generate(set); }
    void generate(FileSet set){ tsux.generate(set); }

    //misc
    Module* module(const std::string& name){ return tsux.module(name); }

    //accessors
    const std::string& uri()const{ return tsux.uri(); }
    const std::string& location()const{ return tsux.location(); }

    //streams
    std::ostream& out;
    std::istream& in;
    std::ostream& err;
    std::stringstream& response;

    //data
    ParamSet &post, &get, &header, &route, &param, &cookie;
    FileSet &file;

    /* Module */
    //bind action for this module
    template<typename T> void bind(const std::string& path, void (T::*action)(void)){
      tsux.bind(path, Action((ModAction)action, this));
    }

    //accessors
    const std::string& name()const{ return _name; }

  private:
    Tsux& tsux;
    std::string _name;
};

typedef void (Module::*ModAction)(void);

#endif
<commit_msg>add locale shortcuts<commit_after>/*
 * Module
 *
 * let you manage your code into modules
 *
 * writen by ImagicTheCat for Tsux
 * https://github.com/ImagicTheCat/Tsux
 */

#ifndef H_MODULE
#define H_MODULE

#include <iostream>
#include "Tsux.hpp"

class Module{
  public:
    //the name need to be unique
    Module(Tsux& tsux, const std::string& name);
    ~Module();

    /* Interface to tsux */
    //time in seconds
    void createCookie(const std::string& name, const std::string& data, int time){
      tsux.createCookie(name, data, time);
    }

    //generate html : 404, etc
    void generate(int code){ tsux.generate(code); }
    void generate(ParamSet set){ tsux.generate(set); }
    void generate(FileSet set){ tsux.generate(set); }

    //misc
    Module* module(const std::string& name){ return tsux.module(name); }

    //accessors
    const std::string& uri()const{ return tsux.uri(); }
    const std::string& location()const{ return tsux.location(); }

    const std::string& locale()const{ return tsux.locale(); }
    void locale(const std::string& loc){ tsux.locale(loc); }

    //streams
    std::ostream& out;
    std::istream& in;
    std::ostream& err;
    std::stringstream& response;

    //data
    ParamSet &post, &get, &header, &route, &param, &cookie;
    FileSet &file;

    /* Module */
    //bind action for this module
    template<typename T> void bind(const std::string& path, void (T::*action)(void)){
      tsux.bind(path, Action((ModAction)action, this));
    }

    //accessors
    const std::string& name()const{ return _name; }

  private:
    Tsux& tsux;
    std::string _name;
};

typedef void (Module::*ModAction)(void);

#endif
<|endoftext|>


<commit_before>// Copyright (c) 2013-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "hash.h"
#include "crypto/common.h"
#include "crypto/hmac_sha512.h"
#include "pubkey.h"

inline uint32_t ROTL32(uint32_t x, int8_t r)
{
    return (x << r) | (x >> (32 - r));
}

unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash)
{
    // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
    uint32_t h1 = nHashSeed;
    if (vDataToHash.size() > 0)
    {
        const uint32_t c1 = 0xcc9e2d51;
        const uint32_t c2 = 0x1b873593;

        const int nblocks = vDataToHash.size() / 4;

        //----------
        // body
        const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;

        for (int i = -nblocks; i; i++) {
            uint32_t k1 = ReadLE32(blocks + i*4);

            k1 *= c1;
            k1 = ROTL32(k1, 15);
            k1 *= c2;

            h1 ^= k1;
            h1 = ROTL32(h1, 13);
            h1 = h1 * 5 + 0xe6546b64;
        }

        //----------
        // tail
        const uint8_t* tail = (const uint8_t*)(&vDataToHash[0] + nblocks * 4);

        uint32_t k1 = 0;

        switch (vDataToHash.size() & 3) {
        case 3:
            k1 ^= tail[2] << 16;
        case 2:
            k1 ^= tail[1] << 8;
        case 1:
            k1 ^= tail[0];
            k1 *= c1;
            k1 = ROTL32(k1, 15);
            k1 *= c2;
            h1 ^= k1;
        }
    }

    //----------
    // finalization
    h1 ^= vDataToHash.size();
    h1 ^= h1 >> 16;
    h1 *= 0x85ebca6b;
    h1 ^= h1 >> 13;
    h1 *= 0xc2b2ae35;
    h1 ^= h1 >> 16;

    return h1;
}

void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
{
    unsigned char num[4];
    num[0] = (nChild >> 24) & 0xFF;
    num[1] = (nChild >> 16) & 0xFF;
    num[2] = (nChild >>  8) & 0xFF;
    num[3] = (nChild >>  0) & 0xFF;
    CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
}

#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))

#define SIPROUND do { \
    v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \
    v0 = ROTL(v0, 32); \
    v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
    v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
    v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \
    v2 = ROTL(v2, 32); \
} while (0)

CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
{
    v[0] = 0x736f6d6570736575ULL ^ k0;
    v[1] = 0x646f72616e646f6dULL ^ k1;
    v[2] = 0x6c7967656e657261ULL ^ k0;
    v[3] = 0x7465646279746573ULL ^ k1;
    count = 0;
    tmp = 0;
}

CSipHasher& CSipHasher::Write(uint64_t data)
{
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];

    assert(count % 8 == 0);

    v3 ^= data;
    SIPROUND;
    SIPROUND;
    v0 ^= data;

    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;

    count += 8;
    return *this;
}

CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
{
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
    uint64_t t = tmp;
    int c = count;

    while (size--) {
        t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
        c++;
        if ((c & 7) == 0) {
            v3 ^= t;
            SIPROUND;
            SIPROUND;
            v0 ^= t;
            t = 0;
        }
    }

    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
    count = c;
    tmp = t;

    return *this;
}

uint64_t CSipHasher::Finalize() const
{
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];

    uint64_t t = tmp | (((uint64_t)count) << 56);

    v3 ^= t;
    SIPROUND;
    SIPROUND;
    v0 ^= t;
    v2 ^= 0xFF;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    return v0 ^ v1 ^ v2 ^ v3;
}

uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
{
    /* Specialized implementation for efficiency */
    uint64_t d = val.GetUint64(0);

    uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
    uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
    uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
    uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;

    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(1);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(2);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(3);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    v3 ^= ((uint64_t)4) << 59;
    SIPROUND;
    SIPROUND;
    v0 ^= ((uint64_t)4) << 59;
    v2 ^= 0xFF;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    return v0 ^ v1 ^ v2 ^ v3;
}
<commit_msg>Format hash.cpp<commit_after>// Copyright (c) 2013-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "hash.h"
#include "crypto/common.h"
#include "crypto/hmac_sha512.h"
#include "pubkey.h"

inline uint32_t ROTL32(uint32_t x, int8_t r) {
    return (x << r) | (x >> (32 - r));
}

unsigned int MurmurHash3(unsigned int nHashSeed,
                         const std::vector<unsigned char> &vDataToHash) {
    // The following is MurmurHash3 (x86_32), see
    // http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
    uint32_t h1 = nHashSeed;
    if (vDataToHash.size() > 0) {
        const uint32_t c1 = 0xcc9e2d51;
        const uint32_t c2 = 0x1b873593;

        const int nblocks = vDataToHash.size() / 4;

        //----------
        // body
        const uint8_t *blocks = &vDataToHash[0] + nblocks * 4;

        for (int i = -nblocks; i; i++) {
            uint32_t k1 = ReadLE32(blocks + i * 4);

            k1 *= c1;
            k1 = ROTL32(k1, 15);
            k1 *= c2;

            h1 ^= k1;
            h1 = ROTL32(h1, 13);
            h1 = h1 * 5 + 0xe6546b64;
        }

        //----------
        // tail
        const uint8_t *tail = (const uint8_t *)(&vDataToHash[0] + nblocks * 4);

        uint32_t k1 = 0;

        switch (vDataToHash.size() & 3) {
            case 3:
                k1 ^= tail[2] << 16;
            case 2:
                k1 ^= tail[1] << 8;
            case 1:
                k1 ^= tail[0];
                k1 *= c1;
                k1 = ROTL32(k1, 15);
                k1 *= c2;
                h1 ^= k1;
        }
    }

    //----------
    // finalization
    h1 ^= vDataToHash.size();
    h1 ^= h1 >> 16;
    h1 *= 0x85ebca6b;
    h1 ^= h1 >> 13;
    h1 *= 0xc2b2ae35;
    h1 ^= h1 >> 16;

    return h1;
}

void BIP32Hash(const ChainCode &chainCode, unsigned int nChild,
               unsigned char header, const unsigned char data[32],
               unsigned char output[64]) {
    unsigned char num[4];
    num[0] = (nChild >> 24) & 0xFF;
    num[1] = (nChild >> 16) & 0xFF;
    num[2] = (nChild >> 8) & 0xFF;
    num[3] = (nChild >> 0) & 0xFF;
    CHMAC_SHA512(chainCode.begin(), chainCode.size())
        .Write(&header, 1)
        .Write(data, 32)
        .Write(num, 4)
        .Finalize(output);
}

#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))

#define SIPROUND                                                               \
    do {                                                                       \
        v0 += v1;                                                              \
        v1 = ROTL(v1, 13);                                                     \
        v1 ^= v0;                                                              \
        v0 = ROTL(v0, 32);                                                     \
        v2 += v3;                                                              \
        v3 = ROTL(v3, 16);                                                     \
        v3 ^= v2;                                                              \
        v0 += v3;                                                              \
        v3 = ROTL(v3, 21);                                                     \
        v3 ^= v0;                                                              \
        v2 += v1;                                                              \
        v1 = ROTL(v1, 17);                                                     \
        v1 ^= v2;                                                              \
        v2 = ROTL(v2, 32);                                                     \
    } while (0)

CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) {
    v[0] = 0x736f6d6570736575ULL ^ k0;
    v[1] = 0x646f72616e646f6dULL ^ k1;
    v[2] = 0x6c7967656e657261ULL ^ k0;
    v[3] = 0x7465646279746573ULL ^ k1;
    count = 0;
    tmp = 0;
}

CSipHasher &CSipHasher::Write(uint64_t data) {
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];

    assert(count % 8 == 0);

    v3 ^= data;
    SIPROUND;
    SIPROUND;
    v0 ^= data;

    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;

    count += 8;
    return *this;
}

CSipHasher &CSipHasher::Write(const unsigned char *data, size_t size) {
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
    uint64_t t = tmp;
    int c = count;

    while (size--) {
        t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
        c++;
        if ((c & 7) == 0) {
            v3 ^= t;
            SIPROUND;
            SIPROUND;
            v0 ^= t;
            t = 0;
        }
    }

    v[0] = v0;
    v[1] = v1;
    v[2] = v2;
    v[3] = v3;
    count = c;
    tmp = t;

    return *this;
}

uint64_t CSipHasher::Finalize() const {
    uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];

    uint64_t t = tmp | (((uint64_t)count) << 56);

    v3 ^= t;
    SIPROUND;
    SIPROUND;
    v0 ^= t;
    v2 ^= 0xFF;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    return v0 ^ v1 ^ v2 ^ v3;
}

uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val) {
    /* Specialized implementation for efficiency */
    uint64_t d = val.GetUint64(0);

    uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
    uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
    uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
    uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;

    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(1);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(2);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    d = val.GetUint64(3);
    v3 ^= d;
    SIPROUND;
    SIPROUND;
    v0 ^= d;
    v3 ^= ((uint64_t)4) << 59;
    SIPROUND;
    SIPROUND;
    v0 ^= ((uint64_t)4) << 59;
    v2 ^= 0xFF;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    SIPROUND;
    return v0 ^ v1 ^ v2 ^ v3;
}
<|endoftext|>


<commit_before>/*
 * This file is part of DGD, https://github.com/dworkin/dgd
 * Copyright (C) 1993-2010 Dworkin B.V.
 * Copyright (C) 2010-2016 DGD Authors (see the commit log for details)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

# include "dgd.h"
# include "hash.h"

/*
 * Generic string hash table.
 */

unsigned char Hashtab::tab[256] = {
    u'\001', u'\127', u'\061', u'\014', u'\260', u'\262', u'\146', u'\246',
    u'\171', u'\301', u'\006', u'\124', u'\371', u'\346', u'\054', u'\243',
    u'\016', u'\305', u'\325', u'\265', u'\241', u'\125', u'\332', u'\120',
    u'\100', u'\357', u'\030', u'\342', u'\354', u'\216', u'\046', u'\310',
    u'\156', u'\261', u'\150', u'\147', u'\215', u'\375', u'\377', u'\062',
    u'\115', u'\145', u'\121', u'\022', u'\055', u'\140', u'\037', u'\336',
    u'\031', u'\153', u'\276', u'\106', u'\126', u'\355', u'\360', u'\042',
    u'\110', u'\362', u'\024', u'\326', u'\364', u'\343', u'\225', u'\353',
    u'\141', u'\352', u'\071', u'\026', u'\074', u'\372', u'\122', u'\257',
    u'\320', u'\005', u'\177', u'\307', u'\157', u'\076', u'\207', u'\370',
    u'\256', u'\251', u'\323', u'\072', u'\102', u'\232', u'\152', u'\303',
    u'\365', u'\253', u'\021', u'\273', u'\266', u'\263', u'\000', u'\363',
    u'\204', u'\070', u'\224', u'\113', u'\200', u'\205', u'\236', u'\144',
    u'\202', u'\176', u'\133', u'\015', u'\231', u'\366', u'\330', u'\333',
    u'\167', u'\104', u'\337', u'\116', u'\123', u'\130', u'\311', u'\143',
    u'\172', u'\013', u'\134', u'\040', u'\210', u'\162', u'\064', u'\012',
    u'\212', u'\036', u'\060', u'\267', u'\234', u'\043', u'\075', u'\032',
    u'\217', u'\112', u'\373', u'\136', u'\201', u'\242', u'\077', u'\230',
    u'\252', u'\007', u'\163', u'\247', u'\361', u'\316', u'\003', u'\226',
    u'\067', u'\073', u'\227', u'\334', u'\132', u'\065', u'\027', u'\203',
    u'\175', u'\255', u'\017', u'\356', u'\117', u'\137', u'\131', u'\020',
    u'\151', u'\211', u'\341', u'\340', u'\331', u'\240', u'\045', u'\173',
    u'\166', u'\111', u'\002', u'\235', u'\056', u'\164', u'\011', u'\221',
    u'\206', u'\344', u'\317', u'\324', u'\312', u'\327', u'\105', u'\345',
    u'\033', u'\274', u'\103', u'\174', u'\250', u'\374', u'\052', u'\004',
    u'\035', u'\154', u'\025', u'\367', u'\023', u'\315', u'\047', u'\313',
    u'\351', u'\050', u'\272', u'\223', u'\306', u'\300', u'\233', u'\041',
    u'\244', u'\277', u'\142', u'\314', u'\245', u'\264', u'\165', u'\114',
    u'\214', u'\044', u'\322', u'\254', u'\051', u'\066', u'\237', u'\010',
    u'\271', u'\350', u'\161', u'\304', u'\347', u'\057', u'\222', u'\170',
    u'\063', u'\101', u'\034', u'\220', u'\376', u'\335', u'\135', u'\275',
    u'\302', u'\213', u'\160', u'\053', u'\107', u'\155', u'\270', u'\321',
};

/*
 * NAME:	Hashtab::create()
 * DESCRIPTION:	hashtable factory
 */
Hashtab *Hashtab::create(unsigned int size, unsigned int maxlen, bool mem)
{
    return new HashtabImpl(size, maxlen, mem);
}

/*
 * NAME:	Hashtab::hashstr()
 * DESCRIPTION:	Hash string s, considering at most len characters. Return
 *		an unsigned modulo size.
 *		Based on Peter K. Pearson's article in CACM 33-6, pp 677.
 */
unsigned short Hashtab::hashstr(const char *str, unsigned int len)
{
    unsigned char h, l;

    h = l = 0;
    while (*str != '\0' && len > 0) {
	h = l;
	l = tab[l ^ (unsigned char) *str++];
	--len;
    }
    return (unsigned short) ((h << 8) | l);
}

/*
 * NAME:	Hashtab::hashmem()
 * DESCRIPTION:	hash memory
 */
unsigned short Hashtab::hashmem(const char *mem, unsigned int len)
{
    unsigned char h, l;

    h = l = 0;
    while (len > 0) {
	h = l;
	l = tab[l ^ (unsigned char) *mem++];
	--len;
    }
    return (unsigned short) ((h << 8) | l);
}

/*
 * NAME:	HashtabImpl()
 * DESCRIPTION:	create a new hashtable of size "size", where "maxlen" characters
 *		of each string are significant
 */
HashtabImpl::HashtabImpl(unsigned int size, unsigned int maxlen, bool mem)
{
    m_size = size;
    m_maxlen = maxlen;
    m_mem = mem;
    m_table = ALLOC(Entry*, size);
    memset(m_table, '\0', size * sizeof(Entry*));
}

/*
 * NAME:	~HashtabImpl()
 * DESCRIPTION:	delete a hash table
 */
HashtabImpl::~HashtabImpl()
{
    FREE(m_table);
}

/*
 * NAME:	HashtabImpl::lookup()
 * DESCRIPTION:	lookup a name in a hashtable, return the address of the entry
 *		or &NULL if none found
 */
Hashtab::Entry **HashtabImpl::lookup(const char *name, bool move)
{
    Entry **first, **e, *next;

    if (m_mem) {
	first = e = &(m_table[hashmem(name, m_maxlen) % m_size]);
	while (*e != (Entry *) NULL) {
	    if (memcmp((*e)->name, name, m_maxlen) == 0) {
		if (move && e != first) {
		    /* move to first position */
		    next = (*e)->next;
		    (*e)->next = *first;
		    *first = *e;
		    *e = next;
		    return first;
		}
		break;
	    }
	    e = &((*e)->next);
	}
    } else {
	first = e = &(m_table[hashstr(name, m_maxlen) % m_size]);
	while (*e != (Entry *) NULL) {
	    if (strcmp((*e)->name, name) == 0) {
		if (move && e != first) {
		    /* move to first position */
		    next = (*e)->next;
		    (*e)->next = *first;
		    *first = *e;
		    *e = next;
		    return first;
		}
		break;
	    }
	    e = &((*e)->next);
	}
    }
    return e;
}
<commit_msg>Alternative fix for build error with g++ v6<commit_after>/*
 * This file is part of DGD, https://github.com/dworkin/dgd
 * Copyright (C) 1993-2010 Dworkin B.V.
 * Copyright (C) 2010-2016 DGD Authors (see the commit log for details)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

# include "dgd.h"
# include "hash.h"

/*
 * Generic string hash table.
 */

unsigned char Hashtab::tab[256] = {
    0001, 0127, 0061, 0014, 0260, 0262, 0146, 0246,
    0171, 0301, 0006, 0124, 0371, 0346, 0054, 0243,
    0016, 0305, 0325, 0265, 0241, 0125, 0332, 0120,
    0100, 0357, 0030, 0342, 0354, 0216, 0046, 0310,
    0156, 0261, 0150, 0147, 0215, 0375, 0377, 0062,
    0115, 0145, 0121, 0022, 0055, 0140, 0037, 0336,
    0031, 0153, 0276, 0106, 0126, 0355, 0360, 0042,
    0110, 0362, 0024, 0326, 0364, 0343, 0225, 0353,
    0141, 0352, 0071, 0026, 0074, 0372, 0122, 0257,
    0320, 0005, 0177, 0307, 0157, 0076, 0207, 0370,
    0256, 0251, 0323, 0072, 0102, 0232, 0152, 0303,
    0365, 0253, 0021, 0273, 0266, 0263, 0000, 0363,
    0204, 0070, 0224, 0113, 0200, 0205, 0236, 0144,
    0202, 0176, 0133, 0015, 0231, 0366, 0330, 0333,
    0167, 0104, 0337, 0116, 0123, 0130, 0311, 0143,
    0172, 0013, 0134, 0040, 0210, 0162, 0064, 0012,
    0212, 0036, 0060, 0267, 0234, 0043, 0075, 0032,
    0217, 0112, 0373, 0136, 0201, 0242, 0077, 0230,
    0252, 0007, 0163, 0247, 0361, 0316, 0003, 0226,
    0067, 0073, 0227, 0334, 0132, 0065, 0027, 0203,
    0175, 0255, 0017, 0356, 0117, 0137, 0131, 0020,
    0151, 0211, 0341, 0340, 0331, 0240, 0045, 0173,
    0166, 0111, 0002, 0235, 0056, 0164, 0011, 0221,
    0206, 0344, 0317, 0324, 0312, 0327, 0105, 0345,
    0033, 0274, 0103, 0174, 0250, 0374, 0052, 0004,
    0035, 0154, 0025, 0367, 0023, 0315, 0047, 0313,
    0351, 0050, 0272, 0223, 0306, 0300, 0233, 0041,
    0244, 0277, 0142, 0314, 0245, 0264, 0165, 0114,
    0214, 0044, 0322, 0254, 0051, 0066, 0237, 0010,
    0271, 0350, 0161, 0304, 0347, 0057, 0222, 0170,
    0063, 0101, 0034, 0220, 0376, 0335, 0135, 0275,
    0302, 0213, 0160, 0053, 0107, 0155, 0270, 0321,
};

/*
 * NAME:	Hashtab::create()
 * DESCRIPTION:	hashtable factory
 */
Hashtab *Hashtab::create(unsigned int size, unsigned int maxlen, bool mem)
{
    return new HashtabImpl(size, maxlen, mem);
}

/*
 * NAME:	Hashtab::hashstr()
 * DESCRIPTION:	Hash string s, considering at most len characters. Return
 *		an unsigned modulo size.
 *		Based on Peter K. Pearson's article in CACM 33-6, pp 677.
 */
unsigned short Hashtab::hashstr(const char *str, unsigned int len)
{
    unsigned char h, l;

    h = l = 0;
    while (*str != '\0' && len > 0) {
	h = l;
	l = tab[l ^ (unsigned char) *str++];
	--len;
    }
    return (unsigned short) ((h << 8) | l);
}

/*
 * NAME:	Hashtab::hashmem()
 * DESCRIPTION:	hash memory
 */
unsigned short Hashtab::hashmem(const char *mem, unsigned int len)
{
    unsigned char h, l;

    h = l = 0;
    while (len > 0) {
	h = l;
	l = tab[l ^ (unsigned char) *mem++];
	--len;
    }
    return (unsigned short) ((h << 8) | l);
}

/*
 * NAME:	HashtabImpl()
 * DESCRIPTION:	create a new hashtable of size "size", where "maxlen" characters
 *		of each string are significant
 */
HashtabImpl::HashtabImpl(unsigned int size, unsigned int maxlen, bool mem)
{
    m_size = size;
    m_maxlen = maxlen;
    m_mem = mem;
    m_table = ALLOC(Entry*, size);
    memset(m_table, '\0', size * sizeof(Entry*));
}

/*
 * NAME:	~HashtabImpl()
 * DESCRIPTION:	delete a hash table
 */
HashtabImpl::~HashtabImpl()
{
    FREE(m_table);
}

/*
 * NAME:	HashtabImpl::lookup()
 * DESCRIPTION:	lookup a name in a hashtable, return the address of the entry
 *		or &NULL if none found
 */
Hashtab::Entry **HashtabImpl::lookup(const char *name, bool move)
{
    Entry **first, **e, *next;

    if (m_mem) {
	first = e = &(m_table[hashmem(name, m_maxlen) % m_size]);
	while (*e != (Entry *) NULL) {
	    if (memcmp((*e)->name, name, m_maxlen) == 0) {
		if (move && e != first) {
		    /* move to first position */
		    next = (*e)->next;
		    (*e)->next = *first;
		    *first = *e;
		    *e = next;
		    return first;
		}
		break;
	    }
	    e = &((*e)->next);
	}
    } else {
	first = e = &(m_table[hashstr(name, m_maxlen) % m_size]);
	while (*e != (Entry *) NULL) {
	    if (strcmp((*e)->name, name) == 0) {
		if (move && e != first) {
		    /* move to first position */
		    next = (*e)->next;
		    (*e)->next = *first;
		    *first = *e;
		    *e = next;
		    return first;
		}
		break;
	    }
	    e = &((*e)->next);
	}
    }
    return e;
}
<|endoftext|>