/* IEView Plugin for Miranda IM Copyright (C) 2005-2010 Piotr Piastucki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Template.h" #include "Utils.h" TokenDef::TokenDef(const char *tokenString) { this->tokenString = tokenString; this->tokenLen = (int)strlen(tokenString); this->token = 0; this->escape = 0; } TokenDef::TokenDef(const char *tokenString, int token, int escape) { this->tokenString = tokenString; this->token = token; this->tokenLen = (int)strlen(tokenString); this->escape = escape; } Token::Token(int type, const char *text, int escape) { next = NULL; this->type = type; this->escape = escape; if (text!=NULL) { this->text = Utils::dupString(text); } else { this->text = NULL; } } Token::~Token() { if (text!=NULL) { delete text; } } Token * Token::getNext() { return next; } void Token::setNext(Token *ptr) { next = ptr; } int Token::getType() { return type; } int Token::getEscape() { return escape; } const char *Token::getText() { return text; } Template::Template(const char *name, const char *text) { next = NULL; tokens = NULL; this->text = Utils::dupString(text); this->name = Utils::dupString(name); tokenize(); } Template::~Template() { if (text != NULL) delete text; if (name != NULL) delete name; Token *ptr = tokens, *ptr2; tokens = NULL; for (;ptr!=NULL;ptr = ptr2) { ptr2 = ptr->getNext(); delete ptr; } } const char *Template::getText() { return text; } const char *Template::getName() { return name; } Template* Template::getNext() { return next; } bool Template::equals(const char *name) { if (!strcmp(name, this->name)) { return true; } return false; } static TokenDef tokenNames[] = { TokenDef("%name%", Token::NAME, 0), TokenDef("%time%", Token::TIME, 0), TokenDef("%text%", Token::TEXT, 0), TokenDef("%date%", Token::DATE, 0), TokenDef("%base%", Token::BASE, 0), TokenDef("%avatar%", Token::AVATAR, 0), TokenDef("%cid%", Token::CID, 0), TokenDef("%proto%", Token::PROTO, 0), TokenDef("%avatarIn%", Token::AVATARIN, 0), TokenDef("%avatarOut%", Token::AVATAROUT, 0), TokenDef("%nameIn%", Token::NAMEIN, 0), TokenDef("%nameOut%", Token::NAMEOUT, 0), TokenDef("%uin%", Token::UIN, 0), TokenDef("%uinIn%", Token::UININ, 0), TokenDef("%uinOut%", Token::UINOUT, 0), TokenDef("%nickIn%", Token::NICKIN, 0), TokenDef("%nickOut%", Token::NICKOUT, 1), TokenDef("%statusMsg%", Token::STATUSMSG, 0), TokenDef("%fileDesc%", Token::FILEDESC, 0), TokenDef("%\\name%", Token::NAME, 1), TokenDef("%\\time%", Token::TIME, 1), TokenDef("%\\text%", Token::TEXT, 1), TokenDef("%\\date%", Token::DATE, 1), TokenDef("%\\base%", Token::BASE, 1), TokenDef("%\\avatar%", Token::AVATAR, 1), TokenDef("%\\cid%", Token::CID, 1), TokenDef("%\\proto%", Token::PROTO, 1), TokenDef("%\\avatarIn%", Token::AVATARIN, 1), TokenDef("%\\avatarOut%", Token::AVATAROUT, 1), TokenDef("%\\nameIn%", Token::NAMEIN, 1), TokenDef("%\\nameOut%", Token::NAMEOUT, 1), TokenDef("%\\uin%", Token::UIN, 1), TokenDef("%\\uinIn%", Token::UININ, 1), TokenDef("%\\uinOut%", Token::UINOUT, 1), TokenDef("%\\nickIn%", Token::NICKIN, 1), TokenDef("%\\nickOut%", Token::NICKOUT, 1), TokenDef("%\\statusMsg%", Token::STATUSMSG, 1), TokenDef("%\\fileDesc%", Token::FILEDESC, 1) }; void Template::tokenize() { if (text!=NULL) { // debugView->writef("Tokenizing: %s
---
", text); char *str = Utils::dupString(text); Token *lastToken = NULL; int lastTokenType = Token::PLAIN; int lastTokenEscape = 0; int l = (int)strlen(str); for (int i=0, lastTokenStart=0; i<=l;) { Token *newToken; int newTokenType = 0, newTokenSize = 0, newTokenEscape = 0; if (str[i]=='\0') { newTokenType = Token::END; newTokenSize = 1; newTokenEscape = 0; } else { bool found = false; for (unsigned int j=0; j<(sizeof(tokenNames)/sizeof(tokenNames[0])); j++) { if (!strncmp(str+i, tokenNames[j].tokenString, tokenNames[j].tokenLen)) { newTokenType = tokenNames[j].token; newTokenSize = tokenNames[j].tokenLen; newTokenEscape = tokenNames[j].escape; found = true; break; } } if (!found) { newTokenType = Token::PLAIN; newTokenSize = 1; newTokenEscape = 0; } } if (newTokenType != Token::PLAIN) { if (str[i + newTokenSize] == '%') { //newTokenSize++; } str[i] = '\0'; } if ((lastTokenType!=newTokenType || lastTokenEscape != newTokenEscape) && i!=lastTokenStart) { if (lastTokenType == Token::PLAIN) { newToken = new Token(lastTokenType, str+lastTokenStart, lastTokenEscape); } else { newToken = new Token(lastTokenType, NULL, lastTokenEscape); } if (lastToken != NULL) { lastToken->setNext(newToken); } else { tokens = newToken; } lastToken = newToken; lastTokenStart = i; } lastTokenEscape = newTokenEscape; lastTokenType = newTokenType; i += newTokenSize; } delete str; } } Token * Template::getTokens() { return tokens; } TemplateMap* TemplateMap::mapList = NULL; TemplateMap::TemplateMap(const char *name) { entries = NULL; next = NULL; filename = NULL; this->name = Utils::dupString(name); this->grouping = false; this->rtl = false; } TemplateMap::~TemplateMap() { if (name != NULL) { delete name; } if (filename != NULL) { delete filename; } clear(); } TemplateMap* TemplateMap::add(const char *id, const char *filename) { TemplateMap *map; for (map=mapList; map!=NULL; map=map->next) { if (!strcmp(map->name, id)) { map->clear(); map->setFilename(filename); return map; } } map = new TemplateMap(id); map->setFilename(filename); map->next = mapList; mapList = map; return map; } void TemplateMap::addTemplate(const char *name, const char *text) { Template *tmplate = new Template(name, text); tmplate->next = entries; entries = tmplate; } void TemplateMap::clear() { Template *ptr, *ptr2; ptr = entries; entries = NULL; for (;ptr!=NULL;ptr=ptr2) { ptr2 = ptr->getNext(); delete ptr; } } static TokenDef templateNames[] = { TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef("") }; TemplateMap* TemplateMap::loadTemplateFile(const char *id, const char *filename, bool onlyInfo) { FILE* fh; char lastTemplate[1024], tmp2[1024]; unsigned int i=0; TemplateMap *tmap; if (filename == NULL || strlen(filename) == 0) { return NULL; } fh = fopen(filename, "rt"); if (fh == NULL) { return NULL; } if (!onlyInfo) { tmap = TemplateMap::add(id, filename); } else { tmap = new TemplateMap(id); } char store[4096]; bool wasTemplate = false; char *templateText = NULL; int templateTextSize = 0; while (fgets(store, sizeof(store), fh) != NULL) { if (sscanf(store, "%s", tmp2) == EOF) continue; //template start bool bFound = false; for (unsigned i = 0; i < sizeof(templateNames) / sizeof (templateNames[0]); i++) { if (!strncmp(store, templateNames[i].tokenString, templateNames[i].tokenLen)) { bFound = true; break; } } if (bFound) { if (wasTemplate) { tmap->addTemplate(lastTemplate, templateText); } if (templateText!=NULL) { free (templateText); } templateText = NULL; templateTextSize = 0; wasTemplate = true; sscanf(store, "