/* * Makes an operator form the specified string. * * @param operator_string: Operator in the string form. * @param operand: Operand to add into the operator. */ libtocc::ConnectiveExpr* make_operator(std::string operator_string, libtocc::Expr* operand) { if (operator_string == "and") { if (operand->get_type() == libtocc::expr_type::CONNECTIVE) { return new libtocc::And((libtocc::ConnectiveExpr&)*operand); } else { return new libtocc::And((libtocc::FieldExpr&)*operand); } } if (operator_string == "or") { if (operand->get_type() == libtocc::expr_type::CONNECTIVE) { return new libtocc::Or((libtocc::ConnectiveExpr&)*operand); } else { return new libtocc::Or((libtocc::FieldExpr&)*operand); } } // None of the above. throw InvalidParametersError("Unknown operator: Expected one of 'and', 'or', etc, found: " + operator_string); }
/* * Creates a title expression. * * @param opt: Operation to use. * @param value: Value to compare title to. */ libtocc::Expr* create_title(std::string opt, std::string value) { if (opt == "=") { return new libtocc::Title(value.c_str()); } // Nothing matched. throw InvalidParametersError("Invalid operator: " + opt); }
void RemoveAction::execute(std::vector<libtocc::FileInfo> files, std::vector<std::string> cmd_arguments) { if(!cmd_arguments.empty()) { throw InvalidParametersError("-r, --remove, doesn't accept arguments."); } //Extracting files ids into an array const char* file_ids[files.size()]; for(int i = 0; i < files.size(); i++) { file_ids[i] = files[i].get_id(); } //Removing the files if(libtocc_manager != 0) { this->libtocc_manager->remove_files(file_ids, files.size()); } }
/* * Throws a parsing exception, and formats its message in a pretty form. * * @param arguments: Arguments that had error. * @param index: Index should point to the element of `arguments' that * was parsing before the error occur. * @param message: Error message. */ void throw_parsing_exception(std::vector<std::string>& arguments, int index, std::string message) { std::stringstream args_stream; std::stringstream error_marker_stream; int error_marker_index = 0; std::vector<std::string>::iterator iterator = arguments.begin(); for (; iterator != arguments.end(); ++iterator) { args_stream << " " << *iterator; if (error_marker_index < index) { std::string spaces(iterator->size(), ' '); error_marker_stream << " " << spaces; error_marker_index++; } } error_marker_stream << "^"; throw InvalidParametersError(message + "\n" + args_stream.str() + "\n" + error_marker_stream.str()); }
void AssignAction::execute(std::vector<libtocc::FileInfo> files, std::vector<std::string> cmd_arguments) { if (cmd_arguments.empty()) { throw InvalidParametersError("-a, --assign, must have at least one argument."); } // Converting files vector to array. const char* files_array[files.size()]; for (int i = 0; i < files.size(); i++) { files_array[i] = files[i].get_id(); } // Converting tags vector to a tags collection. libtocc::TagsCollection tags_collection(cmd_arguments.size()); std::vector<std::string>::iterator args_iterator = cmd_arguments.begin(); for (; args_iterator != cmd_arguments.end(); args_iterator++) { tags_collection.add_tag(args_iterator->c_str()); } this->libtocc_manager->assign_tags(files_array, files.size(), &tags_collection); }
void CmdManager::execute(std::vector<CmdParam> cmd_parameters) { // The algorithm: // We look through the parameters to see what Selectors or Actions are // passed. First, we loop through the parameters and execute each selector. // But actions are kept for later. Because first we should have all the // files user selected, then do the actions on them. // Keeps files that are selected by Selectors. std::vector<libtocc::FileInfo> selected_files; // Keeps actions that should be executed later. // First element of pair is the action, and second one is the argument // passed in the command line. std::vector<std::pair<Action*, std::vector<std::string> > > actions_to_execute; // Looping through parameters to see if --version or --help is passed. // If so, we just print out help or version and exit. std::vector<CmdParam>::iterator params_iterator = cmd_parameters.begin(); for (; params_iterator < cmd_parameters.end(); ++params_iterator) { if ((*params_iterator).option == "-h" || (*params_iterator).option == "--help") { if (!(*params_iterator).arguments.empty()) { throw InvalidParametersError("-h or --help don't accept an argument."); } // Print usage and end. print_usage(); return; } if ((*params_iterator).option == "-v" || (*params_iterator).option == "--version") { if (!(*params_iterator).arguments.empty()) { throw InvalidParametersError("-v or --version don't accept an argument."); } // Print version and end. print_version(); return; } } // Looping through parameters again, and executing Selectors and Actions. params_iterator = cmd_parameters.begin(); for (; params_iterator < cmd_parameters.end(); ++params_iterator) { if ((*params_iterator).option == "-b" || (*params_iterator).option == "--base-path") { // This option already handled in `main'. Ignoring. continue; } // Will set to true if any Selector or Action found for this option. bool option_handler_found = false; // Looking for Selectors among parameters. std::vector<Selector*>::iterator selectors_iterator = this->selectors.begin(); for (; selectors_iterator < this->selectors.end(); ++selectors_iterator) { if ((*params_iterator).option == (*selectors_iterator)->get_short_form() || (*params_iterator).option == (*selectors_iterator)->get_long_form()) { // Executing the selector. std::vector<libtocc::FileInfo> files = (*selectors_iterator)->execute((*params_iterator).arguments); // Appending elements of `files' to `selected_files'. selected_files.insert(selected_files.end(), files.begin(), files.end()); option_handler_found = true; break; } } if (option_handler_found) { // No need to check actions. continue; } // Looking for actions among parameters. std::vector<Action*>::iterator actions_iterator = this->actions.begin(); for (; actions_iterator < this->actions.end(); ++actions_iterator) { if ((*params_iterator).option == (*actions_iterator)->get_short_form() || (*params_iterator).option == (*actions_iterator)->get_long_form()) { actions_to_execute.push_back( std::make_pair(*actions_iterator, (*params_iterator).arguments)); option_handler_found = true; break; } } if (!option_handler_found) { // It means that this parameter didn't match any of the known ones. std::string error_message("Unknown option: "); error_message += (*params_iterator).option; throw InvalidParametersError(error_message.c_str()); } } // Now that all selectors executed and we have all the selected files, // we're going to run actions on them. std::vector<std::pair<Action*, std::vector<std::string> > >::iterator actions_iterator = actions_to_execute.begin(); for (; actions_iterator < actions_to_execute.end(); ++actions_iterator) { (*actions_iterator).first->execute(selected_files, (*actions_iterator).second); } }
/* * Parses the arguments, extracts and parse the next term in it. * * @param arguments: Arguments to be parsed. * @param index: Should points to where the next term begin. This method moves * the index to the element after the term. * * @return: Equivalent expression of the term. */ libtocc::ConnectiveExpr* extract_next_term(std::vector<std::string>& arguments, int& index) { std::pair<std::string, libtocc::ConnectiveExpr*> last_operator; libtocc::ConnectiveExpr* result; // The first argument must be an operand. libtocc::Expr* first_operand = extract_next_operand(arguments, index); // Auto releasing pointer. ExprPointerHolder expr_pointer_holder(first_operand); if (index >= arguments.size()) { // This term only had one operand. We add it to the default operator. return make_operator("and", first_operand); } // Next one should be an operator. // Everything comes next will be added to this operator. So this is the // result (root operator) of this method. result = make_operator(arguments[index], first_operand); last_operator = std::make_pair(arguments[index], result); index++; // Then, one operand and one operator, until the end. while (true) { if (index >= arguments.size()) { throw InvalidParametersError("Expected an operand, but reached end of file."); } libtocc::Expr* operand = extract_next_operand(arguments, index); // Auto release this pointer. expr_pointer_holder.add(operand); if (index >= arguments.size()) { // End of the string. Adding the operand to the previous operator. if (operand->get_type() == libtocc::expr_type::CONNECTIVE) { last_operator.second->add((libtocc::ConnectiveExpr&)*operand); } else { last_operator.second->add((libtocc::FieldExpr&)*operand); } // Ending the loop. break; } if (arguments[index] == last_operator.first) { // It's same as the previous operator. No need to create a new one. if (operand->get_type() == libtocc::expr_type::CONNECTIVE) { last_operator.second->add((libtocc::ConnectiveExpr&)*operand); } else { last_operator.second->add((libtocc::FieldExpr&)*operand); } index++; } else { // Making a new operator and add it to the previous one. libtocc::ConnectiveExpr* new_operator = make_operator(arguments[index], operand); // Auto release pointer. expr_pointer_holder.add(new_operator); last_operator.second->add((libtocc::ConnectiveExpr&)*new_operator); last_operator = std::make_pair(arguments[index], new_operator); } } return result; }