/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2010, Tomasz Sowa * All rights reserved. * */ #include "mountparser.h" #include "data.h" #include "log.h" #include "misc.h" bool MountParser::IsWhite(int c) { if( c==' ' || c=='\t' || c==13 || c==160 ) return true; return false; } void MountParser::SkipWhite() { while( IsWhite(*pinput) ) ++pinput; } void MountParser::SkipLine() { while( *pinput && *pinput != 10 ) ++pinput; if( *pinput == 10 ) ++pinput; } void MountParser::ReadWordQuote(std::string & res) { ++pinput; while( *pinput && *pinput!=10 && *pinput!='\"' ) { if( pinput[0]=='\\' && pinput[1]=='\"' ) { res += '\"'; pinput += 2; } else if( pinput[0]=='\\' && pinput[1]=='\\' ) { res += '\\'; pinput += 2; } else { res += *pinput; pinput += 1; } } if( *pinput == '"' ) ++pinput; } // a white character is the separator void MountParser::ReadWordWhite(std::string & res) { while( *pinput && *pinput!=10 && !IsWhite(*pinput) ) { res += *pinput; ++pinput; } } // the comma or the second bracket ')' are the separators void MountParser::ReadWordComma(std::string & res) { while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' ) { res += *pinput; ++pinput; } // trimming last white characters // (white characters can be in the middle of the string) TrimWhite(res); } void MountParser::ReadWord(std::string & res, bool comma_bracket_separator) { res.clear(); SkipWhite(); if( *pinput == '"' ) { ReadWordQuote(res); } else if( comma_bracket_separator ) { ReadWordComma(res); } else { ReadWordWhite(res); } } void MountParser::ReadParamArgsLoop(Mount::ParamArg & args) { SkipWhite(); while( *pinput && *pinput!=10 && *pinput!=')' ) { ReadWord(temp_arg, true); if( !temp_arg.empty() ) args.push_back(temp_arg); if( *pinput == ',' ) ++pinput; } } void MountParser::ReadParamArgs(Mount::ParamArg & args) { SkipWhite(); args.clear(); if( *pinput == '(' ) { ++pinput; ReadParamArgsLoop(args); if( *pinput != ')' ) { // there should be ')' at the end // temporarily we do nothing } else { ++pinput; } } } void MountParser::ReadParamName(std::string & res) { SkipWhite(); res.clear(); while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) ) { res += *pinput; ++pinput; } } void MountParser::ReadParam(std::string & res, Mount::ParamArg & args) { ReadParamName(res); if( res.empty() ) return; ReadParamArgs(args); SkipWhite(); if( *pinput == ',' ) ++pinput; } void MountParser::ReadMountType() { ReadWord(temp); if( temp.empty() ) { // an empty line (some white characters only) err = WINIX_ERR_EMPTY; } else if( temp == "cms" ) { mount.type = Mount::cms; log << log3 << "MP: mount type: cms" << logend; } else if( temp == "thread" ) { mount.type = Mount::thread; log << log3 << "MP: mount type: thread" << logend; } else if( temp == "ticket" ) { mount.type = Mount::ticket; log << log3 << "MP: mount type: ticket" << logend; } else { err = WINIX_ERR_MOUNT_UNKNOWN; log << log1 << "MP: unknown mount type: " << temp << logend; } } void MountParser::ReadMountPoint() { ReadWord(temp); pdir = data.dirs.GetDir(temp); if( pdir ) { mount.dir_id = pdir->id; log << log3 << "MP: mount point: " << temp << logend; } else { err = WINIX_ERR_NO_MOUNTPOINT; log << log1 << "MP: there is no such a mount point: " << temp << logend; } } void MountParser::ReadFs() { ReadWord(temp); if( temp == "simplefs" ) { mount.fs = Mount::simplefs; log << log1 << "MP: file system: simplefs" << logend; } else if( temp == "hashfs" ) { mount.fs = Mount::hashfs; log << log1 << "MP: file system: hashfs" << logend; } else { err = WINIX_ERR_UNKNOWN_FILESYSTEM; log << log1 << "MP: unknown filesystem: " << temp << logend; } } void MountParser::LogMountParams() { size_t i; log << log3 << "MP: mount param: " << temp << "("; for(i=0 ; i & output) { ReadMountType(); if( err == WINIX_ERR_EMPTY ) { err = WINIX_ERR_OK; SkipLine(); return; } if( err == WINIX_ERR_OK ) ReadMountPoint(); if( err == WINIX_ERR_OK ) ReadFs(); if( err == WINIX_ERR_OK ) ReadMountParams(); if( err == WINIX_ERR_OK ) { std::pair::iterator, bool> res = output.insert( std::make_pair(mount.dir_id, mount) ); if( !res.second ) log << log1 << "MP: this mount point exists (skipped)" << logend; } SkipLine(); } Error MountParser::Parse(const std::string & input, std::map & output) { pinput = input.c_str(); err = WINIX_ERR_OK; output.clear(); while( *pinput && err == WINIX_ERR_OK ) ReadRow(output); return err; }