<commit_before>#include <arpa/inet.h>
#include <assert.h>
#include <map>
#include <openssl/sha.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zlib.h>

using namespace std;

namespace {

static const string NUL = string(1, '\0');
static const string SP = " ";
static const string LF = "\n";

__attribute__((noreturn)) void perror_abort(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    perror("");
    abort();
}

string compress(const string &in) {
    string out(compressBound(in.size()), ' ');
    size_t destLen = out.size();
    int status = compress2((Bytef*)&out[0], &destLen, (const Bytef*)&in[0],
            in.size(), 9);
    if (status == Z_OK) {
        out.erase(destLen);
    } else {
        fprintf(stderr, "zlib error: %d (%s)\n", status, zError(status));
        abort();
    }
    return out;
}

string read_file(const string &name) {
    struct stat buf;
    if (stat(name.c_str(), &buf) < 0) {
        perror_abort("stat: \"%s\"", name.c_str());
    }
    const size_t size = buf.st_size;
    string res(size, ' ');
    FILE *fp = fopen(name.c_str(), "rb");
    size_t pos = 0;
    while (pos < size) {
        ssize_t n = fread(&res[pos], 1, size - pos, fp);
        if (n < 0) {
            perror_abort("fread");
        }
        pos += n;
    }
    assert(res.size() == size);
    fclose(fp);
    return res;
}

enum GitType {
    OBJ_COMMIT = 1,
    OBJ_TREE = 2,
    OBJ_BLOB = 3,
};

string hex(const string& bin) {
    string res;
    for (unsigned char c : bin) {
        char buf[3];
        snprintf(buf, sizeof(buf), "%02x", c);
        res += buf;
    }
    return res;
}

string sha1(const string& header, const string& data) {
    SHA_CTX sha;
    SHA1_Init(&sha);
    SHA1_Update(&sha, header.data(), header.size());
    SHA1_Update(&sha, data.data(), data.size());
    unsigned char temp[SHA_DIGEST_LENGTH];
    SHA1_Final(temp, &sha);
    return string((const char *)temp, sizeof(temp));
}

const char *gittype_name(GitType type) {
    switch (type) {
    case OBJ_COMMIT:
        return "commit";
    case OBJ_TREE:
        return "tree";
    case OBJ_BLOB:
        return "blob";
    }
    abort();
}

string git_header(GitType type, size_t length) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%s %zu", gittype_name(type), length);
    // Trailing NUL is included as a separator
    return string(buf, strlen(buf) + 1);
}

struct Object {
    GitType type;
    const string* data;
};

void xfwrite(FILE *fp, const void *p_, size_t size) {
    const char *p = (const char *)p_;
    while (size) {
        ssize_t n = fwrite(p, 1, size, fp);
        if (n < 0) perror_abort("fwrite");
        size -= n;
        p += n;
    }
}
void xfwrite(FILE *fp, const string& data) {
    xfwrite(fp, data.data(), data.size());
}

struct Pack {
    map<string, Object> objects;
    SHA_CTX sha;

    void add(const string& hash, const Object& obj) {
        if (objects.find(hash) == objects.end()) {
            objects[hash] = obj;
        }
    }

    string hash_add(const Object& obj) {
        string hash = sha1(git_header(obj.type, obj.data->size()), *obj.data);
        add(hash, obj);
        return hash;
    }

    void write_vint(FILE *fp, size_t x) {
        assert(x);
        while (x) {
            char c = x & 0x7f;
            if (x >>= 7) c |= 0x80;
            writec(fp, c);
        }
    }

    void writec(FILE *fp, char c) {
        fputc(c, fp);
        SHA1_Update(&sha, &c, 1);
    }
    void write(FILE *fp, const string& data) {
        write(fp, data.data(), data.size());
    }
    void write(FILE *fp, const void *p, size_t size) {
        SHA1_Update(&sha, p, size);
        xfwrite(fp, p, size);
    }

    void print(FILE *fp) {
        SHA1_Init(&sha);
        char header[] = "PACK\0\0\0\2\0\0\0";
        ((uint32_t*)header)[2] = htonl(objects.size());
        write(fp, header, sizeof(header));
        for (const auto& i: objects) {
            // first byte: low 4 bits is size, high bit is "size cont'd",
            // middle three bits are type
            //const string& hash = i.first;
            const Object& obj = i.second;

            assert(obj.type);
            size_t size = obj.data->size();
            long file_pos = ftell(fp);
            write_vint(fp, ((size >> 4) << 7) | (obj.type << 4) | (size & 15));
            long file_pos2 = ftell(fp);
            const string compressed = compress(*obj.data);
            write(fp, compressed);

            if (0 && file_pos > 0) {
                // SHA-1 type size size-in-packfile offset-in-packfile
                fprintf(stderr, "%s %-6s %zu %zu %ld\n",
                        hex(i.first).c_str(),
                        gittype_name(obj.type),
                        size,
                        compressed.size() + (file_pos2 - file_pos),
                        file_pos);
            }
        }
        unsigned char md[SHA_DIGEST_LENGTH];
        SHA1_Final(md, &sha);
        write(fp, md, sizeof(md));
    }
};

string branch, author, commitmessage, parent;
Pack pack;

struct Tree {

    string path_;
    string data_;
    string hash_;
    struct stat stat_;
    map<string, Tree> files_;

    Tree(const string& path): path_(path) {
        ::stat(path.c_str(), &stat_);
    }

    void addpath(const string& path, const size_t pos = 0) {
        size_t end = path.find('/', pos);
        Tree& sub = addfile(path.substr(pos, end), path.substr(0, end));
        if (end != string::npos) {
            sub.addpath(path, end + 1);
        }
    }

    Tree& addfile(const string& name, const string& path) {
        auto it = files_.find(name);
        if (it == files_.end()) {
            return files_.insert(make_pair(name, Tree(path))).first->second;
        } else {
            return it->second;
        }
    }

    const struct stat& stat() {
        return stat_;
    }

    const string& data() {
        if (data_.size() == 0) {
            if (S_ISDIR(stat().st_mode)) {
                for (auto& it: files_) {
                    string hash = it.second.hash();

                    char buf[12];
                    snprintf(buf, sizeof(buf), "%o ", it.second.git_mode());
                    const string entry = buf + it.first + NUL + hash;
                    data_ += entry;
//                    fprintf(stderr, "%s: %s %s\n", path_.c_str(), entry.c_str(), hex(hash).c_str());
                }
            } else if (S_ISREG(stat().st_mode)) {
                data_ = read_file(path_);
            } else {
                fprintf(stderr, "Unhandled file type (mode %o) for %s\n",
                        stat().st_mode, path_.c_str());
                abort();
            }
        }
        return data_;
    }

    string header() {
        return git_header(gittype(), data().size());
    }

    const string& hash() {
        if (hash_.empty()) {
            hash_ = sha1(header(), data());
//            fprintf(stderr, "%s: %s\n", path_.c_str(), hex(hash_).c_str());
            pack.add(hash_, object());
        }
        return hash_;
    }

    GitType gittype() {
        return S_ISDIR(stat().st_mode) ? OBJ_TREE : OBJ_BLOB;
    }

    int git_mode() {
        int m = stat().st_mode;
        // file types recognized by git
        const int type_mask = S_IFDIR | S_IFREG | S_IFLNK;
        const int exec_mask = 0111;

        if ((m & S_IFMT) != (m & type_mask))
        {
            fprintf(stderr, "Unknown file type (mode %o) for %s\n",
                    m, path_.c_str());
            abort();
        }
        return (m & type_mask) | 0644 | (m & exec_mask ? exec_mask : 0);
    }

    Object object() {
        return Object { gittype(), &data() };
    }
};

Tree root(".");

// output: safe_name <safe_email> git_date
string make_author() {
    char buf[256];
    snprintf(buf, sizeof(buf), "%s %ld +0000", author.c_str(), time(nullptr));
    return buf;
}

string make_commit(const string& tree, const string& commitmessage) {
    const string author = make_author();
    return "tree " + tree +
        "\nparent " + parent +
        "\nauthor " + author +
        "\ncommitter " + author +
        "\n\n" + commitmessage;
}

void pktline(const string& payload) {
    if (payload.size() > 65516) {
        fprintf(stderr, "FATAL: payload too large for pktline format\n");
        abort();
    }

    printf("%04zx", payload.size() + 4);
    xfwrite(stdout, payload);
}

}

