void str_words_in_rev(char *input, int len){
	int i = 0, j = 0, count = 0, k = 0;
	strreverse(input, 0, len - 1);
	while (input[k] != '\0'){
		if (input[k] == ' '){
			count++;
		}
		k++;
	}
	if (count == 0){
		strreverse(input, 0, len - 1);
	}
	else{
		while (input[j] != '\0'){
			if (input[j] == ' ' && input[j + 1] != ' '){
				i = j + 1;
			}
			else if (input[j + 1] == ' '){
				strreverse(input, i, j);
				i = j + 1;
			}
			else if (input[j + 1] == '\0'){
				strreverse(input, i, j);
			}
			j++;
		}
	}
}
Example #2
0
/**
 * Converts an integer into a string using an arbitrary base. Make sure the buffer for
 * the converted string is large enough. The smaller the base the more space is required, eg
 * for converting a 32 bit integer you can expect 35 bytes to be sufficient
 * (base 2: 32 bytes for digits + 1 byte for the terminator + some space just to feel safe
 * and take into account future format changes).
 * In other, GAD inspired words:
 * bufsize >= ceil(log2(MAX_INT)) which is equal to: bufsize >= sizeof(int) * 8
 *
 * This is not a part of the C standard library.
 *
 * @param n the number to convert
 * @param str the target string buffer
 * @param base the base to use for the conversion
 * @return The original value of str
 */
