int TLwTermBs::AddTermGetTermId(const PLwTerm& Term){ IAssert(Term->GetTermId()==-1); Term->PutTermId(MxTermId+1); AddTerm(Term); return Term->GetTermId(); }
bool nsEudoraFilters::RealImport() { nsresult rv; rv = Init(); if (NS_FAILED(rv)) { IMPORT_LOG0("*** Error initializing filter import process\n"); return false; } nsCOMPtr <nsIInputStream> inputStream; rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), m_pLocation); if (NS_FAILED(rv)) { IMPORT_LOG0("*** Error opening filters file for reading\n"); return false; } rv = LoadServers(); if (NS_FAILED(rv)) { IMPORT_LOG0("*** Error loading servers with filters\n"); return false; } nsCOMPtr<nsILineInputStream> lineStream(do_QueryInterface(inputStream, &rv)); NS_ENSURE_SUCCESS(rv, false); nsCString line; bool more = true; nsAutoCString header; nsAutoCString verb; nsAutoString name; // Windows Eudora filters files have a version header as a first line - just skip it #if defined(XP_WIN) rv = lineStream->ReadLine(line, &more); #endif while (more && NS_SUCCEEDED(rv)) { rv = lineStream->ReadLine(line, &more); const char* pLine = line.get(); if (NS_SUCCEEDED(rv)) { // New filters start with a "rule <name>" line if (!strncmp(pLine, "rule ", 5)) { rv = FinalizeFilter(); if (NS_SUCCEEDED(rv)) { const char* pName = pLine + 5; NS_CopyNativeToUnicode(nsCString(pName), name); rv = CreateNewFilter(pName); } } #ifdef XP_MACOSX else if (!strncmp(pLine, "id ", 3)) ;// ids have no value to us, but we don't want them to produce a warning either #endif else if (!strncmp(pLine, "conjunction ", 12)) { const char* cj = pLine + 12; if (!strcmp(cj, "and")) m_isAnd = true; else if (!strcmp(cj, "unless")) m_isUnless = true; else if (!strcmp(cj, "ignore")) m_ignoreTerm = true; } else if (!strncmp(pLine, "header ", 7)) header = (pLine + 7); else if (!strncmp(pLine, "verb ", 5)) verb = (pLine + 5); else if (!strncmp(pLine, "value ", 6)) { if (!m_ignoreTerm) { rv = AddTerm(header.get(), verb.get(), pLine + 6, (m_isAnd || m_isUnless), m_isUnless); // For now, ignoring terms that can't be represented in TB filters if (rv == NS_ERROR_INVALID_ARG) { rv = NS_OK; m_termNotGroked = true; } } } else if (!strcmp(pLine, "incoming")) m_isIncoming = true; else if (!strncmp(pLine, "transfer ", 9) || !strncmp(pLine, "copy ", 5)) { const char* pMailboxPath = strchr(pLine, ' ') + 1; bool isTransfer = (*pLine == 't'); rv = AddMailboxAction(pMailboxPath, isTransfer); if (rv == NS_ERROR_INVALID_ARG) { nsAutoString unicodeMailboxPath; NS_CopyNativeToUnicode(nsCString(pMailboxPath), unicodeMailboxPath); m_errorLog += NS_LITERAL_STRING("- "); m_errorLog += name; m_errorLog += NS_LITERAL_STRING(": "); m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_MAILBOX_MISSING, unicodeMailboxPath.get()); m_errorLog += NS_LITERAL_STRING("\n"); rv = NS_OK; } } // Doing strncmp() here because Win Eudora puts a space after "stop" but Mac Eudora doesn't else if (!strncmp(pLine, "stop", 4)) m_hasStop = true; else if (!strncmp(pLine, "forward ", 8)) rv = AddStringAction(nsMsgFilterAction::Forward, pLine + 8); else if (!strncmp(pLine, "reply ", 6)) rv = AddStringAction(nsMsgFilterAction::Reply, pLine + 6); else if (!strncmp(pLine, "priority ", 9)) { // Win Eudora's priority values are 0 (highest) to 4 (lowest) // Mac Eudora's priority values are 1 (highest) to 5 (lowest) // Thunderbird's priority values are 6 (highest) to 2 (lowest) int32_t TBPriority = 6 - atoi(pLine + 9); #ifdef XP_MACOSX TBPriority++; #endif rv = AddPriorityAction(TBPriority); } else if (!strncmp(pLine, "label ", 6)) { nsAutoCString tagName("$label"); tagName += pLine + 6; rv = AddStringAction(nsMsgFilterAction::AddTag, tagName.get()); } // Doing strncmp() here because Win Eudora puts a space after "junk" but Mac Eudora doesn't else if (!strncmp(pLine, "junk", 4)) rv = AddJunkAction(100); else if (!strncmp(pLine, "status ", 7)) { // Win Eudora's read status is 1, whereas Mac Eudora's read status is 2 uint32_t status = atoi(pLine + 7); #ifdef XP_MACOSX status--; #endif if (status == 1) rv = AddAction(nsMsgFilterAction::MarkRead); } else if (!strncmp(pLine, "serverOpt ", 10)) { // Win and Mac Eudora have the two bits swapped in the file uint32_t bits = atoi(pLine + 10); #if defined(XP_WIN) bool bFetch = (bits & 1); bool bDelete = (bits & 2); #endif #ifdef XP_MACOSX bool bFetch = (bits & 2); bool bDelete = (bits & 1); #endif rv = AddAction(bDelete? (nsMsgRuleActionType)nsMsgFilterAction::DeleteFromPop3Server : (nsMsgRuleActionType)nsMsgFilterAction::LeaveOnPop3Server); if (NS_SUCCEEDED(rv) && bFetch) rv = AddAction(nsMsgFilterAction::FetchBodyFromPop3Server); } else if (strcmp(pLine, "manual") == 0) ;// Just ignore manual as TB handles manual in a different way else if (strcmp(pLine, "outgoing") == 0) { m_errorLog += NS_LITERAL_STRING("- "); m_errorLog += name; m_errorLog += NS_LITERAL_STRING(": "); m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_OUTGOING); m_errorLog += NS_LITERAL_STRING("\n"); } else { nsAutoString unicodeLine; NS_CopyNativeToUnicode(nsCString(pLine), unicodeLine); m_errorLog += NS_LITERAL_STRING("- "); m_errorLog += name; m_errorLog += NS_LITERAL_STRING(": "); m_errorLog += nsEudoraStringBundle::FormatString(EUDORAIMPORT_FILTERS_WARN_ACTION, unicodeLine.get()); m_errorLog += NS_LITERAL_STRING("\n"); } } } // Process the last filter if (!more && NS_SUCCEEDED(rv)) rv = FinalizeFilter(); inputStream->Close(); if (more) { IMPORT_LOG0("*** Error reading the filters, didn't reach the end\n"); return false; } rv = SaveFilters(); return NS_SUCCEEDED(rv); }
void FormStates(Exp E) { int S, I, Diff; Exp A, B; int AX, BX; STab = 0, Ss = 0; AddState(MakeExp(ZeroX)); AddState(E); TList = 0, TMax = 0; for (S = 0; S < Ss; S++) { PushQ(STab[S]); while (Xs > 0) { E = XStack[Xs - 1]; if (E->Normal) { PopQ(); continue; } switch (E->Tag) { case ZeroX: case OneX: E->Terms = 0, E->Sum = 0, E->Normal = 1; PopQ(); break; case SymX: E->Terms = 1, E->Sum = Allocate(sizeof *E->Sum); E->Sum[0].X = E->Body.Leaf, E->Sum[0].Q = MakeExp(OneX); E->Normal = 1; PopQ(); break; case OptX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } E->Terms = A->Terms, E->Sum = A->Sum; E->Normal = 1; PopQ(); break; case StarX: case PlusX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } B = E->Unit? E: MakeExp(StarX, A); Catenate: E->Terms = A->Terms; E->Sum = Allocate(E->Terms * sizeof *E->Sum); for (I = 0; I < E->Terms; I++) E->Sum[I].X = A->Sum[I].X, E->Sum[I].Q = CatExp(A->Sum[I].Q, B); E->Normal = 1; PopQ(); break; case CatX: case OrX: case AndX: case DiffX: case ProdX: A = E->Body.Arg[0]; if (!A->Normal) { PushQ(A); continue; } B = E->Body.Arg[1]; if (E->Tag == CatX && !A->Unit) goto Catenate; if (!B->Normal) { PushQ(B); continue; } for (AX = BX = Ts = 0; AX < A->Terms || BX < B->Terms; ) { Exp dA, dB; Symbol xA, xB; Diff = 0; if (AX >= A->Terms) Diff = 1; else dA = A->Sum[AX].Q, xA = A->Sum[AX].X; if (BX >= B->Terms) Diff = -1; else dB = B->Sum[BX].Q, xB = B->Sum[BX].X; if (Diff == 0) Diff = strcmp(xA->Name, xB->Name); if (Diff <= 0) AX++; if (Diff >= 0) BX++; switch (E->Tag) { case AndX: if (Diff == 0) AddTerm(xA, BinExp(AndX, dA, dB)); break; case CatX: if (Diff <= 0) dA = CatExp(dA, B); goto Join; case ProdX: if (Diff <= 0) dA = BinExp(ProdX, dA, B); if (Diff >= 0) dB = BinExp(ProdX, dB, A); case OrX: Join: if (Diff < 0) AddTerm(xA, dA); else if (Diff > 0) AddTerm(xB, dB); else AddTerm(xA, BinExp(OrX, dA, dB)); break; case DiffX: if (Diff == 0) dA = MakeExp(DiffX, dA, dB); if (Diff <= 0) AddTerm(xA, dA); break; default: break; } } E->Terms = Ts; E->Sum = Allocate(E->Terms * sizeof *E->Sum); for (I = 0; I < Ts; I++) E->Sum[I] = TList[I]; E->Normal = 1; PopQ(); break; } } E = STab[S]; for (I = 0; I < E->Terms; I++) AddState(E->Sum[I].Q); } free(XStack), XMax = 0; free(TList), TMax = 0; }