// fgt-make-commit-pack BRANCH COMMITMSGFILE PARENT
int main(int argc, const char *argv[]) {
    assert(argc >= 5);
    branch = argv[1];
    author = argv[2];
    commitmessage = read_file(argv[3]);
    parent = argv[4];
    assert(parent.size() == 40);

    char *line = nullptr;
    size_t n = 0;
    while (getdelim(&line, &n, '\0', stdin) >= 0)
    {
        if (string(line) == "./tmp.pack" || string(line) == "./tmp.idx")
            continue;
        const char *path = strchr(line, '/');
        if (path)
            root.addpath(path + 1);
    }

    string tree = root.hash();
    string commitobj = make_commit(hex(tree), commitmessage);
    string commithash = pack.hash_add(Object { OBJ_COMMIT, &commitobj });

    fprintf(stderr, "%s\n", commitobj.c_str());

    pktline(parent + SP + hex(commithash) + SP + branch + LF);
    printf("0000");
    pack.print(stdout);

    FILE *fp = fopen("tmp.pack", "wb");
    pack.print(fp);
    fclose(fp);
}
<commit_msg>Add capabilities so that pushing works with github<commit_after>#include <arpa/inet.h>
#include <assert.h>
#include <map>
#include <openssl/sha.h>
#include <stdarg.h>
#include <stdio.h>
#include <string>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <zlib.h>

using namespace std;

namespace {

static const string NUL = string(1, '\0');
static const string SP = " ";
static const string LF = "\n";

__attribute__((noreturn)) void perror_abort(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    perror("");
    abort();
}

string compress(const string &in) {
    string out(compressBound(in.size()), ' ');
    size_t destLen = out.size();
    int status = compress2((Bytef*)&out[0], &destLen, (const Bytef*)&in[0],
            in.size(), 9);
    if (status == Z_OK) {
        out.erase(destLen);
    } else {
        fprintf(stderr, "zlib error: %d (%s)\n", status, zError(status));
        abort();
    }
    return out;
}

string read_file(const string &name) {
    struct stat buf;
    if (stat(name.c_str(), &buf) < 0) {
        perror_abort("stat: \"%s\"", name.c_str());
    }
    const size_t size = buf.st_size;
    string res(size, ' ');
    FILE *fp = fopen(name.c_str(), "rb");
    size_t pos = 0;
    while (pos < size) {
        ssize_t n = fread(&res[pos], 1, size - pos, fp);
        if (n < 0) {
            perror_abort("fread");
        }
        pos += n;
    }
    assert(res.size() == size);
    fclose(fp);
    return res;
}

enum GitType {
    OBJ_COMMIT = 1,
    OBJ_TREE = 2,
    OBJ_BLOB = 3,
};

string hex(const string& bin) {
    string res;
    for (unsigned char c : bin) {
        char buf[3];
        snprintf(buf, sizeof(buf), "%02x", c);
        res += buf;
    }
    return res;
}

string sha1(const string& header, const string& data) {
    SHA_CTX sha;
    SHA1_Init(&sha);
    SHA1_Update(&sha, header.data(), header.size());
    SHA1_Update(&sha, data.data(), data.size());
    unsigned char temp[SHA_DIGEST_LENGTH];
    SHA1_Final(temp, &sha);
    return string((const char *)temp, sizeof(temp));
}

const char *gittype_name(GitType type) {
    switch (type) {
    case OBJ_COMMIT:
        return "commit";
    case OBJ_TREE:
        return "tree";
    case OBJ_BLOB:
        return "blob";
    }
    abort();
}

string git_header(GitType type, size_t length) {
    char buf[32];
    snprintf(buf, sizeof(buf), "%s %zu", gittype_name(type), length);
    // Trailing NUL is included as a separator
    return string(buf, strlen(buf) + 1);
}

struct Object {
    GitType type;
    const string* data;
};

void xfwrite(FILE *fp, const void *p_, size_t size) {
    const char *p = (const char *)p_;
    while (size) {
        ssize_t n = fwrite(p, 1, size, fp);
        if (n < 0) perror_abort("fwrite");
        size -= n;
        p += n;
    }
}
void xfwrite(FILE *fp, const string& data) {
    xfwrite(fp, data.data(), data.size());
}

struct Pack {
    map<string, Object> objects;
    SHA_CTX sha;

    void add(const string& hash, const Object& obj) {
        if (objects.find(hash) == objects.end()) {
            objects[hash] = obj;
        }
    }

    string hash_add(const Object& obj) {
        string hash = sha1(git_header(obj.type, obj.data->size()), *obj.data);
        add(hash, obj);
        return hash;
    }

    void write_vint(FILE *fp, size_t x) {
        assert(x);
        while (x) {
            char c = x & 0x7f;
            if (x >>= 7) c |= 0x80;
            writec(fp, c);
        }
    }

    void writec(FILE *fp, char c) {
        fputc(c, fp);
        SHA1_Update(&sha, &c, 1);
    }
    void write(FILE *fp, const string& data) {
        write(fp, data.data(), data.size());
    }
    void write(FILE *fp, const void *p, size_t size) {
        SHA1_Update(&sha, p, size);
        xfwrite(fp, p, size);
    }

    void print(FILE *fp) {
        SHA1_Init(&sha);
        char header[] = "PACK\0\0\0\2\0\0\0";
        ((uint32_t*)header)[2] = htonl(objects.size());
        write(fp, header, sizeof(header));
        for (const auto& i: objects) {
            // first byte: low 4 bits is size, high bit is "size cont'd",
            // middle three bits are type
            //const string& hash = i.first;
            const Object& obj = i.second;

            assert(obj.type);
            size_t size = obj.data->size();
            long file_pos = ftell(fp);
            write_vint(fp, ((size >> 4) << 7) | (obj.type << 4) | (size & 15));
            long file_pos2 = ftell(fp);
            const string compressed = compress(*obj.data);
            write(fp, compressed);

            if (0 && file_pos > 0) {
                // SHA-1 type size size-in-packfile offset-in-packfile
                fprintf(stderr, "%s %-6s %zu %zu %ld\n",
                        hex(i.first).c_str(),
                        gittype_name(obj.type),
                        size,
                        compressed.size() + (file_pos2 - file_pos),
                        file_pos);
            }
        }
        unsigned char md[SHA_DIGEST_LENGTH];
        SHA1_Final(md, &sha);
        write(fp, md, sizeof(md));
    }
};

string branch, author, commitmessage, parent;
Pack pack;

struct Tree {

    string path_;
    string data_;
    string hash_;
    struct stat stat_;
    map<string, Tree> files_;

    Tree(const string& path): path_(path) {
        ::stat(path.c_str(), &stat_);
    }

    void addpath(const string& path, const size_t pos = 0) {
        size_t end = path.find('/', pos);
        Tree& sub = addfile(path.substr(pos, end), path.substr(0, end));
        if (end != string::npos) {
            sub.addpath(path, end + 1);
        }
    }

    Tree& addfile(const string& name, const string& path) {
        auto it = files_.find(name);
        if (it == files_.end()) {
            return files_.insert(make_pair(name, Tree(path))).first->second;
        } else {
            return it->second;
        }
    }

    const struct stat& stat() {
        return stat_;
    }

    const string& data() {
        if (data_.size() == 0) {
            if (S_ISDIR(stat().st_mode)) {
                for (auto& it: files_) {
                    string hash = it.second.hash();

                    char buf[12];
                    snprintf(buf, sizeof(buf), "%o ", it.second.git_mode());
                    const string entry = buf + it.first + NUL + hash;
                    data_ += entry;
//                    fprintf(stderr, "%s: %s %s\n", path_.c_str(), entry.c_str(), hex(hash).c_str());
                }
            } else if (S_ISREG(stat().st_mode)) {
                data_ = read_file(path_);
            } else {
                fprintf(stderr, "Unhandled file type (mode %o) for %s\n",
                        stat().st_mode, path_.c_str());
                abort();
            }
        }
        return data_;
    }

    string header() {
        return git_header(gittype(), data().size());
    }

    const string& hash() {
        if (hash_.empty()) {
            hash_ = sha1(header(), data());
//            fprintf(stderr, "%s: %s\n", path_.c_str(), hex(hash_).c_str());
            pack.add(hash_, object());
        }
        return hash_;
    }

    GitType gittype() {
        return S_ISDIR(stat().st_mode) ? OBJ_TREE : OBJ_BLOB;
    }

    int git_mode() {
        int m = stat().st_mode;
        // file types recognized by git
        const int type_mask = S_IFDIR | S_IFREG | S_IFLNK;
        const int exec_mask = 0111;

        if ((m & S_IFMT) != (m & type_mask))
        {
            fprintf(stderr, "Unknown file type (mode %o) for %s\n",
                    m, path_.c_str());
            abort();
        }
        return (m & type_mask) | 0644 | (m & exec_mask ? exec_mask : 0);
    }

