Beispiel #1
0
void LibOMF::addSymbol(ObjModule *om, const char *name, int pickAny)
{
#if LOG
    printf("LibOMF::addSymbol(%s, %s, %d)\n", om->name, name, pickAny);
#endif
    StringValue *s = tab.insert(name, strlen(name));
    if (!s)
    {   // already in table
        if (!pickAny)
        {   s = tab.lookup(name, strlen(name));
            assert(s);
            ObjSymbol *os = (ObjSymbol *)s->ptrvalue;
            error("multiple definition of %s: %s and %s: %s",
                om->name, name, os->om->name, os->name);
        }
    }
    else
    {
        ObjSymbol *os = new ObjSymbol();
        os->name = strdup(name);
        os->om = om;
        s->ptrvalue = (void *)os;

        objsymbols.push(os);
    }
}
Beispiel #2
0
/***********************************************************************************
 **
 **
 ** MailRecovery::CheckAndFixLexicon
 ***********************************************************************************/
OP_STATUS MailRecovery::CheckAndFixLexicon()
{

    OpString path;
    RETURN_IF_ERROR(MailFiles::GetLexiconPath(path));
    StringTable lexicon;
    // Open the string table
    if (lexicon.Open(path.CStr(), LEXICON_FILENAME) == OpBoolean::IS_TRUE)
    {
        OpStringC8 log_heading("Lexicon");
        OpStatus::Ignore(DesktopFileLogger::Log(m_recovery_log,log_heading,"Checking consistency"));

        if (lexicon.CheckConsistency(FALSE) == OpBoolean::IS_FALSE)
        {
            OpStatus::Ignore(DesktopFileLogger::Log(m_recovery_log,log_heading,"Database not consistent, deleting file and reindexing."));

            // close Lexicon stringtable and delete file
            RETURN_IF_ERROR(lexicon.Close(1));
            OpFile lexicon_file;
            RETURN_IF_ERROR(lexicon_file.Construct(path.CStr()));
            RETURN_IF_ERROR(lexicon_file.Delete(TRUE));
        }
        else
        {
            OpStatus::Ignore(DesktopFileLogger::Log(m_recovery_log,log_heading,"Database consistent"));
            RETURN_IF_ERROR(lexicon.Close());
        }

    }

    return OpStatus::OK;
}
Beispiel #3
0
 GameString text(const GameStringKey& id) const {
     auto a = m_strings.find(id);
     if (a != m_strings.end()) {
         return a->second;
     }
     return GameStringUtil::fromString("MISSING: " + id);
 }
void SaveSettings()
{
  /*
   * NOTE! This code needs to stay in sync with the preference setting
   *       code in in nsExceptionHandler.cpp.
   */

  StringTable settings;

  ReadStringsFromFile(gSettingsPath + "/" + kIniFile, settings, true);
  if (!gEmailFieldHint)
    settings["Email"] = gtk_entry_get_text(GTK_ENTRY(gEmailEntry));
  else
    settings.erase("Email");

  settings["EmailMe"] =
    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gEmailMeCheck)) ? "1" : "0";
  if (gIncludeURLCheck != 0)
    settings["IncludeURL"] =
      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck))
      ? "1" : "0";
  settings["SubmitReport"] =
    gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck))
    ? "1" : "0";

  WriteStringsToFile(gSettingsPath + "/" + kIniFile,
                     "Crash Reporter", settings, true);
}
Beispiel #5
0
    StyleProviderImpl(const StyleSheet& stylesheet, StringTable& stringTable) :
        stringTable(stringTable),
        filters(),
        gradients()
    {
        filters.nodes.reserve(24);
        filters.ways.reserve(24);
        filters.areas.reserve(24);
        filters.relations.reserve(24);
        filters.canvases.reserve(24);

        for (const Rule& rule : stylesheet.rules) {
            for (const Selector& selector : rule.selectors) {
                for (const std::string& name : selector.names) {
                    FilterMap* filtersPtr = nullptr;
                    if (name == "node") filtersPtr = &filters.nodes;
                    else if (name == "way") filtersPtr = &filters.ways;
                    else if (name == "area") filtersPtr = &filters.areas;
                    else if (name == "relation") filtersPtr = &filters.relations;
                    else if (name == "canvas") filtersPtr = &filters.canvases;
                    else
                        std::domain_error("Unexpected selector name:" + name);

                    Filter filter = Filter();
                    filter.conditions.reserve(selector.conditions.size());
                    for (const Condition& condition : selector.conditions) {
                        ConditionType c;
                        if (condition.operation == "") c.type = OpType::Exists;
                        else if (condition.operation == "=") c.type = OpType::Equals;
                        else if (condition.operation == "!=") c.type = OpType::NotEquals;
                        else
                            std::domain_error("Unexpected condition operation:" + condition.operation);

                        c.key = stringTable.getId(condition.key);
                        c.value = stringTable.getId(condition.value);
                        filter.conditions.push_back(c);
                    }

                    filter.declarations.reserve(rule.declarations.size());
                    for (auto i = 0; i < rule.declarations.size(); ++i) {
                        Declaration declaration = rule.declarations[i];
                        uint32_t key = stringTable.getId(declaration.key);

                        if (utymap::utils::GradientUtils::isGradient(declaration.value))
                            addGradient(declaration.value);

                        filter.declarations[key] = Style::value_type(new StyleDeclaration(key, declaration.value));
                    }

                    std::sort(filter.conditions.begin(), filter.conditions.end(),
                        [](const ConditionType& c1, const ConditionType& c2) { return c1.key > c2.key; });
                    for (int i = selector.zoom.start; i <= selector.zoom.end; ++i) {
                        (*filtersPtr)[i].push_back(filter);
                    }
                }
            }
        }
    }
