戻る 目次へ
§5.1.18 stack.cc
戻る 目次へ

  1: /******************************************************************************
  2:   ezht - Copyright (C) 2004 Tradcrafts
  3:   This file is part of the ezht.
  4:                                                                        
  5:   ezht is free software; you can redistribute it and/or modify
  6:   it under the terms of the GNU General Public License as published by the 
  7:   Free Software Foundation;   either version 2 of the License,  or (at your 
  8:   option) any later version.
  9: 
 10:   ezht is distributed in the hope that it will be useful, but 
 11:   WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 12:   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 13:   more details.
 14: 
 15:   You should have received a copy of the GNU General Public License along with
 16:   this program; see the file COPYING.  If not, write to the Free Software 
 17:   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 18: ******************************************************************************/
 19: 
 20: #include "reader.h"
 21: #include "stack.h"
 22: #include "error.h"
 23: 
 24: #include <string.h>
 25: #include <deque>
 26: #include <map>
 27: #include <string>
 28: 
 29: 
 30: typedef std::map< std::string , std::deque<std::string> > stack_t;
 31: static stack_t stacks;
 32: 
 33: typedef std::map< std::string , void (*)(const char*) > checkstack_t;
 34: static checkstack_t stack_checkers;
 35: 
 36: static void charset_checker(const char *charset)
 37: {
 38:   if( strcasecmp(charset,"EUC-JP")==0 ||
 39:       strcasecmp(charset,"Shift_JIS")==0 ){
 40:     return;
 41:   }
 42:       
 43:   error("stack `charset' doesn't allowed the value `%s'",charset);
 44: }
 45: 
 46: static void filename_rule_checker(const char *rule)
 47: {
 48:   if( strcmp(rule,"line")==0 ||
 49:       strcmp(rule,"serial")==0 ||
 50:       strcmp(rule,"section")==0 
 51:       ){
 52:     return;
 53:   }
 54:       
 55: error("stack `rule' doesn't allowed the value `%s'",rule);
 56: }
 57: 
 58: 
 59: void stack_init()
 60: {
 61:   stacks[STACKNAME_LANG];
 62: 
 63:   stacks[STACKNAME_CHARSET];
 64:   stack_checkers[STACKNAME_CHARSET] = charset_checker;
 65: 
 66:   stacks[STACKNAME_DOCNAME];
 67: 
 68:   stacks[STACKNAME_HT_HEAD];
 69: 
 70:   stacks[STACKNAME_BODY_HEADER];
 71: 
 72:   stacks[STACKNAME_BODY_FOOTER];
 73: 
 74:   stacks[STACKNAME_BODY_ATTRIBUTES];
 75: 
 76:   stacks[STACKNAME_INDEXFILE_INTRODUCTION];
 77: 
 78:   stacks[STACKNAME_SECTION_BAR_COLOR];
 79: 
 80:   stacks[STACKNAME_SECTION_MARK];
 81: 
 82:   stacks[STACKNAME_NUMBER_SEPARATOR];
 83: 
 84:   stacks[STACKNAME_TEXT_INDEX];
 85: 
 86:   stacks[STACKNAME_TEXT_RELATION];
 87: 
 88:   stacks[STACKNAME_TEXT_SECTION_DISJOINED];
 89: 
 90:   stacks[STACKNAME_ANCHOR_INDEX];
 91: 
 92:   stacks[STACKNAME_ANCHOR_UP];
 93: 
 94:   stacks[STACKNAME_ANCHOR_PREV];
 95: 
 96:   stacks[STACKNAME_ANCHOR_NEXT];
 97: 
 98:   stacks[STACKNAME_ANCHOR_BACK];
 99: 
100:   stacks[STACKNAME_INDEXFILE];
101: 
102:   stacks[STACKNAME_FILENAME_PREFIX];
103: 
104:   stacks[STACKNAME_FILENAME_SUFFIX];
105: 
106:   stacks[STACKNAME_FILENAME_RULE];
107:   stack_checkers[STACKNAME_FILENAME_RULE] = filename_rule_checker;
108:   
109:   stacks[STACKNAME_INCLUDE_FILTER];
110: 
111:   stacks[STACKNAME_INCLUDE_HEADER];
112: 
113:   stacks[STACKNAME_INCLUDE_FOOTER];
114: 
115:   stacks[STACKNAME_TAB_SPACES];
116: 
117: }
118: 
119: void stack_push(const char *stackname, const char *body)
120: {
121:   stack_t::iterator p = stacks.find(stackname);
122:   if( p == stacks.end() ){
123:     error("stack `%s' doesn't exists",stackname);
124:     return ; // Not found.
125:   }
126: 
127:   p->second.push_front( body );
128: }
129: 
130: void stack_pop(const char *stackname)
131: {
132:   stack_t::iterator p = stacks.find(stackname);
133:   if( p != stacks.end() ){
134:     if( p->second.size() == 0 ){
135:       error("stack `%s' is already empty",stackname); return;
136:     }
137:     p->second.pop_front();
138:   }else{
139:     error("stack `%s' doesn't exists",stackname); return;
140:   }
141: }
142: 
143: const char *stack_peep(const char *elementname,const char *default_body)
144: {
145:   stack_t::iterator p = stacks.find(elementname);
146:   if( p != stacks.end() ){
147:     if( p->second.size() > 0 )
148:       return p->second[0].c_str();
149:     else
150:       return default_body;
151:   }else{
152:     error("internal error! %s",elementname);
153:     return NULL;
154:   }
155: }
156: 
157: 
158: static void check_stack_value(const char *stackname,const char *value)
159: {
160:   checkstack_t::iterator checker = stack_checkers.find(stackname);
161:   if( checker != stack_checkers.end() )
162:     (*checker->second)(value);
163: }
164: 
165: void cmd_push(std::vector<std::string> &args)
166: {
167:   if( args.size() > 3 ){
168:     error("@push: too many parameters");
169:     return;
170:   }
171:   
172:   if( args.size()==1 ){
173:     error("@push: element not specified");
174:     return;
175:   }
176:   
177:   if( args.size()==3 ){
178:     check_stack_value(args[1].c_str(),args[2].c_str());
179:     stack_push(args[1].c_str() ,args[2].c_str());
180:   }else if( args.size() == 2 ){
181:     
182:     std::string body;
183:     const char *line;
184:     while( NULL != (line=getline(true)) ){
185:       if( 0 == strcmp(line,"@end") )
186:         break;
187:       body += line;
188:     }
189:     if( line == NULL ){
190:       error("@push: unexpected end of file"); return;
191:     }
192:     check_stack_value(args[1].c_str(),body.c_str());
193:     stack_push(args[1].c_str() ,body.c_str()); 
194:   }
195:   
196: }
197: 
198: void cmd_pop(std::vector<std::string> &args)
199: {
200:   if( args.size() == 1 ){
201:     error("@pop: no stack specified"); return; 
202:   }
203:   
204:   int end = args.size();
205:   for(int i=1; i<end; i++)
206:     stack_pop(args[i].c_str());
207: }
208: 
209: void cmd_autopop(std::list<std::string> &autopop_list, std::vector<std::string> &args)
210: {
211:   if( args.size() == 1 ){
212:     warn("@autopop: no stack specified");
213:     return;
214:   }
215:   
216:   int n = (int)args.size();
217:   for(int i=1; i<n; i++){
218:     if( stacks.end() != stacks.find(args[i]) )
219:       autopop_list.push_back(args[i]);
220:     else
221:       error("@autopop: unknown stack `%s'",args[i].c_str()); 
222:   }
223: }




Copyright 2004 Tradcrafts. ALL RIGHTS RESERVED.