    Object object() {
        return Object { gittype(), &data() };
    }
};

Tree root(".");

// output: safe_name <safe_email> git_date
string make_author() {
    char buf[256];
    snprintf(buf, sizeof(buf), "%s %ld +0000", author.c_str(), time(nullptr));
    return buf;
}

string make_commit(const string& tree, const string& commitmessage) {
    const string author = make_author();
    return "tree " + tree +
        "\nparent " + parent +
        "\nauthor " + author +
        "\ncommitter " + author +
        "\n\n" + commitmessage;
}

void pktline(const string& payload) {
    if (payload.size() > 65516) {
        fprintf(stderr, "FATAL: payload too large for pktline format\n");
        abort();
    }

    printf("%04zx", payload.size() + 4);
    xfwrite(stdout, payload);
}

}

// fgt-make-commit-pack BRANCH COMMITMSGFILE PARENT
int main(int argc, const char *argv[]) {
    assert(argc >= 5);
    branch = argv[1];
    author = argv[2];
    commitmessage = read_file(argv[3]);
    parent = argv[4];
    assert(parent.size() == 40);

    char *line = nullptr;
    size_t n = 0;
    while (getdelim(&line, &n, '\0', stdin) >= 0)
    {
        if (string(line) == "./tmp.pack" || string(line) == "./tmp.idx")
            continue;
        const char *path = strchr(line, '/');
        if (path)
            root.addpath(path + 1);
    }

    string tree = root.hash();
    string commitobj = make_commit(hex(tree), commitmessage);
    string commithash = pack.hash_add(Object { OBJ_COMMIT, &commitobj });

    fprintf(stderr, "%s\n", commitobj.c_str());

    const string capabilities = "report-status";
    pktline(parent + SP + hex(commithash) + SP + branch +
            NUL + capabilities + LF);
    printf("0000");
    pack.print(stdout);

    FILE *fp = fopen("tmp.pack", "wb");
    pack.print(fp);
    fclose(fp);
}
<|endoftext|>


<commit_before>#include "motors_old.h"

#define MINREQSPEED 5
#define POLARITY -1     // direction of forward / connection to motor

Motors_Old::Motors_Old()
{
	//ctor
	fdMotor = -1;
	dVelocityScale = 1;
	_max_speed_=50;
	//SetupSerial();
}

Motors_Old::~Motors_Old()
{
	//dtor
	ShutdownSerial();
}

int Motors_Old::SetupSerial()
{
	/* Open serial port with the specified flags
	 * O_RDWR - for reading and writing
	 * O_NOCTTY - don't act as the controlling terminal for the port
	 * O_DSYNC | O_RSYNC - complete i/o operiations as definded by synchronized i/o data
	 *	integrity completion (i.e. waits for the data but not meta-data to be written
	 *	to the file before continuing execution) - this doesn't seem to work
	 * O_NDELAY - don't wait for the DCD line to go to the space voltage
	 */
	if ((fdMotor = open(DEFAULT_PORT, O_RDWR | O_NOCTTY | O_DSYNC | O_RSYNC | O_NDELAY)) < 0)
	{
		printf("SetupSerial(): could not open port %s, %s\n", DEFAULT_PORT, strerror(errno));
		return(-1);
	}

	/* Set the port back to blocking (waiting) behavior for calls to read() */
	//fcntl(fdMotor, F_SETFL, 0);
	/*no! => go nonblocking!*/
	fcntl(fdMotor, F_SETFL, O_NONBLOCK);

	/* Get the current options for the port */
	struct termios options;
	if (tcgetattr(fdMotor, &options) < 0)
	{
		printf("SetupSerial(): could not get the serial port options, %s\n", strerror(errno));
		ShutdownSerial();
		return(-1);
	}

	/* Configure the port options */
	options.c_cflag |= (CREAD | CLOCAL); /* Enable the receiver and set local mode */
	cfsetispeed(&options, B115200); /* Set 115200 baud rate */
	cfsetospeed(&options, B115200);
	options.c_cflag &= ~PARENB; /* Set no parity */
	options.c_cflag &= ~CSTOPB; /* Set 1 stop bit */
	options.c_cflag &= ~CSIZE; /* Set 8 data bits */
	options.c_cflag |= CS8;
	options.c_cc[VMIN]  = 0; /* Set .2 sec timeout */
	options.c_cc[VTIME] = 2;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Set raw input and output */
	options.c_oflag &= ~OPOST;

	/* Flush input and output buffers and then set the new options for the port */
	if (tcsetattr(fdMotor, TCSAFLUSH, &options) < 0 )
	{
		printf("SetupSerial(): could not set the serial port options, %s\n", strerror(errno));
		ShutdownSerial();
		return(-1);
	}
	return(0);
}

int Motors_Old::ShutdownSerial()
{
	if (close(fdMotor) < 0)
	{
		printf("ShutdownSerial(): could not close the serial port, %s\n", strerror(errno));
		fdMotor = -1;
		return(-1);
	}
	fdMotor = -1;
	return(0);
}

int Motors_Old::Shutdown()
{
	return(ShutdownSerial());
}

/* NOTE:
 *	When you raise the DTR line, if the motor controller is in AUTONOMOUS_MODE,
 *	it reads in any data in its uart buffer (4 bytes at most). Then, in all modes,
 *	it sends back its current motor states, control mode, and any errors it had
 *	with the transmission.
 */
int Motors_Old::set_motors(int iLeftVelocity, int iRightVelocity)
{
	/* Scale the motor velocities, limit them to vaild values, and store them in the
	 * correct form to transmit to the motor controller.
	 * 	Alternate Title: fun with the ? operator
	 */
	int iScaledLeftVel = POLARITY * (int)(dVelocityScale * iLeftVelocity);
	int iScaledRightVel = POLARITY * (int)(dVelocityScale * iRightVelocity);
	unsigned char data[3] =
	{
		(unsigned char)( (((iScaledLeftVel < 0) ? REVERSE : FORWARD) << LEFT_DIR_OFFSET) | (((iScaledRightVel < 0) ? REVERSE : FORWARD) << RIGHT_DIR_OFFSET) ),
		(unsigned char)( min(abs(iScaledLeftVel), 255) ),
		(unsigned char)( min(abs(iScaledRightVel), 255) )
	};

	/* Send the motor states to the motor controller */
	if ( write(fdMotor, data, 3) != 3 )
	{
		printf("set_motors(): could not write to serial port, %s\n", strerror(errno));
		return(-1);
	}

	/* Make sure the data has finished being written - this can be removed if the option can be made work in open() */
	tcdrain(fdMotor);

	/* Get the current motor states from the motor controller */
	return( get_motor_states() );
}

int Motors_Old::get_motor_states(void)
{
	/* Flush any old data in the read buffer */
	tcflush(fdMotor, TCIFLUSH);

	/* Set the DTR line high to intterupt the motor controller */
	int status;
	if (ioctl(fdMotor, TIOCMGET, &status))
	{
		printf("get_motor_states(): could not get serial port status, %s\n", strerror(errno));
		return(-1);
	}
	status |= TIOCM_DTR;
	if (ioctl(fdMotor, TIOCMSET, &status))
	{
		printf("get_motor_states(): could not set RTS high, %s\n", strerror(errno));
		return(-1);
	}

	/*
	 * If the DTR line can be raised and lowered in less than a full clock cycle
	 * of the controller, there should be a delay here to make sure the motor
	 * controller interrupts.
	 */

	/* Set the DTR line back to low
	 *	If there are problems, you might need to get the motor status again with
	 *	ioctl(fdMotor, TIOCMGET, &status) before doing this.
	 */
	status &= ~TIOCM_DTR;
	if (ioctl(fdMotor, TIOCMSET, &status))
	{
		printf("get_motor_states(): could not set RTS low, %s\n", strerror(errno));
		return(-1);
	}

	/* Read each byte sent from the controller */
	unsigned char u8Buff[3];
	int bytesRead;
	if ((bytesRead = read(fdMotor, u8Buff, 3)) != 3)
	{
		printf("get_motor_states(): the motor controller did not respond or only partial responded, \n%s, %d bytes read\n", strerror(errno), bytesRead);
		//return(-1);
	}

	//Test
	printf("%d bytes read\n", bytesRead);
	for (int i = 0; i < bytesRead; i++)
	{
		printf("%d ", u8Buff[i]);
	}
	printf("\n");

	/* Report any errors the motor controller had with the transmission */
	int iError = (u8Buff[0] & ERROR_MASK) >> ERROR_OFFSET;
	if ( iError & (FRAME_ERROR|DATA_OVERRUN_ERROR|PARITY_ERROR|TIMEOUT_ERROR) )
	{
		printf("get_motor_states(): the motor controller could not process comand, Error %d\n", iError);
		return(-1);
	}

	/* Store the current control mode */
	controlMode = ( u8Buff[0] & CONTROL_MODE_MASK ) >> CONTROL_MODE_OFFSET;

	/* Store the current motor velocities */
	_iLeftVelocity = ((((u8Buff[0] & LEFT_DIR_MASK) >> LEFT_DIR_OFFSET)==FORWARD) ? 1 : -1) * (int)u8Buff[1];
	_iRightVelocity = ((((u8Buff[0] & RIGHT_DIR_MASK) >> RIGHT_DIR_OFFSET)==FORWARD)? 1 : -1) * (int)u8Buff[2];

	return(0);
}