Beispiel #6
0
int main()
{
	StringTable st;
	assert(st.GetIndexByName("test1")==0);
	assert(st.GetIndexByName("test2")==1);
	assert(st.GetIndexByName("test1")==0);
	assert(st.GetNameByIndex(1)=="test2");
	cout<<"PASS"<<endl;
}
Beispiel #7
0
void StringTable::mergeTables(const StringTable& other)
{
  TableIterator iter = other.getBegin();
  const TableIterator endIter = other.getEnd();
  while (iter!=endIter)
  {
    m_Strings[iter->first] = iter->second;
    ++iter;
  }//while
}
Beispiel #8
0
//---------------------------------------------------------------------------
const char* StringValue( const unsigned int stringID )
{
	const char* errorValue = "empty!";
	StringTable::iterator iter;
	for ( iter = s_theStringTable.begin(); iter != s_theStringTable.end(); ++ iter )
	{
		if ( iter->second.m_id == stringID ) return iter->second.m_originalString.c_str();
	}
	return errorValue;
}
static void LoadSettings()
{
  /*
   * NOTE! This code needs to stay in sync with the preference checking
   *       code in in nsExceptionHandler.cpp.
   */

  StringTable settings;
  if (ReadStringsFromFile(gSettingsPath + "/" + kIniFile, settings, true)) {
    if (settings.find("Email") != settings.end()) {
      gtk_entry_set_text(GTK_ENTRY(gEmailEntry), settings["Email"].c_str());
      gEmailFieldHint = false;
    }
    if (settings.find("EmailMe") != settings.end()) {
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gEmailMeCheck),
                                   settings["EmailMe"][0] != '0');
    }
    if (settings.find("IncludeURL") != settings.end() &&
        gIncludeURLCheck != 0) {
      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck),
                                   settings["IncludeURL"][0] != '0');
    }
    bool enabled;
    if (settings.find("SubmitReport") != settings.end())
      enabled = settings["SubmitReport"][0] != '0';
    else
      enabled = ShouldEnableSending();
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck),
                                 enabled);
  }
}
Beispiel #10
0
void initTraitsStringTable()
{
    traitsStringTable._init();

    for (size_t idx = 0; ; idx++)
    {
        const char *s = traits[idx];
        if (!s) break;
        StringValue *sv = traitsStringTable.insert(s, strlen(s));
        sv->ptrvalue = (void *)traits[idx];
    }
}
Beispiel #11
0
 QuadKeyBuilderImpl(GeoStore& geoStore, StringTable& stringTable) :
     geoStore_(geoStore),
     stringTable_(stringTable),
     builderKeyId_(stringTable.getId(BuilderKeyName)),
     builderFactory_()
 {
 }
static void CountOccurrences(int nthreads) {
    StringTable table;

    tick_count t0 = tick_count::now();
    parallel_for( blocked_range<MyString*>( Data, Data+N, 1000 ), Tally(table) );
    tick_count t1 = tick_count::now();

    int n = 0;
    for( StringTable::iterator i=table.begin(); i!=table.end(); ++i ) {
        if( verbose && nthreads )
            printf("%s %d\n",i->first.c_str(),i->second);
        n += i->second;
    }

    if ( !silent ) printf("total = %d  unique = %u  time = %g\n", n, unsigned(table.size()), (t1-t0).seconds());
}
static void UpdateURL()
{
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck))) {
    gQueryParameters["URL"] = gURLParameter;
  } else {
    gQueryParameters.erase("URL");
  }
}
Beispiel #14
0
//---------------------------------------------------------------------------
unsigned int StringID( const std::string& stringValue )
{
	std::string value( stringValue );
	ToLower( value );
	StringTable::iterator iter = s_theStringTable.find( value );
	if ( iter != s_theStringTable.end() )
	{
		return iter->second.m_id;
	}
	else
	{
		StringTableEntry newEntry;
		newEntry.m_id = s_nextStringID;
		newEntry.m_originalString = stringValue;
		s_theStringTable.insert( std::make_pair( value, newEntry ) );
		++ s_nextStringID;
		return newEntry.m_id;
	}
}
    void Save(const char* filename)
    {
        const std::string header("String #");
        const std::string header_next(" is ");
        const char splitter = '~';

        if(_origin.empty())
            return;

        std::ofstream  fin(filename);

        fin << "// Total:" << _origin.size() << std::endl;
        StringTable::iterator itr = _origin.begin();
        for(;itr!=_origin.end();itr++)
        {
            fin << header << itr->first << header_next << splitter
                << itr->second << splitter << std::endl;
        }
    }
Beispiel #16
0
void *trait_search_fp(void *arg, const char *seed)
{
    //printf("trait_search_fp('%s')\n", seed);
    size_t len = strlen(seed);
    if (!len)
        return NULL;

    StringValue *sv = traitsStringTable.lookup(seed, len);
    return sv ? (void*)sv->ptrvalue : NULL;
}
    unsigned int PushString(unsigned int index, const std::string& content)
    {
        StringTable::iterator ot = _origin.find(index);
        if(ot != _origin.end())
            throw std::runtime_error( "String ID conflict." );

        StringTableRev::iterator otr = _origin_rev.find(content);
        if(otr != _origin_rev.end())
            return otr->second; // duplicated string

        // got unique string
        _origin[index] = content;
        _origin_rev[content] = index;

        if(_max_id < index)
            _max_id = index;

        return index;
    }
bool WriteStrings(ostream& out,
                  const string& header,
                  StringTable& strings,
                  bool escape)
{
  out << "[" << header << "]" << std::endl;
  for (StringTable::iterator iter = strings.begin();
       iter != strings.end();
       iter++) {
    out << iter->first << "=";
    if (escape)
      out << Escape(iter->second);
    else
      out << iter->second;

    out << std::endl;
  }

  return true;
}
Beispiel #19
0
TEST(scanner, token) {
    StringTable table;
    Pos start(1, 1);
    Pos end(2, 2);

    // test for bool literal token
    auto boolToken = Token::makeBoolLiteral(true, start, end);
    EXPECT_EQ(true, boolToken.getBoolValue());
    EXPECT_EQ(TK_BOOL_CONST, boolToken.getTokenKind());

    // test for string literal token
    auto symbol = table.addString("zhang");
    auto stringLiteralToken = Token::makeStrLiteral(symbol, start, end);
    EXPECT_EQ(TK_STR_CONST, stringLiteralToken.getTokenKind());
    EXPECT_TRUE(stringLiteralToken.getSymbol()->equalString("zhang"));

    // test for identifier token
    auto idToken = Token::makeIdentifier(symbol, start, end);
    EXPECT_EQ(TK_ID, idToken.getTokenKind());
    EXPECT_TRUE(idToken.getSymbol()->equalString("zhang"));
}
Beispiel #20
0
static void CountOccurrences(int nthreads) {
    StringTable table;

    tick_count t0 = tick_count::now();
    parallel_for( blocked_range<mystring*>( Data, Data+N, 1000 ), Tally(table) );
    tick_count t1 = tick_count::now();

    int n = 0;
    for( StringTable::iterator i=table.begin(); i!=table.end(); ++i ) {
        if( Verbose && nthreads )
            printf("%s %d\n",i->first.c_str(),i->second);
        n += i->second;
    }

    if (is_number_of_threads_set) {
        printf("threads = %d  total = %d  unique = %u  time = %g\n", nthreads, n, unsigned(table.size()), (t1-t0).seconds());
    } else {
        if ( nthreads == 1 ) {
            printf("serial run   total = %d  unique = %u  time = %g\n", n, unsigned(table.size()), (t1-t0).seconds());
        } else {
            printf("parallel run total = %d  unique = %u  time = %g\n", n, unsigned(table.size()), (t1-t0).seconds());
        }
    }
}
    unsigned int Load(const char* filename)
    {
        _origin.clear();
        _origin_rev.clear();
        _max_id = 0;

        const std::string header("String #");
        const std::string header_next(" is ");
        const char splitter = '~';

        std::ifstream  fin(filename);
        std::string    line;

        unsigned int index = INDEX_INVALID;
        std::string content;
        std::stringstream ss(content);
        while(std::getline(fin, line))
        {
            //not including the \n 
            if( line.length() >= header.length() &&
                line.substr(0, header.length()) == header)
            {
                if(index != INDEX_INVALID)
                {
                    PushString(ss, splitter, index);
                }

                int pos = line.find_first_of(splitter);
                std::string index_str = line.substr(header.length(), pos - header_next.length() - header.length());
                index = atoi(index_str.c_str());

                ss << line.substr(pos + 1);
            }
            else if(index != INDEX_INVALID)
            {
                ss << std::endl;
                ss << line;
            }
        }

        if(index != INDEX_INVALID)
        {
            PushString(ss, splitter, index);
        }

        return _max_id;
    }