char* itoa(int n, char *str, unsigned int base)
{
        char *ret = str;
        bool neg = FALSE;

        /* Treat negative base 10 integers specially. */
        if (base == 10 && n < 0) {
                *str++ = '-';
                n = -n;
                neg = TRUE;
        }

        /* Convert to unsigned to get proper two's complement hex strings. */
        unsigned int num = n;

        do {
                int rem = num % base;
                *str++ = rem < 10 ? '0' + rem : 55 + rem;
        } while (num /= base);

        *str = '\0';

        /* Do not change the position of the minus sign. */
        if (neg) {
                strreverse(++ret);
                return --ret;
        } else
                return strreverse(ret);
}
Example #3
0
void ltoa(long value, char* str, int base)
{
	char* wstr = str;
	long sign;
	div_t res;
	
	// Validate base
	if (base<2 || base>35)
  {
    *wstr='\0';
    return;
  }	
	
	// Take care of sign	
	if ((sign=value) < 0)
    value = -value;	
	
	// Conversion. Number is reversed.	
	do
  {	
		res = div(value,base);	
		*wstr++ = num[res.rem];	
	} while (value=res.quot);

	if (sign<0)
    *wstr++='-';
	
	*wstr='\0';
	
	// Reverse string	
	strreverse(str, wstr-1);
}
Example #4
0
File: string.c Project: ORCOS/ORCOS
void lltoa( long long value, char* str, int base ) {
    static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    char* wstr = str;
    int sign = 0;
    // for all other bases we interpret value as unsigned!
    if (base != 10) return (uitoa((unsigned int) value,str,base));

    // Validate base
    if ( base < 2 || base > 35 ) {
        *wstr = '\0';
        return;
    }


    if ( ( sign = value ) < 0 )
        value = -value;

    // Conversion. Number is reversed.
    do
        *wstr++ = num[ value % base ];
    while ( value /= base );

    if ( sign < 0 )
        *wstr++ = '-';

    *wstr = '\0';

    // Reverse string
    strreverse( str, wstr - 1 );
}
Example #5
0
File: 1109_2.c Project: sktwj/var
int main(void)
{
	char s[] = "world";
	strreverse(s);
	printf("after reverse, s = %s\n", s);
	return 0;
}
void itoa(int value, char* str, int base) {
  static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  char* wstr=str;
  int sign;

  // Validate base
  if (base<2 || base>35) {
    *wstr='\0';
    return;
  }

  // Take care of sign
  if ((sign=value) < 0)
    value = -value;

  // Conversion. Number is reversed.
  do
    *wstr++ = num[value%base];
  while(value/=base);

  if(sign<0)
    *wstr++='-';

  *wstr='\0';

  // Reverse string
  strreverse(str,wstr-1);
}
void str_words_in_rev(char *input, int len){
	int i, j;
	for (i = 0, j = 0; i <= len; i++){
		if (input[i] == ' '){
			strreverse(input, j, i - 1);
			while (input[i + 1] == ' '&&input[i + 1] != '\0'){
				i = i + 1;
			}
			j = i + 1;
		}
		else if (input[i] == '\0'){
			strreverse(input, j, i - 1);
		}
	}
	strreverse(input, 0, len - 1);
}
Example #8
0
void modp_ulitoa10(uint64_t value, char* str)
{
    char* wstr=str;
    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (value % 10)); while (value /= 10);
    *wstr='\0';
    // Reverse string
    strreverse(str, wstr-1);
}
Example #9
0
size_t modp_uitoa10(uint32_t value, char* str)
{
    char* wstr=str;
    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (value % 10)); while (value /= 10);
    *wstr='\0';
    // Reverse string
    strreverse(str, wstr-1);
    return (size_t)(wstr - str);
}
Example #10
0
static void reverse_onwrite(sst_t* self, sst_chunk_t* chunk) {
  char *s;
  sst_chunk_t *chunk_out;
  s = (char*)chunk->data;

  chunk_out = sst_chunk_new(strreverse(s), free);
  self->emit(self, chunk_out);

  sst_chunk_free(chunk);
}
Example #11
0
// int to str
void itoa(int value, char* str, int base) {
	static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
	char* wstr=str;
	int sign;
	if (base<2 || base>35){ *wstr='\0'; return; }
	if ((sign=value) < 0) value = -value;
	do *wstr++ = num[value%base]; while(value/=base);
	if(sign<0) *wstr++='-';
	*wstr='\0';
	strreverse(str,wstr-1);
}
Example #12
0
void modp_litoa10(int64_t value, char* str)
{
    char* wstr=str;
    unsigned long uvalue = (value < 0) ? -value : value;

    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
    if (value < 0) *wstr++ = '-';
    *wstr='\0';

    // Reverse string
    strreverse(str,wstr-1);
}
Example #13
0
size_t modp_itoa10(int32_t value, char* str)
{
    char* wstr=str;
    /* Take care of sign */
    uint32_t uvalue = (value < 0) ? (uint32_t)(-value) : (uint32_t)(value);
    /* Conversion. Number is reversed. */
    do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
    if (value < 0) *wstr++ = '-';
    *wstr='\0';

    /* Reverse string */
    strreverse(str,wstr-1);
    return (size_t)(wstr - str);
}
Example #14
0
unsigned modp_itoa10(int32_t value, char* str)
{
    char* wstr=str;
    // Take care of sign
    unsigned int uvalue = (value < 0) ? -value : value;
    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
    if (value < 0) *wstr++ = '-';
    *wstr='\0';

    // Reverse string
    strreverse(str,wstr-1);
    return wstr-str;
}
Example #15
0
size_t modp_litoa10(int64_t value, char* str)
{
    char* wstr=str;
    uint64_t uvalue = (value < 0) ? (uint64_t)(-value) : (uint64_t)(value);

    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (uvalue % 10)); while(uvalue /= 10);
    if (value < 0) *wstr++ = '-';
    *wstr='\0';

    // Reverse string
    strreverse(str,wstr-1);
    return (size_t)(wstr - str);
}
Example #16
0
static void long2str(long value, TCHAR *str)
{
  int i = 0;
  long sign = value;
  int n;

  /* generate digits in reverse order */
  do {
    n = (int)(value % 10);              /* get next lowest digit */
    str[i++] = (TCHAR)(ABS(n) + '0');   /* handle case of negative digit */
  } while (value /= 10);                /* delete the lowest digit */
  if (sign < 0)
    str[i++] = '-';
  str[i] = '\0';

  strreverse(str);
}
Example #17
0
ALWAYS_INLINE int32_t
int_to_string(int32_t value, char *str)
{
    char *wstr = str;
    // Take care of sign
    unsigned int uvalue = (value < 0) ? -value : value;
    // Conversion. Number is reversed.
    do
        *wstr++ = (char) decimal_digits[uvalue % 10];
    while (uvalue /= 10);
    if (value < 0)
        *wstr++ = '-';
    *wstr = '\0';
    // Reverse string
    strreverse(str, wstr - 1);

    return wstr - str;
}
Example #18
0
File: string.c Project: ORCOS/ORCOS
void ulltoa( unsigned long long value, char* str, int base ) {
    static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    char* wstr = str;

    // Validate base
    if ( base < 2 || base > 35 ) {
        *wstr = '\0';
        return;
    }

    // Conversion. Number is reversed.
    do
        *wstr++ = num[ value % base ];
    while ( value /= base );

      *wstr = '\0';

    // Reverse string
    strreverse( str, wstr - 1 );
}
Example #19
0
File: aux.c Project: kevinw/kracket
static void itoa(intptr_t value, char* str, int base) {
	static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
	char* wstr=str;
	intptr_t sign;
	div_t res;

	// Validate base
	if (base<2 || base>35){ *wstr='\0'; return; }

	// Take care of sign
	if ((sign=value) < 0) value = -value;

	// Conversion. Number is reversed.
	do {
		res = div(value, base);
		*wstr++ = num[res.rem];
	} while((value=res.quot));
	if (sign < 0) *wstr++='-';
	*wstr = '\0';

	// Reverse string
	strreverse(str, wstr - 1);
}
Example #20
0
void utoa(unsigned int value, char* str, int base)
{
	char* wstr = str;
	div_t res;
	
	// Validate base
	if (base<2 || base>35)
  {
    *wstr='\0';
    return;
  }	
	
	// Conversion. Number is reversed.	
	do
  {	
		res = div(value,base);	
		*wstr++ = num[res.rem];	
	} while (value=res.quot);

	*wstr='\0';
	
	// Reverse string	
	strreverse(str, wstr-1);
}
Example #21
0
void modp_dtoa(double value, char* str, int prec)
{
    /* Hacky test for NaN
     * under -fast-math this won't work, but then you also won't
     * have correct nan values anyways.  The alternative is
     * to link with libmath (bad) or hack IEEE double bits (bad)
     */
    if (! (value == value)) {
        str[0] = 'n'; str[1] = 'a'; str[2] = 'n'; str[3] = '\0';
        return;
    }
    /* if input is larger than thres_max, revert to exponential */
    const double thres_max = (double)(0x7FFFFFFF);

    double diff = 0.0;
    char* wstr = str;

    if (prec < 0) {
        prec = 0;
    } else if (prec > 9) {
        /* precision of >= 10 can lead to overflow errors */
        prec = 9;
    }


    /* we'll work in positive values and deal with the
       negative sign issue later */
    int neg = 0;
    if (value < 0) {
        neg = 1;
        value = -value;
    }


    int whole = (int) value;
    double tmp = (value - whole) * pow10a[prec];
    uint32_t frac = (uint32_t)(tmp);
    diff = tmp - frac;

    if (diff > 0.5) {
        ++frac;
        /* handle rollover, e.g.  case 0.99 with prec 1 is 1.0  */
        if (frac >= pow10a[prec]) {
            frac = 0;
            ++whole;
        }
    } else if (diff == 0.5 && ((frac == 0) || (frac & 1))) {
        /* if halfway, round up if odd, OR
           if last digit is 0.  That last part is strange */
        ++frac;
    }

    /* for very large numbers switch back to native sprintf for exponentials.
       anyone want to write code to replace this? */
    /*
      normal printf behavior is to print EVERY whole number digit
      which can be 100s of characters overflowing your buffers == bad
    */
    if (value > thres_max) {
        sprintf(str, "%e", neg ? -value : value);
        return;
    }

    if (prec == 0) {
        diff = value - whole;
        if (diff > 0.5) {
            /* greater than 0.5, round up, e.g. 1.6 -> 2 */
            ++whole;
        } else if (diff == 0.5 && (whole & 1)) {
            /* exactly 0.5 and ODD, then round up */
            /* 1.5 -> 2, but 2.5 -> 2 */
            ++whole;
        }
    } else {
        int count = prec;
        // now do fractional part, as an unsigned number
        do {
            --count;
            *wstr++ = (char)(48 + (frac % 10));
        } while (frac /= 10);
        // add extra 0s
        while (count-- > 0) *wstr++ = '0';
        // add decimal
        *wstr++ = '.';
    }

    // do whole part
    // Take care of sign
    // Conversion. Number is reversed.
    do *wstr++ = (char)(48 + (whole % 10)); while (whole /= 10);
    if (neg) {
        *wstr++ = '-';
    }
    *wstr='\0';
    strreverse(str, wstr-1);
}
Example #22
0
void itoa(int pvalue, char* pstr, size_t *rlen) {

	static char num[] = "0123456789";
	
	int value = pvalue;
	char *str = pstr;
 
	// take care of sign
	if(pvalue<0) { *str++ = '-'; value = -value; }

	/* -999 - +999 */
	if (value<1000) {
		// printf(" x %d", value);
		// printf("Rest: %d $ ", value);
		if(!mux) initmux();
		char *q = mux + value*4;
		char qq;
		*str++=*q++; if((qq=*q++)) { *str++=qq; if((qq=*q++)) { *str++=qq; } }
		#ifdef FLEECE_ALWAYS_DELIMIT
		*str=0;
		#endif
		*rlen = str - pstr;
		goto ret;
	}

	if (value<1000000) {
		if(!mux) initmux();
		char *q = mux + (value/1000*4);
		char qq;
		*(str++)=*q++; if((qq=*q++)) { *(str++)=qq; if((qq=*q++)) { *(str++)=qq; } }
		// printf("Now: %s $ ", pstr);
		value %= 1000;
		q = mux0 + (4*value);
		*str++=*q++;
		*str++=*q++;
		*str++=*q++;
		#ifdef FLEECE_ALWAYS_DELIMIT
		*str=0;
		#endif
		*rlen = str - pstr;
		goto ret;
	}

	/* #4 any length
	   Source: Stuart Lowe's optimization of the Kernighan & Ritchie sample
       at http://www.strudel.org.uk/itoa/
       DO NOT CHANGE ANYTHING IN THIS FUNCTION WITHOUT SYNCHING ilen() */	

	/* prototype TODO: move */
	void strreverse(char* begin, char* end);

	/* note: sign is taken care of above. if minus, *str IS alread '-' here. */	
	char* wstr=str;
	div_t res;
	
	// Conversion. Number is reversed in the end.	
	do {
		res = div(value,10);
		*wstr++ = num[res.rem];
	} while((value=res.quot));

	#ifdef FLEECE_ALWAYS_DELIMIT
	*wstr='\0';
	#endif
	*rlen = wstr - pstr;
	
	// Reverse string
	strreverse(str,wstr-1);

	#if SELFCHECK >=3
	    *(pstr+*rlen) = 0;
		char test[32];
		sprintf(test, "%d", pvalue);
		if(strcmp(test, pstr)) {
			printf("fleece [3]: ** fast integer K&R conversion error: %d made to '%s', should be '%s'.\n", pvalue, pstr,test);
			exit(180);
		}
	#endif
	
	ret:;
	#if SELFCHECK >=3
	    *(pstr+*rlen) = 0;
		sprintf(test, "%d", pvalue);
		if(strcmp(test, pstr)) {
			printf("fleece [3]: ** fast integer look up conversion error: %d made to '%s', should be '%s'.\n", pvalue, pstr,test);
			exit(194);
		}
	#endif

	return;
}
Example #23
0
// from stringencoders with modifications ( Copyright (C) 2007 Nick Galbreath ) - BSD License
std::string float_to_string( const float number, int prec /* = 6 */ )
{
	double value = number;
	/* if input is larger than thres_max, revert to native */
	const double thres_max = static_cast<double>(0x7FFFFFFF);

	double diff = 0.0;
	char str[64];
	char* wstr = str;

	if (prec < 0)
	{
		prec = 0;
	}
	else if (prec > 6)
	{
		/* precision of >= 7 for float can lead to overflow errors */
		prec = 6;
	}

	/* we'll work in positive values and deal with the
	   negative sign issue later */
	int neg = 0;
	if (value < 0)
	{
		neg = 1;
		value = -value;
	}

	int whole = static_cast<int>(value);
	double tmp = (value - whole) * pow_of_10[prec];
	uint32_t frac = static_cast<uint32_t>(tmp);
	diff = tmp - frac;

	if(diff > 0.5)
	{
		++frac;
		/* handle rollover, e.g.  case 0.99 with prec 1 is 1.0  */
		if(frac >= pow_of_10[prec])
		{
			frac = 0;
			++whole;
		}
	}
	else if( diff == 0.5 && ((frac == 0) || (frac & 1)) )
	{
		/* if halfway, round up if odd, OR
		   if last digit is 0.  That last part is strange */
		++frac;
	}

	/* for very large numbers switch back to native */
	/*
		normal printf behavior is to print EVERY whole number digit
		which can be 100s of characters overflowing your buffers == bad
	*/
	if( value > thres_max )
	{
		std::ostringstream temp;
		temp.setf( std::ios_base::fixed );
		temp << number;

		return temp.str();
	}

	if( prec == 0 )
	{
		diff = value - whole;
		if(diff > 0.5)
		{
			/* greater than 0.5, round up, e.g. 1.6 -> 2 */
			++whole;
		}
		else if(diff == 0.5 && (whole & 1))
		{
			/* exactly 0.5 and ODD, then round up */
			/* 1.5 -> 2, but 2.5 -> 2 */
			++whole;
		}
	}
	else
	{
		int count = prec;
		// now do fractional part, as an unsigned number
		do
		{
			--count;
			*wstr++ = 48 + (frac % 10);
		}
		while(frac /= 10);
		// add extra 0s
		while(count-- > 0) *wstr++ = '0';
		// add decimal
		*wstr++ = '.';
	}

	// do whole part
	// Take care of sign
	// Conversion. Number is reversed.
	do *wstr++ = 48 + (whole % 10); while (whole /= 10);
	if(neg)
	{
		*wstr++ = '-';
	}

	*wstr='\0';
	strreverse(str, wstr-1);

	return str;
}
Example #24
0
static int on_d2cs_charloginreq(t_connection * c, t_packet const * packet)
{
	t_connection *	client;
	char const *	charname;
	char const *	portrait;
	char const *	clienttag;
	char *	temp;
	unsigned int	sessionnum;
	t_realm * 	realm;
	char const *	realmname;
	unsigned int	pos, reply;
	t_packet *	rpacket;
	
	if (packet_get_size(packet)<sizeof(t_d2cs_bnetd_charloginreq)) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad packet size");
		return -1;
	}
	sessionnum=bn_int_get(packet->u.d2cs_bnetd_charloginreq.sessionnum);
	pos=sizeof(t_d2cs_bnetd_charloginreq);
	if (!(charname=packet_get_str_const(packet,pos,CHAR_NAME_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character name");
		return -1;
	}
	pos+=strlen(charname)+1;
	if (!(portrait=packet_get_str_const(packet,pos,CHAR_PORTRAIT_LEN))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got bad character portrait");
		return -1;
	}
	if (!(client=connlist_find_connection_by_sessionnum(sessionnum))) {
		eventlog(eventlog_level_error,__FUNCTION__,"user %d not found",sessionnum);
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else if (!(clienttag=clienttag_uint_to_str(conn_get_clienttag(client)))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL clienttag");
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else if (!(realm=conn_get_realm(client))) {
		eventlog(eventlog_level_error,__FUNCTION__,"got NULL realm");
		reply = BNETD_D2CS_CHARLOGINREPLY_FAILED;
	} else {
		char revtag[8];

		realmname = realm_get_name(realm);
		temp=xmalloc(strlen(clienttag)+strlen(realmname)+1+strlen(charname)+1+
			strlen(portrait)+1);
		reply = BNETD_D2CS_CHARLOGINREPLY_SUCCEED;
		strcpy(revtag,clienttag);
		strreverse(revtag);
		sprintf(temp,"%4s%s,%s,%s",revtag,realmname,charname,portrait);
		conn_set_charname(client,charname);
		conn_set_realminfo(client,temp);
		xfree(temp);
		eventlog(eventlog_level_debug,__FUNCTION__,
			"loaded portrait for character %s",charname);
	}
	if ((rpacket=packet_create(packet_class_d2cs_bnetd))) {
		packet_set_size(rpacket,sizeof(t_bnetd_d2cs_charloginreply));
		packet_set_type(rpacket,BNETD_D2CS_CHARLOGINREPLY);
		bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.h.seqno,
			bn_int_get(packet->u.d2cs_bnetd_charloginreq.h.seqno));
		bn_int_set(&rpacket->u.bnetd_d2cs_charloginreply.reply,reply);
		conn_push_outqueue(c,rpacket);
		packet_del_ref(rpacket);
	}
	return 0;
}
Example #25
0
		// read "count" lines from the end starting from "startline"
		extern std::map<long, char*> userlog_read(const char * username, long startline, const char * search_substr)
		{
			std::map<long, char*> lines;

			long linecount = 0;
			char line[MAX_MESSAGE_LEN+1];
			int linepos = 0;

			char c, prev_c = 0;
			long pos;

			char * filename = userlog_filename(username);
			if (FILE *fp = fopen(filename, "r"))
			{
				// set position to the end of file
				fseek(fp, 0, SEEK_END);
				pos = ftell(fp);

				// read file reversely by byte
				do {
					pos--;
					fseek(fp, pos, SEEK_SET);
					c = fgetc(fp);

					// add char into line array
					if (c != '\n')
						line[linepos] = c;

					// end of line (or start of file)
					if ((c == '\n' && c != prev_c) || pos == -1)
					{
						// hack for large lines (instead we will receive cut line without start symbols)
						if (linepos == MAX_MESSAGE_LEN)
						{
							// return carriage to read whole line to(from) start
							pos = pos + MAX_MESSAGE_LEN;
							linepos = 0;
						}
						if (linepos > 0)
						{
							line[linepos] = '\0'; // set end of string
							strreverse(line);

							linepos = 0; // reset position inside line

							linecount++;
							if (linecount >= startline)
							{
								if (search_substr && strlen(search_substr) > 0)
								{
									if (find_substr(line, search_substr))
										lines[linecount] = xstrdup(line);
								}
								else
								{
									lines[linecount] = xstrdup(line);
								}
							}

							// limitation of results
							if (lines.size() >= userlog_max_output_lines)
								break;
						}
					}
					prev_c = c;
					if (c != '\n' && linepos < MAX_MESSAGE_LEN)
						linepos++;

				} while (c != EOF);

				fclose(fp);
			}
			return lines;
		}
Example #26
0
static int logg_internal(const enum loglevel level,
                         const char *file,
                         const char *func,
                         const unsigned int line,
                         int log_errno,
                         const char *fmt,
                         va_list args
                        )
{
	struct big_buff *logg_buff;
	int ret_val, old_errno, retry_cnt;

	old_errno  = errno;

	/* get our tls-print buf */
	if(!(logg_buff = logg_get_buf()))
	{
		/*
		 * hmmm, something went wrong, lets see, if we can get the message to
		 * the user by other means
		 */
		return do_vlogging(level, fmt, args);
	}

	/* add time, if wanted, to buffer */
	if(server.settings.logging.add_date_time)
		logg_buff->pos += add_time_to_buffer(buffer_start(*logg_buff), buffer_remaining(*logg_buff));

	/* put out the "extra" stuff, if there */
	if(file)
	{
		retry_cnt = 0;
		prefetch(strlpcpy);
		prefetch(file);
		prefetch(func);
		/*
		 * calling snprintf for 2 * strcpy + an itoa is "nice"
		 * but goes round the full stdio bloat:
		 * snprintf->vsnprintf->vfprintf-> myriads of funcs to print
		 */
		do
		{
			char *sptr, *stmp, *rstart;
			size_t remaining;

			stmp = sptr = buffer_start(*logg_buff);
			remaining = buffer_remaining(*logg_buff);
			rstart = strlpcpy(sptr, file, remaining);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 7))
				goto realloc;
			sptr = rstart;

			*sptr++ = ':';
			remaining--;
			rstart = strlpcpy(sptr, func, remaining);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 18)) /* make sure we have enough space */
				goto realloc;
			sptr = rstart;

			*sptr++ = '(';
			*sptr++ = ')';
			*sptr++ = '@';
			remaining -= 3;
			rstart = put_dec_trunc(sptr, line); /* 99,999 lines should be... */
			strreverse(sptr, rstart - 1);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 2))
				goto realloc;
			sptr = rstart;
			*sptr++ = ':';
			*sptr++ = ' ';
			logg_buff->pos += sptr - stmp;
			break;