/* Set motors based on given velocity:
 * Fwd range [0,255]
 * Rot range [-128,127]
 */
int Motors_Old::set_heading(int iFwdVelocity, int iRotation)
{
    // XXX: hack!
    //printf("irotation %d",iRotation);
	iRotation *= 1.15;
    //printf("\tirotation %d\n",iRotation);

	// convert
	int left  = iFwdVelocity + iRotation ;
	int right = iFwdVelocity - iRotation ;

	if (1)
	{
		// scale speed
		left  = ( left  * _max_speed_ / 255 ) ;
		right = ( right * _max_speed_ / 255 ) ;
	}
	else
	{
		// cap speed
		if (left  > _max_speed_) left  = _max_speed_ ;
		if (right > _max_speed_) right = _max_speed_ ;
	}

	// don't go backwards
	if (right < 0) right = 0 ;
	if (left  < 0) left  = 0 ;

	// motors don't respond until certain output is reached
	if (right != 0) right += MINREQSPEED ;
	if (left  != 0) left  += MINREQSPEED ;

	// show
	printf("Motors: L=%d R=%d \n",left,right);

	// do it!
	return this->set_motors( left , right );
}

void Motors_Old::set_max_speed(int maxspeed)
{
	/* 0-255 */
	_max_speed_ = maxspeed;
}

<commit_msg>...forgot the motors file on previous commit<commit_after>#include "motors_old.h"

#define MINREQSPEED 5
#define POLARITY -1     // direction of forward / connection to motor

Motors_Old::Motors_Old()
{
	//ctor
	fdMotor = -1;
	dVelocityScale = 1;
	_max_speed_=50;
	//SetupSerial();
}

Motors_Old::~Motors_Old()
{
	//dtor
	ShutdownSerial();
}

int Motors_Old::SetupSerial()
{
	/* Open serial port with the specified flags
	 * O_RDWR - for reading and writing
	 * O_NOCTTY - don't act as the controlling terminal for the port
	 * O_DSYNC | O_RSYNC - complete i/o operiations as definded by synchronized i/o data
	 *	integrity completion (i.e. waits for the data but not meta-data to be written
	 *	to the file before continuing execution) - this doesn't seem to work
	 * O_NDELAY - don't wait for the DCD line to go to the space voltage
	 */
	if ((fdMotor = open(DEFAULT_PORT, O_RDWR | O_NOCTTY | O_DSYNC | O_RSYNC | O_NDELAY)) < 0)
	{
		printf("SetupSerial(): could not open port %s, %s\n", DEFAULT_PORT, strerror(errno));
		return(-1);
	}

	/* Set the port back to blocking (waiting) behavior for calls to read() */
	//fcntl(fdMotor, F_SETFL, 0);
	/*no! => go nonblocking!*/
	fcntl(fdMotor, F_SETFL, O_NONBLOCK);

	/* Get the current options for the port */
	struct termios options;
	if (tcgetattr(fdMotor, &options) < 0)
	{
		printf("SetupSerial(): could not get the serial port options, %s\n", strerror(errno));
		ShutdownSerial();
		return(-1);
	}

	/* Configure the port options */
	options.c_cflag |= (CREAD | CLOCAL); /* Enable the receiver and set local mode */
	cfsetispeed(&options, B115200); /* Set 115200 baud rate */
	cfsetospeed(&options, B115200);
	options.c_cflag &= ~PARENB; /* Set no parity */
	options.c_cflag &= ~CSTOPB; /* Set 1 stop bit */
	options.c_cflag &= ~CSIZE; /* Set 8 data bits */
	options.c_cflag |= CS8;
	options.c_cc[VMIN]  = 0; /* Set .2 sec timeout */
	options.c_cc[VTIME] = 2;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* Set raw input and output */
	options.c_oflag &= ~OPOST;

	/* Flush input and output buffers and then set the new options for the port */
	if (tcsetattr(fdMotor, TCSAFLUSH, &options) < 0 )
	{
		printf("SetupSerial(): could not set the serial port options, %s\n", strerror(errno));
		ShutdownSerial();
		return(-1);
	}
	return(0);
}

int Motors_Old::ShutdownSerial()
{
	if (close(fdMotor) < 0)
	{
		printf("ShutdownSerial(): could not close the serial port, %s\n", strerror(errno));
		fdMotor = -1;
		return(-1);
	}
	fdMotor = -1;
	return(0);
}

int Motors_Old::Shutdown()
{
	return(ShutdownSerial());
}

/* NOTE:
 *	When you raise the DTR line, if the motor controller is in AUTONOMOUS_MODE,
 *	it reads in any data in its uart buffer (4 bytes at most). Then, in all modes,
 *	it sends back its current motor states, control mode, and any errors it had
 *	with the transmission.
 */
int Motors_Old::set_motors(int iLeftVelocity, int iRightVelocity)
{
	/* Scale the motor velocities, limit them to vaild values, and store them in the
	 * correct form to transmit to the motor controller.
	 * 	Alternate Title: fun with the ? operator
	 */
	int iScaledLeftVel = POLARITY * (int)(dVelocityScale * iLeftVelocity);
	int iScaledRightVel = POLARITY * (int)(dVelocityScale * iRightVelocity);
	unsigned char data[3] =
	{
		(unsigned char)( (((iScaledLeftVel < 0) ? REVERSE : FORWARD) << LEFT_DIR_OFFSET) | (((iScaledRightVel < 0) ? REVERSE : FORWARD) << RIGHT_DIR_OFFSET) ),
		(unsigned char)( min(abs(iScaledLeftVel), 255) ),
		(unsigned char)( min(abs(iScaledRightVel), 255) )
	};

	/* Send the motor states to the motor controller */
	if ( write(fdMotor, data, 3) != 3 )
	{
		printf("set_motors(): could not write to serial port, %s\n", strerror(errno));
		return(-1);
	}

	/* Make sure the data has finished being written - this can be removed if the option can be made work in open() */
	tcdrain(fdMotor);

	/* Get the current motor states from the motor controller */
	return( get_motor_states() );
}

int Motors_Old::get_motor_states(void)
{
	/* Flush any old data in the read buffer */
	tcflush(fdMotor, TCIFLUSH);

	/* Set the DTR line high to intterupt the motor controller */
	int status;
	if (ioctl(fdMotor, TIOCMGET, &status))
	{
		printf("get_motor_states(): could not get serial port status, %s\n", strerror(errno));
		return(-1);
	}
	status |= TIOCM_DTR;
	if (ioctl(fdMotor, TIOCMSET, &status))
	{
		printf("get_motor_states(): could not set RTS high, %s\n", strerror(errno));
		return(-1);
	}

	/*
	 * If the DTR line can be raised and lowered in less than a full clock cycle
	 * of the controller, there should be a delay here to make sure the motor
	 * controller interrupts.
	 */

	/* Set the DTR line back to low
	 *	If there are problems, you might need to get the motor status again with
	 *	ioctl(fdMotor, TIOCMGET, &status) before doing this.
	 */
	status &= ~TIOCM_DTR;
	if (ioctl(fdMotor, TIOCMSET, &status))
	{
		printf("get_motor_states(): could not set RTS low, %s\n", strerror(errno));
		return(-1);
	}

	/* Read each byte sent from the controller */
	unsigned char u8Buff[3];
	int bytesRead;
	if ((bytesRead = read(fdMotor, u8Buff, 3)) != 3)
	{
		printf("get_motor_states(): the motor controller did not respond or only partial responded, \n%s, %d bytes read\n", strerror(errno), bytesRead);
		//return(-1);
	}

	//Test
	printf("%d bytes read\n", bytesRead);
	for (int i = 0; i < bytesRead; i++)
	{
		printf("%d ", u8Buff[i]);
	}
	printf("\n");

	/* Report any errors the motor controller had with the transmission */
	int iError = (u8Buff[0] & ERROR_MASK) >> ERROR_OFFSET;
	if ( iError & (FRAME_ERROR|DATA_OVERRUN_ERROR|PARITY_ERROR|TIMEOUT_ERROR) )
	{
		printf("get_motor_states(): the motor controller could not process comand, Error %d\n", iError);
		return(-1);
	}

	/* Store the current control mode */
	controlMode = ( u8Buff[0] & CONTROL_MODE_MASK ) >> CONTROL_MODE_OFFSET;

	/* Store the current motor velocities */
	_iLeftVelocity = ((((u8Buff[0] & LEFT_DIR_MASK) >> LEFT_DIR_OFFSET)==FORWARD) ? 1 : -1) * (int)u8Buff[1];
	_iRightVelocity = ((((u8Buff[0] & RIGHT_DIR_MASK) >> RIGHT_DIR_OFFSET)==FORWARD)? 1 : -1) * (int)u8Buff[2];

	return(0);
}