Beispiel #22
0
bool LogicTable::CreateLogicTable(wstring name, vector<wstring> inputs, vector<wstring> outputs)
{
	bool retval = false;
	try
	{
		BuildDataSet(name);

		if (m_ds.TableCount() > 0)
		{
			//input table, inputs listed along left col downward
			StringTable<wstring>* inputTable = m_ds.GetTable(INPUT_TABLE);
			inputTable->AddColumn(INPUT_COL);
			for (vector<wstring>::iterator it = inputs.begin(); it != inputs.end(); it++)
			{
				vector<wstring> newRow = inputTable->NewRow();
				newRow[0] = *it;
				inputTable->AddRow(newRow);
			}

			//output table, outputs listed along left col downward
			StringTable<wstring>* outputTable = m_ds.GetTable(OUTPUT_TABLE);
			outputTable->AddColumn(OUTPUT_COL);
			for (vector<wstring>::iterator it = outputs.begin(); it != outputs.end(); it++)
			{
				vector<wstring> newRow = outputTable->NewRow();
				newRow[0] = *it;
				outputTable->AddRow(newRow);
			}
		}
	}
	catch(...)
	{
		ReportError("CreateLogicTable");
		m_ds.Clear();
	}
	return retval;
}
Beispiel #23
0
 void LoadStrings(const json_t* root, StringTable& stringTable)
 {
     auto jsonStrings = json_object_get(root, "strings");
     const char* key;
     json_t* jlanguages;
     json_object_foreach(jsonStrings, key, jlanguages)
     {
         auto stringId = ParseStringId(key);
         if (stringId != OBJ_STRING_ID_UNKNOWN)
         {
             const char* locale;
             json_t* jstring;
             json_object_foreach(jlanguages, locale, jstring)
             {
                 auto langId = language_get_id_from_locale(locale);
                 if (langId != LANGUAGE_UNDEFINED)
                 {
                     auto string = json_string_value(jstring);
                     stringTable.SetString(stringId, langId, string);
                 }
             }
         }
Beispiel #24
0
SymbolRef
ElfSymbol::CreateSymbol(Object& object, const StringTable& strtab) const
{
    SymbolRef sym(0);
    std::string name = strtab.getString(m_name_index);

    if (m_bind == STB_GLOBAL || m_bind == STB_WEAK)
    {
        sym = object.getSymbol(name);
        if (m_index == SHN_UNDEF)
            sym->Declare(Symbol::EXTERN);
        else
            sym->Declare(Symbol::GLOBAL);
    }
    else
    {
        // don't index by name, just append
        sym = object.AppendSymbol(name);
    }

    if (m_index == SHN_ABS)
    {
        if (hasSize())
            sym->DefineEqu(m_size);
        else
            sym->DefineEqu(Expr(0));
    }
    else if (m_index == SHN_COMMON)
    {
        sym->Declare(Symbol::COMMON);
    }
    else if (m_sect != 0)
    {
        Location loc = {&m_sect->bytecodes_front(), m_value.getUInt()};
        sym->DefineLabel(loc);
    }

    return sym;
}
static bool AddSubmittedReport(const string& serverResponse)
{
  StringTable responseItems;
  istringstream in(serverResponse);
  ReadStrings(in, responseItems, false);

  if (responseItems.find("StopSendingReportsFor") != responseItems.end()) {
    // server wants to tell us to stop sending reports for a certain version
    string reportPath =
      gSettingsPath + UI_DIR_SEPARATOR + "EndOfLife" +
      responseItems["StopSendingReportsFor"];

    ofstream* reportFile = UIOpenWrite(reportPath);
    if (reportFile->is_open()) {
      // don't really care about the contents
      *reportFile << 1 << "\n";
      reportFile->close();
    }
    delete reportFile;
  }

  if (responseItems.find("Discarded") != responseItems.end()) {
    // server discarded this report... save it so the user can resubmit it
    // manually
    return false;
  }

  if (responseItems.find("CrashID") == responseItems.end())
    return false;

  string submittedDir =
    gSettingsPath + UI_DIR_SEPARATOR + "submitted";
  if (!UIEnsurePathExists(submittedDir)) {
    return false;
  }

  string path = submittedDir + UI_DIR_SEPARATOR +
    responseItems["CrashID"] + ".txt";

  ofstream* file = UIOpenWrite(path);
  if (!file->is_open()) {
    delete file;
    return false;
  }

  char buf[1024];
  UI_SNPRINTF(buf, 1024,
              gStrings["CrashID"].c_str(),
              responseItems["CrashID"].c_str());
  *file << buf << "\n";

  if (responseItems.find("ViewURL") != responseItems.end()) {
    UI_SNPRINTF(buf, 1024,
                gStrings["CrashDetailsURL"].c_str(),
                responseItems["ViewURL"].c_str());
    *file << buf << "\n";
  }

  file->close();
  delete file;

  WriteSubmissionEvent(Succeeded, responseItems["CrashID"]);
  return true;
}
Beispiel #26
0
ElementStore::ElementStore(StringTable& stringTable) :
    clipKeyId_(stringTable.getId(ClipKey)),
    skipKeyId_(stringTable.getId(SkipKey)),
    sizeKeyId_(stringTable.getId(SizeKey))
{
}
Beispiel #27
0
Expression *BinExp::arrayOp(Scope *sc)
{
    //printf("BinExp::arrayOp() %s\n", toChars());

    if (type->toBasetype()->nextOf()->toBasetype()->ty == Tvoid)
    {
        error("Cannot perform array operations on void[] arrays");
        return new ErrorExp();
    }

    Expressions *arguments = new Expressions();

    /* The expression to generate an array operation for is mangled
     * into a name to use as the array operation function name.
     * Mangle in the operands and operators in RPN order, and type.
     */
    OutBuffer buf;
    buf.writestring("_array");
    buildArrayIdent(&buf, arguments);
    buf.writeByte('_');

    /* Append deco of array element type
     */
#if DMDV2
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco);
#else
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif

    size_t namelen = buf.offset;
    buf.writeByte(0);
    char *name = (char *)buf.extractData();

    /* Look up name in hash table
     */
    StringValue *sv = arrayfuncs.update(name, namelen);
    FuncDeclaration *fd = (FuncDeclaration *)sv->ptrvalue;
    if (!fd)
    {
	/* Some of the array op functions are written as library functions,
	 * presumably to optimize them with special CPU vector instructions.
	 * List those library functions here, in alpha order.
	 */
	static const char *libArrayopFuncs[] =
	{
	    "_arrayExpSliceAddass_a",
	    "_arrayExpSliceAddass_d",		// T[]+=T
	    "_arrayExpSliceAddass_f",		// T[]+=T
	    "_arrayExpSliceAddass_g",
	    "_arrayExpSliceAddass_h",
	    "_arrayExpSliceAddass_i",
	    "_arrayExpSliceAddass_k",
	    "_arrayExpSliceAddass_s",
	    "_arrayExpSliceAddass_t",
	    "_arrayExpSliceAddass_u",
	    "_arrayExpSliceAddass_w",

	    "_arrayExpSliceDivass_d",		// T[]/=T
	    "_arrayExpSliceDivass_f",		// T[]/=T

	    "_arrayExpSliceMinSliceAssign_a",
	    "_arrayExpSliceMinSliceAssign_d",	// T[]=T-T[]
	    "_arrayExpSliceMinSliceAssign_f",	// T[]=T-T[]
	    "_arrayExpSliceMinSliceAssign_g",
	    "_arrayExpSliceMinSliceAssign_h",
	    "_arrayExpSliceMinSliceAssign_i",
	    "_arrayExpSliceMinSliceAssign_k",
	    "_arrayExpSliceMinSliceAssign_s",
	    "_arrayExpSliceMinSliceAssign_t",
	    "_arrayExpSliceMinSliceAssign_u",
	    "_arrayExpSliceMinSliceAssign_w",

	    "_arrayExpSliceMinass_a",
	    "_arrayExpSliceMinass_d",		// T[]-=T
	    "_arrayExpSliceMinass_f",		// T[]-=T
	    "_arrayExpSliceMinass_g",
	    "_arrayExpSliceMinass_h",
	    "_arrayExpSliceMinass_i",
	    "_arrayExpSliceMinass_k",
	    "_arrayExpSliceMinass_s",
	    "_arrayExpSliceMinass_t",
	    "_arrayExpSliceMinass_u",
	    "_arrayExpSliceMinass_w",

	    "_arrayExpSliceMulass_d",		// T[]*=T
	    "_arrayExpSliceMulass_f",		// T[]*=T
	    "_arrayExpSliceMulass_i",
	    "_arrayExpSliceMulass_k",
	    "_arrayExpSliceMulass_s",
	    "_arrayExpSliceMulass_t",
	    "_arrayExpSliceMulass_u",
	    "_arrayExpSliceMulass_w",

	    "_arraySliceExpAddSliceAssign_a",
	    "_arraySliceExpAddSliceAssign_d",	// T[]=T[]+T
	    "_arraySliceExpAddSliceAssign_f",	// T[]=T[]+T
	    "_arraySliceExpAddSliceAssign_g",
	    "_arraySliceExpAddSliceAssign_h",
	    "_arraySliceExpAddSliceAssign_i",
	    "_arraySliceExpAddSliceAssign_k",
	    "_arraySliceExpAddSliceAssign_s",
	    "_arraySliceExpAddSliceAssign_t",
	    "_arraySliceExpAddSliceAssign_u",
	    "_arraySliceExpAddSliceAssign_w",

	    "_arraySliceExpDivSliceAssign_d",	// T[]=T[]/T
	    "_arraySliceExpDivSliceAssign_f",	// T[]=T[]/T

	    "_arraySliceExpMinSliceAssign_a",
	    "_arraySliceExpMinSliceAssign_d",	// T[]=T[]-T
	    "_arraySliceExpMinSliceAssign_f",	// T[]=T[]-T
	    "_arraySliceExpMinSliceAssign_g",
	    "_arraySliceExpMinSliceAssign_h",
	    "_arraySliceExpMinSliceAssign_i",
	    "_arraySliceExpMinSliceAssign_k",
	    "_arraySliceExpMinSliceAssign_s",
	    "_arraySliceExpMinSliceAssign_t",
	    "_arraySliceExpMinSliceAssign_u",
	    "_arraySliceExpMinSliceAssign_w",

	    "_arraySliceExpMulSliceAddass_d",	// T[] += T[]*T
	    "_arraySliceExpMulSliceAddass_f",
	    "_arraySliceExpMulSliceAddass_r",

	    "_arraySliceExpMulSliceAssign_d",	// T[]=T[]*T
	    "_arraySliceExpMulSliceAssign_f",	// T[]=T[]*T
	    "_arraySliceExpMulSliceAssign_i",
	    "_arraySliceExpMulSliceAssign_k",
	    "_arraySliceExpMulSliceAssign_s",
	    "_arraySliceExpMulSliceAssign_t",
	    "_arraySliceExpMulSliceAssign_u",
	    "_arraySliceExpMulSliceAssign_w",

	    "_arraySliceExpMulSliceMinass_d",	// T[] -= T[]*T
	    "_arraySliceExpMulSliceMinass_f",
	    "_arraySliceExpMulSliceMinass_r",

	    "_arraySliceSliceAddSliceAssign_a",
	    "_arraySliceSliceAddSliceAssign_d",	// T[]=T[]+T[]
	    "_arraySliceSliceAddSliceAssign_f",	// T[]=T[]+T[]
	    "_arraySliceSliceAddSliceAssign_g",
	    "_arraySliceSliceAddSliceAssign_h",
	    "_arraySliceSliceAddSliceAssign_i",
	    "_arraySliceSliceAddSliceAssign_k",
	    "_arraySliceSliceAddSliceAssign_r",	// T[]=T[]+T[]
	    "_arraySliceSliceAddSliceAssign_s",
	    "_arraySliceSliceAddSliceAssign_t",
	    "_arraySliceSliceAddSliceAssign_u",
	    "_arraySliceSliceAddSliceAssign_w",

	    "_arraySliceSliceAddass_a",
	    "_arraySliceSliceAddass_d",		// T[]+=T[]
	    "_arraySliceSliceAddass_f",		// T[]+=T[]
	    "_arraySliceSliceAddass_g",
	    "_arraySliceSliceAddass_h",
	    "_arraySliceSliceAddass_i",
	    "_arraySliceSliceAddass_k",
	    "_arraySliceSliceAddass_s",
	    "_arraySliceSliceAddass_t",
	    "_arraySliceSliceAddass_u",
	    "_arraySliceSliceAddass_w",

	    "_arraySliceSliceMinSliceAssign_a",
	    "_arraySliceSliceMinSliceAssign_d",	// T[]=T[]-T[]
	    "_arraySliceSliceMinSliceAssign_f",	// T[]=T[]-T[]
	    "_arraySliceSliceMinSliceAssign_g",
	    "_arraySliceSliceMinSliceAssign_h",
	    "_arraySliceSliceMinSliceAssign_i",
	    "_arraySliceSliceMinSliceAssign_k",
	    "_arraySliceSliceMinSliceAssign_r",	// T[]=T[]-T[]
	    "_arraySliceSliceMinSliceAssign_s",
	    "_arraySliceSliceMinSliceAssign_t",
	    "_arraySliceSliceMinSliceAssign_u",
	    "_arraySliceSliceMinSliceAssign_w",

	    "_arraySliceSliceMinass_a",
	    "_arraySliceSliceMinass_d",		// T[]-=T[]
	    "_arraySliceSliceMinass_f",		// T[]-=T[]
	    "_arraySliceSliceMinass_g",
	    "_arraySliceSliceMinass_h",
	    "_arraySliceSliceMinass_i",
	    "_arraySliceSliceMinass_k",
	    "_arraySliceSliceMinass_s",
	    "_arraySliceSliceMinass_t",
	    "_arraySliceSliceMinass_u",
	    "_arraySliceSliceMinass_w",

	    "_arraySliceSliceMulSliceAssign_d",	// T[]=T[]*T[]
	    "_arraySliceSliceMulSliceAssign_f",	// T[]=T[]*T[]
	    "_arraySliceSliceMulSliceAssign_i",
	    "_arraySliceSliceMulSliceAssign_k",
	    "_arraySliceSliceMulSliceAssign_s",
	    "_arraySliceSliceMulSliceAssign_t",
	    "_arraySliceSliceMulSliceAssign_u",
	    "_arraySliceSliceMulSliceAssign_w",

	    "_arraySliceSliceMulass_d",		// T[]*=T[]
	    "_arraySliceSliceMulass_f",		// T[]*=T[]
	    "_arraySliceSliceMulass_i",
	    "_arraySliceSliceMulass_k",
	    "_arraySliceSliceMulass_s",
	    "_arraySliceSliceMulass_t",
	    "_arraySliceSliceMulass_u",
	    "_arraySliceSliceMulass_w",
	};

	int i = binary(name, libArrayopFuncs, sizeof(libArrayopFuncs) / sizeof(char *));
	if (i == -1)
	{
#ifdef DEBUG	// Make sure our array is alphabetized
	    for (i = 0; i < sizeof(libArrayopFuncs) / sizeof(char *); i++)
	    {
		if (strcmp(name, libArrayopFuncs[i]) == 0)
		    assert(0);
	    }
#endif
	    /* Not in library, so generate it.
	     * Construct the function body:
	     *	foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
	     *	    loopbody;
	     *	return p;
	     */

	    Arguments *fparams = new Arguments();
	    Expression *loopbody = buildArrayLoop(fparams);
	    Argument *p = (Argument *)fparams->data[0 /*fparams->dim - 1*/];
#if DMDV1
	    // for (size_t i = 0; i < p.length; i++)
	    Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
	    Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
	    Statement *s1 = new ForStatement(0,
		new DeclarationStatement(0, d),
		new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
		new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
		new ExpStatement(0, loopbody));
#else
	    // foreach (i; 0 .. p.length)
	    Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
		new Argument(0, NULL, Id::p, NULL),
		new IntegerExp(0, 0, Type::tint32),
		new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
		new ExpStatement(0, loopbody));
#endif
	    Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident));
	    //printf("s2: %s\n", s2->toChars());
	    Statement *fbody = new CompoundStatement(0, s1, s2);

	    /* Construct the function
	     */
	    TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc);
	    //printf("ftype: %s\n", ftype->toChars());
	    fd = new FuncDeclaration(0, 0, Lexer::idPool(name), STCundefined, ftype);
	    fd->fbody = fbody;
	    fd->protection = PROTpublic;
	    fd->linkage = LINKc;

	    sc->module->importedFrom->members->push(fd);

	    sc = sc->push();
	    sc->parent = sc->module->importedFrom;
	    sc->stc = 0;
	    sc->linkage = LINKc;
	    fd->semantic(sc);
	    fd->semantic2(sc);
	    fd->semantic3(sc);
	    sc->pop();
	}
	else
	{   /* In library, refer to it.
	     */
	    fd = FuncDeclaration::genCfunc(type, name);
	}
	sv->ptrvalue = fd;	// cache symbol in hash table
    }

    /* Call the function fd(arguments)
     */
    Expression *ec = new VarExp(0, fd);
    Expression *e = new CallExp(loc, ec, arguments);
    e->type = type;
    return e;
}
Beispiel #28
0
static FIBITMAP * DLL_CALLCONV 
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	if( data == NULL ) {
		return NULL;
	}
	GIFinfo *info = (GIFinfo *)data;

	if( page == -1 ) {
		page = 0;
	}
	if( page < 0 || page >= (int)info->image_descriptor_offsets.size() ) {
		return NULL;
	}

	FIBITMAP *dib = NULL;
	try {
		bool have_transparent = false, no_local_palette = false, interlaced = false;
		int disposal_method = GIF_DISPOSAL_LEAVE, delay_time = 0, transparent_color = 0;
		WORD left, top, width, height;
		BYTE packed, b;
		WORD w;

		//playback pages to generate what the user would see for this frame
		if( (flags & GIF_PLAYBACK) == GIF_PLAYBACK ) {
			//Logical Screen Descriptor
			io->seek_proc(handle, 6, SEEK_SET);
			WORD logicalwidth, logicalheight;
			io->read_proc(&logicalwidth, 2, 1, handle);
			io->read_proc(&logicalheight, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
			SwapShort(&logicalwidth);
			SwapShort(&logicalheight);
#endif
			//set the background color with 0 alpha
			RGBQUAD background;
			if( info->global_color_table_offset != 0 && info->background_color < info->global_color_table_size ) {
				io->seek_proc(handle, info->global_color_table_offset + (info->background_color * 3), SEEK_SET);
				io->read_proc(&background.rgbRed, 1, 1, handle);
				io->read_proc(&background.rgbGreen, 1, 1, handle);
				io->read_proc(&background.rgbBlue, 1, 1, handle);
			} else {
				background.rgbRed = 0;
				background.rgbGreen = 0;
				background.rgbBlue = 0;
			}
			background.rgbReserved = 0;

			//allocate entire logical area
			dib = FreeImage_Allocate(logicalwidth, logicalheight, 32);
			if( dib == NULL ) {
				throw "DIB allocated failed";
			}

			//fill with background color to start
			int x, y;
			RGBQUAD *scanline;
			for( y = 0; y < logicalheight; y++ ) {
				scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
				for( x = 0; x < logicalwidth; x++ ) {
					*scanline++ = background;
				}
			}

			//cache some info about each of the pages so we can avoid decoding as many of them as possible
			std::vector<PageInfo> pageinfo;
			int start = page, end = page;
			while( start >= 0 ) {
				//Graphic Control Extension
				io->seek_proc(handle, info->graphic_control_extension_offsets[start] + 1, SEEK_SET);
				io->read_proc(&packed, 1, 1, handle);
				have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false;
				disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2;
				//Image Descriptor
				io->seek_proc(handle, info->image_descriptor_offsets[page], SEEK_SET);
				io->read_proc(&left, 2, 1, handle);
				io->read_proc(&top, 2, 1, handle);
				io->read_proc(&width, 2, 1, handle);
				io->read_proc(&height, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
				SwapShort(&left);
				SwapShort(&top);
				SwapShort(&width);
				SwapShort(&height);
#endif

				pageinfo.push_back(PageInfo(disposal_method, left, top, width, height));

				if( start != end ) {
					if( left == 0 && top == 0 && width == logicalwidth && height == logicalheight ) {
						if( disposal_method == GIF_DISPOSAL_BACKGROUND ) {
							pageinfo.pop_back();
							start++;
							break;
						} else if( disposal_method != GIF_DISPOSAL_PREVIOUS ) {
							if( !have_transparent ) {
								break;
							}
						}
					}
				}
				start--;
			}
			if( start < 0 ) {
				start = 0;
			}

			//draw each page into the logical area
			for( page = start; page <= end; page++ ) {
				PageInfo &info = pageinfo[end - page];
				//things we can skip having to decode
				if( page != end ) {
					if( info.disposal_method == GIF_DISPOSAL_PREVIOUS ) {
						continue;
					}
					if( info.disposal_method == GIF_DISPOSAL_BACKGROUND ) {
						for( y = 0; y < info.height; y++ ) {
							scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, logicalheight - (y + info.top) - 1) + info.left;
							for( x = 0; x < info.width; x++ ) {
								*scanline++ = background;
							}
						}
					}
				}

				//decode page
				FIBITMAP *pagedib = Load(io, handle, page, GIF_LOAD256, data);
				if( pagedib != NULL ) {
					RGBQUAD *pal = FreeImage_GetPalette(pagedib);
					have_transparent = false;
					if( FreeImage_IsTransparent(pagedib) ) {
						int count = FreeImage_GetTransparencyCount(pagedib);
						BYTE *table = FreeImage_GetTransparencyTable(pagedib);
						for( int i = 0; i < count; i++ ) {
							if( table[i] == 0 ) {
								have_transparent = true;
								transparent_color = i;
								break;
							}
						}
					}
					//copy page data into logical buffer, with full alpha opaqueness
					for( y = 0; y < info.height; y++ ) {
						scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, logicalheight - (y + info.top) - 1) + info.left;
						BYTE *pageline = FreeImage_GetScanLine(pagedib, info.height - y - 1);
						for( x = 0; x < info.width; x++ ) {
							if( !have_transparent || *pageline != transparent_color ) {
								*scanline = pal[*pageline];
								scanline->rgbReserved = 255;
							}
							scanline++;
							pageline++;
						}
					}
					FreeImage_Unload(pagedib);
				}
			}

			return dib;
		}

		//get the actual frame image data for a single frame

		//Image Descriptor
		io->seek_proc(handle, info->image_descriptor_offsets[page], SEEK_SET);
		io->read_proc(&left, 2, 1, handle);
		io->read_proc(&top, 2, 1, handle);
		io->read_proc(&width, 2, 1, handle);
		io->read_proc(&height, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
		SwapShort(&left);
		SwapShort(&top);
		SwapShort(&width);
		SwapShort(&height);
#endif
		io->read_proc(&packed, 1, 1, handle);
		interlaced = (packed & GIF_PACKED_ID_INTERLACED) ? true : false;
		no_local_palette = (packed & GIF_PACKED_ID_HAVELCT) ? false : true;

		int bpp = 8;
		if( (flags & GIF_LOAD256) == 0 ) {
			if( !no_local_palette ) {
				int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
				if( size <= 2 ) bpp = 1;
				else if( size <= 16 ) bpp = 4;
			} else if( info->global_color_table_offset != 0 ) {
				if( info->global_color_table_size <= 2 ) bpp = 1;
				else if( info->global_color_table_size <= 16 ) bpp = 4;
			}
		}
		dib = FreeImage_Allocate(width, height, bpp);
		if( dib == NULL ) {
			throw "DIB allocated failed";
		}

		FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameLeft", ANIMTAG_FRAMELEFT, FIDT_SHORT, 1, 2, &left);
		FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameTop", ANIMTAG_FRAMETOP, FIDT_SHORT, 1, 2, &top);
		b = no_local_palette ? 1 : 0;
		FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "NoLocalPalette", ANIMTAG_NOLOCALPALETTE, FIDT_BYTE, 1, 1, &b);
		b = interlaced ? 1 : 0;
		FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Interlaced", ANIMTAG_INTERLACED, FIDT_BYTE, 1, 1, &b);

		//Palette
		RGBQUAD *pal = FreeImage_GetPalette(dib);
		if( !no_local_palette ) {
			int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);

			int i = 0;
			while( i < size ) {
				io->read_proc(&pal[i].rgbRed, 1, 1, handle);
				io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
				io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
				i++;
			}
		} else if( info->global_color_table_offset != 0 ) {
			long pos = io->tell_proc(handle);
			io->seek_proc(handle, info->global_color_table_offset, SEEK_SET);

			int i = 0;
			while( i < info->global_color_table_size ) {
				io->read_proc(&pal[i].rgbRed, 1, 1, handle);
				io->read_proc(&pal[i].rgbGreen, 1, 1, handle);
				io->read_proc(&pal[i].rgbBlue, 1, 1, handle);
				i++;
			}

			io->seek_proc(handle, pos, SEEK_SET);
		} else {
			//its legal to have no palette, but we're going to generate *something*
			for( int i = 0; i < 256; i++ ) {
				pal[i].rgbRed = i;
				pal[i].rgbGreen = i;
				pal[i].rgbBlue = i;
			}
		}

		//LZW Minimum Code Size
		io->read_proc(&b, 1, 1, handle);
		StringTable stringtable;
		stringtable.Initialize(b);

		//Image Data Sub-blocks
		int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0;
		BYTE *scanline = FreeImage_GetScanLine(dib, height - 1);
		BYTE buf[1024];
		io->read_proc(&b, 1, 1, handle);
		while( b ) {
			io->read_proc(stringtable.FillInputBuffer(b), b, 1, handle);
			int size = sizeof(buf);
			while( stringtable.Decompress(buf, &size) ) {
				for( int i = 0; i < size; i++ ) {
					scanline[xpos] |= (buf[i] & mask) << shift;
					if( shift > 0 ) {
						shift -= bpp;
					} else {
						xpos++;
						shift = 8 - bpp;
					}
					if( ++x >= width ) {
						if( interlaced ) {
							y += g_GifInterlaceIncrement[interlacepass];
							if( y >= height && interlacepass < GIF_INTERLACE_PASSES ) {
								y = g_GifInterlaceOffset[++interlacepass];
							}
						} else {
							y++;
						}
						if( y >= height ) {
							stringtable.Done();
							break;
						}
						x = xpos = 0;
						shift = 8 - bpp;
						scanline = FreeImage_GetScanLine(dib, height - y - 1);
					}
				}
				size = sizeof(buf);
			}
			io->read_proc(&b, 1, 1, handle);
		}

		if( page == 0 ) {
			size_t idx;

			//Logical Screen Descriptor
			io->seek_proc(handle, 6, SEEK_SET);
			WORD logicalwidth, logicalheight;
			io->read_proc(&logicalwidth, 2, 1, handle);
			io->read_proc(&logicalheight, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
			SwapShort(&logicalwidth);
			SwapShort(&logicalheight);
#endif
			FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "LogicalWidth", ANIMTAG_LOGICALWIDTH, FIDT_SHORT, 1, 2, &logicalwidth);
			FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "LogicalHeight", ANIMTAG_LOGICALHEIGHT, FIDT_SHORT, 1, 2, &logicalheight);

			//Global Color Table
			if( info->global_color_table_offset != 0 ) {
				RGBQUAD globalpalette[256];
				io->seek_proc(handle, info->global_color_table_offset, SEEK_SET);
				int i = 0;
				while( i < info->global_color_table_size ) {
					io->read_proc(&globalpalette[i].rgbRed, 1, 1, handle);
					io->read_proc(&globalpalette[i].rgbGreen, 1, 1, handle);
					io->read_proc(&globalpalette[i].rgbBlue, 1, 1, handle);
					globalpalette[i].rgbReserved = 0;
					i++;
				}
				FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "GlobalPalette", ANIMTAG_GLOBALPALETTE, FIDT_PALETTE, info->global_color_table_size, info->global_color_table_size * 4, globalpalette);
				//background color
				if( info->background_color < info->global_color_table_size ) {
					FreeImage_SetBackgroundColor(dib, &globalpalette[info->background_color]);
				}
			}

			//Application Extension
			LONG loop = 1; //If no AE with a loop count is found, the default must be 1
			for( idx = 0; idx < info->application_extension_offsets.size(); idx++ ) {
				io->seek_proc(handle, info->application_extension_offsets[idx], SEEK_SET);
				io->read_proc(&b, 1, 1, handle);
				if( b == 11 ) { //All AEs start with an 11 byte sub-block to determine what type of AE it is
					char buf[11];
					io->read_proc(buf, 11, 1, handle);
					if( !memcmp(buf, "NETSCAPE2.0", 11) || !memcmp(buf, "ANIMEXTS1.0", 11) ) { //Not everybody recognizes ANIMEXTS1.0 but it is valid
						io->read_proc(&b, 1, 1, handle);
						if( b == 3 ) { //we're supposed to have a 3 byte sub-block now
							io->read_proc(&b, 1, 1, handle); //this should be 0x01 but isn't really important
							io->read_proc(&w, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
							SwapShort(&w);
#endif
							loop = w;
							if( loop > 0 ) loop++;
							break;
						}
					}
				}
			}
			FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Loop", ANIMTAG_LOOP, FIDT_LONG, 1, 4, &loop);

			//Comment Extension
			for( idx = 0; idx < info->comment_extension_offsets.size(); idx++ ) {
				io->seek_proc(handle, info->comment_extension_offsets[idx], SEEK_SET);
				std::string comment;
				char buf[255];
				io->read_proc(&b, 1, 1, handle);
				while( b ) {
					io->read_proc(buf, b, 1, handle);
					comment.append(buf, b);
					io->read_proc(&b, 1, 1, handle);
				}
				comment.append(1, '\0');
				sprintf(buf, "Comment%d", idx);
				FreeImage_SetMetadataEx(FIMD_COMMENTS, dib, buf, 1, FIDT_ASCII, comment.size(), comment.size(), comment.c_str());
			}
		}

		//Graphic Control Extension
		if( info->graphic_control_extension_offsets[page] != 0 ) {
			io->seek_proc(handle, info->graphic_control_extension_offsets[page] + 1, SEEK_SET);
			io->read_proc(&packed, 1, 1, handle);
			io->read_proc(&w, 2, 1, handle);
#ifdef FREEIMAGE_BIGENDIAN
			SwapShort(&w);
#endif
			io->read_proc(&b, 1, 1, handle);
			have_transparent = (packed & GIF_PACKED_GCE_HAVETRANS) ? true : false;
			disposal_method = (packed & GIF_PACKED_GCE_DISPOSAL) >> 2;
			delay_time = w * 10; //convert cs to ms
			transparent_color = b;
			if( have_transparent ) {
				int size = 1 << bpp;
				if( transparent_color <= size ) {
					BYTE table[256];
					memset(table, 0xFF, size);
					table[transparent_color] = 0;
					FreeImage_SetTransparencyTable(dib, table, size);
				}
			}
		}