realloc:
			/* now we are in a slow path, no need to hurry */
			{
				struct big_buff *tmp_buff;
				size_t len = strlen(file) + strlen(func) + 6 + 30 + strlen(fmt) * 3;
				len = ROUND_ALIGN(len * 2, 2048) + logg_buff->capacity;
				tmp_buff = realloc(logg_buff, sizeof(*logg_buff) + len);
				if(tmp_buff) {
					logg_buff = tmp_buff;
					logg_buff->limit = logg_buff->capacity = len;
				} else
					break;
				retry_cnt++;
			}
		} while(retry_cnt < 4);
	}

	ret_val = 0; retry_cnt = 0;
	/* format the message in tls */
	do
	{
		size_t len = logg_buff->capacity;
		va_list tmp_valist;
		if(ret_val < 0)
		{
			len *= 2;
			if(++retry_cnt > 4) {
				ret_val = 0;
				break;
			}
		}
		else if((size_t)ret_val > buffer_remaining(*logg_buff))
			len = ROUND_ALIGN((size_t)ret_val * 2, 1024); /* align to a k */
		if(unlikely(len != logg_buff->capacity))
		{
			struct big_buff *tmp_buf = realloc(logg_buff, sizeof(*logg_buff) + len);
			if(tmp_buf) {
				logg_buff = tmp_buf;
				logg_buff->limit = logg_buff->capacity = len;
			} else {
				ret_val = buffer_remaining(*logg_buff);
				break;
			}
		}
		/* put msg printed out in buffer */
		va_copy(tmp_valist, args);
		ret_val = my_vsnprintf(buffer_start(*logg_buff), buffer_remaining(*logg_buff), fmt, tmp_valist);
		va_end(tmp_valist);
		/* error? repeat */
	} while(unlikely(ret_val < 0 || (size_t)ret_val > buffer_remaining(*logg_buff)));
	logg_buff->pos += (size_t)ret_val;

	/* add errno string if wanted */
	if(log_errno)
	{
		if(buffer_remaining(*logg_buff) < STRERROR_R_SIZE + 4)
		{
			size_t len = logg_buff->capacity * 2;
			struct big_buff *tmp_buff = realloc(logg_buff, sizeof(*logg_buff) + len);
			if(!tmp_buff)
				goto no_errno;
			logg_buff = tmp_buff;
			logg_buff->limit = logg_buff->capacity += len;
		}
		*buffer_start(*logg_buff) = ':'; logg_buff->pos++;
		*buffer_start(*logg_buff) = ' '; logg_buff->pos++;
		{
#if defined STRERROR_R_CHAR_P || defined HAVE_MTSAFE_STRERROR || WIN32 || !(defined HAVE_STRERROR_R || HAVE_DECL_STRERROR_R-0 > 0)
			size_t err_str_len;
# ifdef WIN32
			const char *s = buffer_start(*logg_buff);
			if(!(err_str_len = FormatMessage(
				FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
				0, /* pointer to other source */
				old_errno, /* msg id */
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* language */
				buffer_start(*logg_buff), /* buffer */
				buffer_remaining(*logg_buff)-1, /* size */
				0 /* va_args */
			))) {
				s = "Unknown system error";
				err_str_len = strlen(s) < buffer_remaining(*logg_buff)-2 ?
				              strlen(s) : buffer_remaining(*logg_buff)-2;
			}
# else
#  ifdef STRERROR_R_CHAR_P
			/*
			 * the f***ing GNU-Version of strerror_r wich returns
			 * a char * to the buffer....
			 * This sucks especially in conjunction with strnlen,
			 * wich needs a #define __GNU_SOURCE, but conflicts
			 * with this...
			 */
			const char *s = strerror_r(old_errno, buffer_start(*logg_buff), buffer_remaining(*logg_buff)-2);
#  else
			/*
			 * Ol Solaris seems to have a static msgtable, so
			 * strerror is threadsafe and we don't have a
			 * _r version
			 */
			/*
			 * we also simply fall into here if strerror is not thread
			 * safe, but we have nothing else.
			 * Since what should we do in this case... _sys_errlist
			 * is a bsd extentions.
			 */
			const char *s = strerror(old_errno);
#  endif
			if(s)
				err_str_len = strnlen(s, buffer_remaining(*logg_buff)-2);
			else {
				s = "Unknown system error";
				err_str_len = strlen(s) < (buffer_remaining(*logg_buff)-2) ?
				              strlen(s) : buffer_remaining(*logg_buff)-2;
			}
# endif

			if(s != buffer_start(*logg_buff))
				my_memcpy(buffer_start(*logg_buff), s, err_str_len);
			logg_buff->pos += err_str_len;
#else
			if(!strerror_r(old_errno, buffer_start(*logg_buff), buffer_remaining(*logg_buff)))
//			if(!strerror_s(buffer_start(*logg_buff), buffer_remaining(*logg_buff), old_errno))
				logg_buff->pos += strnlen(buffer_start(*logg_buff), buffer_remaining(*logg_buff));
			else
			{
				size_t err_l;
				const char *bs;
				if(EINVAL == errno) {
					err_l = str_size("Unknown errno value!");
					bs = "Unknown errno value!";
				} else if(ERANGE == errno) {
					err_l = str_size("errno msg to long for buffer!");
					bs = "errno msg to long for buffer!";
				} else {
					err_l = str_size("failure while retrieving errno msg!");
					bs = "failure while retrieving errno msg!";
				}
				err_l = (buffer_remaining(*logg_buff)-2) >= err_l ? err_l : (buffer_remaining(*logg_buff)-2);
				my_memcpy(buffer_start(*logg_buff), bs, err_l);
				logg_buff->pos += err_l;
			}
#endif
		}
		*buffer_start(*logg_buff) = '\n'; logg_buff->pos++;
		*buffer_start(*logg_buff) = '\0';
	}