/* Set motors based on given velocity:
 * Fwd range [0,255]
 * Rot range [-128,127]
 */
int Motors_Old::set_heading(int iFwdVelocity, int iRotation)
{
    // XXX: hack!
    //printf("irotation %d",iRotation);
	//iRotation *= 1.1;
    //printf("\tirotation %d\n",iRotation);

	// convert
	int left  = iFwdVelocity + iRotation ;
	int right = iFwdVelocity - iRotation ;

	if (1)
	{
		// scale speed
		left  = ( left  * _max_speed_ / 255 ) ;
		right = ( right * _max_speed_ / 255 ) ;
	}
	else
	{
		// cap speed
		if (left  > _max_speed_) left  = _max_speed_ ;
		if (right > _max_speed_) right = _max_speed_ ;
	}

	// don't go backwards
	if (right < 0) right = 0 ;
	if (left  < 0) left  = 0 ;

	// motors don't respond until certain output is reached
	if (right != 0) right += MINREQSPEED ;
	if (left  != 0) left  += MINREQSPEED ;

	// show
	printf("Motors: L=%d R=%d \n",left,right);

	// do it!
	return this->set_motors( left , right );
}

void Motors_Old::set_max_speed(int maxspeed)
{
	/* 0-255 */
	_max_speed_ = maxspeed;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: languageoptions.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-05 13:37:12 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifdef  SVL_DLLIMPLEMENTATION
#undef  SVL_DLLIMPLEMENTATION
#endif
#define SVT_DLLIMPLEMENTATION

#include "languageoptions.hxx"

#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <cjkoptions.hxx>
#endif
#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include <ctloptions.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif

// global ----------------------------------------------------------------------

namespace { struct ALMutex : public rtl::Static< ::osl::Mutex, ALMutex > {}; }

// class SvtLanguageOptions ----------------------------------------------------

SvtLanguageOptions::SvtLanguageOptions( sal_Bool _bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( ALMutex::get() );

    m_pCJKOptions = new SvtCJKOptions( _bDontLoad );
    m_pCTLOptions = new SvtCTLOptions( _bDontLoad );
    StartListening(*m_pCTLOptions);
}
//------------------------------------------------------------------------------
SvtLanguageOptions::~SvtLanguageOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( ALMutex::get() );

    delete m_pCJKOptions;
    delete m_pCTLOptions;
}
//------------------------------------------------------------------------------
// CJK options -----------------------------------------------------------------
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCJKFontEnabled() const
{
    return m_pCJKOptions->IsCJKFontEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalTextEnabled() const
{
    return m_pCJKOptions->IsVerticalTextEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAsianTypographyEnabled() const
{
    return m_pCJKOptions->IsAsianTypographyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsJapaneseFindEnabled() const
{
    return m_pCJKOptions->IsJapaneseFindEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsRubyEnabled() const
{
    return m_pCJKOptions->IsRubyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsChangeCaseMapEnabled() const
{
    return m_pCJKOptions->IsChangeCaseMapEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsDoubleLinesEnabled() const
{
    return m_pCJKOptions->IsDoubleLinesEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsEmphasisMarksEnabled() const
{
    return m_pCJKOptions->IsEmphasisMarksEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalCallOutEnabled() const
{
    return m_pCJKOptions->IsVerticalCallOutEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetAll( sal_Bool _bSet )
{
    m_pCJKOptions->SetAll( _bSet );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAnyEnabled() const
{
    return m_pCJKOptions->IsAnyEnabled();
}
//------------------------------------------------------------------------------
// CTL options -----------------------------------------------------------------
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLFontEnabled() const
{
    return m_pCTLOptions->IsCTLFontEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLSequenceChecking( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLSequenceChecking() const
{
    return m_pCTLOptions->IsCTLSequenceChecking();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const
{
    sal_Bool bReadOnly = sal_False;
    switch(eOption)
    {
        // cjk options
        case SvtLanguageOptions::E_CJKFONT          : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT        ); break;
        case SvtLanguageOptions::E_VERTICALTEXT     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT   ); break;
        case SvtLanguageOptions::E_ASIANTYPOGRAPHY  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break;
        case SvtLanguageOptions::E_JAPANESEFIND     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND   ); break;
        case SvtLanguageOptions::E_RUBY             : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY           ); break;
        case SvtLanguageOptions::E_CHANGECASEMAP    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP  ); break;
        case SvtLanguageOptions::E_DOUBLELINES      : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES    ); break;
        case SvtLanguageOptions::E_EMPHASISMARKS    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS  ); break;
        case SvtLanguageOptions::E_VERTICALCALLOUT  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break;
        case SvtLanguageOptions::E_ALLCJK           : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL            ); break;
        // ctl options
        case SvtLanguageOptions::E_CTLFONT              : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT            ); break;
        case SvtLanguageOptions::E_CTLSEQUENCECHECKING  : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break;
        case SvtLanguageOptions::E_CTLCURSORMOVEMENT    : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT  ); break;
        case SvtLanguageOptions::E_CTLTEXTNUMERALS      : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS    ); break;
    }
    return bReadOnly;
}
/* -----------------30.04.2003 11:03-----------------

 --------------------------------------------------*/
void SvtLanguageOptions::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    vos::OGuard aVclGuard( Application::GetSolarMutex() );
    Broadcast( rHint );
}

// -----------------------------------------------------------------------------
// returns for a language the scripttype
sal_uInt16 SvtLanguageOptions::GetScriptTypeOfLanguage( sal_uInt16 nLang )
{
    if( LANGUAGE_DONTKNOW == nLang )
        nLang = LANGUAGE_ENGLISH_US;
    else if( LANGUAGE_SYSTEM == nLang  )
        nLang = Application::GetSettings().GetLanguage();

    USHORT nScript;
    switch( nLang )
    {
        // CJK
        case LANGUAGE_CHINESE:
        case LANGUAGE_CHINESE_TRADITIONAL:
        case LANGUAGE_CHINESE_SIMPLIFIED:
        case LANGUAGE_CHINESE_HONGKONG:
        case LANGUAGE_CHINESE_SINGAPORE:
        case LANGUAGE_CHINESE_MACAU:
        case LANGUAGE_JAPANESE:
        case LANGUAGE_KOREAN:
        case LANGUAGE_KOREAN_JOHAB:
        case LANGUAGE_USER_KOREAN_NORTH:
            nScript = SCRIPTTYPE_ASIAN;
            break;

        // CTL
        case LANGUAGE_ARABIC:
        case LANGUAGE_ARABIC_SAUDI_ARABIA:
        case LANGUAGE_ARABIC_IRAQ:
        case LANGUAGE_ARABIC_EGYPT:
        case LANGUAGE_ARABIC_LIBYA:
        case LANGUAGE_ARABIC_ALGERIA:
        case LANGUAGE_ARABIC_MOROCCO:
        case LANGUAGE_ARABIC_TUNISIA:
        case LANGUAGE_ARABIC_OMAN:
        case LANGUAGE_ARABIC_YEMEN:
        case LANGUAGE_ARABIC_SYRIA:
        case LANGUAGE_ARABIC_JORDAN:
        case LANGUAGE_ARABIC_LEBANON:
        case LANGUAGE_ARABIC_KUWAIT:
        case LANGUAGE_ARABIC_UAE:
        case LANGUAGE_ARABIC_BAHRAIN:
        case LANGUAGE_ARABIC_QATAR:
        case LANGUAGE_ASSAMESE:
        case LANGUAGE_BENGALI:
        case LANGUAGE_BENGALI_BANGLADESH:
        case LANGUAGE_FARSI:
        case LANGUAGE_HEBREW:
        case LANGUAGE_MARATHI:
        case LANGUAGE_PUNJABI:
        case LANGUAGE_GUJARATI:
        case LANGUAGE_HINDI:
        case LANGUAGE_KANNADA:
        case LANGUAGE_KASHMIRI:
        case LANGUAGE_KASHMIRI_INDIA:
        case LANGUAGE_KHMER:
        case LANGUAGE_LAO:
        case LANGUAGE_MALAYALAM:
        case LANGUAGE_MANIPURI:
        case LANGUAGE_MONGOLIAN_MONGOLIAN:
        case LANGUAGE_NEPALI:
        case LANGUAGE_NEPALI_INDIA:
        case LANGUAGE_ORIYA:
        case LANGUAGE_SANSKRIT:
        case LANGUAGE_SINDHI:
        case LANGUAGE_SINDHI_PAKISTAN:
        case LANGUAGE_SINHALESE_SRI_LANKA:
        case LANGUAGE_SYRIAC:
        case LANGUAGE_TAMIL:
        case LANGUAGE_TELUGU:
        case LANGUAGE_THAI:
        case LANGUAGE_TIBETAN:
        case LANGUAGE_DZONGKHA:
        case LANGUAGE_URDU:
        case LANGUAGE_URDU_PAKISTAN:
        case LANGUAGE_URDU_INDIA:
        case LANGUAGE_USER_KURDISH_IRAQ:
        case LANGUAGE_USER_KURDISH_IRAN:
        case LANGUAGE_VIETNAMESE:
            nScript = SCRIPTTYPE_COMPLEX;
            break;

// currently not knowing scripttype - defaultet to LATIN:
/*
#define LANGUAGE_ARMENIAN                   0x042B
#define LANGUAGE_INDONESIAN                 0x0421
#define LANGUAGE_KAZAK                      0x043F
#define LANGUAGE_KONKANI                    0x0457
#define LANGUAGE_MACEDONIAN                 0x042F
#define LANGUAGE_TATAR                      0x0444
*/

    default:
        switch ( nLang & LANGUAGE_MASK_PRIMARY )
        {
            // CJK catcher
            case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
                nScript = SCRIPTTYPE_ASIAN;
                break;
            // CTL catcher
            case LANGUAGE_ARABIC & LANGUAGE_MASK_PRIMARY:
                nScript = SCRIPTTYPE_COMPLEX;
                break;
            // Western (actually not necessarily Latin but also Cyrillic, for example)
            default:
                nScript = SCRIPTTYPE_LATIN;
        }
        break;
    }
    return nScript;
}
// -----------------------------------------------------------------------------
<commit_msg>INTEGRATION: CWS ooo19126 (1.13.2); FILE MERGED 2005/09/05 14:52:05 rt 1.13.2.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: languageoptions.cxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 14:41:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifdef  SVL_DLLIMPLEMENTATION
#undef  SVL_DLLIMPLEMENTATION
#endif
#define SVT_DLLIMPLEMENTATION

#include "languageoptions.hxx"

#ifndef _SVTOOLS_CJKOPTIONS_HXX
#include <cjkoptions.hxx>
#endif
#ifndef _SVTOOLS_CTLOPTIONS_HXX
#include <ctloptions.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif
#ifndef INCLUDED_RTL_INSTANCE_HXX
#include <rtl/instance.hxx>
#endif

// global ----------------------------------------------------------------------

namespace { struct ALMutex : public rtl::Static< ::osl::Mutex, ALMutex > {}; }

// class SvtLanguageOptions ----------------------------------------------------

SvtLanguageOptions::SvtLanguageOptions( sal_Bool _bDontLoad )
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( ALMutex::get() );

    m_pCJKOptions = new SvtCJKOptions( _bDontLoad );
    m_pCTLOptions = new SvtCTLOptions( _bDontLoad );
    StartListening(*m_pCTLOptions);
}
//------------------------------------------------------------------------------
SvtLanguageOptions::~SvtLanguageOptions()
{
    // Global access, must be guarded (multithreading)
    ::osl::MutexGuard aGuard( ALMutex::get() );

    delete m_pCJKOptions;
    delete m_pCTLOptions;
}
//------------------------------------------------------------------------------
// CJK options -----------------------------------------------------------------
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCJKFontEnabled() const
{
    return m_pCJKOptions->IsCJKFontEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalTextEnabled() const
{
    return m_pCJKOptions->IsVerticalTextEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAsianTypographyEnabled() const
{
    return m_pCJKOptions->IsAsianTypographyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsJapaneseFindEnabled() const
{
    return m_pCJKOptions->IsJapaneseFindEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsRubyEnabled() const
{
    return m_pCJKOptions->IsRubyEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsChangeCaseMapEnabled() const
{
    return m_pCJKOptions->IsChangeCaseMapEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsDoubleLinesEnabled() const
{
    return m_pCJKOptions->IsDoubleLinesEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsEmphasisMarksEnabled() const
{
    return m_pCJKOptions->IsEmphasisMarksEnabled();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsVerticalCallOutEnabled() const
{
    return m_pCJKOptions->IsVerticalCallOutEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetAll( sal_Bool _bSet )
{
    m_pCJKOptions->SetAll( _bSet );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsAnyEnabled() const
{
    return m_pCJKOptions->IsAnyEnabled();
}
//------------------------------------------------------------------------------
// CTL options -----------------------------------------------------------------
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLFontEnabled( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLFontEnabled( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLFontEnabled() const
{
    return m_pCTLOptions->IsCTLFontEnabled();
}
//------------------------------------------------------------------------------
void SvtLanguageOptions::SetCTLSequenceChecking( sal_Bool _bEnabled )
{
    m_pCTLOptions->SetCTLSequenceChecking( _bEnabled );
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsCTLSequenceChecking() const
{
    return m_pCTLOptions->IsCTLSequenceChecking();
}
//------------------------------------------------------------------------------
sal_Bool SvtLanguageOptions::IsReadOnly(SvtLanguageOptions::EOption eOption) const
{
    sal_Bool bReadOnly = sal_False;
    switch(eOption)
    {
        // cjk options
        case SvtLanguageOptions::E_CJKFONT          : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CJKFONT        ); break;
        case SvtLanguageOptions::E_VERTICALTEXT     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALTEXT   ); break;
        case SvtLanguageOptions::E_ASIANTYPOGRAPHY  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ASIANTYPOGRAPHY); break;
        case SvtLanguageOptions::E_JAPANESEFIND     : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_JAPANESEFIND   ); break;
        case SvtLanguageOptions::E_RUBY             : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_RUBY           ); break;
        case SvtLanguageOptions::E_CHANGECASEMAP    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_CHANGECASEMAP  ); break;
        case SvtLanguageOptions::E_DOUBLELINES      : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_DOUBLELINES    ); break;
        case SvtLanguageOptions::E_EMPHASISMARKS    : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_EMPHASISMARKS  ); break;
        case SvtLanguageOptions::E_VERTICALCALLOUT  : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_VERTICALCALLOUT); break;
        case SvtLanguageOptions::E_ALLCJK           : bReadOnly = m_pCJKOptions->IsReadOnly(SvtCJKOptions::E_ALL            ); break;
        // ctl options
        case SvtLanguageOptions::E_CTLFONT              : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLFONT            ); break;
        case SvtLanguageOptions::E_CTLSEQUENCECHECKING  : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLSEQUENCECHECKING); break;
        case SvtLanguageOptions::E_CTLCURSORMOVEMENT    : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLCURSORMOVEMENT  ); break;
        case SvtLanguageOptions::E_CTLTEXTNUMERALS      : bReadOnly = m_pCTLOptions->IsReadOnly(SvtCTLOptions::E_CTLTEXTNUMERALS    ); break;
    }
    return bReadOnly;
}
/* -----------------30.04.2003 11:03-----------------

 --------------------------------------------------*/
void SvtLanguageOptions::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
    vos::OGuard aVclGuard( Application::GetSolarMutex() );
    Broadcast( rHint );
}

