1 /* 2 * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana 3 * University Research and Technology 4 * Corporation. All rights reserved. 5 * Copyright (c) 2004-2005 The University of Tennessee and The University 6 * of Tennessee Research Foundation. All rights 7 * reserved. 8 * Copyright (c) 2004-2008 High Performance Computing Center Stuttgart, 9 * University of Stuttgart. All rights reserved. 10 * Copyright (c) 2004-2005 The Regents of the University of California. 11 * All rights reserved. 12 * Copyright (c) 2007 Los Alamos National Security, LLC. 13 * All rights reserved. 14 * Copyright (c) 2007 Voltaire. All rights reserved. 15 * Copyright (c) 2012 Los Alamos National Security, LLC. All rights reserved. 16 * Copyright (c) 2015-2016 Intel, Inc. All rights reserved. 17 * 18 * Copyright (c) 2015-2019 Research Organization for Information Science 19 * and Technology (RIST). All rights reserved. 20 * $COPYRIGHT$ 21 * 22 * Additional copyrights may follow 23 * 24 * $HEADER$ 25 */ 26 27 /** 28 * @file 29 * 30 * Generic routines for "argv"-like handling. Helpful for creating 31 * arrays of strings, especially when creating command lines. 32 */ 33 34 #ifndef PMIX_ARGV_H 35 #define PMIX_ARGV_H 36 37 #include <src/include/pmix_config.h> 38 39 40 #ifdef HAVE_SYS_TYPES_H 41 #include <sys/types.h> 42 #endif 43 44 #include <pmix_common.h> 45 46 BEGIN_C_DECLS 47 48 /** 49 * Append a string (by value) to an new or existing NULL-terminated 50 * argv array. 51 * 52 * @param argc Pointer to the length of the argv array. Must not be 53 * NULL. 54 * @param argv Pointer to an argv array. 55 * @param str Pointer to the string to append. 56 * 57 * @retval PMIX_SUCCESS On success 58 * @retval PMIX_ERROR On failure 59 * 60 * This function adds a string to an argv array of strings by value; 61 * it is permissable to pass a string on the stack as the str 62 * argument to this function. 63 * 64 * To add the first entry to an argv array, call this function with 65 * (*argv == NULL). This function will allocate an array of length 66 * 2; the first entry will point to a copy of the string passed in 67 * arg, the second entry will be set to NULL. 68 * 69 * If (*argv != NULL), it will be realloc'ed to be 1 (char*) larger, 70 * and the next-to-last entry will point to a copy of the string 71 * passed in arg. The last entry will be set to NULL. 72 * 73 * Just to reinforce what was stated above: the string is copied by 74 * value into the argv array; there is no need to keep the original 75 * string (i.e., the arg parameter) after invoking this function. 76 */ 77 PMIX_EXPORT pmix_status_t pmix_argv_append(int *argc, char ***argv, const char *arg) __pmix_attribute_nonnull__(1) __pmix_attribute_nonnull__(3); 78 79 /** 80 * Append to an argv-style array, but ignore the size of the array. 81 * 82 * @param argv Pointer to an argv array. 83 * @param str Pointer to the string to append. 84 * 85 * @retval PMIX_SUCCESS On success 86 * @retval PMIX_ERROR On failure 87 * 88 * This function is identical to the pmix_argv_append() function 89 * except that it does not take a pointer to an argc (integer 90 * representing the size of the array). This is handy for 91 * argv-style arrays that do not have integers that are actively 92 * maintaing their sizes. 93 */ 94 PMIX_EXPORT pmix_status_t pmix_argv_append_nosize(char ***argv, const char *arg); 95 96 /** 97 * Insert the provided arg at the beginning of the array 98 * 99 * @param argv Pointer to an argv array 100 * @param str Pointer to the string to prepend 101 * 102 * @retval PMIX_SUCCESS On success 103 * @retval PMIX_ERROR On failure 104 */ 105 PMIX_EXPORT pmix_status_t pmix_argv_prepend_nosize(char ***argv, const char *arg); 106 107 /** 108 * Append to an argv-style array, but only if the provided argument 109 * doesn't already exist somewhere in the array. Ignore the size of the array. 110 * 111 * @param argv Pointer to an argv array. 112 * @param str Pointer to the string to append. 113 * 114 * @retval PMIX_SUCCESS On success 115 * @retval PMIX_ERROR On failure 116 * 117 * This function is identical to the pmix_argv_append_nosize() function 118 * except that it only appends the provided argument if it does not already 119 * exist in the provided array. 120 */ 121 PMIX_EXPORT pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const char *arg); 122 123 /** 124 * Append to an argv-style array, but only if the provided argument 125 * doesn't already exist somewhere in the array. Ignore the size of the array. 126 * Defines the index of the found/added item in the array. 127 * 128 * @param idx Index the found/added item in the array. 129 * @param argv Pointer to an argv array. 130 * @param str Pointer to the string to append. 131 * 132 * @retval PMIX_SUCCESS On success 133 * @retval PMIX_ERROR On failure 134 * 135 * This function is identical to the pmix_argv_append_unique_nosize() function 136 * but it has an extra argument defining the index of the item in the array. 137 */ 138 PMIX_EXPORT pmix_status_t pmix_argv_append_unique_idx(int *idx, char ***argv, const char *arg); 139 140 /** 141 * Free a NULL-terminated argv array. 142 * 143 * @param argv Argv array to free. 144 * 145 * This function frees an argv array and all of the strings that it 146 * contains. Since the argv parameter is passed by value, it is not 147 * set to NULL in the caller's scope upon return. 148 * 149 * It is safe to invoke this function with a NULL pointer. It is 150 * not safe to invoke this function with a non-NULL-terminated argv 151 * array. 152 */ 153 PMIX_EXPORT void pmix_argv_free(char **argv); 154 155 /** 156 * Split a string into a NULL-terminated argv array. Do not include empty 157 * strings in result array. 158 * 159 * @param src_string Input string. 160 * @param delimiter Delimiter character. 161 * 162 * @retval argv pointer to new argv array on success 163 * @retval NULL on error 164 * 165 * All strings are insertted into the argv array by value; the 166 * newly-allocated array makes no references to the src_string 167 * argument (i.e., it can be freed after calling this function 168 * without invalidating the output argv). 169 */ 170 PMIX_EXPORT char **pmix_argv_split(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; 171 172 /** 173 * Split a string into a NULL-terminated argv array. Include empty 174 * strings in result array. 175 * 176 * @param src_string Input string. 177 * @param delimiter Delimiter character. 178 * 179 * @retval argv pointer to new argv array on success 180 * @retval NULL on error 181 * 182 * All strings are insertted into the argv array by value; the 183 * newly-allocated array makes no references to the src_string 184 * argument (i.e., it can be freed after calling this function 185 * without invalidating the output argv). 186 */ 187 PMIX_EXPORT char **pmix_argv_split_with_empty(const char *src_string, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; 188 189 /** 190 * Return the length of a NULL-terminated argv array. 191 * 192 * @param argv The input argv array. 193 * 194 * @retval 0 If NULL is passed as argv. 195 * @retval count Number of entries in the argv array. 196 * 197 * The argv array must be NULL-terminated. 198 */ 199 PMIX_EXPORT int pmix_argv_count(char **argv); 200 201 /** 202 * Join all the elements of an argv array into a single 203 * newly-allocated string. 204 * 205 * @param argv The input argv array. 206 * @param delimiter Delimiter character placed between each argv string. 207 * 208 * @retval new_string Output string on success. 209 * @retval NULL On failure. 210 * 211 * Similar to the Perl join function, this function takes an input 212 * argv and joins them into into a single string separated by the 213 * delimiter character. 214 * 215 * It is the callers responsibility to free the returned string. 216 */ 217 PMIX_EXPORT char *pmix_argv_join(char **argv, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; 218 219 PMIX_EXPORT char *pmix_argv_join_range(char **argv, size_t start, size_t end, int delimiter) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; 220 221 /** 222 * Return the number of bytes consumed by an argv array. 223 * 224 * @param argv The input argv array. 225 * 226 * Count the number of bytes consumed by a NULL-terminated argv 227 * array. This includes the number of bytes used by each of the 228 * strings as well as the pointers used in the argv array. 229 */ 230 PMIX_EXPORT size_t pmix_argv_len(char **argv); 231 232 /** 233 * Copy a NULL-terminated argv array. 234 * 235 * @param argv The input argv array. 236 * 237 * @retval argv Copied argv array on success. 238 * @retval NULL On failure. 239 * 240 * Copy an argv array, including copying all off its strings. 241 * Specifically, the output argv will be an array of the same length 242 * as the input argv, and strcmp(argv_in[i], argv_out[i]) will be 0. 243 */ 244 PMIX_EXPORT char **pmix_argv_copy(char **argv) __pmix_attribute_malloc__ __pmix_attribute_warn_unused_result__; 245 246 /** 247 * Delete one or more tokens from the middle of an argv. 248 * 249 * @param argv The argv to delete from 250 * @param start The index of the first token to delete 251 * @param num_to_delete How many tokens to delete 252 * 253 * @retval PMIX_SUCCESS Always 254 * 255 * Delete some tokens from within an existing argv. The start 256 * parameter specifies the first token to delete, and will delete 257 * (num_to_delete-1) tokens following it. argv will be realloc()ed 258 * to *argc - num_deleted size. 259 * 260 * If start is beyond the end of the argv array, this function is 261 * a no-op. 262 * 263 * If num_to_delete runs beyond the end of the argv array, this 264 * function will delete all tokens starting with start to the end 265 * of the array. 266 * 267 * All deleted items in the argv array will have their contents 268 * free()ed (it is assumed that the argv "owns" the memory that 269 * the pointer points to). 270 */ 271 PMIX_EXPORT pmix_status_t pmix_argv_delete(int *argc, char ***argv, 272 int start, int num_to_delete); 273 274 /** 275 * Insert one argv array into the middle of another 276 * 277 * @param target The argv to insert tokens into 278 * @param start Index where the first token will be placed in target 279 * @param source The argv to copy tokens from 280 * 281 * @retval PMIX_SUCCESS upon success 282 * @retval PMIX_BAD_PARAM if any parameters are non-sensical 283 * 284 * This function takes one arg and inserts it in the middle of 285 * another. The first token in source will be insertted at index 286 * start in the target argv; all other tokens will follow it. 287 * Similar to pmix_argv_append(), the target may be realloc()'ed 288 * to accomodate the new storage requirements. 289 * 290 * The source array is left unaffected -- its contents are copied 291 * by value over to the target array (i.e., the strings that 292 * source points to are strdup'ed into the new locations in 293 * target). 294 */ 295 PMIX_EXPORT pmix_status_t pmix_argv_insert(char ***target, int start, char **source); 296 297 /** 298 * Insert one argv element in front of a specific position in an array 299 * 300 * @param target The argv to insert tokens into 301 * @param location Index where the token will be placed in target 302 * @param source The token to be inserted 303 * 304 * @retval PMIX_SUCCESS upon success 305 * @retval PMIX_BAD_PARAM if any parameters are non-sensical 306 * 307 * This function takes one arg and inserts it in the middle of 308 * another. The token will be inserted at the specified index 309 * in the target argv; all other tokens will be shifted down. 310 * Similar to pmix_argv_append(), the target may be realloc()'ed 311 * to accomodate the new storage requirements. 312 * 313 * The source token is left unaffected -- its contents are copied 314 * by value over to the target array (i.e., the string that 315 * source points to is strdup'ed into the new location in 316 * target). 317 */ 318 PMIX_EXPORT pmix_status_t pmix_argv_insert_element(char ***target, int location, char *source); 319 320 END_C_DECLS 321 322 #endif /* PMIX_ARGV_H */