no_errno:

	/* output that stuff */
	buffer_flip(*logg_buff);
	ret_val = do_logging(level, buffer_start(*logg_buff), buffer_remaining(*logg_buff));
	logg_ret_buf(logg_buff);
	return ret_val;
}
Example #27
0
t_parsed_exeinfo * parse_exeinfo(char const * _exeinfo)
{
  t_parsed_exeinfo * parsed_exeinfo;

    if (!_exeinfo) {
	return NULL;
    }

    parsed_exeinfo = (t_parsed_exeinfo*)xmalloc(sizeof(t_parsed_exeinfo));
    parsed_exeinfo->exe = xstrdup(_exeinfo);
    parsed_exeinfo->time = 0;
    parsed_exeinfo->size = 0;
    
    if (strcmp(prefs_get_version_exeinfo_match(),"parse")==0) 
    {
#ifdef HAVE_MKTIME
	struct tm t1;
	char *exe;
	char mask[MAX_EXEINFO_STR+1];
	char * marker;
	int size;
        char time_invalid = 0;

	if ((parsed_exeinfo->exe[0]=='\0') ||	   //happens when using war3-noCD and having deleted war3.org
	    (strcmp(parsed_exeinfo->exe,"badexe")==0)) //happens when AUTHREQ had no owner/exeinfo entry
	{
          xfree((void *)parsed_exeinfo->exe);
          xfree((void *)parsed_exeinfo);
          eventlog(eventlog_level_error,__FUNCTION__,"found empty exeinfo");
          return NULL;
	}

        memset(&t1,0,sizeof(t1));
        t1.tm_isdst = -1;

		char *exeinfo = xstrdup(_exeinfo);

        exeinfo    = strreverse((char *)exeinfo);
        if (!(marker     = strchr(exeinfo,' ')))
        {
	  xfree((void *)parsed_exeinfo->exe);
	  xfree((void *)parsed_exeinfo);
	  xfree((void*)exeinfo);
	  return NULL;
        }
	for (; marker[0]==' ';marker++); 

        if (!(marker     = strchr(marker,' ')))
        {
	  xfree((void *)parsed_exeinfo->exe);
	  xfree((void *)parsed_exeinfo);
	  xfree((void*)exeinfo);
	  return NULL;
	} 
	for (; marker[0]==' ';marker++);

        if (!(marker     = strchr(marker,' ')))
        {
	  xfree((void *)parsed_exeinfo->exe);
	  xfree((void *)parsed_exeinfo);
	  xfree((void*)exeinfo);
	  return NULL;
	}
        for (; marker[0]==' ';marker++);
        marker--;
        marker[0]  = '\0';
        marker++; 
        
        exe = xstrdup(marker);
		xfree((void*)exeinfo);
        xfree((void *)parsed_exeinfo->exe);
        parsed_exeinfo->exe = strreverse((char *)exe);

        exeinfo    = strreverse((char *)exeinfo);

	sprintf(mask,"%%02u/%%02u/%%u %%02u:%%02u:%%02u %%u");

	if (sscanf(exeinfo,mask,&t1.tm_mon,&t1.tm_mday,&t1.tm_year,&t1.tm_hour,&t1.tm_min,&t1.tm_sec,&size)!=7) {
            if (sscanf(exeinfo,"%*s %*s %u",&size) != 1)
            {

	      eventlog(eventlog_level_warn,__FUNCTION__,"parser error while parsing pattern \"%s\"",exeinfo);
	      xfree((void *)parsed_exeinfo->exe);
	      xfree((void *)parsed_exeinfo);
	      return NULL; /* neq */
            }
            time_invalid=1;
	}

       /* Now we have a Y2K problem :)  Thanks for using a 2 digit decimal years, Blizzard. */ 
       /* 00-79 -> 2000-2079 
	*             * 80-99 -> 1980-1999 
	*             * 100+ unchanged */ 
       if (t1.tm_year<80) 
	 t1.tm_year = t1.tm_year + 100; 

       if (time_invalid)
         parsed_exeinfo->time = -1;
       else 
         parsed_exeinfo->time = mktime(&t1);
       parsed_exeinfo->size = size;

#else
	eventlog(eventlog_level_error,__FUNCTION__,"Your system does not support mktime(). Please select another exeinfo matching method.");
	return NULL;
#endif
  }

  return parsed_exeinfo;
}