Beispiel #29
0
inline void save_string_table(BinaryFile &bf, const StringTable &st)
{
    bf.save_pod_vector(st.indices());
    bf.save_pod_vector(st.strings());
}
int main(int argc, char** argv)
{
  gArgc = argc;
  gArgv = argv;

  if (!ReadConfig()) {
    UIError("Couldn't read configuration.");
    return 0;
  }

  if (!UIInit())
    return 0;

  if (argc > 1) {
    gReporterDumpFile = argv[1];
  }

  if (gReporterDumpFile.empty()) {
    // no dump file specified, run the default UI
    UIShowDefaultUI();
  } else {
    // Start by running minidump analyzer to gather stack traces.
    string reporterDumpFile = gReporterDumpFile;
    vector<string> args = { reporterDumpFile };
    UIRunProgram(GetProgramPath(UI_MINIDUMP_ANALYZER_FILENAME),
                 args, /* wait */ true);

    // go ahead with the crash reporter
    gExtraFile = GetAdditionalFilename(gReporterDumpFile, kExtraDataExtension);
    if (gExtraFile.empty()) {
      UIError(gStrings[ST_ERROR_BADARGUMENTS]);
      return 0;
    }

    if (!UIFileExists(gExtraFile)) {
      UIError(gStrings[ST_ERROR_EXTRAFILEEXISTS]);
      return 0;
    }

    gMemoryFile = GetAdditionalFilename(gReporterDumpFile,
                                        kMemoryReportExtension);
    if (!UIFileExists(gMemoryFile)) {
      gMemoryFile.erase();
    }

    StringTable queryParameters;
    if (!ReadStringsFromFile(gExtraFile, queryParameters, true)) {
      UIError(gStrings[ST_ERROR_EXTRAFILEREAD]);
      return 0;
    }

    if (queryParameters.find("ProductName") == queryParameters.end()) {
      UIError(gStrings[ST_ERROR_NOPRODUCTNAME]);
      return 0;
    }

    // There is enough information in the extra file to rewrite strings
    // to be product specific
    RewriteStrings(queryParameters);

    if (queryParameters.find("ServerURL") == queryParameters.end()) {
      UIError(gStrings[ST_ERROR_NOSERVERURL]);
      return 0;
    }

    // Hopefully the settings path exists in the environment. Try that before
    // asking the platform-specific code to guess.
    gSettingsPath = UIGetEnv("MOZ_CRASHREPORTER_DATA_DIRECTORY");
    if (gSettingsPath.empty()) {
      string product = queryParameters["ProductName"];
      string vendor = queryParameters["Vendor"];
      if (!UIGetSettingsPath(vendor, product, gSettingsPath)) {
        gSettingsPath.clear();
      }
    }

    if (gSettingsPath.empty() || !UIEnsurePathExists(gSettingsPath)) {
      UIError(gStrings[ST_ERROR_NOSETTINGSPATH]);
      return 0;
    }

    OpenLogFile();

    gEventsPath = UIGetEnv("MOZ_CRASHREPORTER_EVENTS_DIRECTORY");
    gPingPath = UIGetEnv("MOZ_CRASHREPORTER_PING_DIRECTORY");

    // Assemble and send the crash ping
    string hash;
    string pingUuid;

    hash = ComputeDumpHash();
    if (!hash.empty()) {
      AppendToEventFile("MinidumpSha256Hash", hash);
    }

    if (SendCrashPing(queryParameters, hash, pingUuid, gPingPath)) {
      AppendToEventFile("CrashPingUUID", pingUuid);
    }

    // Update the crash event with stacks if they are present
    auto stackTracesItr = queryParameters.find("StackTraces");
    if (stackTracesItr != queryParameters.end()) {
      AppendToEventFile(stackTracesItr->first, stackTracesItr->second);
    }

    if (!UIFileExists(gReporterDumpFile)) {
      UIError(gStrings[ST_ERROR_DUMPFILEEXISTS]);
      return 0;
    }

    string pendingDir = gSettingsPath + UI_DIR_SEPARATOR + "pending";
    if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile,
                       gMemoryFile)) {
      return 0;
    }

    string sendURL = queryParameters["ServerURL"];
    // we don't need to actually send this
    queryParameters.erase("ServerURL");

    queryParameters["Throttleable"] = "1";

    // re-set XUL_APP_FILE for xulrunner wrapped apps
    const char *appfile = getenv("MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE");
    if (appfile && *appfile) {
      const char prefix[] = "XUL_APP_FILE=";
      char *env = (char*) malloc(strlen(appfile) + strlen(prefix) + 1);
      if (!env) {
        UIError("Out of memory");
        return 0;
      }
      strcpy(env, prefix);
      strcat(env, appfile);
      putenv(env);
      free(env);
    }

    vector<string> restartArgs;

    ostringstream paramName;
    int i = 0;
    paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++;
    const char *param = getenv(paramName.str().c_str());
    while (param && *param) {
      restartArgs.push_back(param);

      paramName.str("");
      paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++;
      param = getenv(paramName.str().c_str());
    }

    // allow override of the server url via environment variable
    //XXX: remove this in the far future when our robot
    // masters force everyone to use XULRunner
    char* urlEnv = getenv("MOZ_CRASHREPORTER_URL");
    if (urlEnv && *urlEnv) {
      sendURL = urlEnv;
    }

     // see if this version has been end-of-lifed
     if (queryParameters.find("Version") != queryParameters.end() &&
         CheckEndOfLifed(queryParameters["Version"])) {
       UIError(gStrings[ST_ERROR_ENDOFLIFE]);
       DeleteDump();
       return 0;
     }

    StringTable files;
    files["upload_file_minidump"] = gReporterDumpFile;
    if (!gMemoryFile.empty()) {
      files["memory_report"] = gMemoryFile;
    }

    if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs))
      DeleteDump();
  }

  UIShutdown();

  return 0;
}