Back to index

glibc  2.9
argz-insert.c
Go to the documentation of this file.
00001 /* Routines for dealing with '\0' separated arg vectors.
00002    Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Written by Miles Bader <miles@gnu.ai.mit.edu>
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <argz.h>
00022 #include <string.h>
00023 #include <stdlib.h>
00024 
00025 /* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
00026    existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
00027    Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
00028    ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ.  If BEFORE is not
00029    in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
00030    ARGZ, ENOMEM is returned, else 0.  */
00031 error_t
00032 __argz_insert (char **argz, size_t *argz_len, char *before, const char *entry)
00033 {
00034   if (! before)
00035     return __argz_add (argz, argz_len, entry);
00036 
00037   if (before < *argz || before >= *argz + *argz_len)
00038     return EINVAL;
00039 
00040   if (before > *argz)
00041     /* Make sure before is actually the beginning of an entry.  */
00042     while (before[-1])
00043       before--;
00044 
00045   {
00046     size_t after_before = *argz_len - (before - *argz);
00047     size_t entry_len = strlen  (entry) + 1;
00048     size_t new_argz_len = *argz_len + entry_len;
00049     char *new_argz = realloc (*argz, new_argz_len);
00050 
00051     if (new_argz)
00052       {
00053        before = new_argz + (before - *argz);
00054        memmove (before + entry_len, before, after_before);
00055        memmove (before, entry, entry_len);
00056        *argz = new_argz;
00057        *argz_len = new_argz_len;
00058        return 0;
00059       }
00060     else
00061       return ENOMEM;
00062   }
00063 }
00064 weak_alias (__argz_insert, argz_insert)