Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

ircsprintf.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: ircsprintf.c,v 1.17.2.1 2004/12/07 03:05:13 pneumatus Exp $
 */

#include "ircsprintf.h"
#include "memory.h"
#include "common.h"
#include "struct.h"
#include "h.h"

char ircnum[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char itoa_tab[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char xtoa_tab[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

int ircvsprintf(char *str, const char *pattern, va_list vl)
{
      const char *p = pattern;
      char *buf = str, *s, c;
      va_list ap;
      unsigned long i, u;
      int len = 0;

      VA_COPY(ap, vl);

      for (p = pattern; *p != '\0'; p++) {
            if (*p != '%') {
                  buf[len++] = *p;
                  continue;
            }

            p++;
            u = 0;

            switch (*p) {
                  case 's':
                        if ((s = va_arg(ap, char *)) == NULL) {
                              break;
                        }
                        while (*s != '\0') {
                              buf[len++] = *s++;
                        }
                        break;
                  case 'c':
                        buf[len++] = (char)va_arg(ap, int);
                        break;
                  case 'u':
                        p--;
                  case 'l':
                        u = (*(p + 1) == 'u') ? 1 : 0;
                        if (*(p + 1) == 'u' || *(p + 1) == 'd') {
                              p++;
                        }
                  case 'd':
                  case 'i':
                        i = va_arg(ap, unsigned long);
                        s = &ircnum[11];

                        if (!u && (i & 0x80000000)) {
                              buf[len++] = '-';
                              i = 0x80000000 - (i & ~0x80000000);
                        }

                        do {
                              *--s = itoa_tab[i % 10];
                              i /= 10;
                        } while (i != 0);

                        while (*s != '\0') {
                              buf[len++] = *s++;
                        }
                        break;
                  case 'B':
                  case 'b':
                        i = va_arg(ap, long);
                        buf[len++] = '!';
                        for (s = base64enc(i); *s != '\0'; s++) {
                              buf[len++] = *s;
                        }
                        break;
                  case 'X':
                  case 'x':
                  case 'n':
                        i = va_arg(ap, long);
                        s = &ircnum[11];

                        do {
                              c = xtoa_tab[i % 16];
                              if (*p == 'X' && (c >= 'a' || c <= 'f')) {
                                    c = ToUpper(c);
                              }

                              *--s = c;
                              i /= 16;
                        } while (i != 0);

                        while (*s != '\0') {
                              buf[len++] = *s++;
                        }
                        break;
                  default:
                        return vsprintf(str, pattern, vl);
                        break;
            }
      }
      buf[len] = '\0';
      return len;
}

int ircvsnprintf(char *str, size_t size, const char *pattern, va_list vl)
{
      const char *p = pattern;
      char *buf = str, *s, c;
      va_list ap;
      unsigned long i, u;
      int len = 0;

      VA_COPY(ap, vl);

      for (p = pattern; *p != '\0' && (len < size); p++) {
            if (*p != '%') {
                  buf[len++] = *p;
                  continue;
            }

            p++;
            u = 0;

            switch (*p) {
                  case 's':
                        if ((s = va_arg(ap, char *)) == NULL) {
                              break;
                        }
                        while (*s != '\0' && (len < size)) {
                              buf[len++] = *s++;
                        }
                        break;
                  case 'c':
                        buf[len++] = (char)va_arg(ap, int);
                        break;
                  case 'u':
                        p--;
                  case 'l':
                        u = (*(p + 1) == 'u') ? 1 : 0;
                        if (*(p + 1) == 'u' || *(p + 1) == 'd') {
                              p++;
                        }
                  case 'd':
                  case 'i':
                        i = va_arg(ap, unsigned long);
                        s = &ircnum[11];

                        if (!u && (i & 0x80000000)) {
                              buf[len++] = '-';
                              i = 0x80000000 - (i & ~0x80000000);
                        }

                        do {
                              *--s = itoa_tab[i % 10];
                              i /= 10;
                        } while (i != 0);

                        while (*s != '\0' && (len < size)) {
                              buf[len++] = *s++;
                        }
                        break;
                  case 'B':
                        buf[len++] = '!';
                  case 'b':
                        i = va_arg(ap, long);
                        for (s = base64enc(i); *s != '\0'; s++) {
                              buf[len++] = *s;
                        }
                        break;
                  case 'X':
                  case 'x':
                  case 'n':
                        i = va_arg(ap, long);
                        s = &ircnum[11];

                        do {
                              c = xtoa_tab[i % 16];
                              if (*p == 'X' && (c >= 'a' || c <= 'f')) {
                                    c = ToUpper(c);
                              }

                              *--s = c;
                              i /= 16;
                        } while (i != 0);

                        while (*s != '\0' && (len < size)) {
                              buf[len++] = *s++;
                        }
                        break;
                  default:
                        return vsprintf(str, pattern, vl);
                        break;
            }
      }
      buf[len] = '\0';
      return len;
}

int ircsprintf(char *str, const char *pattern, ...)
{
      int len;
      va_list vl;

      va_start(vl, pattern);
      len = ircvsprintf(str, pattern, vl);
      va_end(vl);

      return len;
}

int ircsnprintf(char *str, size_t size, const char *pattern, ...)
{
      int len;
      va_list vl;

      va_start(vl, pattern);
      len = ircvsnprintf(str, size, pattern, vl);
      va_end(vl);

      return len;
}

Generated by  Doxygen 1.6.0   Back to index