<commit_before>#include "AhoCorasickAutomata.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

#define TEST_MAX 1024

struct Test {
  string text;
  vector<string> pattern;
  unordered_map<string, vector<int>> match;
} tests[] = {
    {
        "sting",
        {"i", "in", "tin", "sting"},
        {
            {"i", {2}},
            {"in", {2}},
            {"tin", {1}},
            {"sting", {0}},
        },
    },
    {
        "abedget",
        {"ab", "about", "at", "ate", "be", "bed", "edge", "get"},
        {
            {"ab", {0}},
            {"about", {}},
            {"at", {}},
            {"ate", {}},
            {"be", {1}},
            {"bed", {1}},
            {"edge", {2}},
            {"get", {4}},
        },
    },
    {
        "aaaaaaaa",
        {"a", "aa", "aaa", "aaaa"},
        {
            {"a", {0, 1, 2, 3, 4, 5, 6, 7}},
            {"aa", {0, 1, 2, 3, 4, 5, 6}},
            {"aaa", {0, 1, 2, 3, 4, 5}},
            {"aaaa", {0, 1, 2, 3, 4}},
        },
    },
    {
        "shherishers",
        {"he", "she", "his", "her", "hers"},
        {
            {"he", {2, 7}},
            {"she", {6}},
            {"his", {}},
            {"her", {2, 7}},
            {"hers", {7}},
        },
    },
    {
        "asdfasdfasdfasdf",
        {"asdf"},
        {
            {"asdf", {0, 4, 8, 12}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo"},
        {
            {"oo", {11, 30, 34}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo", "world", "good", "i"},
        {
            {"oo", {11, 30, 34}},
            {"world", {5, 17}},
            {"good", {10, 29}},
            {"i", {24, 26, 40, 48}},
        },
    },
};

void AssertEqual(vector<int> s1, vector<int> s2) {
  sort(s1.begin(), s1.end());
  sort(s2.begin(), s2.end());
  assert(s1.size() == s2.size());
  for (int i = 0; i < s1.size(); i++) {
    assert(s1[i] == s2[i]);
  }
}

void AssertEqual(unordered_map<string, vector<int>> m1,
                 unordered_map<string, vector<int>> m2) {

  unordered_map<string, vector<int>> tmp1 = m1;
  unordered_map<string, vector<int>> tmp2 = m2;
  m1.clear();
  m2.clear();
  for (unordered_map<string, vector<int>>::iterator i = tmp1.begin();
       i != tmp1.end(); i++) {
    string k1 = i->first;
    vector<int> s1 = i->second;
    if (!s1.empty()) {
      m1.insert(make_pair(k1, s1));
    }
  }
  for (unordered_map<string, vector<int>>::iterator i = tmp2.begin();
       i != tmp2.end(); i++) {
    string k2 = i->first;
    vector<int> s2 = i->second;
    if (!s2.empty()) {
      m2.insert(make_pair(k2, s2));
    }
  }

  assert(m1.size() == m2.size());
  for (unordered_map<string, vector<int>>::iterator i = m1.begin();
       i != m1.end(); i++) {
    string k1 = i->first;
    vector<int> s1 = i->second;
    assert(m2.find(k1) != m2.end());
    vector<int> s2 = m2[k1];
    AssertEqual(s1, s2);
  }
}

int main() {
  for (int i = 0; i < sizeof(tests) / sizeof(Test); i++) {
    Test &t = tests[i];

	cout << "i: " << i << endl;
    AcNode *root = AhoCorasickAutomataNew(t.pattern);
    AssertEqual(AhoCorasickAutomataMatch(root, t.text), t.match);
    AhoCorasickAutomataFree(root);
  }
  return 0;
}

<commit_msg>fix test bug, pass all tests<commit_after>#include "AhoCorasickAutomata.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

#define TEST_MAX 1024

struct Test {
  string text;
  vector<string> pattern;
  unordered_map<string, vector<int>> match;
} tests[] = {
    {
        "sting",
        {"i", "in", "tin", "sting"},
        {
            {"i", {2}},
            {"in", {2}},
            {"tin", {1}},
            {"sting", {0}},
        },
    },
    {
        "abedget",
        {"ab", "about", "at", "ate", "be", "bed", "edge", "get"},
        {
            {"ab", {0}},
            {"about", {}},
            {"at", {}},
            {"ate", {}},
            {"be", {1}},
            {"bed", {1}},
            {"edge", {2}},
            {"get", {4}},
        },
    },
    {
        "aaaaaaaa",
        {"a", "aa", "aaa", "aaaa"},
        {
            {"a", {0, 1, 2, 3, 4, 5, 6, 7}},
            {"aa", {0, 1, 2, 3, 4, 5, 6}},
            {"aaa", {0, 1, 2, 3, 4, 5}},
            {"aaaa", {0, 1, 2, 3, 4}},
        },
    },
    {
        "shherishers",
        {"he", "she", "his", "her", "hers"},
        {
            {"he", {2, 7}},
            {"she", {6}},
            {"his", {}},
            {"her", {2, 7}},
            {"hers", {7}},
        },
    },
    {
        "asdfasdfasdfasdf",
        {"asdf"},
        {
            {"asdf", {0, 4, 8, 12}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo"},
        {
            {"oo", {11, 30, 34}},
        },
    },
    {
        "helloworldgoodbyeworldthisisagoodbookformanycomputersciencestudentihop"
        "eyouenjoy",
        {"oo", "world", "good", "i"},
        {
            {"oo", {11, 30, 34}},
            {"world", {5, 17}},
            {"good", {10, 29}},
            {"i", {24, 26, 54, 66}},
        },
    },
};

void AssertEqual(vector<int> s1, vector<int> s2) {
  sort(s1.begin(), s1.end());
  sort(s2.begin(), s2.end());
  assert(s1.size() == s2.size());
  for (int i = 0; i < s1.size(); i++) {
    assert(s1[i] == s2[i]);
  }
}

void AssertEqual(unordered_map<string, vector<int>> m1,
                 unordered_map<string, vector<int>> m2) {

  unordered_map<string, vector<int>> tmp1 = m1;
  unordered_map<string, vector<int>> tmp2 = m2;
  m1.clear();
  m2.clear();
  for (unordered_map<string, vector<int>>::iterator i = tmp1.begin();
       i != tmp1.end(); i++) {
    string k1 = i->first;
    vector<int> s1 = i->second;
    if (!s1.empty()) {
      m1.insert(make_pair(k1, s1));
    }
  }
  for (unordered_map<string, vector<int>>::iterator i = tmp2.begin();
       i != tmp2.end(); i++) {
    string k2 = i->first;
    vector<int> s2 = i->second;
    if (!s2.empty()) {
      m2.insert(make_pair(k2, s2));
    }
  }

  assert(m1.size() == m2.size());
  for (unordered_map<string, vector<int>>::iterator i = m1.begin();
       i != m1.end(); i++) {
    string k1 = i->first;
    vector<int> s1 = i->second;
    assert(m2.find(k1) != m2.end());
    vector<int> s2 = m2[k1];
    AssertEqual(s1, s2);
  }
}

void DumpResult(const unordered_map<string, vector<int>> &result) {
  cout << endl << "dump size: " << result.size() << endl;
  for (auto i = result.begin(); i != result.end(); i++) {
    string key = i->first;
    vector<int> val = i->second;
    cout << "\tkey:" << key << endl;
    cout << "\tval:";
    for (int j = 0; j < val.size(); j++) {
      cout << "\t" << val[j];
    }
    cout << endl;
  }
}

int main() {
  for (int i = 0; i < sizeof(tests) / sizeof(Test); i++) {
    Test &t = tests[i];

    AcNode *root = AhoCorasickAutomataNew(t.pattern);
    AssertEqual(AhoCorasickAutomataMatch(root, t.text), t.match);
    AhoCorasickAutomataFree(root);
  }
  return 0;
}

<|endoftext|>


<commit_before>#include <unistd.h>
#include <signal.h>
#include <fstream>
#include <assert.h>
#include <iostream>
#include <exception>
#include <algorithm>
#include <memory>
#include <libpstack/proc.h>
#include <libpstack/elf.h>
#include <libpstack/dwarf.h>
#include <sys/types.h>

using namespace std;

static int
globmatchR(const char *pattern, const char *name)
{
    for (;; name++) {
        switch (*pattern) {
        case '*':
            // if the rest of the name matches the bit of pattern after '*',
            for (;;) {
                ++name;
                if (globmatchR(pattern + 1, name))
                    return 1;
                if (*name == 0) // exhuasted name without finding a match
                    return 0;
            }
        default:
            if (*name != *pattern)
                return 0;
        }
        if (*pattern++ == 0)
            return 1;
    }
}

static int
globmatch(const string &pattern, const string &name)
{
    return globmatchR(pattern.c_str(), name.c_str());
}

struct ListedSymbol {
    Elf_Sym sym;
    Elf_Off objbase;
    string name;
    size_t count;
    string objname;
    ListedSymbol(const Elf_Sym &sym_, Elf_Off objbase_, string name_, string object)
        : sym(sym_)
        , objbase(objbase_)
        , objname(object)
        , count(0)
        , name(name_)
    {}
    Elf_Off memaddr() const { return  sym.st_value + objbase; }
};

bool operator < (const ListedSymbol &sym, Elf_Off addr) {
    return sym.memaddr() + sym.sym.st_size < addr;
}

static const char *virtpattern = "_ZTV*"; /* wildcard for all vtbls */
static bool compareSymbolsByAddress(const ListedSymbol &l, const ListedSymbol &r) { return l.memaddr() < r.memaddr(); };
static bool compareSymbolsByFrequency(const ListedSymbol &l, const ListedSymbol &r) { return l.count > r.count; };

int
mainExcept(int argc, char *argv[])
{
    std::vector<std::string> patterns;
    shared_ptr<ElfObject> exec;
    shared_ptr<ElfObject> core;
    shared_ptr<Process> process;
    int c;
    int verbose = 0;
    bool showaddrs = false;
    int rate = 1;

    std::vector<std::pair<Elf_Off, Elf_Off>> searchaddrs;
    std::vector<std::pair<std::string, std::string>> pathReplacements;
    char *strbuf = 0;
    char *findstr = 0;
    size_t findstrlen;
    int symOffset = -1;
    bool showloaded = false;

    while ((c = getopt(argc, argv, "o:vhr:sp:f:e:S:R:K:y:l")) != -1) {
        switch (c) {
            case 'p':
                virtpattern = optarg;
                break;
            case 's':
                showaddrs = true;
                break;
            case 'v':
                debug = &clog;
                verbose++;
                break;
            case 'h':
                clog << "usage: canal [exec] <core>" << endl;
                return 0;
            case 'o': // offset within a symbol that the pointers must meet.
                symOffset = strtol(optarg, 0, 0);
                break;

            case 'y':
                patterns.push_back(optarg);
                virtpattern = 0;
                break;

            case 'r': {
                char *from = strdup(optarg);
                char *to  = strchr(from, '=');
                if (to == 0)
                    throw "must specify <to>=<from> for '-r'";
                *to++ = 0;
                pathReplacements.push_back(std::make_pair(from, to));
                break;
            }

            case 'S':
                findstr = optarg;
                findstrlen = strlen(findstr);
                strbuf = new char[findstrlen];
                break;

            case 'f': {
                Elf_Off start = strtoll(optarg, 0, 0);
                searchaddrs.push_back(make_pair(start, start + 1));
                break;
            }

            case 'K':
                rate = atoi(optarg);
                break;
            case 'R': {
                std::ifstream in;
                in.open(optarg);
                if (!in.good())
                    abort();
                char buf[1024];
                int count = 0;
                while (in.good()) {
                    in.getline(buf, sizeof buf);
                    if (in.eof())
                        break;
                    if (++count % rate != 0)
                        continue;
                    char *p = buf;
                    while (isspace(*p))
                        p++;
                    Elf_Off start = strtoll(p, &p, 0);
                    while (*p && isspace(*p))
                        p++;
                    Elf_Off end = *p ? strtoll(p, &p, 0) : start + 1;
                    searchaddrs.push_back(make_pair(start, end));
                    std::clog << "push " << hex << start << ", " << end  << " (" << int(*p) << ")" << std::endl;
                }
                break;
            }

            case 'e':
                searchaddrs.back().second = strtoll(optarg, 0, 0);
                break;

            case 'X':
                ps_lgetfpregs(0, 0, 0);
                break;

            case 'l':
                showloaded = true;
                break;
        }
    }

    if (argc - optind >= 2) {
        exec = make_shared<ElfObject>(argv[optind]);
        optind++;
    }

    if (argc - optind < 1) {
        clog << "usage: canal [exec] <core>" << endl;
        return 0;
    }

    pid_t pid = 0;
    std::istringstream(argv[optind]) >> pid;
    if (pid != 0 && kill(pid, 0) == 0) {
       std::clog << "attaching to live process" << std::endl;
       process = make_shared<LiveProcess>(exec, pid, pathReplacements);
    } else {
       core = make_shared<ElfObject>(argv[optind]);
       process = make_shared<CoreProcess>(exec, core, pathReplacements);
    }
    process->load();
    if (searchaddrs.size()) {
        std::clog << "finding references to " << dec << searchaddrs.size() << " addresses\n";
        for (auto &addr : searchaddrs)
            std::clog << "\t" << addr.first <<" - " << addr.second << "\n";
    }
    clog << "opened process " << process << endl;

    if (showloaded) {
        for (auto loaded = process->objects.begin(); loaded != process->objects.end(); ++loaded)
            std::cout << loaded->object->getName() << "\n";
        exit(0);
    }

    if (virtpattern)
        patterns.push_back(virtpattern);

    vector<ListedSymbol> listed;
    for (auto loaded = process->objects.begin(); loaded != process->objects.end(); ++loaded) {
        size_t count = 0;
        auto syms = loaded->object->getSymbols(".dynsym");
        for (auto sym = syms.begin(); sym != syms.end(); ++sym) {
            for (auto &pattern : patterns) {
                if (globmatch(pattern, (*sym).second)) {
                    listed.push_back(ListedSymbol((*sym).first, loaded->reloc, (*sym).second, loaded->object->io->describe()));
                    count++;
                }
            }
        }
        if (debug)
            *debug << "found " << count << " symbols in " << loaded->object->io->describe() << endl;
    }
    sort(listed.begin() , listed.end() , compareSymbolsByAddress);

    // Now run through the corefile, searching for virtual objects.
    off_t filesize = 0;
    off_t memsize = 0;
    auto segments = core->getSegments();
    for (auto &hdr : segments) {
        if (hdr.p_type != PT_LOAD)
            continue;
        Elf_Off p;
        filesize += hdr.p_filesz;
        memsize += hdr.p_memsz;
        if (debug) {
            *debug << "scan " << hex << hdr.p_vaddr <<  " to " << hdr.p_vaddr + hdr.p_memsz
                << " (filesiz = " << hdr.p_filesz  << ", memsiz=" << hdr.p_memsz << ") ";
        }

        if (findstr) {
            for (auto loc = hdr.p_vaddr; loc < hdr.p_vaddr + hdr.p_filesz - findstrlen; loc++) {
                size_t rc = process->io->read(loc, findstrlen, strbuf);
                assert(rc == findstrlen);
                if (memcmp(strbuf, findstr, rc) == 0)
                    std::cout << "0x" << hex << loc << "\n";
            }
        } else {
            for (auto loc = hdr.p_vaddr; loc < hdr.p_vaddr + hdr.p_filesz; loc += sizeof p) {
                // log a '.' every megabyte.
                if (verbose && (loc - hdr.p_vaddr) % (1024 * 1024) == 0)
                    clog << '.';
                process->io->readObj(loc, &p);
                if (searchaddrs.size()) {
                    for (auto range = searchaddrs.begin(); range != searchaddrs.end(); ++range) {
                        if (p >= range->first && p < range->second && (p % 4 == 0))
                            cout << "0x" << hex << loc << "\n";
                    }
                } else {
                    auto found = lower_bound(listed.begin(), listed.end(), p);
                    if (found != listed.end() &&
                            (symOffset != -1
                                ? found->memaddr() + symOffset == p
                                : found->memaddr() <= p && found->memaddr() + found->sym.st_size > p)) {
                        if (showaddrs)
                            cout
                                << found->name << " 0x" << std::hex << loc
                                << std::dec <<  " ... size=" << found->sym.st_size
                                << ", diff=" << p - found->memaddr() << endl;
                        found->count++;
                    }
                }
            }
        }

        if (debug)
            *debug << endl;

    }
    if (debug)
        *debug << "core file contains " << filesize << " out of " << memsize << " bytes of memory\n";

    sort(listed.begin() , listed.end() , compareSymbolsByFrequency);

    for (auto &i : listed)
        if (i.count)
            cout << dec << i.count << " " << i.name << " ( from " << i.objname << ")" << endl;
    return 0;
}

int
main(int argc, char *argv[])
{
    try {
        return mainExcept(argc, argv);
    }
    catch (const exception &ex) {
        cerr << "exception: " << ex.what() << endl;
        return -1;
    }
}
<commit_msg>Iterate over both .dynsym and .symtab to find vtbls<commit_after>#include <unistd.h>
#include <signal.h>
#include <fstream>
#include <assert.h>
#include <iostream>
#include <exception>
#include <algorithm>
#include <memory>
#include <libpstack/proc.h>
#include <libpstack/elf.h>
#include <libpstack/dwarf.h>
#include <sys/types.h>

using namespace std;

static int
globmatchR(const char *pattern, const char *name)
{
    for (;; name++) {
        switch (*pattern) {
        case '*':
            // if the rest of the name matches the bit of pattern after '*',
            for (;;) {
                ++name;
                if (globmatchR(pattern + 1, name))
                    return 1;
                if (*name == 0) // exhuasted name without finding a match
                    return 0;
            }
        default:
            if (*name != *pattern)
                return 0;
        }
        if (*pattern++ == 0)
            return 1;
    }
}

static int
globmatch(const string &pattern, const string &name)
{
    return globmatchR(pattern.c_str(), name.c_str());
}

struct ListedSymbol {
    Elf_Sym sym;
    Elf_Off objbase;
    string name;
    size_t count;
    string objname;
    ListedSymbol(const Elf_Sym &sym_, Elf_Off objbase_, string name_, string object)
        : sym(sym_)
        , objbase(objbase_)
        , objname(object)
        , count(0)
        , name(name_)
    {}
    Elf_Off memaddr() const { return  sym.st_value + objbase; }
};

bool operator < (const ListedSymbol &sym, Elf_Off addr) {
    return sym.memaddr() + sym.sym.st_size < addr;
}

static const char *virtpattern = "_ZTV*"; /* wildcard for all vtbls */
static bool compareSymbolsByAddress(const ListedSymbol &l, const ListedSymbol &r) { return l.memaddr() < r.memaddr(); };
static bool compareSymbolsByFrequency(const ListedSymbol &l, const ListedSymbol &r) { return l.count > r.count; };

int
mainExcept(int argc, char *argv[])
{
    std::vector<std::string> patterns;
    shared_ptr<ElfObject> exec;
    shared_ptr<ElfObject> core;
    shared_ptr<Process> process;
    int c;
    int verbose = 0;
    bool showaddrs = false;
    int rate = 1;

    std::vector<std::pair<Elf_Off, Elf_Off>> searchaddrs;
    std::vector<std::pair<std::string, std::string>> pathReplacements;
    char *strbuf = 0;
    char *findstr = 0;
    size_t findstrlen;
    int symOffset = -1;
    bool showloaded = false;

    while ((c = getopt(argc, argv, "o:vhr:sp:f:e:S:R:K:y:l")) != -1) {
        switch (c) {
            case 'p':
                virtpattern = optarg;
                break;
            case 's':
                showaddrs = true;
                break;
            case 'v':
                debug = &clog;
                verbose++;
                break;
            case 'h':
                clog << "usage: canal [exec] <core>" << endl;
                return 0;
            case 'o': // offset within a symbol that the pointers must meet.
                symOffset = strtol(optarg, 0, 0);
                break;

            case 'y':
                patterns.push_back(optarg);
                virtpattern = 0;
                break;

            case 'r': {
                char *from = strdup(optarg);
                char *to  = strchr(from, '=');
                if (to == 0)
                    throw "must specify <to>=<from> for '-r'";
                *to++ = 0;
                pathReplacements.push_back(std::make_pair(from, to));
                break;
            }

            case 'S':
                findstr = optarg;
                findstrlen = strlen(findstr);
                strbuf = new char[findstrlen];
                break;

            case 'f': {
                Elf_Off start = strtoll(optarg, 0, 0);
                searchaddrs.push_back(make_pair(start, start + 1));
                break;
            }

            case 'K':
                rate = atoi(optarg);
                break;
            case 'R': {
                std::ifstream in;
                in.open(optarg);
                if (!in.good())
                    abort();
                char buf[1024];
                int count = 0;
                while (in.good()) {
                    in.getline(buf, sizeof buf);
                    if (in.eof())
                        break;
                    if (++count % rate != 0)
                        continue;
                    char *p = buf;
                    while (isspace(*p))
                        p++;
                    Elf_Off start = strtoll(p, &p, 0);
                    while (*p && isspace(*p))
                        p++;
                    Elf_Off end = *p ? strtoll(p, &p, 0) : start + 1;
                    searchaddrs.push_back(make_pair(start, end));
                    std::clog << "push " << hex << start << ", " << end  << " (" << int(*p) << ")" << std::endl;
                }
                break;
            }

            case 'e':
                searchaddrs.back().second = strtoll(optarg, 0, 0);
                break;

            case 'X':
                ps_lgetfpregs(0, 0, 0);
                break;

            case 'l':
                showloaded = true;
                break;
        }
    }

    if (argc - optind >= 2) {
        exec = make_shared<ElfObject>(argv[optind]);
        optind++;
    }

    if (argc - optind < 1) {
        clog << "usage: canal [exec] <core>" << endl;
        return 0;
    }

    pid_t pid = 0;
    std::istringstream(argv[optind]) >> pid;
    if (pid != 0 && kill(pid, 0) == 0) {
       std::clog << "attaching to live process" << std::endl;
       process = make_shared<LiveProcess>(exec, pid, pathReplacements);
    } else {
       core = make_shared<ElfObject>(argv[optind]);
       process = make_shared<CoreProcess>(exec, core, pathReplacements);
    }
    process->load();
    if (searchaddrs.size()) {
        std::clog << "finding references to " << dec << searchaddrs.size() << " addresses\n";
        for (auto &addr : searchaddrs)
            std::clog << "\t" << addr.first <<" - " << addr.second << "\n";
    }
    clog << "opened process " << process << endl;

    if (showloaded) {
        for (auto loaded = process->objects.begin(); loaded != process->objects.end(); ++loaded)
            std::cout << loaded->object->getName() << "\n";
        exit(0);
    }

    if (virtpattern)
        patterns.push_back(virtpattern);

    vector<ListedSymbol> listed;
    for (auto loaded = process->objects.begin(); loaded != process->objects.end(); ++loaded) {
        size_t count = 0;

        struct SymbolSection symtabs[2] = {
           loaded->object->getSymbols(".dynsym"),
           loaded->object->getSymbols(".symtab")
        };

        for (auto &syms : symtabs) {
           for (auto sym = syms.begin(); sym != syms.end(); ++sym) {
               for (auto &pattern : patterns) {
                   if (globmatch(pattern, (*sym).second)) {
                       listed.push_back(ListedSymbol((*sym).first, loaded->reloc, (*sym).second, loaded->object->io->describe()));
                       count++;
                   }
               }
           }
        }
        if (debug)
            *debug << "found " << count << " symbols in " << loaded->object->io->describe() << endl;
    }
    sort(listed.begin() , listed.end() , compareSymbolsByAddress);

    // Now run through the corefile, searching for virtual objects.
    off_t filesize = 0;
    off_t memsize = 0;
    auto segments = core->getSegments();
    for (auto &hdr : segments) {
        if (hdr.p_type != PT_LOAD)
            continue;
        Elf_Off p;
        filesize += hdr.p_filesz;
        memsize += hdr.p_memsz;
        if (debug) {
            *debug << "scan " << hex << hdr.p_vaddr <<  " to " << hdr.p_vaddr + hdr.p_memsz
                << " (filesiz = " << hdr.p_filesz  << ", memsiz=" << hdr.p_memsz << ") ";
        }

        if (findstr) {
            for (auto loc = hdr.p_vaddr; loc < hdr.p_vaddr + hdr.p_filesz - findstrlen; loc++) {
                size_t rc = process->io->read(loc, findstrlen, strbuf);
                assert(rc == findstrlen);
                if (memcmp(strbuf, findstr, rc) == 0)
                    std::cout << "0x" << hex << loc << "\n";
            }
        } else {
            for (auto loc = hdr.p_vaddr; loc < hdr.p_vaddr + hdr.p_filesz; loc += sizeof p) {
                // log a '.' every megabyte.
                if (verbose && (loc - hdr.p_vaddr) % (1024 * 1024) == 0)
                    clog << '.';
                process->io->readObj(loc, &p);
                if (searchaddrs.size()) {
                    for (auto range = searchaddrs.begin(); range != searchaddrs.end(); ++range) {
                        if (p >= range->first && p < range->second && (p % 4 == 0))
                            cout << "0x" << hex << loc << "\n";
                    }
                } else {
                    auto found = lower_bound(listed.begin(), listed.end(), p);
                    if (found != listed.end() &&
                            (symOffset != -1
                                ? found->memaddr() + symOffset == p
                                : found->memaddr() <= p && found->memaddr() + found->sym.st_size > p)) {
                        if (showaddrs)
                            cout
                                << found->name << " 0x" << std::hex << loc
                                << std::dec <<  " ... size=" << found->sym.st_size
                                << ", diff=" << p - found->memaddr() << endl;
                        found->count++;
                    }
                }
            }
        }

        if (debug)
            *debug << endl;

    }
    if (debug)
        *debug << "core file contains " << filesize << " out of " << memsize << " bytes of memory\n";

    sort(listed.begin() , listed.end() , compareSymbolsByFrequency);

    for (auto &i : listed)
        if (i.count)
            cout << dec << i.count << " " << i.name << " ( from " << i.objname << ")" << endl;
    return 0;
}

int
main(int argc, char *argv[])
{
    try {
        return mainExcept(argc, argv);
    }
    catch (const exception &ex) {
        cerr << "exception: " << ex.what() << endl;
        return -1;
    }
}
<|endoftext|>


<commit_before>#ifndef COFFEE_MILL_VECTOR_EXPRESSION_H
#define COFFEE_MILL_VECTOR_EXPRESSION_H
#include <cmath>
#include "Expression.hpp"

namespace coffeemill
{
    template <class L, class R>
    class VectorAdd
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorAdd(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] + r[i];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class L, class R>
    class VectorSub
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorSub(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] - r[i];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class R>
    class VectorSclMul
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = R::size;

            VectorSclMul(const double& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l * r[i];
            }

        private:
            const double l;
            const R& r;
    };

    template <class L>
    class VectorSclDiv
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorSclDiv(const L& lhs, const double& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] / r;
            }

        private:
            const L& l;
            const double r;
    };

    // 3D vector only...
    template <class L, class R>
    class VectorCross
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorCross(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[(i+1)%3] * r[(i+2)%3] - l[(i+2)%3] * r[(i+1)%3];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    VectorAdd<L,R> operator+(const L& lhs, const R& rhs)
    {
        return VectorAdd<L,R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    VectorSub<L,R> operator-(const L& lhs, const R& rhs)
    {
        return VectorSub<L,R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_ScalarType<R>::value>::type*& = enabler>
    VectorSclMul<L> operator*(const L& lhs, const R& rhs)
    {
        return VectorSclMul<L>(rhs, lhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_ScalarType<L>::value>::type*& = enabler>
    VectorSclMul<R> operator*(const L& lhs, const R& rhs)
    {
        return VectorSclMul<R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_ScalarType<R>::value>::type*& = enabler>
    VectorSclDiv<L> operator/(const L& lhs, const R& rhs)
    {
        return VectorSclDiv<L>(lhs, rhs);
    }

    template <class L,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value
                  >::type*& = enabler>
    double len_square(const L& l)
    {
        double len(0e0);
        for(size_t i(0); i<L::size; ++i)
            len += l[i] * l[i];
        return len;
    }

    template <class L,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value
                  >::type*& = enabler>
    double length(const L& l)
    {
        return std::sqrt(len_square(l));
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    double dot_prod(const L& lhs, const R& rhs)
    {
        double dot(0e0);
        for(size_t i(0); i<L::size; ++i)
            dot += lhs[i] * rhs[i];
        return dot;
    }

    //now, cross_product can be used for only 3D vector.
    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, 3>::value&&
                  is_SameSize<R::size, 3>::value
                  >::type*& = enabler>
    VectorCross<L,R> cross_prod(const L& lhs, const R& rhs)
    {
        return VectorCross<L,R>(lhs, rhs);
    }

}

#endif //COFFEE_MILL_VECTOR3_EXPRESSION_H
<commit_msg>add: Vector normalize<commit_after>#ifndef COFFEE_MILL_VECTOR_EXPRESSION_H
#define COFFEE_MILL_VECTOR_EXPRESSION_H
#include <cmath>
#include "Expression.hpp"

namespace coffeemill
{
    template <class L, class R>
    class VectorAdd
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorAdd(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] + r[i];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class L, class R>
    class VectorSub
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorSub(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] - r[i];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class R>
    class VectorSclMul
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = R::size;

            VectorSclMul(const double& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l * r[i];
            }

        private:
            const double l;
            const R& r;
    };

    template <class L>
    class VectorSclDiv
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorSclDiv(const L& lhs, const double& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[i] / r;
            }

        private:
            const L& l;
            const double r;
    };

    // 3D vector only...
    template <class L, class R>
    class VectorCross
    {
        public:
            typedef VectorExp value_trait;
            constexpr static size_t size = L::size;

            VectorCross(const L& lhs, const R& rhs)
                : l(lhs), r(rhs)
            {}

            double operator[](const int i) const
            {
                return l[(i+1)%3] * r[(i+2)%3] - l[(i+2)%3] * r[(i+1)%3];
            }

        private:
            const L& l;
            const R& r;
    };

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    VectorAdd<L,R> operator+(const L& lhs, const R& rhs)
    {
        return VectorAdd<L,R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    VectorSub<L,R> operator-(const L& lhs, const R& rhs)
    {
        return VectorSub<L,R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_ScalarType<R>::value>::type*& = enabler>
    VectorSclMul<L> operator*(const L& lhs, const R& rhs)
    {
        return VectorSclMul<L>(rhs, lhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_ScalarType<L>::value>::type*& = enabler>
    VectorSclMul<R> operator*(const L& lhs, const R& rhs)
    {
        return VectorSclMul<R>(lhs, rhs);
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_ScalarType<R>::value>::type*& = enabler>
    VectorSclDiv<L> operator/(const L& lhs, const R& rhs)
    {
        return VectorSclDiv<L>(lhs, rhs);
    }

    template <class L,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value
                  >::type*& = enabler>
    double len_square(const L& l)
    {
        double len(0e0);
        for(size_t i(0); i<L::size; ++i)
            len += l[i] * l[i];
        return len;
    }

    template <class L,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value
                  >::type*& = enabler>
    double length(const L& l)
    {
        return std::sqrt(len_square(l));
    }

    template <class L,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value
                  >::type*& = enabler>
    VectorSclDiv<L> normalize(const L& l)
    {
        return VectorSclDiv<L>(l, length(l));
    }

    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, R::size>::value
                  >::type*& = enabler>
    double dot_prod(const L& lhs, const R& rhs)
    {
        double dot(0e0);
        for(size_t i(0); i<L::size; ++i)
            dot += lhs[i] * rhs[i];
        return dot;
    }

    //now, cross_product can be used for only 3D vector.
    template <class L, class R,
              typename std::enable_if<
                  is_VectorExpression<typename L::value_trait>::value&&
                  is_VectorExpression<typename R::value_trait>::value&&
                  is_SameSize<L::size, 3>::value&&
                  is_SameSize<R::size, 3>::value
                  >::type*& = enabler>
    VectorCross<L,R> cross_prod(const L& lhs, const R& rhs)
    {
        return VectorCross<L,R>(lhs, rhs);
    }

}

#endif //COFFEE_MILL_VECTOR3_EXPRESSION_H
<|endoftext|>


<commit_before>#include "analizerCDC.h"
#include <QtMath>
analizerCDC::analizerCDC(QObject *parent) : QObject(parent)
{
    qRegisterMetaType<QtCharts::QAbstractSeries*>();
    qRegisterMetaType<QtCharts::QAbstractAxis*>();
    documentsPath = QDir::currentPath()+QString("/data/");
    rangeVal.append(QPointF(0,0));
    rangeVal.append(QPointF(0,0));
    device = new QSerialPort(this);
    connect(device, &QSerialPort::readyRead, this, &analizerCDC::readData);
    etalonPoints = new QVector<QPointF>(43,QPointF(1,1));
    drawLines = false;
}

analizerCDC::~analizerCDC()
{
    if (device != NULL)
    {
        device->disconnect();
        delete device;
    }
}

void analizerCDC::cppSlot(const QString &msg)
{
    //Найдем строки ввода
    QObject* field1 = this->parent()->findChild<QObject*>("field1");
    QObject* field2 = this->parent()->findChild<QObject*>("field2");
    //Найдем поле вывода
    QObject* textArea = this->parent()->findChild<QObject*>("textArea");

    //Считаем информацию со строк ввода через свойство text
    QString str1=(field1->property("text")).toString();
    QString str2=(field2->property("text")).toString();

    int a = str1.toInt();//Переведем строку в число
    int b = str2.toInt();//Переведем строку в число

    int c = a + b; //Вычисления наши

    QString strResult=QString::number(c);//Переведем результат в строку

    //Ну и наконец выведем в поле вывода нашу информацию
    textArea->setProperty("text", str1+" + "+str2+" = "+strResult+" "+msg);
}

void analizerCDC::initDevice(QString port, QString baudR)
{
#if 0
    qDebug() << port << "\n" << baudR;
#else
    device->setPortName(port);
    device->setBaudRate(QSerialPort::Baud115200);
    device->setDataBits(QSerialPort::Data8);
    device->setParity(QSerialPort::NoParity);
    device->setStopBits(QSerialPort::OneStop);
    device->setFlowControl(QSerialPort::NoFlowControl);
    if(device->open(QIODevice::ReadWrite)){
        qDebug() << "Connected to: " << device->portName();
        emit sendDebugInfo("Connected to: " + device->portName());
    }
    else {
        qDebug() << "Can't open port" << port;
        emit sendDebugInfo("Can't open port" + port);
    }
#endif
}

void analizerCDC::getListOfPort()
{
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
        ports.push_back(info.portName());
        emit sendPortName(info.portName());
        qDebug() << info.portName();
    }
//    emit sendPortName(QString("teststr"));
//    QObject* comboBox = this->parent()->findChild<QObject*>("availablePorts");
    //    comboBox->setProperty("append", info.portName());
}

void analizerCDC::readData()
{
    while (device->canReadLine()) processLine(device->readLine());
}

void analizerCDC::doMeasurements(QtCharts::QAbstractSeries *series, bool _etalon)
{
    qDebug() << "doMeasurements";
    currentPoints = new QVector<QPointF> ;
    etalon = _etalon;
    qDebug() << etalon;
#if 1
    device->write("m");
    currentSeries = series;
#else
    auto colCount =43;
    // Append the new data depending on the type
    currentPoints->reserve(colCount);
    for (int j(0); j < colCount; j++) {
        qreal x(0);
        qreal y(0), _y(0);
      // data with sin + random component
        _y = qSin(3.14159265358979 / 30 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX;
        y = _y < 1.5 ? _y : 0;
        x = micrometers[j];
        //find borders
        if (etalon && drawLines) {
            if ( rangeVal[0].x() > x )
                rangeVal[0].setX(x);
            if ( rangeVal[1].x() < x )
                rangeVal[1].setX(x);
            if ( rangeVal[0].y() > y )
                rangeVal[0].setY(y);
            if ( rangeVal[1].y() < y )
                rangeVal[1].setY(y);
            }
        //add data to graph
        currentPoints->append(QPointF(x, y));
    }

    if (etalon)
    {
        etalonPoints = new QVector<QPointF>(*currentPoints);
    }
    else
    {
        QVector<QPointF> calibratedSeries;
        for (int i=0; i < currentPoints->size(); i++)
        {
            calibratedSeries.append(
                        QPointF(currentPoints->at(i).x(),
                      currentPoints->at(i).y() / etalonPoints->at(i).y()*100.0));
        }
//        delete currentPoints;
        qDebug() << *currentPoints;
        *currentPoints = calibratedSeries;
        qDebug() << *currentPoints;
        qreal xMin = std::numeric_limits<qreal>::max(); // everything is <= this
        qreal xMax = std::numeric_limits<qreal>::min(); // everything is >= this
        qreal yMin = std::numeric_limits<qreal>::max();
        qreal yMax = std::numeric_limits<qreal>::min();
        foreach (QPointF p,  *currentPoints) {
            xMin = qMin(xMin, p.x());
            xMax = qMax(xMax, p.x());
            yMin = qMin(yMin, p.y());
            yMax = qMax(yMax, p.y());
        }
        //find borders
        if ( rangeVal[0].x() > xMin )
            rangeVal[0].setX(xMin);
        if ( rangeVal[1].x() < xMax )
            rangeVal[1].setX(xMax);
        if ( rangeVal[0].y() > yMin )
            rangeVal[0].setY(yMin);
        if ( rangeVal[1].y() < yMax )
            rangeVal[1].setY(yMax);

    }
    if (!etalon || (etalon && drawLines))
    {
        m_data.append(*currentPoints);
        lines.insert(series, m_data.back()); //save series and data pointers for future
        emit adjustAxis(rangeVal[0], rangeVal[1]);
        update(series);
    }

#endif

}

void analizerCDC::saveDataToCSV(QString filename="data.csv")
{
    qDebug() << "save to csv..";
    qDebug() <<filename;
    qDebug() << documentsPath;

    QDir dataDir(documentsPath);
    if (!dataDir.exists())
        dataDir.mkpath(".");

    std::fstream f(QString(documentsPath+"/"+filename).toStdString(),
                   std::fstream::out);
    if (!f.is_open())
        qDebug() << "can't open file\n";
    int i = 1;
    for (auto series : lines.keys())
    {
        f << "Sample: " << series->name().toStdString() << "\n";
        for ( auto& p : lines.value(series))
            f << p.x() << ", " << p.y() << "\n";
        ++i;
    }
    f.close();
    qDebug() << ".done";
}

void analizerCDC::deleteSeries(QtCharts::QAbstractSeries *series)
{
    if (lines.contains(series))
        lines.remove(series);
}

void analizerCDC::update(QtCharts::QAbstractSeries *series)
{
    if (series && lines.contains(series)) {
        QtCharts::QXYSeries *xySeries = static_cast<QtCharts::QXYSeries *>(series);
//        QVector<QPointF> points = lines.value(series);
        // Use replace instead of clear + append, it's optimized for performance
        xySeries->replace(lines.value(series));
    }
}

void analizerCDC::processLine(const QByteArray &_line)
{
//    QByteArray line = device->readAll();

    QStringList line;//(_line);
    for (auto w : _line.split(','))
    {
        line.append(QString(w));
    }
//    line.append(_line.split(','));

//    qDebug()  << _line;
//    qDebug() << line;
    if( line.first().compare("x=m\n") == 0)
    {
        emit makeSeries();
        qDebug() << "signal from button";
    }
    if( line.first().compare("x=d") ==0)
    {
//        qDebug() << "data " << line.at(1).toFloat() <<" "
//                 <<line.at(3).toFloat();
        auto x = line.at(1).toFloat();
        auto y = line.at(3).toFloat();// < 3600 ? line.at(3).toFloat() : 0;
        currentPoints->append(QPointF(x, y));
        if (etalon && drawLines)
        {
            if ( rangeVal[0].x() > x )
                rangeVal[0].setX(x);
            if ( rangeVal[1].x() < x )
                rangeVal[1].setX(x);
            if ( rangeVal[0].y() > y )
                rangeVal[0].setY(y);
            if ( rangeVal[1].y() < y )
                rangeVal[1].setY(y);
        }
    }
    if( line.first().compare("x=e\n") ==0)
    {
        //save series and data for future
        if (etalon)
        {
            etalonPoints = new QVector<QPointF>(*currentPoints);
            qDebug() << "set etalon";
        }
        else
        {
            QVector<QPointF> calibratedSeries;
            for (int i=0; i < currentPoints->size(); i++)
            {
                calibratedSeries.append(
                            QPointF(currentPoints->at(i).x(),
                          currentPoints->at(i).y() / etalonPoints->at(i).y()*100.0));
            }
//            delete currentPoints;
            *currentPoints = calibratedSeries;
            //adjust borders
            qreal xMin = std::numeric_limits<qreal>::max(); // everything is <= this
            qreal xMax = std::numeric_limits<qreal>::min(); // everything is >= this
            qreal yMin = std::numeric_limits<qreal>::max();
            qreal yMax = std::numeric_limits<qreal>::min();
            foreach (QPointF p,  *currentPoints) {
                xMin = qMin(xMin, p.x());
                xMax = qMax(xMax, p.x());
                yMin = qMin(yMin, p.y());
                yMax = qMax(yMax, p.y());
            }
            //find borders
            if ( rangeVal[0].x() > xMin )
                rangeVal[0].setX(xMin);
            if ( rangeVal[1].x() < xMax )
                rangeVal[1].setX(xMax);
            if ( rangeVal[0].y() > yMin )
                rangeVal[0].setY(yMin);
            if ( rangeVal[1].y() < yMax )
                rangeVal[1].setY(yMax);
        }
//        m_data.append(*currentPoints);
//        lines.insert(currentSeries, m_data.back());
//        emit adjustAxis(rangeVal[0], rangeVal[1]);
//        update(currentSeries);
//        qDebug() << "end";// << *currentPoints;

        if (!etalon || (etalon && drawLines))
        {
            m_data.append(*currentPoints);
            lines.insert(currentSeries, m_data.back()); //save series and data pointers for future
            emit adjustAxis(rangeVal[0], rangeVal[1]);
            update(currentSeries);
        }
    }
}

<commit_msg>fix 6600<commit_after>#include "analizerCDC.h"
#include <QtMath>
analizerCDC::analizerCDC(QObject *parent) : QObject(parent)
{
    qRegisterMetaType<QtCharts::QAbstractSeries*>();
    qRegisterMetaType<QtCharts::QAbstractAxis*>();
    documentsPath = QDir::currentPath()+QString("/data/");
    rangeVal.append(QPointF(0,0));
    rangeVal.append(QPointF(0,0));
    device = new QSerialPort(this);
    connect(device, &QSerialPort::readyRead, this, &analizerCDC::readData);
    etalonPoints = new QVector<QPointF>(43,QPointF(1,1));
    drawLines = false;
}

analizerCDC::~analizerCDC()
{
    if (device != NULL)
    {
        device->disconnect();
        delete device;
    }
}

void analizerCDC::cppSlot(const QString &msg)
{
    //Найдем строки ввода
    QObject* field1 = this->parent()->findChild<QObject*>("field1");
    QObject* field2 = this->parent()->findChild<QObject*>("field2");
    //Найдем поле вывода
    QObject* textArea = this->parent()->findChild<QObject*>("textArea");

    //Считаем информацию со строк ввода через свойство text
    QString str1=(field1->property("text")).toString();
    QString str2=(field2->property("text")).toString();

    int a = str1.toInt();//Переведем строку в число
    int b = str2.toInt();//Переведем строку в число

    int c = a + b; //Вычисления наши

    QString strResult=QString::number(c);//Переведем результат в строку

    //Ну и наконец выведем в поле вывода нашу информацию
    textArea->setProperty("text", str1+" + "+str2+" = "+strResult+" "+msg);
}

void analizerCDC::initDevice(QString port, QString baudR)
{
#if 0
    qDebug() << port << "\n" << baudR;
#else
    device->setPortName(port);
    device->setBaudRate(QSerialPort::Baud115200);
    device->setDataBits(QSerialPort::Data8);
    device->setParity(QSerialPort::NoParity);
    device->setStopBits(QSerialPort::OneStop);
    device->setFlowControl(QSerialPort::NoFlowControl);
    if(device->open(QIODevice::ReadWrite)){
        qDebug() << "Connected to: " << device->portName();
        emit sendDebugInfo("Connected to: " + device->portName());
    }
    else {
        qDebug() << "Can't open port" << port;
        emit sendDebugInfo("Can't open port" + port);
    }
#endif
}

void analizerCDC::getListOfPort()
{
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()){
        ports.push_back(info.portName());
        emit sendPortName(info.portName());
        qDebug() << info.portName();
    }
//    emit sendPortName(QString("teststr"));
//    QObject* comboBox = this->parent()->findChild<QObject*>("availablePorts");
    //    comboBox->setProperty("append", info.portName());
}

void analizerCDC::readData()
{
    while (device->canReadLine()) processLine(device->readLine());
}

void analizerCDC::doMeasurements(QtCharts::QAbstractSeries *series, bool _etalon)
{
    qDebug() << "doMeasurements";
    currentPoints = new QVector<QPointF> ;
    etalon = _etalon;
    qDebug() << etalon;
#if 1
    device->write("m");
    currentSeries = series;
#else
    auto colCount =43;
    // Append the new data depending on the type
    currentPoints->reserve(colCount);
    for (int j(0); j < colCount; j++) {
        qreal x(0);
        qreal y(0), _y(0);
      // data with sin + random component
        _y = qSin(3.14159265358979 / 30 * j) + 0.5 + (qreal) rand() / (qreal) RAND_MAX;
        y = _y < 1.5 ? _y : 0;
        x = micrometers[j];
        //find borders
        if (etalon && drawLines) {
            if ( rangeVal[0].x() > x )
                rangeVal[0].setX(x);
            if ( rangeVal[1].x() < x )
                rangeVal[1].setX(x);
            if ( rangeVal[0].y() > y )
                rangeVal[0].setY(y);
            if ( rangeVal[1].y() < y )
                rangeVal[1].setY(y);
            }
        //add data to graph
        currentPoints->append(QPointF(x, y));
    }

    if (etalon)
    {
        etalonPoints = new QVector<QPointF>(*currentPoints);
    }
    else
    {
        QVector<QPointF> calibratedSeries;
        for (int i=0; i < currentPoints->size(); i++)
        {
            calibratedSeries.append(
                        QPointF(currentPoints->at(i).x(),
                      currentPoints->at(i).y() / etalonPoints->at(i).y()*100.0));
        }
//        delete currentPoints;
        qDebug() << *currentPoints;
        *currentPoints = calibratedSeries;
        qDebug() << *currentPoints;
        qreal xMin = std::numeric_limits<qreal>::max(); // everything is <= this
        qreal xMax = std::numeric_limits<qreal>::min(); // everything is >= this
        qreal yMin = std::numeric_limits<qreal>::max();
        qreal yMax = std::numeric_limits<qreal>::min();
        foreach (QPointF p,  *currentPoints) {
            xMin = qMin(xMin, p.x());
            xMax = qMax(xMax, p.x());
            yMin = qMin(yMin, p.y());
            yMax = qMax(yMax, p.y());
        }
        //find borders
        if ( rangeVal[0].x() > xMin )
            rangeVal[0].setX(xMin);
        if ( rangeVal[1].x() < xMax )
            rangeVal[1].setX(xMax);
        if ( rangeVal[0].y() > yMin )
            rangeVal[0].setY(yMin);
        if ( rangeVal[1].y() < yMax )
            rangeVal[1].setY(yMax);

    }
    if (!etalon || (etalon && drawLines))
    {
        m_data.append(*currentPoints);
        lines.insert(series, m_data.back()); //save series and data pointers for future
        emit adjustAxis(rangeVal[0], rangeVal[1]);
        update(series);
    }

#endif

}

void analizerCDC::saveDataToCSV(QString filename="data.csv")
{
    qDebug() << "save to csv..";
    qDebug() <<filename;
    qDebug() << documentsPath;

    QDir dataDir(documentsPath);
    if (!dataDir.exists())
        dataDir.mkpath(".");

    std::fstream f(QString(documentsPath+"/"+filename).toStdString(),
                   std::fstream::out);
    if (!f.is_open())
        qDebug() << "can't open file\n";
    int i = 1;
    for (auto series : lines.keys())
    {
        f << "Sample: " << series->name().toStdString() << "\n";
        for ( auto& p : lines.value(series))
            f << p.x() << ", " << p.y() << "\n";
        ++i;
    }
    f.close();
    qDebug() << ".done";
}

void analizerCDC::deleteSeries(QtCharts::QAbstractSeries *series)
{
    if (lines.contains(series))
        lines.remove(series);
}

void analizerCDC::update(QtCharts::QAbstractSeries *series)
{
    if (series && lines.contains(series)) {
        QtCharts::QXYSeries *xySeries = static_cast<QtCharts::QXYSeries *>(series);
//        QVector<QPointF> points = lines.value(series);
        // Use replace instead of clear + append, it's optimized for performance
        xySeries->replace(lines.value(series));
    }
}

void analizerCDC::processLine(const QByteArray &_line)
{
//    QByteArray line = device->readAll();

    QStringList line;//(_line);
    for (auto w : _line.split(','))
    {
        line.append(QString(w));
    }
//    line.append(_line.split(','));

//    qDebug()  << _line;
//    qDebug() << line;
    if( line.first().compare("x=m\n") == 0)
    {
        emit makeSeries();
        qDebug() << "signal from button";
    }
    if( line.first().compare("x=d") ==0)
    {
//        qDebug() << "data " << line.at(1).toFloat() <<" "
//                 <<line.at(3).toFloat();
        auto x = line.at(1).toFloat();
        auto y = line.at(3).toFloat() < 6600 ? line.at(3).toFloat() : line.at(3).toFloat()-6600;
        currentPoints->append(QPointF(x, y));
        if (etalon && drawLines)
        {
            if ( rangeVal[0].x() > x )
                rangeVal[0].setX(x);
            if ( rangeVal[1].x() < x )
                rangeVal[1].setX(x);
            if ( rangeVal[0].y() > y )
                rangeVal[0].setY(y);
            if ( rangeVal[1].y() < y )
                rangeVal[1].setY(y);
        }
    }
    if( line.first().compare("x=e\n") ==0)
    {
        //save series and data for future
        if (etalon)
        {
            etalonPoints = new QVector<QPointF>(*currentPoints);
            qDebug() << "set etalon";
        }
        else
        {
            QVector<QPointF> calibratedSeries;
            for (int i=0; i < currentPoints->size(); i++)
            {
                calibratedSeries.append(
                            QPointF(currentPoints->at(i).x(),
                          currentPoints->at(i).y() / etalonPoints->at(i).y()*100.0));
            }
//            delete currentPoints;
            *currentPoints = calibratedSeries;
            //adjust borders
            qreal xMin = std::numeric_limits<qreal>::max(); // everything is <= this
            qreal xMax = std::numeric_limits<qreal>::min(); // everything is >= this
            qreal yMin = std::numeric_limits<qreal>::max();
            qreal yMax = std::numeric_limits<qreal>::min();
            foreach (QPointF p,  *currentPoints) {
                xMin = qMin(xMin, p.x());
                xMax = qMax(xMax, p.x());
                yMin = qMin(yMin, p.y());
                yMax = qMax(yMax, p.y());
            }
            //find borders
            if ( rangeVal[0].x() > xMin )
                rangeVal[0].setX(xMin);
            if ( rangeVal[1].x() < xMax )
                rangeVal[1].setX(xMax);
            if ( rangeVal[0].y() > yMin )
                rangeVal[0].setY(yMin);
            if ( rangeVal[1].y() < yMax )
                rangeVal[1].setY(yMax);
        }
//        m_data.append(*currentPoints);
//        lines.insert(currentSeries, m_data.back());
//        emit adjustAxis(rangeVal[0], rangeVal[1]);
//        update(currentSeries);
//        qDebug() << "end";// << *currentPoints;

        if (!etalon || (etalon && drawLines))
        {
            m_data.append(*currentPoints);
            lines.insert(currentSeries, m_data.back()); //save series and data pointers for future
            emit adjustAxis(rangeVal[0], rangeVal[1]);
            update(currentSeries);
        }
    }
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ClassAssemblingUtils.h"

#include <boost/algorithm/string.hpp>

#include "Creators.h"
#include "DexStore.h"
#include "DexUtil.h"
#include "Model.h"
#include "ReachableClasses.h"
#include "Show.h"
#include "Trace.h"

using namespace class_merging;

namespace {

void patch_iget_for_int_like_types(DexMethod* meth,
                                   const IRList::iterator& it,
                                   IRInstruction* convert) {
  auto insn = it->insn;
  auto move_result_it = std::next(it);
  auto src_dest = move_result_it->insn->dest();
  convert->set_src(0, src_dest)->set_dest(src_dest);
  meth->get_code()->insert_after(move_result_it, convert);
  insn->set_opcode(OPCODE_IGET);
}

std::string_view get_merger_package_name(const DexType* type) {
  auto pkg_name = type::get_package_name(type);
  // Avoid an Android OS like package name, which might confuse the custom class
  // loader.
  if (boost::starts_with(pkg_name, "Landroid") ||
      boost::starts_with(pkg_name, "Ldalvik") ||
      boost::starts_with(pkg_name, "Ljava")) {
    return "Lcom/facebook/redex/";
  }
  return pkg_name;
}

} // namespace

namespace class_merging {

DexClass* create_class(const DexType* type,
                       const DexType* super_type,
                       const std::string_view pkg_name,
                       const std::vector<DexField*>& fields,
                       const TypeSet& interfaces,
                       bool with_default_ctor,
                       DexAccessFlags access) {
  DexType* t = const_cast<DexType*>(type);
  always_assert(!pkg_name.empty());
  auto name = std::string(type->get_name()->c_str());
  name = pkg_name + name.substr(1);
  t->set_name(DexString::make_string(name));
  // Create class.
  ClassCreator creator(t);
  creator.set_access(access);
  always_assert(super_type != nullptr);
  creator.set_super(const_cast<DexType*>(super_type));
  for (const auto& itf : interfaces) {
    creator.add_interface(const_cast<DexType*>(itf));
  }
  for (const auto& field : fields) {
    creator.add_field(field);
    field->set_deobfuscated_name(show_deobfuscated(field));
  }
  auto cls = creator.create();
  // Keeping class-merging generated classes from being renamed.
  cls->rstate.set_keepnames();

  if (!with_default_ctor) {
    return cls;
  }
  // Create ctor.
  auto super_ctors = type_class(super_type)->get_ctors();
  for (auto super_ctor : super_ctors) {
    auto mc = new MethodCreator(t,
                                DexString::make_string("<init>"),
                                super_ctor->get_proto(),
                                ACC_PUBLIC | ACC_CONSTRUCTOR);
    // Call to super.<init>
    std::vector<Location> args;
    size_t args_size = super_ctor->get_proto()->get_args()->size();
    for (size_t arg_loc = 0; arg_loc < args_size + 1; ++arg_loc) {
      args.push_back(mc->get_local(arg_loc));
    }
    auto mb = mc->get_main_block();
    mb->invoke(OPCODE_INVOKE_DIRECT, super_ctor, args);
    mb->ret_void();
    auto ctor = mc->create();
    TRACE(CLMG, 4, " default ctor created %s", SHOW(ctor));
    cls->add_method(ctor);
  }
  return cls;
}

std::vector<DexField*> create_merger_fields(
    const DexType* owner, const std::vector<DexField*>& mergeable_fields) {
  std::vector<DexField*> res;
  size_t cnt = 0;
  for (const auto f : mergeable_fields) {
    auto type = f->get_type();
    std::string name;
    if (type == type::_byte() || type == type::_char() ||
        type == type::_short() || type == type::_int()) {
      type = type::_int();
      name = "i";
    } else if (type == type::_boolean()) {
      type = type::_boolean();
      name = "z";
    } else if (type == type::_long()) {
      type = type::_long();
      name = "j";
    } else if (type == type::_float()) {
      type = type::_float();
      name = "f";
    } else if (type == type::_double()) {
      type = type::_double();
      name = "d";
    } else {
      static DexType* string_type = DexType::make_type("Ljava/lang/String;");
      if (type == string_type) {
        type = string_type;
        name = "s";
      } else {
        char t = type::type_shorty(type);
        always_assert(t == 'L' || t == '[');
        type = type::java_lang_Object();
        name = "l";
      }
    }

    name += std::to_string(cnt);
    auto field = DexField::make_field(owner, DexString::make_string(name), type)
                     ->make_concrete(ACC_PUBLIC);
    res.push_back(field);
    cnt++;
  }

  TRACE(CLMG, 8, "  created merger fields %zu ", res.size());
  return res;
}

void cook_merger_fields_lookup(
    const std::vector<DexField*>& new_fields,
    const FieldsMap& fields_map,
    std::unordered_map<DexField*, DexField*>& merger_fields_lookup) {
  for (const auto& fmap : fields_map) {
    const auto& old_fields = fmap.second;
    always_assert(new_fields.size() == old_fields.size());
    for (size_t i = 0; i < new_fields.size(); i++) {
      if (old_fields.at(i) != nullptr) {
        merger_fields_lookup[old_fields.at(i)] = new_fields.at(i);
      }
    }
  }
}

DexClass* create_merger_class(const DexType* type,
                              const DexType* super_type,
                              const std::vector<DexField*>& merger_fields,
                              const TypeSet& interfaces,
                              bool add_type_tag_field,
                              bool with_default_ctor /* false */) {
  always_assert(type && super_type);
  std::vector<DexField*> fields;

  if (add_type_tag_field) {
    auto type_tag_field =
        DexField::make_field(
            type, DexString::make_string(INTERNAL_TYPE_TAG_FIELD_NAME),
            type::_int())
            ->make_concrete(ACC_PUBLIC | ACC_FINAL);
    fields.push_back(type_tag_field);
  }

  for (auto f : merger_fields) {
    fields.push_back(f);
  }
  // Put merger class in the same package as super_type.
  auto pkg_name = get_merger_package_name(super_type);
  auto cls = create_class(type, super_type, pkg_name, fields, interfaces,
                          with_default_ctor);
  TRACE(CLMG, 3, "  created merger class w/ fields %s ", SHOW(cls));
  return cls;
}

void patch_iput(const IRList::iterator& it) {
  auto insn = it->insn;
  const auto op = insn->opcode();
  always_assert(opcode::is_an_iput(op));
  switch (op) {
  case OPCODE_IPUT_BYTE:
  case OPCODE_IPUT_CHAR:
  case OPCODE_IPUT_SHORT:
    insn->set_opcode(OPCODE_IPUT);
    break;
  default:
    break;
  }
};

void patch_iget(DexMethod* meth,
                const IRList::iterator& it,
                DexType* original_field_type) {
  auto insn = it->insn;
  const auto op = insn->opcode();
  always_assert(opcode::is_an_iget(op));
  switch (op) {
  case OPCODE_IGET_OBJECT: {
    auto dest = std::next(it)->insn->dest();
    auto cast = ModelMethodMerger::make_check_cast(original_field_type, dest);
    meth->get_code()->insert_after(insn, cast);
    break;
  }
  case OPCODE_IGET_BYTE: {
    always_assert(original_field_type == type::_byte());
    auto int_to_byte = new IRInstruction(OPCODE_INT_TO_BYTE);
    patch_iget_for_int_like_types(meth, it, int_to_byte);
    break;
  }
  case OPCODE_IGET_CHAR: {
    always_assert(original_field_type == type::_char());
    auto int_to_char = new IRInstruction(OPCODE_INT_TO_CHAR);
    patch_iget_for_int_like_types(meth, it, int_to_char);
    break;
  }
  case OPCODE_IGET_SHORT: {
    always_assert(original_field_type == type::_short());
    auto int_to_short = new IRInstruction(OPCODE_INT_TO_SHORT);
    patch_iget_for_int_like_types(meth, it, int_to_short);
    break;
  }
  default:
    break;
  }
};

void add_class(DexClass* new_cls,
               Scope& scope,
               DexStoresVector& stores,
               boost::optional<size_t> dex_id) {
  always_assert(new_cls != nullptr);
  TRACE(CLMG, 4, " ClassMerging Adding class %s to dex(%s) scope[%zu]",
        SHOW(new_cls), dex_id ? std::to_string(*dex_id).c_str() : "last",
        scope.size());
  scope.push_back(new_cls);
  DexStore::add_class(new_cls, stores, dex_id);
}

} // namespace class_merging
<commit_msg>Only use special Redex package name for external roots<commit_after>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ClassAssemblingUtils.h"

#include <boost/algorithm/string.hpp>

#include "Creators.h"
#include "DexStore.h"
#include "DexUtil.h"
#include "Model.h"
#include "ReachableClasses.h"
#include "Show.h"
#include "Trace.h"

using namespace class_merging;

namespace {

void patch_iget_for_int_like_types(DexMethod* meth,
                                   const IRList::iterator& it,
                                   IRInstruction* convert) {
  auto insn = it->insn;
  auto move_result_it = std::next(it);
  auto src_dest = move_result_it->insn->dest();
  convert->set_src(0, src_dest)->set_dest(src_dest);
  meth->get_code()->insert_after(move_result_it, convert);
  insn->set_opcode(OPCODE_IGET);
}

std::string_view get_merger_package_name(const DexType* root_type) {
  auto pkg_name = type::get_package_name(root_type);
  // Avoid an Android OS like package name, which might confuse the custom class
  // loader. See T34120391 for details.
  if (boost::starts_with(pkg_name, "Landroid/") ||
      boost::starts_with(pkg_name, "Ldalvik/") ||
      boost::starts_with(pkg_name, "Ljava/")) {
    auto cls = type_class(root_type);
    if (cls && cls->is_external()) {
      return "Lcom/facebook/redex/";
    }
  }
  return pkg_name;
}

} // namespace

namespace class_merging {

DexClass* create_class(const DexType* type,
                       const DexType* super_type,
                       const std::string_view pkg_name,
                       const std::vector<DexField*>& fields,
                       const TypeSet& interfaces,
                       bool with_default_ctor,
                       DexAccessFlags access) {
  DexType* t = const_cast<DexType*>(type);
  always_assert(!pkg_name.empty());
  auto name = std::string(type->get_name()->c_str());
  name = pkg_name + name.substr(1);
  t->set_name(DexString::make_string(name));
  // Create class.
  ClassCreator creator(t);
  creator.set_access(access);
  always_assert(super_type != nullptr);
  creator.set_super(const_cast<DexType*>(super_type));
  for (const auto& itf : interfaces) {
    creator.add_interface(const_cast<DexType*>(itf));
  }
  for (const auto& field : fields) {
    creator.add_field(field);
    field->set_deobfuscated_name(show_deobfuscated(field));
  }
  auto cls = creator.create();
  // Keeping class-merging generated classes from being renamed.
  cls->rstate.set_keepnames();

  if (!with_default_ctor) {
    return cls;
  }
  // Create ctor.
  auto super_ctors = type_class(super_type)->get_ctors();
  for (auto super_ctor : super_ctors) {
    auto mc = new MethodCreator(t,
                                DexString::make_string("<init>"),
                                super_ctor->get_proto(),
                                ACC_PUBLIC | ACC_CONSTRUCTOR);
    // Call to super.<init>
    std::vector<Location> args;
    size_t args_size = super_ctor->get_proto()->get_args()->size();
    for (size_t arg_loc = 0; arg_loc < args_size + 1; ++arg_loc) {
      args.push_back(mc->get_local(arg_loc));
    }
    auto mb = mc->get_main_block();
    mb->invoke(OPCODE_INVOKE_DIRECT, super_ctor, args);
    mb->ret_void();
    auto ctor = mc->create();
    TRACE(CLMG, 4, " default ctor created %s", SHOW(ctor));
    cls->add_method(ctor);
  }
  return cls;
}

std::vector<DexField*> create_merger_fields(
    const DexType* owner, const std::vector<DexField*>& mergeable_fields) {
  std::vector<DexField*> res;
  size_t cnt = 0;
  for (const auto f : mergeable_fields) {
    auto type = f->get_type();
    std::string name;
    if (type == type::_byte() || type == type::_char() ||
        type == type::_short() || type == type::_int()) {
      type = type::_int();
      name = "i";
    } else if (type == type::_boolean()) {
      type = type::_boolean();
      name = "z";
    } else if (type == type::_long()) {
      type = type::_long();
      name = "j";
    } else if (type == type::_float()) {
      type = type::_float();
      name = "f";
    } else if (type == type::_double()) {
      type = type::_double();
      name = "d";
    } else {
      static DexType* string_type = DexType::make_type("Ljava/lang/String;");
      if (type == string_type) {
        type = string_type;
        name = "s";
      } else {
        char t = type::type_shorty(type);
        always_assert(t == 'L' || t == '[');
        type = type::java_lang_Object();
        name = "l";
      }
    }

    name += std::to_string(cnt);
    auto field = DexField::make_field(owner, DexString::make_string(name), type)
                     ->make_concrete(ACC_PUBLIC);
    res.push_back(field);
    cnt++;
  }

  TRACE(CLMG, 8, "  created merger fields %zu ", res.size());
  return res;
}

void cook_merger_fields_lookup(
    const std::vector<DexField*>& new_fields,
    const FieldsMap& fields_map,
    std::unordered_map<DexField*, DexField*>& merger_fields_lookup) {
  for (const auto& fmap : fields_map) {
    const auto& old_fields = fmap.second;
    always_assert(new_fields.size() == old_fields.size());
    for (size_t i = 0; i < new_fields.size(); i++) {
      if (old_fields.at(i) != nullptr) {
        merger_fields_lookup[old_fields.at(i)] = new_fields.at(i);
      }
    }
  }
}

DexClass* create_merger_class(const DexType* type,
                              const DexType* super_type,
                              const std::vector<DexField*>& merger_fields,
                              const TypeSet& interfaces,
                              bool add_type_tag_field,
                              bool with_default_ctor /* false */) {
  always_assert(type && super_type);
  std::vector<DexField*> fields;

  if (add_type_tag_field) {
    auto type_tag_field =
        DexField::make_field(
            type, DexString::make_string(INTERNAL_TYPE_TAG_FIELD_NAME),
            type::_int())
            ->make_concrete(ACC_PUBLIC | ACC_FINAL);
    fields.push_back(type_tag_field);
  }

  for (auto f : merger_fields) {
    fields.push_back(f);
  }
  // Put merger class in the same package as super_type.
  auto pkg_name = get_merger_package_name(super_type);
  auto cls = create_class(type, super_type, pkg_name, fields, interfaces,
                          with_default_ctor);
  TRACE(CLMG, 3, "  created merger class w/ fields %s ", SHOW(cls));
  return cls;
}

void patch_iput(const IRList::iterator& it) {
  auto insn = it->insn;
  const auto op = insn->opcode();
  always_assert(opcode::is_an_iput(op));
  switch (op) {
  case OPCODE_IPUT_BYTE:
  case OPCODE_IPUT_CHAR:
  case OPCODE_IPUT_SHORT:
    insn->set_opcode(OPCODE_IPUT);
    break;
  default:
    break;
  }
};

void patch_iget(DexMethod* meth,
                const IRList::iterator& it,
                DexType* original_field_type) {
  auto insn = it->insn;
  const auto op = insn->opcode();
  always_assert(opcode::is_an_iget(op));
  switch (op) {
  case OPCODE_IGET_OBJECT: {
    auto dest = std::next(it)->insn->dest();
    auto cast = ModelMethodMerger::make_check_cast(original_field_type, dest);
    meth->get_code()->insert_after(insn, cast);
    break;
  }
  case OPCODE_IGET_BYTE: {
    always_assert(original_field_type == type::_byte());
    auto int_to_byte = new IRInstruction(OPCODE_INT_TO_BYTE);
    patch_iget_for_int_like_types(meth, it, int_to_byte);
    break;
  }
  case OPCODE_IGET_CHAR: {
    always_assert(original_field_type == type::_char());
    auto int_to_char = new IRInstruction(OPCODE_INT_TO_CHAR);
    patch_iget_for_int_like_types(meth, it, int_to_char);
    break;
  }
  case OPCODE_IGET_SHORT: {
    always_assert(original_field_type == type::_short());
    auto int_to_short = new IRInstruction(OPCODE_INT_TO_SHORT);
    patch_iget_for_int_like_types(meth, it, int_to_short);
    break;
  }
  default:
    break;
  }
};

void add_class(DexClass* new_cls,
               Scope& scope,
               DexStoresVector& stores,
               boost::optional<size_t> dex_id) {
  always_assert(new_cls != nullptr);
  TRACE(CLMG, 4, " ClassMerging Adding class %s to dex(%s) scope[%zu]",
        SHOW(new_cls), dex_id ? std::to_string(*dex_id).c_str() : "last",
        scope.size());
  scope.push_back(new_cls);
  DexStore::add_class(new_cls, stores, dex_id);
}

} // namespace class_merging
<|endoftext|>


<commit_before>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 * Copyright (c) 2010 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "mainwindow.h"

#include <QtGui/QApplication>

int main( int argc, char** argv )
{
    QApplication app( argc, argv );
    app.setOrganizationName( "KDE Gluon" );
    app.setApplicationName( "Gluon Player" );

    GluonPlayer::MainWindow window( argc, argv );
    window.show();

    return app.exec();
}
<commit_msg>BUG: 267987 New: gluon_qtplayer crashes with not existing target<commit_after>/******************************************************************************
 * This file is part of the Gluon Development Platform
 * Copyright (c) 2010 Arjen Hiemstra <ahiemstra@heimr.nl>
 * Copyright (c) 2010 Laszlo Papp <djszapi@archlinux.us>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "mainwindow.h"

#include <QtGui/QApplication>

#include <QtCore/QFile>
#include <QtCore/QDebug>

int main( int argc, char** argv )
{
    if (argc > 1 && !QFile::exists(argv[1])) {
        qDebug() << QString("File does not exist: ") + argv[1];
        return 1;
    }

    QApplication app( argc, argv );
    app.setOrganizationName( "KDE Gluon" );
    app.setApplicationName( "Gluon Player" );

    GluonPlayer::MainWindow window( argc, argv );
    window.show();

    return app.exec();
}
<|endoftext|>


<commit_before>/* ===========================
 *
 * Copyright (c) 2013 Philippe Tillet - National Chiao Tung University
 *
 * CLICA - Hybrid ICA using ViennaCL + Eigen
 *
 * License : MIT X11 - See the LICENSE file in the root folder
 * ===========================*/

#include "Eigen/Dense"

#include "tests/benchmark-utils.hpp"

#include "fmincl/minimize.hpp"
#include "fmincl/backends/openblas.hpp"

#include "src/whiten.hpp"
#include "src/utils.hpp"

namespace parica{

template<class ScalarType>
struct ica_functor{
private:
    static const int alpha_sub = 4;
    static const int alpha_super = 1;
private:
    template <typename T>
    inline int sgn(T val) const {
        return (val>0)?1:-1;
    }
public:
    ica_functor(ScalarType const * data, std::size_t NC, std::size_t NF) : data_(data), NC_(NC), NF_(NF){
        ipiv_ =  new int[NC_+1];

        z1 = new ScalarType[NC_*NF_];
        phi = new ScalarType[NC_*NF_];
        phi_z1t = new ScalarType[NC_*NC_];
        dweights = new ScalarType[NC_*NC_];
        dbias = new ScalarType[NC_];
        W = new ScalarType[NC_*NC_];
        WLU = new ScalarType[NC_*NC_];
        b_ = new ScalarType[NC_];
        alpha = new ScalarType[NC_];
        means_logp = new ScalarType[NC_];
    }

    ~ica_functor(){
        delete ipiv_;
    }

    ScalarType operator()(ScalarType const * x, ScalarType ** grad) const {

        Timer t;
        t.start();

        //Rerolls the variables into the appropriates datastructures
        std::memcpy(W, x,sizeof(ScalarType)*NC_*NC_);
        std::memcpy(b_, x+NC_*NC_, sizeof(ScalarType)*NC_);

        //z1 = W*data_;
        blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,NC_,NF_,NC_,1,W,NC_,data_,NF_,0,z1,NF_);

        //z2 = z1 + b(:, ones(NF_,1));
        //kurt = (mean(z2.^2,2).^2) ./ mean(z2.^4,2) - 3
        //alpha = alpha_sub*(kurt<0) + alpha_super*(kurt>0)
        for(unsigned int c = 0 ; c < NC_ ; ++c){
            ScalarType m2 = 0, m4 = 0;
            ScalarType b = b_[c];
            for(unsigned int f = 0; f < NF_ ; f++){
                ScalarType val = z1[c*NF_+f] + b;
                m2 += std::pow(val,2);
                m4 += std::pow(val,4);
            }
            m2 = std::pow(1/(ScalarType)NF_*m2,2);
            m4 = 1/(ScalarType)NF_*m4;
            ScalarType kurt = m4/m2 - 3;
            alpha[c] = alpha_sub*(kurt<0) + alpha_super*(kurt>=0);
        }

        //mata = alpha(:,ones(NF_,1));
        //logp = log(mata) - log(2) - gammaln(1./mata) - abs(z2).^mata;
        for(unsigned int c = 0 ; c < NC_ ; ++c){
            ScalarType current = 0;
            ScalarType a = alpha[c];
            ScalarType b = b_[c];
            for(unsigned int f = 0; f < NF_ ; f++){
                ScalarType val = z1[c*NF_+f] + b;
                ScalarType fabs_val = std::fabs(val);
                current += (a==alpha_sub)?detail::compile_time_pow<alpha_sub>()(fabs_val):detail::compile_time_pow<alpha_super>()(fabs_val);
            }
            means_logp[c] = -1/(ScalarType)NF_*current + std::log(a) - std::log(2) - lgamma(1/a);
        }

        //H = log(abs(det(w))) + sum(means_logp);

        //LU Decomposition
        std::memcpy(WLU,W,sizeof(ScalarType)*NC_*NC_);
        blas_backend<ScalarType>::getrf(LAPACK_ROW_MAJOR,NC_,NC_,WLU,NC_,ipiv_);

        //det = prod(diag(WLU))
        ScalarType absdet = 1;
        for(std::size_t i = 0 ; i < NC_ ; ++i)
            absdet*=std::abs(WLU[i*NC_+i]);

        ScalarType H = std::log(absdet);
        for(std::size_t i = 0; i < NC_ ; ++i)
            H+=means_logp[i];

        if(grad){

            //phi = mean(mata.*abs(z2).^(mata-1).*sign(z2),2);
            for(unsigned int c = 0 ; c < NC_ ; ++c){
                ScalarType a = alpha[c];
                ScalarType b = b_[c];
                for(unsigned int f = 0 ; f < NF_ ; ++f){
                    ScalarType val = z1[c*NF_+f] + b;
                    ScalarType fabs_val = std::fabs(val);
                    ScalarType fabs_val_pow = (a==alpha_sub)?detail::compile_time_pow<alpha_sub-1>()(fabs_val):detail::compile_time_pow<alpha_super-1>()(fabs_val);
                    phi[c*NF_+f] = a*fabs_val_pow*sgn(val);
                }
            }

            //dbias = mean(phi,2)
            detail::mean(phi,NC_,NF_,dbias);

            /*dweights = -(eye(N) - 1/n*phi*z1')*inv(W)'*/

            //WLU = inv(W)
            blas_backend<ScalarType>::getri(LAPACK_ROW_MAJOR,NC_,WLU,NC_,ipiv_);

            //lhs = I(N,N) - 1/N*phi*z1')
            blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasTrans,NC_,NC_,NF_ ,-1/(ScalarType)NF_,phi,NF_,z1,NF_,0,phi_z1t,NC_);
            for(std::size_t i = 0 ; i < NC_ ; ++i)
                phi_z1t[i*NC_+i] += 1;

            //dweights = -lhs*Winv'
            blas_backend<ScalarType>::gemm(CblasRowMajor, CblasNoTrans,CblasTrans,NC_,NC_,NC_,-1,phi_z1t,NC_,WLU,NC_,0,dweights,NC_);

            //Copy back
            std::memcpy(*grad, dweights,sizeof(ScalarType)*NC_*NC_);
            std::memcpy(*grad+NC_*NC_, dbias, sizeof(ScalarType)*NC_);
        }

        return -H;
    }

private:
    ScalarType const * data_;
    std::size_t NC_;
    std::size_t NF_;

    int *ipiv_;

    ScalarType* z1;
    ScalarType* phi;
    ScalarType* phi_z1t;
    ScalarType* dweights;
    ScalarType* dbias;
    ScalarType* W;
    ScalarType* WLU;
    ScalarType* b_;
    ScalarType* alpha;
    ScalarType* means_logp;
};

fmincl::optimization_options make_default_options(){
    fmincl::optimization_options options;
    options.direction = new fmincl::quasi_newton_tag();
    options.max_iter = 100;
    options.verbosity_level = 0;
    return options;
}

template<class DataType, class OutType>
void inplace_linear_ica(DataType const & dataMat, OutType & outMat, fmincl::optimization_options const & options){
    typedef typename DataType::Scalar ScalarType;
    typedef typename result_of::internal_matrix_type<ScalarType>::type MatrixType;
    typedef typename result_of::internal_vector_type<ScalarType>::type VectorType;

    size_t NC = dataMat.rows();
    size_t NF = dataMat.cols();
    ScalarType const * data = dataMat.data();
    ScalarType* out = outMat.data();

    std::size_t N = NC*NC + NC;

    ScalarType * data_copy = new ScalarType[NC*NF];
    ScalarType * W = new ScalarType[NC*NC];
    ScalarType * b = new ScalarType[NC];
    ScalarType * S = new ScalarType[N];
    ScalarType * X = new ScalarType[N]; std::memset(X,0,N*sizeof(ScalarType));
    ScalarType * white_data = new ScalarType[NC*NF];

    std::memcpy(data_copy,data,NC*NF*sizeof(ScalarType));

    //Optimization Vector

    //Solution vector
    //Initial guess
    for(unsigned int i = 0 ; i < NC; ++i)
        X[i*(NC+1)] = 1;
    for(unsigned int i = NC*NC ; i < NC*(NC+1) ; ++i)
        X[i] = 0;

    //Whiten Data
    whiten<ScalarType>(NC, NF, data_copy,white_data);

    ica_functor<ScalarType> fun(white_data,NC,NF);

//    fmincl::utils::check_grad(fun,X);
    fmincl::minimize<fmincl::backend::OpenBlasTypes<ScalarType> >(S,fun,X,N,options);

    //Copies into datastructures
    std::memcpy(W, S,sizeof(ScalarType)*NC*NC);
    std::memcpy(b, S+NC*NC, sizeof(ScalarType)*NC);

    //out = W*white_data;
    blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,NC,NF,NC,1,W,NC,white_data,NF,0,out,NF);
    for(std::size_t c = 0 ; c < NC ; ++c){
        ScalarType val = b[c];
        for(std::size_t f = 0 ; f < NF ; ++f){
            out[c*NF+f] += val;
        }
    }

    delete[] data_copy;
    delete[] W;
    delete[] b;
    delete[] S;
    delete[] X;
    delete[] white_data;

}

typedef result_of::internal_matrix_type<double>::type MatD;
typedef result_of::internal_matrix_type<float>::type MatF;
template void inplace_linear_ica<MatD,MatD>(MatD  const & data, MatD & out, fmincl::optimization_options const & options);
template void inplace_linear_ica<MatF,MatF>(MatF  const & data, MatF & out, fmincl::optimization_options const & options);

}

<commit_msg>Removed useless bias initialization<commit_after>/* ===========================
 *
 * Copyright (c) 2013 Philippe Tillet - National Chiao Tung University
 *
 * CLICA - Hybrid ICA using ViennaCL + Eigen
 *
 * License : MIT X11 - See the LICENSE file in the root folder
 * ===========================*/

#include "Eigen/Dense"

#include "tests/benchmark-utils.hpp"

#include "fmincl/minimize.hpp"
#include "fmincl/backends/openblas.hpp"

#include "src/whiten.hpp"
#include "src/utils.hpp"

namespace parica{

template<class ScalarType>
struct ica_functor{
private:
    static const int alpha_sub = 4;
    static const int alpha_super = 1;
private:
    template <typename T>
    inline int sgn(T val) const {
        return (val>0)?1:-1;
    }
public:
    ica_functor(ScalarType const * data, std::size_t NC, std::size_t NF) : data_(data), NC_(NC), NF_(NF){
        ipiv_ =  new int[NC_+1];

        z1 = new ScalarType[NC_*NF_];
        phi = new ScalarType[NC_*NF_];
        phi_z1t = new ScalarType[NC_*NC_];
        dweights = new ScalarType[NC_*NC_];
        dbias = new ScalarType[NC_];
        W = new ScalarType[NC_*NC_];
        WLU = new ScalarType[NC_*NC_];
        b_ = new ScalarType[NC_];
        alpha = new ScalarType[NC_];
        means_logp = new ScalarType[NC_];
    }

    ~ica_functor(){
        delete ipiv_;
    }

    ScalarType operator()(ScalarType const * x, ScalarType ** grad) const {

        Timer t;
        t.start();

        //Rerolls the variables into the appropriates datastructures
        std::memcpy(W, x,sizeof(ScalarType)*NC_*NC_);
        std::memcpy(b_, x+NC_*NC_, sizeof(ScalarType)*NC_);

        //z1 = W*data_;
        blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,NC_,NF_,NC_,1,W,NC_,data_,NF_,0,z1,NF_);

        //z2 = z1 + b(:, ones(NF_,1));
        //kurt = (mean(z2.^2,2).^2) ./ mean(z2.^4,2) - 3
        //alpha = alpha_sub*(kurt<0) + alpha_super*(kurt>0)
        for(unsigned int c = 0 ; c < NC_ ; ++c){
            ScalarType m2 = 0, m4 = 0;
            ScalarType b = b_[c];
            for(unsigned int f = 0; f < NF_ ; f++){
                ScalarType val = z1[c*NF_+f] + b;
                m2 += std::pow(val,2);
                m4 += std::pow(val,4);
            }
            m2 = std::pow(1/(ScalarType)NF_*m2,2);
            m4 = 1/(ScalarType)NF_*m4;
            ScalarType kurt = m4/m2 - 3;
            alpha[c] = alpha_sub*(kurt<0) + alpha_super*(kurt>=0);
        }

        //mata = alpha(:,ones(NF_,1));
        //logp = log(mata) - log(2) - gammaln(1./mata) - abs(z2).^mata;
        for(unsigned int c = 0 ; c < NC_ ; ++c){
            ScalarType current = 0;
            ScalarType a = alpha[c];
            ScalarType b = b_[c];
            for(unsigned int f = 0; f < NF_ ; f++){
                ScalarType val = z1[c*NF_+f] + b;
                ScalarType fabs_val = std::fabs(val);
                current += (a==alpha_sub)?detail::compile_time_pow<alpha_sub>()(fabs_val):detail::compile_time_pow<alpha_super>()(fabs_val);
            }
            means_logp[c] = -1/(ScalarType)NF_*current + std::log(a) - std::log(2) - lgamma(1/a);
        }

        //H = log(abs(det(w))) + sum(means_logp);

        //LU Decomposition
        std::memcpy(WLU,W,sizeof(ScalarType)*NC_*NC_);
        blas_backend<ScalarType>::getrf(LAPACK_ROW_MAJOR,NC_,NC_,WLU,NC_,ipiv_);

        //det = prod(diag(WLU))
        ScalarType absdet = 1;
        for(std::size_t i = 0 ; i < NC_ ; ++i)
            absdet*=std::abs(WLU[i*NC_+i]);

        ScalarType H = std::log(absdet);
        for(std::size_t i = 0; i < NC_ ; ++i)
            H+=means_logp[i];

        if(grad){

            //phi = mean(mata.*abs(z2).^(mata-1).*sign(z2),2);
            for(unsigned int c = 0 ; c < NC_ ; ++c){
                ScalarType a = alpha[c];
                ScalarType b = b_[c];
                for(unsigned int f = 0 ; f < NF_ ; ++f){
                    ScalarType val = z1[c*NF_+f] + b;
                    ScalarType fabs_val = std::fabs(val);
                    ScalarType fabs_val_pow = (a==alpha_sub)?detail::compile_time_pow<alpha_sub-1>()(fabs_val):detail::compile_time_pow<alpha_super-1>()(fabs_val);
                    phi[c*NF_+f] = a*fabs_val_pow*sgn(val);
                }
            }

            //dbias = mean(phi,2)
            detail::mean(phi,NC_,NF_,dbias);

            /*dweights = -(eye(N) - 1/n*phi*z1')*inv(W)'*/

            //WLU = inv(W)
            blas_backend<ScalarType>::getri(LAPACK_ROW_MAJOR,NC_,WLU,NC_,ipiv_);

            //lhs = I(N,N) - 1/N*phi*z1')
            blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasTrans,NC_,NC_,NF_ ,-1/(ScalarType)NF_,phi,NF_,z1,NF_,0,phi_z1t,NC_);
            for(std::size_t i = 0 ; i < NC_ ; ++i)
                phi_z1t[i*NC_+i] += 1;

            //dweights = -lhs*Winv'
            blas_backend<ScalarType>::gemm(CblasRowMajor, CblasNoTrans,CblasTrans,NC_,NC_,NC_,-1,phi_z1t,NC_,WLU,NC_,0,dweights,NC_);

            //Copy back
            std::memcpy(*grad, dweights,sizeof(ScalarType)*NC_*NC_);
            std::memcpy(*grad+NC_*NC_, dbias, sizeof(ScalarType)*NC_);
        }

        return -H;
    }

private:
    ScalarType const * data_;
    std::size_t NC_;
    std::size_t NF_;

    int *ipiv_;

    ScalarType* z1;
    ScalarType* phi;
    ScalarType* phi_z1t;
    ScalarType* dweights;
    ScalarType* dbias;
    ScalarType* W;
    ScalarType* WLU;
    ScalarType* b_;
    ScalarType* alpha;
    ScalarType* means_logp;
};

fmincl::optimization_options make_default_options(){
    fmincl::optimization_options options;
    options.direction = new fmincl::quasi_newton_tag();
    options.max_iter = 100;
    options.verbosity_level = 0;
    return options;
}

template<class DataType, class OutType>
void inplace_linear_ica(DataType const & dataMat, OutType & outMat, fmincl::optimization_options const & options){
    typedef typename DataType::Scalar ScalarType;
    typedef typename result_of::internal_matrix_type<ScalarType>::type MatrixType;
    typedef typename result_of::internal_vector_type<ScalarType>::type VectorType;

    size_t NC = dataMat.rows();
    size_t NF = dataMat.cols();
    ScalarType const * data = dataMat.data();
    ScalarType* out = outMat.data();

    std::size_t N = NC*NC + NC;

    ScalarType * data_copy = new ScalarType[NC*NF];
    ScalarType * W = new ScalarType[NC*NC];
    ScalarType * b = new ScalarType[NC];
    ScalarType * S = new ScalarType[N];
    ScalarType * X = new ScalarType[N]; std::memset(X,0,N*sizeof(ScalarType));
    ScalarType * white_data = new ScalarType[NC*NF];

    std::memcpy(data_copy,data,NC*NF*sizeof(ScalarType));

    //Optimization Vector

    //Solution vector
    //Initial guess W_0 = I
    //b_0 = 0
    for(unsigned int i = 0 ; i < NC; ++i)
        X[i*(NC+1)] = 1;

    //Whiten Data
    whiten<ScalarType>(NC, NF, data_copy,white_data);

    ica_functor<ScalarType> fun(white_data,NC,NF);

//    fmincl::utils::check_grad(fun,X);
    fmincl::minimize<fmincl::backend::OpenBlasTypes<ScalarType> >(S,fun,X,N,options);

    //Copies into datastructures
    std::memcpy(W, S,sizeof(ScalarType)*NC*NC);
    std::memcpy(b, S+NC*NC, sizeof(ScalarType)*NC);

    //out = W*white_data;
    blas_backend<ScalarType>::gemm(CblasRowMajor,CblasNoTrans,CblasNoTrans,NC,NF,NC,1,W,NC,white_data,NF,0,out,NF);
    for(std::size_t c = 0 ; c < NC ; ++c){
        ScalarType val = b[c];
        for(std::size_t f = 0 ; f < NF ; ++f){
            out[c*NF+f] += val;
        }
    }

    delete[] data_copy;
    delete[] W;
    delete[] b;
    delete[] S;
    delete[] X;
    delete[] white_data;

}

typedef result_of::internal_matrix_type<double>::type MatD;
typedef result_of::internal_matrix_type<float>::type MatF;
template void inplace_linear_ica<MatD,MatD>(MatD  const & data, MatD & out, fmincl::optimization_options const & options);
template void inplace_linear_ica<MatF,MatF>(MatF  const & data, MatF & out, fmincl::optimization_options const & options);

}

<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int x1;
    int y1;
    int x2;
    int y2;
    int m;

    cout << "Enter x1"<< endl;
    cin >> x1;

    cout << "Enter y1" << endl;
    cin >>y1;

    cout << "Enter x2 " << endl;
    cin >> x2;

    cout <<"Enter y2" << endl;
    cin >> y2;

    m = y2-y1/x2-x1;

    cout << "The gradient of the line is :" << m << endl;
    cout << "The equation of the line is :" << "y =" << m << * "x+b" << endl;
}
<commit_msg>fixed bug gradient of straight line.closes #16<commit_after>#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    int x1;
    int y1;
    int x2;
    int y2;
    int m;

    cout << "Enter x1"<< endl;
    cin >> x1;

    cout << "Enter y1" << endl;
    cin >>y1;

    cout << "Enter x2 " << endl;
    cin >> x2;

    cout <<"Enter y2" << endl;
    cin >> y2;

    m =(y2-y1)/(x2-x1);

    cout << "The gradient of the line is :" << m << endl;
    cout << "The equation of the line is :" << "y =" << m << * "x+b" << endl;
}
<|endoftext|>