/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 2002--2013     The R Core Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  https://www.R-project.org/Licenses/
 *
 * Formerly part of src/main/sprintf.c
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <Defn.h>
#include "RBufferUtils.h"

#undef _
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(String) dgettext ("tools", String)
#else
#define _(String) (String)
#endif


#define MAXLINE MAXELTSIZE
#define MAXNARGS 100
/*               ^^^ not entirely arbitrary, but strongly linked to allowing %$1 to %$99 !*/


#define TRANSLATE_CHAR(_STR_, _i_)  \
   ((use_UTF8) ? translateCharUTF8(STRING_ELT(_STR_, _i_))  \
    : translateChar(STRING_ELT(_STR_, _i_)))

SEXP getfmts(SEXP format)
{
    int cnt, v, nfmt;
    char fmt[MAXLINE+1], bit[MAXLINE+1];
    const char *formatString;
    size_t n, cur, chunk, maxlen = 0;

    int nthis, nstar;
    Rboolean use_UTF8;
    const void *vmax = vmaxget();
    
    SEXP res = PROTECT(allocVector(STRSXP, MAXNARGS));
    
#define SET_RESULT(n, s) {						\
     if (n >= MAXNARGS) error(_("only %d arguments are allowed"), MAXNARGS); \
	maxlen = (n) < maxlen ? maxlen : (n) + 1;			\
	SET_STRING_ELT(res, (n), mkChar(s));				\
    }
    
    if (!isString(format)) error(_("'fmt' is not a character vector"));
    nfmt = LENGTH(format);
    if (nfmt != 1) 
        error(_("'fmt' must be length 1"));

    use_UTF8 = getCharCE(STRING_ELT(format, 0)) == CE_UTF8;
    formatString = TRANSLATE_CHAR(format, 0);
    n = strlen(formatString);
    if (n > MAXLINE)
	error(_("'fmt' length exceeds maximal format length %d"), MAXLINE);
    /* process the format string */
    for (cur = 0, cnt = 0; cur < n; cur += chunk) {
	const char *curFormat = formatString + cur;
	char *starc;
	if (formatString[cur] == '%') { /* handle special format command */

	    if (cur < n - 1 && formatString[cur + 1] == '%') {
		/* take care of %% in the format */
		chunk = 2;
		strcpy(bit, "%");
	    }
	    else {
		/* recognise selected types from Table B-1 of K&R */
		/* NB: we deal with "%%" in branch above. */
		/* This is MBCS-OK, as we are in a format spec */
		    
		/*  Include formats c, u, p and n as well as the R formats; this needs to match */
		/*  C code as well */
		chunk = strcspn(curFormat + 1, "diosfeEgGxXaAcupn") + 2;
		if (cur + chunk > n)
		    error(_("unrecognised format specification '%s'"), curFormat);

		strncpy(fmt, curFormat, chunk);
		fmt[chunk] = '\0';

		nthis = -1;
		/* now look for %n$ or %nn$ form */
		if (strlen(fmt) > 3 && fmt[1] >= '1' && fmt[1] <= '9') {
		    v = fmt[1] - '0';
		    if(fmt[2] == '$') {
			nthis = v-1;
			memmove(fmt+1, fmt+3, strlen(fmt)-2);
		    } else if(fmt[2] >= '0' && fmt[2] <= '9' && fmt[3] == '$') {
			v = 10*v + fmt[2] - '0';
			nthis = v-1;
			memmove(fmt+1, fmt+4, strlen(fmt)-3);
		    }
		}

		starc = Rf_strchr(fmt, '*');
		if (starc) { /* handle  *  format if present */
		    nstar = -1;
		    if (strlen(starc) > 3 && starc[1] >= '1' && starc[1] <= '9') {
			v = starc[1] - '0';
			if(starc[2] == '$') {
			    nstar = v-1;
			    memmove(starc+1, starc+3, strlen(starc)-2);
			} else if(starc[2] >= '0' && starc[2] <= '9'
				  && starc[3] == '$') {
			    v = 10*v + starc[2] - '0';
			    nstar = v-1;
			    memmove(starc+1, starc+4, strlen(starc)-3);
			}
		    }

		    if(nstar < 0) {
			nstar = cnt++;
		    }

		    if (Rf_strchr(starc+1, '*'))
			error(_("at most one asterisk '*' is supported in each conversion specification"));

		    SET_RESULT(nstar, "*");

		}

		if (fmt[strlen(fmt) - 1] == '%') {
		} else {
		    if(nthis < 0) {
			nthis = cnt++;
		    }
		    SET_RESULT(nthis, fmt);
		}
	    }
	}
	else { /* not '%' : handle string part */
	    char *ch = Rf_strchr(curFormat, '%'); /* MBCS-aware version used */
	    chunk = (ch) ? (size_t) (ch - curFormat) : strlen(curFormat);
	    strncpy(bit, curFormat, chunk);
	    bit[chunk] = '\0';
	}
    }  /* end for ( each chunk ) */

    res = xlengthgets(res, maxlen);
    vmaxset(vmax);
    UNPROTECT(1);
    return res;
}
