https://github.com/cran/Hmisc
Raw File
Tip revision: 7728929d8f2cbde7acc6d245955a99eb5809e357 authored by Frank E Harrell Jr on 12 September 2014, 15:50:33 UTC
version 3.14-5
Tip revision: 7728929
nstr.c
#include "Hmisc.h"

static Hmisc_StringBuffer cbuff = {NULL, 0, MAXELTSIZE};


SEXP do_nstr(SEXP s, SEXP n)
{
   SEXP ans;                    /* the returned character string */
   int i, j;                    /* the length of the string and number of reps */
   int s_counter = 0, n_counter = 0;
   int longest, s_length, n_length;
   
   S_EVALUATOR

   n_length = length(n);
   s_length = length(s);
   
   longest = n_length < s_length ? s_length : n_length;
   
   if(n_length == 1 && INTEGER(n)[0] == 1)
      return s;
   
   PROTECT(ans = allocVector(STRSXP, longest));

   for(i=0; i < longest; i++) 
   {
      int n_reps = INTEGER(n)[n_counter];
      
      if(n_reps < 1)
      {
         SET_STRING_ELT(ans, i, mkChar(""));
      }
      else if(n_reps == 1)
      {
         SET_STRING_ELT(ans, i, duplicate(STRING_ELT(s, s_counter)));
      }
      else
      {
         char *cbuf, *buf;
         const char *seg;
         size_t seg_len;

         seg = CHAR(STRING_ELT(s, s_counter));
         seg_len = strlen(seg);
         cbuf = buf = Hmisc_AllocStringBuffer((n_reps * seg_len + 1) * sizeof(char), &cbuff);
   
         for(j=0; j < n_reps; ++j)
         {
            strcpy(buf, seg);
            buf += seg_len;
         }
         *buf = '\0';
   
         SET_STRING_ELT(ans, i, mkChar(cbuf));
      }

      n_counter = (++n_counter < n_length) ? n_counter : 0;
      s_counter = (++s_counter < s_length) ? s_counter : 0;
   }

   Hmisc_FreeStringBuffer(&cbuff);
   
   UNPROTECT(1);
   return ans;
}
back to top