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

util.c

/*
 * YICS: Connect a FICS interface to the Yahoo! Chess server.
 * Copyright (C) 2004  Chris Howie
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _YICS_POSIX
#include <sys/timeb.h>
#endif
#include "util.h"
#include "console.h"
#include "sockets.h"
#include "types.h"
#include "vars.h"

char *ltrim(char *str) {
      char *start = str;

      while ((*start == ' ') || (*start == '\n'))
            start++;

      memmove(str, start, strlen(start) + 1);

      return str;
}

char *rtrim(char *str) {
      char *end = str;

      while (*end)
            end++;

      end--;

      while ((end >= str) && ((*end == ' ') || (*end == '\n')))
            end--;

      end[1] = '\0';

      return str;
}

String *ltrimString(String *str) {
      int i = 0;

      while ((i < str->length) && (str->string[i] == ' '))
            i++;

      if (i == 0) /* nothing to trim */
            return str;

      str->length -= i;
      memmove(str->string, &str->string[i], str->length + 1);
      /* str->string = realloc(str->string, str->length); */

      return str;
}

String *rtrimString(String *str) {
      int i = str->length - 1;

      while ((i >= 0) && (str->string[i] == ' '))
            i--;

      if (i == str->length - 1)     /* nothing to trim */
            return str;

      str->length = i + 1;
      str->string[i + 1] = '\0';
      /* str->string = realloc(str->string, i + 1); */

      return str;
}

/* TODO: Rename these subroutines and add real UTF-8 encoding/decoding. */

char *packutf(char *dest, const char *str, unsigned short length) {
      memmove(&dest[2], str, length);

      length = htons(length);
      memcpy(dest, &length, 2);

      return dest;
}

String *packutfString(String *dest, const String *src) {
      char *tmp;
      String *temp;

      if ((dest == NULL) || (src == NULL))
            return NULL;

      temp = StringCopy(StringNull(), src);
      if (temp == NULL)
            return NULL;

      tmp = realloc(dest->string, src->length + 2);
      if (tmp == NULL) {
            StringFree(temp);
            return NULL;
      }
      dest->string = tmp;

      packutf(dest->string, temp->string, (unsigned short)temp->length);
      dest->length = temp->length + 2;

      StringFree(temp);

      return dest;
}

String *packutfStringP(String *dest, const String *src) {
      char *tmp;

      if ((dest == NULL) || (src == NULL))
            return NULL;

      tmp = realloc(dest->string, dest->length + src->length + 2);
      if (tmp == NULL)
            return NULL;
      dest->string = tmp;

      packutf(&dest->string[dest->length], src->string, (unsigned short)src->length);
      dest->length += src->length + 2;

      return dest;
}

char *unpackutf(char *dest, const char *src) {
      short int length;

      memcpy(&length, src, 2);
      length = ntohs(length);

      memmove(dest, src + 2, length);

      dest[length] = '\0';

      return dest;
}

String *unpackutfString(String *dest, const String *src) {
      short int length;
      String *temp;
      char *ctmp;

      if ((dest == NULL) || (src == NULL))
            return NULL;

      memcpy(&length, src->string, 2);
      length = ntohs(length);
      if (length > src->length - 2)
            length = (unsigned short)(src->length - 2);

      temp = StringCopy(StringNull(), src);     /* allows in-place unpacking */
      if (temp == NULL)
            return NULL;

      ctmp = realloc(dest->string, length + 1);
      if (ctmp == NULL) {
            StringFree(temp);
            return NULL;
      }
      dest->string = ctmp;

      memcpy(dest->string, temp->string + 2, length);
      dest->string[length] = '\0';
      dest->length = length;

      StringFree(temp);

      return dest;
}

String *unpackutfStringP(String *dest, String *src) {
      String *tmp;

      if ((dest == NULL) || (src == NULL))
            return NULL;

      tmp = StringCopy(StringNull(), src);
      if (tmp == NULL)
            return NULL;

      unpackutfString(dest, src);
      StringSet(src, &tmp->string[dest->length + 2],
            src->length - dest->length - 2);

      StringFree(tmp);

      return dest;
}

#define CASE_DIFFERENCE ('a' - 'A')

char *lowercase(char *str) {
      char *sp = str;

      while (*sp) {
            if ((*sp >= 'A') && (*sp <= 'Z'))
                  *sp += CASE_DIFFERENCE;
            sp++;
      }

      return str;
}

char *uppercase(char *str) {
      char *sp = str;

      while (*sp) {
            if ((*sp >= 'a') && (*sp <= 'z'))
                  *sp -= CASE_DIFFERENCE;
            sp++;
      }

      return str;
}

