// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab /* * Ceph - scalable distributed file system * * Copyright (C) 2004-2006 Sage Weil * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software * Foundation. See file COPYING. * */ #include #include "auth/Auth.h" #include "common/ceph_argparse.h" #include "common/config.h" #include "common/version.h" #include "include/str_list.h" /* * Ceph argument parsing library * * We probably should eventually replace this with something standard like popt. * Until we do that, though, this file is the place for argv parsing * stuff to live. */ #undef dout #undef pdout #undef derr #undef generic_dout #undef dendl struct strict_str_convert { const char *str; std::string *err; strict_str_convert(const char *str, std::string *err) : str(str), err(err) {} inline operator float() const { return strict_strtof(str, err); } inline operator int() const { return strict_strtol(str, 10, err); } inline operator long long() const { return strict_strtoll(str, 10, err); } }; void string_to_vec(std::vector& args, std::string argstr) { std::istringstream iss(argstr); while(iss) { std::string sub; iss >> sub; if (sub == "") break; args.push_back(sub); } } std::pair, std::vector> split_dashdash(const std::vector& args) { auto dashdash = std::find_if(args.begin(), args.end(), [](const char* arg) { return strcmp(arg, "--") == 0; }); std::vector options{args.begin(), dashdash}; if (dashdash != args.end()) { ++dashdash; } std::vector arguments{dashdash, args.end()}; return {std::move(options), std::move(arguments)}; } static std::mutex g_str_vec_lock; static std::vector g_str_vec; void clear_g_str_vec() { g_str_vec_lock.lock(); g_str_vec.clear(); g_str_vec_lock.unlock(); } void env_to_vec(std::vector& args, const char *name) { if (!name) name = "CEPH_ARGS"; /* * We can only populate str_vec once. Other threads could hold pointers into * it, so clearing it out and replacing it is not currently safe. */ g_str_vec_lock.lock(); if (g_str_vec.empty()) { char *p = getenv(name); if (!p) { g_str_vec_lock.unlock(); return; } get_str_vec(p, " ", g_str_vec); } std::vector env; for (const auto& s : g_str_vec) { env.push_back(s.c_str()); } g_str_vec_lock.unlock(); auto [env_options, env_arguments] = split_dashdash(env); auto [options, arguments] = split_dashdash(args); args.clear(); args.insert(args.end(), env_options.begin(), env_options.end()); args.insert(args.end(), options.begin(), options.end()); if (arguments.empty() && env_arguments.empty()) { return; } args.push_back("--"); args.insert(args.end(), env_arguments.begin(), env_arguments.end()); args.insert(args.end(), arguments.begin(), arguments.end()); } void argv_to_vec(int argc, const char **argv, std::vector& args) { args.insert(args.end(), argv + 1, argv + argc); } void vec_to_argv(const char *argv0, std::vector& args, int *argc, const char ***argv) { *argv = (const char**)malloc(sizeof(char*) * (args.size() + 1)); if (!*argv) throw std::bad_alloc(); *argc = 1; (*argv)[0] = argv0; for (unsigned i=0; i= '0' && nextargstr[i] <= '9')) { // May be negative numeral value if ((i == 0) && (strlen(nextargstr) >= 2)) { if (nextargstr[0] == '-') continue; } if ( (nextargstr[i] == '.') && (is_float == false) ) { is_float = true; continue; } is_numeric = false; break; } } // -