File:  [ELWIX - Embedded LightWeight unIX -] / libelwix / src / str.c
Revision 1.7: download - view: text, annotated - select for diffs - revision graph
Wed May 18 12:47:42 2016 UTC (8 years ago) by misho
Branches: MAIN
CVS tags: elwix4_9, elwix4_8, elwix4_7, elwix4_6, elwix4_5, elwix4_4, elwix4_3, elwix4_2, elwix4_14, elwix4_13, elwix4_12, elwix4_11, elwix4_10, elwix4_1, HEAD, ELWIX4_9, ELWIX4_8, ELWIX4_7, ELWIX4_6, ELWIX4_5, ELWIX4_4, ELWIX4_3, ELWIX4_2, ELWIX4_13, ELWIX4_12, ELWIX4_11, ELWIX4_10, ELWIX4_1, ELWIX4_0
version 4.0

    1: /*************************************************************************
    2: * (C) 2013 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
    3: *  by Michael Pounov <misho@elwix.org>
    4: *
    5: * $Author: misho $
    6: * $Id: str.c,v 1.7 2016/05/18 12:47:42 misho Exp $
    7: *
    8: **************************************************************************
    9: The ELWIX and AITNET software is distributed under the following
   10: terms:
   11: 
   12: All of the documentation and software included in the ELWIX and AITNET
   13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   14: 
   15: Copyright 2004 - 2015
   16: 	by Michael Pounov <misho@elwix.org>.  All rights reserved.
   17: 
   18: Redistribution and use in source and binary forms, with or without
   19: modification, are permitted provided that the following conditions
   20: are met:
   21: 1. Redistributions of source code must retain the above copyright
   22:    notice, this list of conditions and the following disclaimer.
   23: 2. Redistributions in binary form must reproduce the above copyright
   24:    notice, this list of conditions and the following disclaimer in the
   25:    documentation and/or other materials provided with the distribution.
   26: 3. All advertising materials mentioning features or use of this software
   27:    must display the following acknowledgement:
   28: This product includes software developed by Michael Pounov <misho@elwix.org>
   29: ELWIX - Embedded LightWeight unIX and its contributors.
   30: 4. Neither the name of AITNET nor the names of its contributors
   31:    may be used to endorse or promote products derived from this software
   32:    without specific prior written permission.
   33: 
   34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
   35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   44: SUCH DAMAGE.
   45: */
   46: #include "global.h"
   47: 
   48: 
   49: /*
   50:  * str_FreeNullTerm() - Free dynamic allocated null terminated array with strings
   51:  *
   52:  * @arr = Pointer to array for free
   53:  * return: none
   54:  */
   55: void
   56: str_FreeNullTerm(char *** __restrict arr)
   57: {
   58: 	char **a;
   59: 
   60: 	if (arr && *arr) {
   61: 		a = *arr;
   62: 		while (a && *a)
   63: 			e_free(*a++);
   64: 		e_free(*arr);
   65: 		*arr = NULL;
   66: 	}
   67: }
   68: 
   69: /*
   70:  * str_ArgsNum() Parse and calculate number of arguments
   71:  *
   72:  * @csArgs = Input arguments line
   73:  * @csDelim = Delimiter(s) for separate
   74:  * return: 0 error format; -1 error:: can`t read; >0 ok, number of items
   75:  */
   76: int
   77: str_ArgsNum(const char *csArgs, const char *csDelim)
   78: {
   79: 	register int res;
   80: 	char *pos;
   81: 
   82: 	if (!csArgs || !csDelim)
   83: 		return -1;
   84: 
   85: 	for (res = 1, pos = (char*) csArgs; (pos = strpbrk(pos, csDelim)); res++, pos++);
   86: 
   87: 	return res;
   88: }
   89: 
   90: /*
   91:  * str_ExecArgs() - Build exec arguments from other array
   92:  *
   93:  * @psProg = Program name for execute
   94:  * @oldarg = Arguments array
   95:  * return: NULL error; !=NULL Allocated execution array(must be e_free)
   96:  */
   97: char **
   98: str_ExecArgs(const char *psProg, const char **oldarg)
   99: {
  100: 	char **newarg, **el;
  101: 	register int i, num;
  102: 
  103: 	if (!psProg || !oldarg)
  104: 		return NULL;
  105: 	else
  106: 		newarg = el = NULL;
  107: 
  108: 	/* count items arguments */
  109: 	for (num = 0; oldarg[num]; num++);
  110: 
  111: 	/* create and copy new arguments */
  112: 	newarg = e_calloc(num + 2, sizeof(char*));
  113: 	if (!newarg)
  114: 		return NULL;
  115: 	else
  116: 		el = newarg;
  117: 
  118: 	*el = e_strdup(psProg);
  119: 	el++;
  120: 
  121: 	for (i = 0; oldarg[i]; i++, el++)
  122: 		*el = e_strdup(oldarg[i]);
  123: 	*el = NULL;
  124: 
  125: 	return newarg;
  126: }
  127: 
  128: /*
  129:  * str_CopyEnv() - Copy environment to new environment array;
  130:  *
  131:  * @oldenv = Environment array
  132:  * return: NULL error; !=NULL Allocated new environment array(must be e_free)
  133:  */
  134: char **
  135: str_CopyEnv(const char **oldenv)
  136: {
  137: 	char **newenv, **el;
  138: 	register int i, num;
  139: 
  140: 	if (!oldenv)
  141: 		return NULL;
  142: 	else
  143: 		newenv = el = NULL;
  144: 
  145: 	/* count items environment */
  146: 	for (i = num = 0; oldenv[i]; i++)
  147: 		if (*strchr(oldenv[i], '='))
  148: 			num++;
  149: 
  150: 	/* create and copy new environment */
  151: 	newenv = e_calloc(num + 1, sizeof(char*));
  152: 	if (!newenv)
  153: 		return NULL;
  154: 	else
  155: 		el = newenv;
  156: 
  157: 	for (i = 0; oldenv[i]; i++)
  158: 		if (*strchr(oldenv[i], '=')) {
  159: 			*el = e_strdup(oldenv[i]);
  160: 			el++;
  161: 		}
  162: 	*el = NULL;
  163: 
  164: 	return newenv;
  165: }
  166: 
  167: /*
  168:  * str_Ast() - Function for evaluate string like asterisk variable "{text[:[-]#[:#]]}"
  169:  *
  170:  * @csString = Input string
  171:  * return: NULL error, !=NULL Allocated new string evaluated from input string, 
  172:  * 		must be ait_freeVar()
  173:  */
  174: ait_val_t *
  175: str_Ast(const char *csString)
  176: {
  177: 	char *ext, *str, *eb;
  178: 	int e[2] = { 0, 0 };
  179: 	ait_val_t *out = NULL;
  180: 
  181: 	if (!csString)
  182: 		return NULL;
  183: 
  184: 	if (!strchr(csString, '{') || !strrchr(csString, '}')) {
  185: 		elwix_SetErr(EINVAL, "Invalid input string format ... must be like "
  186: 				"{text[:[-]#[:#]]}");
  187: 		return NULL;
  188: 	} else if (!(out = ait_allocVar()))
  189: 		return NULL;
  190: 	else {
  191: 		AIT_INIT_VAL2(out, string);
  192: 
  193: 		str = e_strdup(strchr(csString, '{') + 1);
  194: 		*strrchr(str, '}') = 0;
  195: 	}
  196: 
  197: 	if ((ext = strchr(str, ':'))) {
  198: 		*ext++ = 0;
  199: 		e[0] = strtol(ext, &eb, 0);
  200: 		if ((ext = strchr(eb, ':')))
  201: 			e[1] = strtol(++ext, NULL, 0);
  202: 
  203: 		/* make cut prefix */
  204: 		if (e[0] >= 0)
  205: 			ext = str + MIN(e[0], strlen(str));
  206: 		else
  207: 			ext = str + MAX(strlen(str) + e[0], 0);
  208: 		/* make cut suffix */
  209: 		if (e[1] > 0)
  210: 			*(ext + MIN(e[1], strlen(ext))) = 0;
  211: 	} else
  212: 		/* ok, clear show */
  213: 		ext = str;
  214: 
  215: 	AIT_SET_STR(out, ext);
  216: 	e_free(str);
  217: 
  218: 	return out;
  219: }
  220: 
  221: /*
  222:  * str_Hex2Dig() - Convert from Hex string to digit array
  223:  *
  224:  * @psLine = Text string
  225:  * return: NULL nothing to do or error; 
  226:  * 		!=0 Allocated new converted data (must be ait_freeVar())
  227:  */
  228: ait_val_t *
  229: str_Hex2Dig(const char *psLine)
  230: {
  231: 	register int i, j;
  232: 	char *str, szWork[3] = { 0, 0, 0 };
  233: 	ait_val_t *v, s = AIT_VAL_INIT;
  234: 	u_char *b;
  235: 	int n;
  236: 
  237: 	if (!psLine || !*psLine)
  238: 		return NULL;
  239: 	else {
  240: 		v = ait_allocVar();
  241: 		if (!v)
  242: 			return NULL;
  243: 
  244: 		/* normalize input string if not even */
  245: 		n = strlen(psLine);
  246: 		if (n % 2)
  247: 			n++;
  248: 		AIT_SET_STRSIZ(&s, n);
  249: 		for (i = strlen(psLine) - 1, j = n - 1, str = AIT_GET_STR(&s), *str = '0'; 
  250: 				i > -1; i--, j--)
  251: 			str[j] = psLine[i];
  252: 	}
  253: 
  254: 	AIT_SET_BUFSIZ(v, 0, n / 2);
  255: 	for (i = 0, b = AIT_GET_BUF(v); i < n && str[i * 2]; i++) {
  256: 		strncpy(szWork, &str[i * 2], 2);
  257: 		b[i] = (u_char) strtol(szWork, NULL, 16);
  258: 	}
  259: 
  260: 	AIT_FREE_VAL(&s);
  261: 	return v;
  262: }
  263: 
  264: /*
  265:  * str_Dig2Hex() - Convert from digit array to Hex string
  266:  *
  267:  * @digz = Digits
  268:  * return: NULL nothing to do or error; 
  269:  * 		!=0 Allocated new converted string (must be e_free())
  270: */
  271: char *
  272: str_Dig2Hex(ait_val_t *digz)
  273: {
  274: 	register int i;
  275: 	char szWork[3] = { 0, 0, 0 }, *str;
  276: 	u_char *b;
  277: 
  278: 	if (!digz || AIT_ISEMPTY(digz))
  279: 		return NULL;
  280: 
  281: 	str = e_malloc(AIT_LEN(digz) * 2 + 1);
  282: 	if (!str)
  283: 		return NULL;
  284: 	else
  285: 		memset(str, 0, AIT_LEN(digz) * 2 + 1);
  286: 
  287: 	for (i = 0, b = AIT_GET_BUF(digz); i < AIT_LEN(digz); i++) {
  288: 		snprintf(szWork, sizeof szWork, "%02hhX", b[i]);
  289: 		strncat(str, szWork, 2);
  290: 	}
  291: 
  292: 	return str;
  293: }
  294: 
  295: /*
  296:  * str_LTrim() - Remove left whitespaces from text string
  297:  *
  298:  * @psLine = Text string
  299:  * return: 0 nothing to do; !=0 Removed bytes
  300:  */
  301: int
  302: str_LTrim(char * __restrict psLine)
  303: {
  304: 	int pos = 0;
  305: 	char *s;
  306: 
  307: 	if (!psLine || !*psLine)
  308: 		return 0;
  309: 
  310: 	for (s = psLine; isspace((u_char) *s); s++);
  311: 	pos = s - psLine;
  312: 
  313: 	memmove(psLine, s, (strlen(psLine) - pos) + 1);
  314: 	return pos;
  315: }
  316: 
  317: /*
  318:  * str_RTrim() - Remove right whitespaces from text string
  319:  *
  320:  * @psLine = Text string
  321:  * return: 0 nothing to do; !=0 Removed bytes
  322:  */
  323: int
  324: str_RTrim(char * __restrict psLine)
  325: {
  326: 	char *t, *pos;
  327: 
  328: 	if (!psLine || !*psLine)
  329: 		return 0;
  330: 
  331: 	pos = psLine + strlen(psLine);
  332: 	for (t = pos - 1; t > psLine && isspace((u_char) *t); t--);
  333: 	*++t = 0;
  334: 
  335: 	return pos - t;
  336: }
  337: 
  338: /*
  339:  * str_Trim() - Remove left and right whitespaces from text string
  340:  *
  341:  * @psLine = Text string
  342:  * return: 0 nothing to do; !=0 Removed bytes
  343:  */
  344: int
  345: str_Trim(char * __restrict psLine)
  346: {
  347: 	int ret = 0;
  348: 
  349: 	ret = str_LTrim(psLine);
  350: 	ret += str_RTrim(psLine);
  351: 
  352: 	return ret;
  353: }
  354: 
  355: /*
  356:  * str_Unquot() - Remove quots from input text string 
  357:  *
  358:  * @psLine = Text string
  359:  * return: 0 nothing to do; 1 successful unquoted string
  360:  */
  361: int
  362: str_Unquot(char * __restrict psLine)
  363: {
  364: 	char *pos, *str = NULL;
  365: 	int flg;
  366: 
  367: 	if (!psLine || !*psLine)
  368: 		return 0;
  369: 
  370: 	if (*psLine == '"' || *psLine == '\'') {
  371: 		str = e_strdup(psLine + 1);
  372: 		for (pos = str, flg = 0; *pos; flg = ('\\' == *pos), pos++) {
  373: 			if (!flg && *pos == *psLine) {
  374: 				*pos = 0;
  375: 				strlcpy(psLine, str, strlen(psLine) + 1);
  376: 				break;
  377: 			}
  378: 		}
  379: 		e_free(str);
  380: 		return 1;
  381: 	}
  382: 
  383: 	return 0;
  384: }
  385: 
  386: /*
  387:  * str_Upper() - Convert all lower characters to upper
  388:  *
  389:  * @psLine = Text string
  390:  * return: 0 nothing to do; !=0 converted chars
  391:  */
  392: int
  393: str_Upper(char * __restrict psLine)
  394: {
  395: 	char *s;
  396: 	register int cx = 0;
  397: 
  398: 	if (!psLine || !*psLine)
  399: 		return 0;
  400: 
  401: 	for (s = psLine; *s; s++)
  402: 		if (islower(*s)) {
  403: 			*s = toupper(*s);
  404: 			cx++;
  405: 		}
  406: 
  407: 	return cx;
  408: }
  409: 
  410: /*
  411:  * str_Lower() - Convert all upper characters to lower
  412:  *
  413:  * @psLine = Text string
  414:  * return: 0 nothing to do; !=0 converted chars
  415:  */
  416: int
  417: str_Lower(char * __restrict psLine)
  418: {
  419: 	char *s;
  420: 	register int cx = 0;
  421: 
  422: 	if (!psLine || !*psLine)
  423: 		return 0;
  424: 
  425: 	for (s = psLine; *s; s++)
  426: 		if (isupper(*s)) {
  427: 			*s = tolower(*s);
  428: 			cx++;
  429: 		}
  430: 
  431: 	return cx;
  432: }
  433: 
  434: /*
  435:  * str_getString() - Get string from data buffer
  436:  *
  437:  * @data = Data buffer
  438:  * @dlen = Data length
  439:  * @next = Return next position after string if !=NULL
  440:  * return: -1 error or size of string 
  441:  */
  442: int
  443: str_getString(const u_char * __restrict data, int dlen, char ** __restrict next)
  444: {
  445: 	const u_char *pos;
  446: 
  447: 	if (!data || !dlen)
  448: 		return -1;
  449: 
  450: 	for (pos = data; pos < data + dlen; pos++)
  451: 		if (!*pos)
  452: 			break;
  453: 	if (*pos) {
  454: 		elwix_SetErr(ENOEXEC, "Not found null-terminated string");
  455: 		return -1;
  456: 	}
  457: 
  458: 	if (next)
  459: 		*next = (char*) pos + 1;
  460: 	return pos - data + 1;
  461: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>