int istrcmp(const char *s1, const char *s2) {
      char a, b;

      while ((*s1 != '\0') || (*s2 != '\0')) {
            a = *s1;
            b = *s2;

            if ((a >= 'a') && (a <= 'z'))
                  a -= CASE_DIFFERENCE;

            if ((b >= 'a') && (b <= 'z'))
                  b -= CASE_DIFFERENCE;

            if (a < b)
                  return -1;
            if (a > b)
                  return 1;

            s1++;
            s2++;
      }

      return 0;
}

int columns(char **items) {
      int maxlength = 0, current = 0, count = 0;
      int length, columns, i, j;
      int percolumn;
      float per;

      if (items[0] == NULL)
            return 0;

      for (i = 0; items[i] != NULL; i++) {
            length = strlen(items[i]);
            if (length > maxlength)
                  maxlength = length;
            count++;
      }

      maxlength += 1;
      columns = 79 / maxlength;
      if (columns == 0)
            columns = 1;

      percolumn = (int) (per = (float) count / (float) columns);
      if (per > percolumn)
            percolumn++;

      for (i = 0; i < percolumn; i++) {
            for (j = 0; j < columns; j++) {
                  current = i + (j * percolumn);
                  if (current < count)
                        iprintf("%-*s", maxlength, items[current]);
            }
            iprint("\n");
      }

      return count;
}

bool isnumeric(const char *str) {
      bool gotone = false;

      while (*str != '\0') {
            if ((*str < '0') || (*str > '9'))
                  return false;
            gotone = true;
            str++;
      }

      return gotone;
}

/* For sorting an array of (char *) */
int s_strcmp(const void *a, const void *b) {
      return strcmp(*((const char **) a), *((const char **) b));
}

/* Same, for case insensitive sort. */
int s_istrcmp(const void *a, const void *b) {
      return istrcmp(*((const char **) a), *((const char **) b));
}

i64_t gettimeofdayll() {
      struct timeval tv;

      gettimeofday(&tv, NULL);
      return tv2ll(tv);
}

i64_t timeleft(Table *t, int color) {
      if (t->clock[color] == 0)
            return 0;

      if (t->clock[color] < 0)
            return -t->clock[color];

      return t->clock[color] - gettimeofdayll();
}

char *fmttime_ms(i64_t time) {
      static char buf[32];

      if (variables[VAR_MS].number)
            snprintf(buf, sizeof(buf), "%d:%02d.%03d",
                        (int)(time / 60000),
                        (int)((time / 1000) % 60),
                        (int)(time % 1000));
      else
            snprintf(buf, sizeof(buf), "%d:%02d",
                        (int)(time / 60000),
                        (int)((time / 1000) % 60));

      return buf;
}

#if !defined (__GNUC__)
int optind = 0;
static char * nextchar = NULL;
char * optarg = NULL;

int getopt (int argc, char * argv[], const char * optstr) {
      int j;

      if (optind >= argc)
            return -1;

      if (nextchar == NULL || nextchar[0] == '\0') {
            optind++;
            if (optind >= argc)
                  return -1;
            if (argv[optind][0] != '-' || argv[optind][1] == '\0')
                  return -1;
            if (argv[optind][1] == '-' && argv[optind][2] == '\0')
                  return -1;
            nextchar = argv[optind] + 1;
      }

      for (j=0; optstr[j] != '\0'; j++) {
            if (optstr[j] == ':')
                  continue;
            if (nextchar[0] == optstr[j]) {
                  nextchar++;
                  if (optstr[j+1] == ':') {
                        /* :: is currently not supported */
                        if (nextchar[0] != '\0')
                              optarg = nextchar;
                        else if (optind == argc)
                              /* Is this correct? */
                              optarg = "";
                        else {
                              optind++;
                              optarg = argv[optind];
                        }
                        nextchar = NULL;
                  }
                  return optstr[j];
            }
      }

      return -1;
}
#endif

#ifndef _YICS_POSIX
int gettimeofday(struct timeval * p, void * z) {
struct _timeb timebuf;

      if (p == NULL) return -__LINE__;
      z = z;
      _ftime(&timebuf);
      p->tv_sec  = timebuf.time;
      p->tv_usec = timebuf.millitm;
      return 0;
}
#endif

#define bswap_64(x) ((unsigned i64_t)(htonl((unsigned long)(x))) << 32) | \
                ((unsigned i64_t)(htonl((unsigned long)(((unsigned i64_t)(x)) >> 32))))

enum endian {
      ES_UNKNOWN = 0,
      ES_LE,
      ES_BE
};

static enum endian es = ES_UNKNOWN;

#define testEndianSwap() ((htons(1) == 1) ? ES_BE : ES_LE)

unsigned i64_t htonll(unsigned i64_t v) {
      if (es == ES_UNKNOWN)
            es = testEndianSwap();

      if (es == ES_LE)
            return bswap_64(v);

      return v;
}

Generated by  Doxygen 1.6.0   Back to index