// -----------------------------------------------------------------------------
// returns for a language the scripttype
sal_uInt16 SvtLanguageOptions::GetScriptTypeOfLanguage( sal_uInt16 nLang )
{
    if( LANGUAGE_DONTKNOW == nLang )
        nLang = LANGUAGE_ENGLISH_US;
    else if( LANGUAGE_SYSTEM == nLang  )
        nLang = Application::GetSettings().GetLanguage();

    USHORT nScript;
    switch( nLang )
    {
        // CJK
        case LANGUAGE_CHINESE:
        case LANGUAGE_CHINESE_TRADITIONAL:
        case LANGUAGE_CHINESE_SIMPLIFIED:
        case LANGUAGE_CHINESE_HONGKONG:
        case LANGUAGE_CHINESE_SINGAPORE:
        case LANGUAGE_CHINESE_MACAU:
        case LANGUAGE_JAPANESE:
        case LANGUAGE_KOREAN:
        case LANGUAGE_KOREAN_JOHAB:
        case LANGUAGE_USER_KOREAN_NORTH:
            nScript = SCRIPTTYPE_ASIAN;
            break;

        // CTL
        case LANGUAGE_ARABIC:
        case LANGUAGE_ARABIC_SAUDI_ARABIA:
        case LANGUAGE_ARABIC_IRAQ:
        case LANGUAGE_ARABIC_EGYPT:
        case LANGUAGE_ARABIC_LIBYA:
        case LANGUAGE_ARABIC_ALGERIA:
        case LANGUAGE_ARABIC_MOROCCO:
        case LANGUAGE_ARABIC_TUNISIA:
        case LANGUAGE_ARABIC_OMAN:
        case LANGUAGE_ARABIC_YEMEN:
        case LANGUAGE_ARABIC_SYRIA:
        case LANGUAGE_ARABIC_JORDAN:
        case LANGUAGE_ARABIC_LEBANON:
        case LANGUAGE_ARABIC_KUWAIT:
        case LANGUAGE_ARABIC_UAE:
        case LANGUAGE_ARABIC_BAHRAIN:
        case LANGUAGE_ARABIC_QATAR:
        case LANGUAGE_ASSAMESE:
        case LANGUAGE_BENGALI:
        case LANGUAGE_BENGALI_BANGLADESH:
        case LANGUAGE_FARSI:
        case LANGUAGE_HEBREW:
        case LANGUAGE_MARATHI:
        case LANGUAGE_PUNJABI:
        case LANGUAGE_GUJARATI:
        case LANGUAGE_HINDI:
        case LANGUAGE_KANNADA:
        case LANGUAGE_KASHMIRI:
        case LANGUAGE_KASHMIRI_INDIA:
        case LANGUAGE_KHMER:
        case LANGUAGE_LAO:
        case LANGUAGE_MALAYALAM:
        case LANGUAGE_MANIPURI:
        case LANGUAGE_MONGOLIAN_MONGOLIAN:
        case LANGUAGE_NEPALI:
        case LANGUAGE_NEPALI_INDIA:
        case LANGUAGE_ORIYA:
        case LANGUAGE_SANSKRIT:
        case LANGUAGE_SINDHI:
        case LANGUAGE_SINDHI_PAKISTAN:
        case LANGUAGE_SINHALESE_SRI_LANKA:
        case LANGUAGE_SYRIAC:
        case LANGUAGE_TAMIL:
        case LANGUAGE_TELUGU:
        case LANGUAGE_THAI:
        case LANGUAGE_TIBETAN:
        case LANGUAGE_DZONGKHA:
        case LANGUAGE_URDU:
        case LANGUAGE_URDU_PAKISTAN:
        case LANGUAGE_URDU_INDIA:
        case LANGUAGE_USER_KURDISH_IRAQ:
        case LANGUAGE_USER_KURDISH_IRAN:
        case LANGUAGE_VIETNAMESE:
            nScript = SCRIPTTYPE_COMPLEX;
            break;

// currently not knowing scripttype - defaultet to LATIN:
/*
#define LANGUAGE_ARMENIAN                   0x042B
#define LANGUAGE_INDONESIAN                 0x0421
#define LANGUAGE_KAZAK                      0x043F
#define LANGUAGE_KONKANI                    0x0457
#define LANGUAGE_MACEDONIAN                 0x042F
#define LANGUAGE_TATAR                      0x0444
*/

    default:
        switch ( nLang & LANGUAGE_MASK_PRIMARY )
        {
            // CJK catcher
            case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY:
                nScript = SCRIPTTYPE_ASIAN;
                break;
            // CTL catcher
            case LANGUAGE_ARABIC & LANGUAGE_MASK_PRIMARY:
                nScript = SCRIPTTYPE_COMPLEX;
                break;
            // Western (actually not necessarily Latin but also Cyrillic, for example)
            default:
                nScript = SCRIPTTYPE_LATIN;
        }
        break;
    }
    return nScript;
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include <limits>

#define FLATC_VERSION "1.3.0 (" __DATE__ ")"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
    flatbuffers::IDLOptions::kMAX,
    "Generate GRPC interfaces",
    flatbuffers::CPPMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH            Prefix PATH to all generated files.\n"
      "  -I PATH            Search for includes in the specified path.\n"
      "  -M                 Print make rules for generated files.\n"
      "  --version          Print the version number of flatc and exit.\n"
      "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
      "                     no trailing commas in tables/vectors.\n"
      "  --defaults-json    Output fields whose value is the default when\n"
      "                     writing JSON\n"
      "  --unknown-json     Allow fields in JSON that are not defined in the\n"
      "                     schema. These fields will be discared when generating\n"
      "                     binaries.\n"
      "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
      "                     also implies --no-prefix.\n"
      "  --gen-includes     (deprecated), this is the default behavior.\n"
      "                     If the original behavior is required (no include\n"
      "                     statements) use --no-includes.\n"
      "  --no-includes      Don\'t generate include statements for included\n"
      "                     schemas the generated file depends on (C++).\n"
      "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile      Generate single output file for C#.\n"
      "  --gen-name-strings		 Generate type name functions for C++.\n"
      "  --escape-proto-identifiers      Disable appending '_' in namespaces names.\n"
      "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
      "                     This may crash flatc given a mismatched schema.\n"
      "  --proto            Input is a .proto, translate to .fbs.\n"
      "  --schema           Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
	    } else if (arg == "--escape-proto-identifiers") {
		    opts.escape_proto_identifiers = true;
	    } else if (arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else if(arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION);
        exit(0);
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator) {
    Error("no options: specify at least one generator.", true);
  }

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        // Check if file contains 0 bytes.
        if (contents.length() != strlen(contents.c_str())) {
          Error("input file appears to be binary: " + *file_it, true);
        }
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase, opts.escape_proto_identifiers)

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<commit_msg>Update flatc.cpp<commit_after>/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include <limits>

