📄 parse.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "parse.h"
// do this because passing five params to a stl for_each callback is a PITA!
static MemoryList *pmemory_list;
static MemoryList *preserve_list;
static ModuleList *pmodule_list;
static FileList *pfile_list;
static Config *pconfig;
/*****************************************************************************
IsDuplicate()
in:
class container - any container class that supports begin(), and end()
members
class object - object type stored in the container
out:
boolean indicating duplicate object
desc:
determins if the object already exists in the list. Used before insertion
to prevent duping data objects.
******************************************************************************/
template<class container, class object>
bool IsDuplicate(const container &cont, const object &item){
if(find(cont.begin(), cont.end(), item) == cont.end())
return false;
cerr << "Warning: Found duplicate entry '" << item << "' ... skipping\n";
return true;
}
/*****************************************************************************
ProcessBIBLine()
in:
StringList token_list - tokenized line
out:
none
desc:
checks the line for section heading, and then parses all line into the
apropriate sections.
******************************************************************************/
void ProcessError(const StringList &slist){
for(unsigned i = 0; i < slist.size(); i++)
cerr << slist[i] << " ";
cerr << endl;
cerr << "\nError: failed setting line\n";
exit(1);
}
void ProcessBIBLine(const StringList &token_list){
static string section = "";
if(token_list.empty())
return;
if(IsSection(token_list[0]))
section = token_list[0];
else if(section.empty())
cerr << "Warning: found '" << token_list[0] << "' before a section header\n";
else if(section == CONFIG){
if(!pconfig->set(token_list, *pmemory_list))
ProcessError(token_list);
}
else if(section == FILES){
File file;
Module module;
if(!file.set(token_list, *pmemory_list, pconfig->compressor_list))
ProcessError(token_list);
if(file.is_file()){
if(!IsDuplicate(*pmodule_list, file) && !IsDuplicate(*pfile_list, file))
pfile_list->push_back(file);
}
else{
if(!module.set(token_list, *pmemory_list, pconfig->compressor_list))
ProcessError(token_list);
if(!IsDuplicate(*pmodule_list, module) && !IsDuplicate(*pfile_list, module))
pmodule_list->push_back(module);
}
}
else if(section == MODULES){
File file;
Module module;
if(!module.set(token_list, *pmemory_list, pconfig->compressor_list))
ProcessError(token_list);
if(module.is_module()){
if(!IsDuplicate(*pmodule_list, module) && !IsDuplicate(*pfile_list, module))
pmodule_list->push_back(module);
}
else{
if(!file.set(token_list, *pmemory_list, pconfig->compressor_list))
ProcessError(token_list);
if(!IsDuplicate(*pmodule_list, file) && !IsDuplicate(*pfile_list, file))
pfile_list->push_back(file);
}
}
else if(section == MEMORY){
Memory memory;
if(!memory.set(token_list))
ProcessError(token_list);
if(memory.type() == RESERVED_TYPE)
preserve_list->push_back(memory);
else if(!IsDuplicate(*pmemory_list, memory))
pmemory_list->push_back(memory);
}
else
cerr << "Internal Error: " << section << " not processed yet!\n";
}
/*****************************************************************************
ParseBIBFile()
in:
string file_name - name of .bib file to parse
...
out:
boolean indicating success
desc:
retrieves and entire file as a vector of lines and passes it off to other
routines for processing
******************************************************************************/
bool ParseBIBFile(const string &file_name,
MemoryList &memory_list,
MemoryList &reserve_list,
ModuleList &module_list,
FileList &file_list,
Config &config){
// do this because passing five params to a stl for_each callback is a PITA!
pmemory_list = &memory_list;
preserve_list = &reserve_list;
pmodule_list = &module_list;
pfile_list = &file_list;
pconfig = &config;
StringList input_listing;
vector<StringList> token_listing;
string line;
if(GetFileAttributes(file_name.c_str()) == -1){
cerr << "Error: Could not find file '" << file_name << "'\n";
return false;
}
ifstream file(file_name.c_str(), ios::in);
if(file.bad()){
cerr << "Error: Could not open '" << file_name << "' for reading\n";
return false;
}
while(GetNextLine(file, line)){
input_listing.push_back(line);
}
if(Token::CheckQuotes("", true)){
cerr << "Error: Missmatched quotes in '" << file_name << "'\n";
return false;
}
file.close();
transform(input_listing.begin(), input_listing.end(), input_listing.begin(), FudgeIfs);
transform(input_listing.begin(), input_listing.end(), input_listing.begin(), ExpandEnvironmentVariables);
transform(input_listing.begin(), input_listing.end(), back_inserter(token_listing), Token::tokenize);
// Note: remove_if() is querky, look it up and make SURE you know how it works before touching this!
token_listing.erase(remove_if(token_listing.begin(), token_listing.end(), SkipLine), token_listing.end());
// if we are still ignoring anything then there was a missmatch
if(SkipLine(StringList())){
cerr << "Error: Unmatched IF/ELSE/ENDIF block... somewhere :(\n"; return false;
}
for_each(token_listing.begin(), token_listing.end(), ProcessBIBLine);
return config.sanity_check(memory_list);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -