int ScanCTFile(char *ctfile) { FILE *fp; char *newline, *line, *idstr, *newidstr, *newstr; struct CatString *cs = NULL; int Result = TRUE; int CodeSet_checked = 0; ScanFile = ctfile; ScanLine = 0; if((fp = fopen(ctfile, "r")) == NULL) { ShowErrorQuick(MSG_ERR_NOCATALOGTRANSLATION, ctfile); } if(!NoBufferedIO) setvbuf(fp, NULL, _IOFBF, buffer_size); while(!feof(fp) && (line = newline = ReadLine(fp, TRUE)) != NULL) { switch(*line) { case ';': if(CopyNEWs == TRUE) { if(cs && Strnicmp(line, Old_Msg_New, (int)strlen(Old_Msg_New)) == 0) { cs->NotInCT = TRUE; } } break; case '#': /* '#' in the first column of a line is the command introducer -- any number of # symbols, blank spaces and tabs afterwards are skipped for compatibility with CatComp */ while(*line == '#' || *line == ' ' || *line == '\t') { ++line; } if(Strnicmp(line, "version", 7) == 0) { if(CatVersionString || CatRcsId || CatName) { ShowError(MSG_ERR_DOUBLECTVERSION); } line += 7; OverSpace(&line); // perform a slightly obfuscated check for the version cookie to // avoid having multiple cookies in the final binary if(line[0] == '$' && Strnicmp(&line[1], "VER:", 4) == 0) { CatVersionString = AllocString(line); } else { ShowError(MSG_ERR_BADCTVERSION); } } else if(Strnicmp(line, "codeset", 7) == 0) { char *ptr; if(CodeSet_checked) { ShowError(MSG_ERR_DOUBLECTCODESET); } line += 7; OverSpace(&line); if(!*line) /* Missing argument for "## codeset" */ { ShowError(MSG_ERR_BADCTCODESET); } for(ptr = line; *ptr; ptr++) if(!isdigit((int)*ptr)) /* Non-digit char detected */ { ShowError(MSG_ERR_BADCTCODESET); } errno = 0; CodeSet = strtoul(line, &line, 0); /* printf("ulong_max es %lu\n",ULONG_MAX); printf("CodeSet obtenido de strtoul es %lu\n",CodeSet);*/ if(errno == ERANGE && CodeSet == ULONG_MAX) { ShowError(MSG_ERR_BADCTCODESET); } CodeSet_checked = 1; // errno = 0; } else if(Strnicmp(line, "language", 8) == 0) { char *ptr; if(CatLanguage) { ShowError(MSG_ERR_DOUBLECTLANGUAGE); } line += 8; OverSpace(&line); CatLanguage = AddCatalogChunk(strdup("LANG"), line); if(LANGToLower) for(ptr = CatLanguage; *ptr; ptr++) *ptr = tolower((int)*ptr); } else if(Strnicmp(line, "chunk", 5) == 0) { char *ID; line += 5; OverSpace(&line); ID = line; line += sizeof(ULONG); OverSpace(&line); AddCatalogChunk(ID, AllocString(line)); } else if(Strnicmp(line, "rcsid", 5) == 0) { if(CatVersionString || CatRcsId) { ShowError(MSG_ERR_DOUBLECTVERSION); } line += 5; OverSpace(&line); CatRcsId = AllocString(line); } else if(Strnicmp(line, "name", 5) == 0) { if(CatVersionString || CatName) { ShowError(MSG_ERR_DOUBLECTVERSION); } line += 4; OverSpace(&line); CatName = AllocString(line); } else { ShowWarn(MSG_ERR_UNKNOWNCTCOMMAND); } /* Stop looking for commands */ break; default: if(*line == ' ' || *line == '\t') { ShowError(MSG_ERR_UNEXPECTEDBLANKS); OverSpace(&line); } idstr = line; while(IS_NUMBER_OR_LETTER(*line) || *line == '_') { ++line; } if(idstr == line) { ShowError(MSG_ERR_NOIDENTIFIER); break; } if((newidstr = malloc(line - idstr + 1)) == NULL) { MemError(); } strncpy(newidstr, idstr, line - idstr); newidstr[line - idstr] = '\0'; OverSpace(&line); if(*line) { ShowError(MSG_ERR_EXTRA_CHARACTERS_ID, newidstr); } if((newstr = ReadLine(fp, FALSE)) != NULL) { for(cs = FirstCatString; cs != NULL; cs = cs->Next) { if(strcmp(cs->ID_Str, newidstr) == 0) { break; } } if(cs == NULL) { ShowWarn(MSG_ERR_UNKNOWNIDENTIFIER, newidstr); } else { size_t reallen; size_t cd_len; if(cs->CT_Str) { ShowError(MSG_ERR_DOUBLE_IDENTIFIER, cs->ID_Str); Result = FALSE; free(cs->CT_Str); } cs->CT_Str = AllocString(newstr); cs->NotInCT = FALSE; /* Get string length */ reallen = strlen(cs->CT_Str); cd_len = strlen(cs->CD_Str); if(cs->MinLen > 0 && reallen < (size_t)cs->MinLen) { ShowWarn(MSG_ERR_STRING_TOO_SHORT, cs->ID_Str); } if(cs->MaxLen > 0 && reallen > (size_t)cs->MaxLen) { ShowWarn(MSG_ERR_STRING_TOO_LONG, cs->ID_Str); } // check for empty translations if(cd_len > 0 && reallen == 0) { ShowWarn(MSG_ERR_EMPTYTRANSLATION, cs->ID_Str); } /* Check for trailing ellipsis. */ if(reallen >= 3 && cd_len >= 3) { if(strcmp(&cs->CD_Str[cd_len - 3], "...") == 0 && strcmp(&cs->CT_Str[reallen - 3], "...") != 0) { ShowWarn(MSG_ERR_TRAILING_ELLIPSIS, cs->ID_Str); } if(strcmp(&cs->CD_Str[cd_len - 3], "...") != 0 && strcmp(&cs->CT_Str[reallen - 3], "...") == 0) { ShowWarn(MSG_ERR_NO_TRAILING_ELLIPSIS, cs->ID_Str); } } /* Check for trailing spaces. */ if(reallen >= 1 && cd_len >= 1) { if(strcmp(&cs->CD_Str[cd_len - 1], " ") == 0 && strcmp(&cs->CT_Str[reallen - 1], " ") != 0) { ShowWarn(MSG_ERR_TRAILING_BLANKS, cs->ID_Str); } if(strcmp(&cs->CD_Str[cd_len - 1], " ") != 0 && strcmp(&cs->CT_Str[reallen - 1], " ") == 0) { ShowWarn(MSG_ERR_NO_TRAILING_BLANKS, cs->ID_Str); } } /* Check for matching placeholders */ if(reallen >= 1 && cd_len >= 1) { char *cdP = cs->CD_Str; char *ctP = cs->CT_Str; do { cdP = strchr(cdP, '%'); ctP = strchr(ctP, '%'); if(cdP == NULL && ctP == NULL) { // no more placeholders, bail out break; } else if(cdP != NULL && ctP != NULL) { // skip the '%' sign cdP++; ctP++; // check the placeholder only if the '%' is followed by an // alpha-numerical character or another percent sign if(IS_NUMBER_OR_LETTER(*cdP) || *cdP == '%') { if(*cdP != *ctP) { ShowWarn(MSG_ERR_MISMATCHING_PLACEHOLDERS, cs->ID_Str); break; } // skip the second '%' sign if(*cdP == '%') cdP++; if(*ctP == '%') ctP++; } else if(IS_NUMBER_OR_LETTER(*ctP) || *ctP == '%') { // the translation uses a placeholder while the description // uses none. ShowWarn(MSG_ERR_EXCESSIVE_PLACEHOLDERS, cs->ID_Str); break; } } else if(cdP != NULL && ctP == NULL) { // skip the '%' sign cdP++; // check if really a placeholder follows or just another percent sign // the original string is allowed to contain more single percent signs than the translated string if(IS_NUMBER_OR_LETTER(*cdP) || *cdP == '%') { // the description uses at least one more placeholder than the translation ShowWarn(MSG_ERR_MISSING_PLACEHOLDERS, cs->ID_Str); } break; } else if(cdP == NULL && ctP != NULL) { // skip the '%' sign ctP++; // check if really a placeholder follows or just another percent sign // the translated string is allowed to contain more single percent signs than the original string if(IS_NUMBER_OR_LETTER(*ctP) || *ctP == '%') { // the translation uses at least one more placeholder than the description ShowWarn(MSG_ERR_EXCESSIVE_PLACEHOLDERS, cs->ID_Str); } break; } } while(TRUE); } } free(newstr); } else { ShowWarn(MSG_ERR_MISSINGSTRING); if(cs) cs->CT_Str = (char *)""; } free(newidstr); } free(newline); // forget the pointers as we just freed them and 'line' must not be freed again after the loop newline = NULL; line = NULL; } if(!CodeSet_checked) { ShowErrorQuick(MSG_ERR_NOCTCODESET); } if(!(CatVersionString || (CatRcsId && CatName))) { ShowErrorQuick(MSG_ERR_NOCTVERSION); } // check if a translation exists for all identifiers for(cs = FirstCatString; cs != NULL; cs = cs->Next) { if(cs->CT_Str == NULL) { ShowWarnQuick(MSG_ERR_MISSINGTRANSLATION, cs->ID_Str); } } if(line != NULL) free(line); fclose(fp); if(WarnCTGaps) { for(cs = FirstCatString; cs != NULL; cs = cs->Next) { if(cs->CT_Str == NULL) { ShowWarn(MSG_ERR_CTGAP, cs->ID_Str); } } } if(Result) CT_Scanned = TRUE; return(Result); }
void cWindowXmlEditor::ModifyCase(cCaseX11Xml * aCase,int aKC) { aCase->Efface(P8COL::green); cWXXInfoCase & anIC = mVInfoCase[aKC]; std::string & aStr0 = anIC.mTree->GetUniqueVal(); std::string aStrInit = aStr0; aStr0 = mW.GetString(Pt2dr(aCase->P0Line()),mW.pdisc()(P8COL::black),mW.pdisc()(P8COL::red),aStr0); bool Ok = true; cElXMLTree * aFilter = anIC.mFilter; { if ((aFilter!=0) && aFilter->HasAttr("Type")) { bool CurrErrorOnXmlInit = GenereErrorOnXmlInit; GenereErrorOnXmlInit = false; const std::string & aType = aFilter->ValAttr("Type"); // std::cout << "TYPEEEE " << aType << "\n"; if (aType=="int") { int anInt; xml_init(anInt,anIC.mTree); } else if (aType=="double") { double aDouble; xml_init(aDouble,anIC.mTree); } else if (aType=="Pt2dr") { Pt2dr aPt; xml_init(aPt,anIC.mTree); } else if (aType=="Pt2di") { Pt2di aPt; xml_init(aPt,anIC.mTree); } else { std::cout << "For type = " << aType << "\n"; ELISE_ASSERT(false,"Bad Type Specif in filter Xml/X11"); } GenereErrorOnXmlInit = CurrErrorOnXmlInit; if (GotErrorOnXmlInit) { ShowWarn(std::string("String=[") +aStr0 + "] not valid for " + aType , "Clik in to continue"); // std::cout << "String=[" << aStr0 << "] not valid for " << aType << "\n"; Ok = false; aStr0 = aStrInit; } } } aCase->Efface(); aCase->string(-10,aStr0); if (Ok) anIC.mTimeModif = mTimeModif++; }