#define FLATC_VERSION "1.3.0 (" __DATE__ ")"

static void Error(const std::string &err, bool usage = false,
                  bool show_exe_name = true);

// This struct allows us to create a table of all possible output generators
// for the various programming languages and formats we support.
struct Generator {
  bool (*generate)(const flatbuffers::Parser &parser,
                   const std::string &path,
                   const std::string &file_name);
  const char *generator_opt_short;
  const char *generator_opt_long;
  const char *lang_name;
  flatbuffers::IDLOptions::Language lang;
  const char *generator_help;

  std::string (*make_rule)(const flatbuffers::Parser &parser,
                           const std::string &path,
                           const std::string &file_name);
};

const Generator generators[] = {
  { flatbuffers::GenerateBinary,   "-b", "--binary", "binary",
    flatbuffers::IDLOptions::kMAX,
    "Generate wire format binaries for any data definitions",
    flatbuffers::BinaryMakeRule },
  { flatbuffers::GenerateTextFile, "-t", "--json", "text",
    flatbuffers::IDLOptions::kMAX,
    "Generate text output for any data definitions",
    flatbuffers::TextMakeRule },
  { flatbuffers::GenerateCPP,      "-c", "--cpp", "C++",
    flatbuffers::IDLOptions::kMAX,
    "Generate C++ headers for tables/structs",
    flatbuffers::CPPMakeRule },
  { flatbuffers::GenerateGo,       "-g", "--go", "Go",
    flatbuffers::IDLOptions::kGo,
    "Generate Go files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGeneral,  "-j", "--java", "Java",
    flatbuffers::IDLOptions::kJava,
    "Generate Java classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateJS,       "-s", "--js", "JavaScript",
    flatbuffers::IDLOptions::kMAX,
    "Generate JavaScript code for tables/structs",
    flatbuffers::JSMakeRule },
  { flatbuffers::GenerateGeneral,  "-n", "--csharp", "C#",
    flatbuffers::IDLOptions::kCSharp,
    "Generate C# classes for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePython,   "-p", "--python", "Python",
    flatbuffers::IDLOptions::kMAX,
    "Generate Python files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
    flatbuffers::IDLOptions::kMAX,
    "Generate PHP files for tables/structs",
    flatbuffers::GeneralMakeRule },
  { flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
    flatbuffers::IDLOptions::kMAX,
    "Generate GRPC interfaces",
    flatbuffers::CPPMakeRule },
};

const char *program_name = nullptr;
flatbuffers::Parser *parser = nullptr;

static void Error(const std::string &err, bool usage, bool show_exe_name) {
  if (show_exe_name) printf("%s: ", program_name);
  printf("%s\n", err.c_str());
  if (usage) {
    printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", program_name);
    for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
      printf("  %-12s %s %s.\n",
             generators[i].generator_opt_long,
             generators[i].generator_opt_short
               ? generators[i].generator_opt_short
               : "  ",
             generators[i].generator_help);
    printf(
      "  -o PATH            Prefix PATH to all generated files.\n"
      "  -I PATH            Search for includes in the specified path.\n"
      "  -M                 Print make rules for generated files.\n"
      "  --version          Print the version number of flatc and exit.\n"
      "  --strict-json      Strict JSON: field names must be / will be quoted,\n"
      "                     no trailing commas in tables/vectors.\n"
      "  --defaults-json    Output fields whose value is the default when\n"
      "                     writing JSON\n"
      "  --unknown-json     Allow fields in JSON that are not defined in the\n"
      "                     schema. These fields will be discared when generating\n"
      "                     binaries.\n"
      "  --no-prefix        Don\'t prefix enum values with the enum type in C++.\n"
      "  --scoped-enums     Use C++11 style scoped and strongly typed enums.\n"
      "                     also implies --no-prefix.\n"
      "  --gen-includes     (deprecated), this is the default behavior.\n"
      "                     If the original behavior is required (no include\n"
      "                     statements) use --no-includes.\n"
      "  --no-includes      Don\'t generate include statements for included\n"
      "                     schemas the generated file depends on (C++).\n"
      "  --gen-mutable      Generate accessors that can mutate buffers in-place.\n"
      "  --gen-onefile      Generate single output file for C#.\n"
      "  --gen-name-strings		 Generate type name functions for C++.\n"
      "  --escape-proto-identifiers      Disable appending '_' in namespaces names.\n"
      "  --raw-binary       Allow binaries without file_indentifier to be read.\n"
      "                     This may crash flatc given a mismatched schema.\n"
      "  --proto            Input is a .proto, translate to .fbs.\n"
      "  --schema           Serialize schemas instead of JSON (use with -b)\n"
      "FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
      "FILEs after the -- must be binary flatbuffer format files.\n"
      "Output files are named using the base file name of the input,\n"
      "and written to the current directory or the path given by -o.\n"
      "example: %s -c -b schema1.fbs schema2.fbs data.json\n",
      program_name);
  }
  if (parser) delete parser;
  exit(1);
}

int main(int argc, const char *argv[]) {
  program_name = argv[0];
  flatbuffers::IDLOptions opts;
  std::string output_path;
  const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
  bool generator_enabled[num_generators] = { false };
  bool any_generator = false;
  bool print_make_rules = false;
  bool raw_binary = false;
  bool schema_binary = false;
  std::vector<std::string> filenames;
  std::vector<const char *> include_directories;
  size_t binary_files_from = std::numeric_limits<size_t>::max();
  for (int argi = 1; argi < argc; argi++) {
    std::string arg = argv[argi];
    if (arg[0] == '-') {
      if (filenames.size() && arg[1] != '-')
        Error("invalid option location: " + arg, true);
      if (arg == "-o") {
        if (++argi >= argc) Error("missing path following: " + arg, true);
        output_path = flatbuffers::ConCatPathFileName(argv[argi], "");
      } else if(arg == "-I") {
        if (++argi >= argc) Error("missing path following" + arg, true);
        include_directories.push_back(argv[argi]);
      } else if(arg == "--strict-json") {
        opts.strict_json = true;
      } else if(arg == "--no-js-exports") {
        opts.skip_js_exports = true;
      } else if(arg == "--defaults-json") {
        opts.output_default_scalars_in_json = true;
      } else if (arg == "--unknown-json") {
        opts.skip_unexpected_fields_in_json = true;
      } else if(arg == "--no-prefix") {
        opts.prefixed_enums = false;
      } else if(arg == "--scoped-enums") {
        opts.prefixed_enums = false;
        opts.scoped_enums = true;
      } else if(arg == "--gen-mutable") {
        opts.mutable_buffer = true;
      } else if(arg == "--gen-name-strings") {
        opts.generate_name_strings = true;
      } else if(arg == "--gen-all") {
        opts.generate_all = true;
        opts.include_dependence_headers = false;
      } else if(arg == "--gen-includes") {
        // Deprecated, remove this option some time in the future.
        printf("warning: --gen-includes is deprecated (it is now default)\n");
      } else if(arg == "--no-includes") {
        opts.include_dependence_headers = false;
      } else if (arg == "--gen-onefile") {
        opts.one_file = true;
      } else if (arg == "--raw-binary") {
        raw_binary = true;
      } else if(arg == "--") {  // Separator between text and binary inputs.
        binary_files_from = filenames.size();
      } else if(arg == "--proto") {
        opts.proto_mode = true;
	    } else if (arg == "--escape-proto-identifiers") {
		    opts.escape_proto_identifiers = true;
	    } else if (arg == "--schema") {
        schema_binary = true;
      } else if(arg == "-M") {
        print_make_rules = true;
      } else if(arg == "--version") {
        printf("flatc version %s\n", FLATC_VERSION);
        exit(0);
      } else {
        for (size_t i = 0; i < num_generators; ++i) {
          if (arg == generators[i].generator_opt_long ||
              (generators[i].generator_opt_short &&
               arg == generators[i].generator_opt_short)) {
            generator_enabled[i] = true;
            any_generator = true;
            goto found;
          }
        }
        Error("unknown commandline argument" + arg, true);
        found:;
      }
    } else {
      filenames.push_back(argv[argi]);
    }
  }

  if (!filenames.size()) Error("missing input files", false, true);

  if (opts.proto_mode) {
    if (any_generator)
      Error("cannot generate code directly from .proto files", true);
  } else if (!any_generator) {
    Error("no options: specify at least one generator.", true);
  }

  // Now process the files:
  parser = new flatbuffers::Parser(opts);
  for (auto file_it = filenames.begin();
            file_it != filenames.end();
          ++file_it) {
      std::string contents;
      if (!flatbuffers::LoadFile(file_it->c_str(), true, &contents))
        Error("unable to load file: " + *file_it);

      bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
                       binary_files_from;
      if (is_binary) {
        parser->builder_.Clear();
        parser->builder_.PushFlatBuffer(
          reinterpret_cast<const uint8_t *>(contents.c_str()),
          contents.length());
        if (!raw_binary) {
          // Generally reading binaries that do not correspond to the schema
          // will crash, and sadly there's no way around that when the binary
          // does not contain a file identifier.
          // We'd expect that typically any binary used as a file would have
          // such an identifier, so by default we require them to match.
          if (!parser->file_identifier_.length()) {
            Error("current schema has no file_identifier: cannot test if \"" +
                 *file_it +
                 "\" matches the schema, use --raw-binary to read this file"
                 " anyway.");
          } else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
                                             parser->file_identifier_.c_str())) {
            Error("binary \"" +
                 *file_it +
                 "\" does not have expected file_identifier \"" +
                 parser->file_identifier_ +
                 "\", use --raw-binary to read this file anyway.");
          }
        }
      } else {
        // Check if file contains 0 bytes.
        if (contents.length() != strlen(contents.c_str())) {
          Error("input file appears to be binary: " + *file_it, true);
        }
        if (flatbuffers::GetExtension(*file_it) == "fbs") {
          // If we're processing multiple schemas, make sure to start each
          // one from scratch. If it depends on previous schemas it must do
          // so explicitly using an include.
          delete parser;
          parser = new flatbuffers::Parser(opts);
        }
        auto local_include_directory = flatbuffers::StripFileName(*file_it);
        include_directories.push_back(local_include_directory.c_str());
        include_directories.push_back(nullptr);
        if (!parser->Parse(contents.c_str(), &include_directories[0],
                          file_it->c_str()))
          Error(parser->error_, false, false);
        if (schema_binary) {
          parser->Serialize();
          parser->file_extension_ = reflection::SchemaExtension();
        }
        include_directories.pop_back();
        include_directories.pop_back();
      }

      std::string filebase = flatbuffers::StripPath(
                               flatbuffers::StripExtension(*file_it));

      for (size_t i = 0; i < num_generators; ++i) {
        parser->opts.lang = generators[i].lang;
        if (generator_enabled[i]) {
          if (!print_make_rules) {
            flatbuffers::EnsureDirExists(output_path);
            if (!generators[i].generate(*parser, output_path, filebase)) {
              Error(std::string("Unable to generate ") +
                    generators[i].lang_name +
                    " for " +
                    filebase);
            }
          } else {
            std::string make_rule = generators[i].make_rule(
                *parser, output_path, *file_it);
            if (!make_rule.empty())
              printf("%s\n", flatbuffers::WordWrap(
                  make_rule, 80, " ", " \\").c_str());
          }
        }
      }

      if (opts.proto_mode) GenerateFBS(*parser, output_path, filebase, opts.escape_proto_identifiers);

      // We do not want to generate code for the definitions in this file
      // in any files coming up next.
      parser->MarkGenerated();
  }

  delete parser;
  return 0;
}
<|endoftext|>