Ejemplo n.º 1
0
int list_cmd(char *args){
	// todo get page number from strtok
	size_t cmd_len = cgc_strlen(args);
	char * pg_num_txt = args;//\\\strtok(NULL, cmd_len);
	if(pg_num_txt == NULL){
		return CMDBADARG;
	}
	if(buf_is_numeric(pg_num_txt) != 1){
		return CMDBADNUMERIC;
	}

	int pg_num_i = atoi(pg_num_txt);
	if(pg_num_i < 0)
		return CMDNEGNUMERIC;

	return transmit_compound_list_page(pg_num_i);
}
Ejemplo n.º 2
0
char *strncat ( char *dest, const char *src, size_t n )
{
    size_t dest_len = cgc_strlen(dest);
    size_t i;

    if (dest == NULL || src == NULL)
    {
      return(dest);
    }
    for (i = 0; i < n && src[i] != '\0'; i++)
    {
      dest[dest_len+i] = src[i];
    }
    dest[dest_len+i] = '\0';

    return(dest);
}
Ejemplo n.º 3
0
compounds_sample_t *sample_compounds(const char *seed, const size_t sample_size){
	if(sample_size > N_FORMULAS-1)
		return NULL;
	unsigned int h = crazy_hash(seed, cgc_strlen(seed), 0xcafeb4b4);

	compounds_sample_t *sample = alloc_sample_st(sample_size);
	// todo check alloc
	if(sample == NULL)
		return NULL;
	for(int i =0; i < sample_size; ++i){
		set_sample_at_idx(sample, i,  (h % (N_FORMULAS-1)));
		
		h = crazy_hash((const char *) &h, sizeof(h), h);
	}

	return sample;
}
Ejemplo n.º 4
0
int input_matrix(matrix_t *m, char *buf, int buf_size)
{
    if (resize_matrix(m, buf, buf_size) == ERROR)
        return ERROR;

    int num_cells = m->num_rows * m->num_cols;
    int cell_val = 0, retval = 0;
    char *num_str = NULL;

    retval = readline(buf, buf_size);
    if (retval == ERROR || retval == FAIL)
    {
        printf("Bad Input\n");
        return retval;
    }

    int number_count = 1;
    int i, j;

    for (i = 0; i < cgc_strlen(buf); i++)
    {
        if (buf[i] == ' ')
            number_count++;
    }

    if (number_count != num_cells)
    {
        printf("Bad Input\n");
        return FAIL;
    }

    for (i = 0; i < m->num_rows; i++)
    {
        for (j = 0; j < m->num_cols; j++)
        {
            num_str = strsep(&buf, " ");
            if (!num_str)
                return ERROR;

            cell_val = strtol(num_str, NULL, 10);
            m->set_cell(m, i, j, cell_val);
        }
    }

    return SUCCESS;
}
Ejemplo n.º 5
0
static int addvar(var_t *var, char *name, varenum type) {

    if (!(var->name = calloc(cgc_strlen(name)+1)))
        return ERRNOMEM;

    strcpy(var->name, name);

    var->type = type;
    if (global_nspace.last)
        global_nspace.last->next = var;
    global_nspace.last = var;
    if (!global_nspace.first)
        global_nspace.first = var; 
    var->next = NULL; //just to be safe
    global_nspace.count++;
    return 0;
}
Ejemplo n.º 6
0
/* 
   help command
 */
int cgc_HelpHandler() {
	ShellCmds *c;
	int len;

	c = cgc_cmds;
	while (c->command) {
		cgc_printf("@s", c->command);
		len = 20-cgc_strlen(c->command);
		while (len-- > 0) {
			cgc_printf(" ");
		}
		cgc_printf("@s\n", c->help);
		c++;
	}

	return(0);
}
Ejemplo n.º 7
0
message *add_random_message(mail_queue *mq) {
    message *m = calloc(sizeof(message));
    m->sender = pick_address();
    m->recipient = pick_address();
    m->subject = gen_random_string(5, 32);
    m->data = gen_random_string(5,256);
    m->data_length = cgc_strlen(m->data);

    if (mq->root != NULL) {
        message *next = mq->root;
        while (next->next != NULL) {
            next = next->next;
        }
        next->next = m;
    }
    return m;
}
Ejemplo n.º 8
0
// examine str to determine if it can be converted to a number
// return 0 if yes and 0/positive, 1 if yes and negative, -1 if no.
int is_numeric(const char *str) {
    int sign = 0;

    if (cgc_strlen(str) == 0)
        return -1;

    if (*str == '-') {
        str++;
        sign = 1;
    }

    while (*str != '\0') {
        if (*str < '0' || *str > '9')
            return -1;
        str++;
    }
    return sign;
}
Ejemplo n.º 9
0
int bloomy_check(bloomy_t *bloomy, const char *buf)
{
  uint8_t bit;
  unsigned int i, n;
  if (bloomy == NULL || bloomy->bits == NULL)
    return -1;
  for (i = 0; i < sizeof(bloomy->hashes) / sizeof(hash_t); ++i)
  {
    if (bloomy->hashes[i])
    {
      n = (bloomy->hashes[i](buf, cgc_strlen(buf)) % bloomy->size);
      bit = (bloomy->bits[n/8] & (1 << (n%8)));
      if (!bit)
        return 0;
    }
  }
  return 1;
}
Ejemplo n.º 10
0
int init(int rot)
{
  int ret = 0;
  size_t numWords = NUM_WORDS;

  //first allocate enough space for the wordlist
  ret = allocate( sizeof(gSeedWords), 0, (void**)(&gWords));
  if (ret != 0)
  {
    return (ret);
  }

  //now calculate how many bytes we need to store the words themselves
  size_t total = 0;
  int i = 0;
  for (i = 0; i < numWords; i++)
  {
    total += cgc_strlen(gSeedWords[i]);
    total += 1; //for the NULL character
  }
 
  ret = allocate(total, 0, (void**)(&gWordData));
  if (ret != 0)
  {
    return (ret);
  } 

  //now that we have both we can fill in the data  
  size_t temp = 0;
  char* pTemp = gWordData;
  for (i = 0; i < numWords; i++)
  {
    gWords[i] = pTemp;
    pTemp += strrotcpy(pTemp, gSeedWords[i], rot);
    pTemp += 1; //for the NULL character
  }
  
  for ( ; i < (PAGE_SIZE / sizeof(char*)); i++)
  {
    gWords[i] = 0;
  }

  return (0);
}
Ejemplo n.º 11
0
int getopt(int argc, char **argv, char *optstring, int *opt_index) {
  
  int option = -1;
  if (*opt_index >= argc || !argv[*opt_index]) {
    goto DONE;
  }
  for (int i = 0; i < cgc_strlen(optstring); i++) {
    if (*argv[*opt_index] == optstring[i]) {
      option = optstring[i];
      (*opt_index)++;
      goto DONE;
    }
  }
  (*opt_index)++;
  option = 0;
    
DONE:
  return option;
}
Ejemplo n.º 12
0
/**
* Destroy the dungeon and free all memory
*
* @param dungeon A pointer to the dungeon structure
*
* @return None
*/
void destroyDungeon(Dungeon* dungeon) {
    size_t len;

    bzero((char *)&dungeon->moveTypes, sizeof(Moves));
    if(dungeon->moveList) {
        len = cgc_strlen(dungeon->moveList);
        bzero(dungeon->moveList, len);
        free(dungeon->moveList);
    }
    dungeon->moveList = NULL;

    Room* nextRoom;
    for(Room* room=dungeon->start; room!=NULL; room=nextRoom) {
        nextRoom = (Room *)room->next;
        destroyRoom(&room->contents);
        free(room);
    }

}
Ejemplo n.º 13
0
size_t strcat( char *dest, char* src )
{
    size_t length = 0;
    size_t start = 0;

    if ( dest == NULL || src == NULL) {
        goto end;
    }

    start = cgc_strlen( dest );

    for ( ; src[length] != 0x00 ; start++, length++ ) {
        dest[start] = src[length];
    }

    length = start;
end:
    return length;
}
Ejemplo n.º 14
0
static char *
append_to_path(char *path, const char *toappend)
{
    char *tmp;
    size_t len;

    len = cgc_strlen(path);
    if ((tmp = realloc(path, len + MAX_FILE_NAME_LENGTH + 2)) == NULL) {
        free(path);
        return NULL;
    }
    path = tmp;

    strcat(path, "/");
    strncat(path, toappend, MAX_FILE_NAME_LENGTH);
    path[len + MAX_FILE_NAME_LENGTH + 1] = '\0';

    return path;
}
Ejemplo n.º 15
0
static cell_t *get_cell(char *cell_id)
{
    char row_str[3];
    char col_str[3];
    int row_idx = 0, col_idx = 0;
    int i, len;

    if (get_rowcol(cell_id, row_str, col_str, '\0') == -1)
        return NULL;

    len = cgc_strlen(row_str);
    for (i = 0; i < len; i++)
        row_idx += ((row_str[i] - 64) * pow(26, len - i - 1));

    --row_idx;
    col_idx = strtol(col_str, NULL, 10);
    return &g_sheet[row_idx][col_idx];

}
Ejemplo n.º 16
0
int run_viewscript(char *script) {

    char *cur = script;
    char **lines;
    int res = 0;
    int idx = 0;
    int count = 0;
    //this is properly null-terminated by main()
    int len = cgc_strlen(script);

    if (len > MAXSCRIPTSIZE)
        return ERRTOOBIG;

    while(*cur) {
        if (*cur == '\n')
            count++;
        cur++;
    }

    if (count == 0)
        return ERRSHORT;

    if (!(lines = calloc((count+1)*sizeof(char *))))
        return ERRNOMEM;

    lines[0] = strtok(script,'\n');
    #ifdef PATCHED
    while (idx < count && (lines[++idx] = strtok(NULL,'\n')));
    #else 
    while ((lines[++idx] = strtok(NULL,'\n')));
    #endif
    for (idx = 0; idx < count; idx++) {
        if ((res = runcmd(lines[idx])))
            return res;
    }

    free(lines);

    LOG("Done.");

    return 0;
}
Ejemplo n.º 17
0
list *str_to_wordlists(const char *s)
{
    size_t len = cgc_strlen(s);
    char *x = calloc(1, len + 1);
    strncpy(x, s, len);
    x[len] = '\0';

    list *words = split_words(x, 1);
    if (!words)
        return NULL;

    free(x);

#define CHAIN_LENGTH 2
    list *chunks = chunk_words(words, CHAIN_LENGTH);
    if (!chunks)
        return NULL;

    return chunks;
}
Ejemplo n.º 18
0
int cgc_rev_cmd(const char *s)
{
  char *r = cgc_calloc(1, cgc_strlen(s) + 1);
  cgc_strcpy(r, s);
  if (!cgc_strchr(r, '\0'))
    return -1;

  char *start = r;
  char *end = cgc_strchr(r, '\0') - 1;
  while (start < end) {
    *start ^= *end;
    *end ^= *start;
    *start ^= *end;
    start++, end--;
  }

  cgc_printf("case > %s\n", r);
  cgc_free(r);
  return 0;
}
Ejemplo n.º 19
0
static int cgc_set_field(interp_t *interp, unsigned int num, const char *value)
{
    char **fields, *copy;
    if (num > MAX_FIELDS)
        return 0;

    if (interp->fields == NULL && num > 0)
    {
        if (!cgc_read_fields(interp))
            return 0;
    }

    if (num > interp->num_fields)
    {
        fields = cgc_realloc(interp->fields, num * sizeof(char *));
        if (fields == NULL)
            return 0;
        interp->fields = fields;
        cgc_memset(&interp->fields[interp->num_fields], 0, sizeof(char *) * (num - interp->num_fields));
        interp->num_fields = num;
    }

    if (num == 0)
    {
        if (cgc_strlen(value) >= BUF_SIZE - 1)
            return 0;
        cgc_strcpy(interp->buf, value);
        free_fields(interp);
        interp->field0 = interp->buf;
    }
    else
    {
        copy = cgc_strdup(value);
        if (copy == NULL)
            return 0;

        interp->fields[num-1] = copy;
        interp->field0 = NULL;
    }
    return 1;
}
Ejemplo n.º 20
0
static int newview(char *name, char *arg) {
    viewvar_t *v = NULL;
    arrvar_t *a = NULL;
    int i = 0;
    int res = 0;

    char *type = strtok(NULL,' ');

    if (!type || cgc_strlen(type) == 0)
        return ERRNOTYPE;

    if (!(a = (arrvar_t*)getvar(arg))) 
        return ERRNOSUCHVAR;

    if (a->v.type != ARRTYPE) 
        return ERRWRONGTYPE;

    if (!(v = calloc(sizeof(viewvar_t))))
        return ERRNOMEM;

    for (i=0; i < sizeof(viewtypes)/sizeof(viewtype_t); i++) {
        if (streq(type,viewtypes[i].name)) {
            v->view = &viewtypes[i];
            break;
        }
    }

    if (!v->view) {
        free(v);
        return ERRNOSUCHTYPE;
    }

    v->arr = a;

    res = addvar((var_t*)v, name, VIEWTYPE);

    if (res)
        free(v);

    return res;
}
Ejemplo n.º 21
0
void sell()
{
    char *name;
    char tmp[50];
    size_t bytes;
    record rec;
    item_details d;

    name = malloc(200);
    read_until(STDIN, name, 200, '\n');
    read_until(STDIN, tmp, sizeof(tmp), '\n');
    d.price = strtol(tmp, NULL, 10);
    read_until(STDIN, tmp, sizeof(tmp), '\n');
    d.count = strtoul(tmp, NULL, 10);
    
    rec.k.data.count = cgc_strlen(name) + 1;
    rec.k.data.data = (opaque *)name;
    rec.data.count = sizeof(d);
    rec.data.data = (opaque *)&d;
    db_insert(rec);
}
Ejemplo n.º 22
0
static char *get_no_ws_line(char *line)
{
    if (line == NULL)
        return NULL;

    size_t size = cgc_strlen(line) + 1, i;
    char *nline = NULL, *iter;
    nline = malloc(size);
    if (nline == NULL)
        return NULL;

    cgc_memset(nline, 0, size);
    iter = nline;
    for (i = 0; i < size; i++) {
        if (strchr(" \t\n", line[i]) == NULL)
            *iter++ = line[i];
    }

    return nline;

}
Ejemplo n.º 23
0
static int compare_line(lc_t *lline, lc_t *rline, int ignore_ws) {
    if (ignore_ws) {
        if (cgc_strlen(lline->no_ws_line) && cgc_strlen(rline->no_ws_line)
                && cgc_strlen(lline->no_ws_line) == cgc_strlen(rline->no_ws_line)
                && lline->no_ws_lhash.hash1 == rline->no_ws_lhash.hash1
                && lline->no_ws_lhash.hash2 == rline->no_ws_lhash.hash2)
        {
            char *left = lline->no_ws_line, *right = rline->no_ws_line;
            return strcmp(left, right);
        }
    } else {
        if (cgc_strlen(lline->pline) && cgc_strlen(rline->pline)
                && cgc_strlen(lline->pline) == cgc_strlen(rline->pline)
                && lline->lhash.hash1 == rline->lhash.hash1
                && lline->lhash.hash2 == rline->lhash.hash2) {

            char *left = lline->pline, *right = rline->pline;
            return strcmp(left, right);
        }
    }

    return -1;
}
Ejemplo n.º 24
0
int puts( const char *s )
{
	size_t tx_bytes;
	size_t s_len;
	size_t total_sent = 0;

	s_len = cgc_strlen(s);

	while (total_sent != s_len) {
		if ( transmit( STDOUT, s+total_sent, s_len-total_sent, &tx_bytes ) != 0 ) {
			return (-1);
		}
		if (tx_bytes == 0) {
			return (-1);
		}
		total_sent += tx_bytes;
	}

	putchar( '\n' );

	return (0);
}
Ejemplo n.º 25
0
char *strstr( char *str, char *sub, size_t len ) 
{
	size_t index = 0;
	size_t stlen = 0;

	if ( str == NULL || sub == NULL || len == 0 ) {
		return NULL;
	}

	stlen = cgc_strlen( sub );

	while ( index < ( len - ( stlen-1)  ) ) {
		if ( str[index] == sub[0] ) {
			if ( strncmp( str + index, sub, stlen ) == 0 ) {
				return str + index;
			}
		} 
		index++;
	}

	return NULL;
}
Ejemplo n.º 26
0
int cgc_push_copy(stack_t **stack, char *data, cgc_size_t size)
{
    if (data == NULL)
        return -1;

    int data_len = cgc_strlen(data) + 1;
    if (data_len > size)
        return -1;

    stack_t *top = cgc_malloc(sizeof(stack_t));
    top->data = cgc_malloc(data_len);
    cgc_memcpy(top->data, data, data_len);

    if(*stack == NULL) {
        top->next = NULL;
        *stack = top;
    } else {
        top->next = *stack;
        *stack = top;
    }

    return 0;
}
Ejemplo n.º 27
0
int main(void) {
    size_t cmd_buf_sz = 20;
    char buf[cmd_buf_sz];
    jokedb_struct jokedb;

    // load with default jokes (array of joke_struct's)
    load_default_jokes(&jokedb);

    // send INITMSG
    send(INITMSG, cgc_strlen(INITMSG));
    
    // send MENU
    do_menu();
    
    while (1) {
        // send ROOTPROMPT
        cgc_memset(buf, '\0', cmd_buf_sz);
        prompt_user(ROOTPROMPT, buf, cmd_buf_sz);

        // receive user input and check for COMMAND
        if (streq(buf, "LIST") == 0) {
            do_list(&jokedb);
        } else if (streq(buf, "ADD") == 0) {
            do_add(&jokedb);
        } else if (streq(buf, "COUNT") == 0) {
            do_count(&jokedb);
        } else if (streq(buf, "SHOW") == 0) {
            do_show(&jokedb);
        } else if (streq(buf, "HELP") == 0) {
            do_help();
        } else if (streq(buf, "QUIT") == 0) {
            do_quit();
        } else {
            do_menu();
        }
    }
}
Ejemplo n.º 28
0
static int
xor_login(char *name)
{
    size_t secret_size = sizeof(secret) - 1;
    size_t token_size, sig_size, signed_token_size;
    char *token, *signed_token;
    char sig[secret_size];

    if ((token = make_token(name)) == NULL)
        return -1;

    token_size = cgc_strlen(token);
    signed_token_size = token_size + 2 * secret_size + 2;

    if ((signed_token = realloc(token, signed_token_size)) == NULL) {
        free(token);
        return -1;
    }

    if ((sig_size = xor_sig(signed_token, token_size, sig)) == 0) {
        free(signed_token);
        return -1;
    }

    signed_token[token_size] = '|';
    bin_to_hex(signed_token + token_size + 1, sig, sig_size);
    signed_token[signed_token_size - 1] = '\n';

    if (write_all(STDOUT, signed_token, signed_token_size) != signed_token_size)
        return -1;

    cgc_memset(sig, '\x00', sig_size);
    cgc_memset(signed_token, '\x00', signed_token_size);
    free(signed_token);

    return 0;
}
Ejemplo n.º 29
0
static int
adler32_login(char *name)
{
    size_t token_size, sig_size, signed_token_size;
    char *token, *signed_token;
    unsigned int sig;

    if ((token = make_token(name)) == NULL)
        return -1;

    token_size = cgc_strlen(token);
    signed_token_size = token_size + 2 * sizeof(sig) + 2;

    if ((signed_token = realloc(token, signed_token_size)) == NULL) {
        free(token);
        return -1;
    }

    if ((sig_size = adler32_sig(signed_token, token_size, (char *)(&sig))) == 0) {
        free(signed_token);
        return -1;
    }

    signed_token[token_size] = '|';
    bin_to_hex(signed_token + token_size + 1, &sig, sig_size);
    signed_token[signed_token_size - 1] = '\n';

    if (write_all(STDOUT, signed_token, signed_token_size) != signed_token_size)
        return -1;

    sig = 0;
    cgc_memset(signed_token, '\x00', signed_token_size);
    free(signed_token);

    return 0;
}
Ejemplo n.º 30
0
//func is responsible for outputing the given character
//user is a pointer to data required by func
static void printf_core(unsigned int (*func)(char, void *, int), void *user, const char *format, va_list ap) {
   int state = STATE_NORMAL;
   int flags;
   int digit_count = 0;
   int value = 0;
   char ch;
   int arg_count = 0;
   int width_value;
   int prec_value;
   int field_arg;
   int length;
   char **args = (char**)ap;
   for (ch = *format++; ch; ch = *format++) {
      switch (state) {
         case STATE_NORMAL:
            if (ch == '%') {
               state = STATE_PERCENT;
            }
            else if (ch == '\\') {
               state = STATE_ESCAPE;
            }
            else {
               func(ch, user, 0);
            }
            break;
         case STATE_ESCAPE:
            switch (ch) {
               case 'n':
                  func('\n', user, 0);
                  break;
               case 't':
                  func('\t', user, 0);
                  break;
               case 'r':
                  func('\r', user, 0);
                  break;
               case 'b':
                  func('\b', user, 0);
                  break;
               case 'f':
                  func('\f', user, 0);
                  break;
               case 'v':
                  func('\v', user, 0);
                  break;
               case '\\': case '\'': case '"':
                  func(ch, user, 0);
                  break;
               case 'x':
                  state = STATE_HEX;
                  digit_count = 0;
                  value = 0;
                  break;
               default:
                  if (ch > '0' && ch < '8') {
                     state = STATE_OCTAL;
                     digit_count = 1;
                     value = ch - '0';
                  }
                  else {
                     func(*format, user, 0);
                  }
                  break;
            }
            if (state == STATE_ESCAPE) {
               state = STATE_NORMAL;
            }
            break;
         case STATE_PERCENT:
            if (ch == '%') {
               func(ch, user, 0);
               state = STATE_NORMAL;
            }
            else {
               state = STATE_NARG;
               flags = 0;
               format--;
            }
            break;
         case STATE_OCTAL:
            if (ch > '0' && ch < '8' && digit_count < 3) {
               digit_count++;
               value = value * 8 + (ch - '0');
               if (digit_count == 3) {
                  func(value, user, 0);
                  state = STATE_NORMAL;
               }
            }
            else {
               func(value, user, 0);
               state = STATE_NORMAL;
               format--;
            }
            break;
         case STATE_HEX:
            if (isxdigit(ch) && digit_count < 2) {
               digit_count++;
               value = value * 16 + hex_value_of(ch);
               if (digit_count == 2) {
                  func(value, user, 0);
                  state = STATE_NORMAL;
               }
            }
            else {
               func(value, user, 0);
               state = STATE_NORMAL;
               format--;
            }
            break;
         case STATE_NARG:
            width_value = -1;
            prec_value = -1;
            flags = 0;
            length = 0;
            field_arg = -1;
            if (ch == '0') {
               format--;
               state = STATE_FLAGS;
               break;
            }
            if (isdigit(ch)) {
               //could be width or could be arg specifier or a 0 flag
               //width and arg values don't start with 0
               width_value = 0;
               while (isdigit(ch)) {
                  width_value = width_value * 10 + (ch - '0');
                  ch = *format++;
               }
               if (ch == '$') {
                  field_arg = width_value - 1;
                  width_value = 0;
                  state = STATE_FLAGS;
               }
               else {
                  //this was a width
                  format--;
                  state = STATE_PRECISION;
               }
            }
            else {
               format--;
               state = STATE_FLAGS;
            }
            break;
         case STATE_FLAGS:
            switch (ch) {
               case '\'':
                  flags |= FLAGS_TICK;
                  break;
               case '-':
                  flags |= FLAGS_LEFT;
                  break;
               case '+':
                  flags |= FLAGS_SIGN;
                  break;
               case ' ':
                  flags |= FLAGS_SPACE;
                  break;
               case '#':
                  flags |= FLAGS_HASH;
                  break;
               case '0':
                  flags |= FLAGS_ZERO;
                  break;
               default:
                  format--;
                  if ((flags & (FLAGS_ZERO | FLAGS_LEFT)) == (FLAGS_ZERO | FLAGS_LEFT)) {
                     //if both '-' and '0' appear, '0' is ignored
                     flags &= ~FLAGS_ZERO;
                  }
                  state = STATE_WIDTH;
                  break;
            }
            break;
         case STATE_WIDTH:
            if (ch == '*') {
               ch = *format++;
               int width_arg = 0;
               if (isdigit(ch)) {
                  while (isdigit(ch)) {
                     width_arg = width_arg * 10 + (ch - '0');
                     ch = *format++;
                  }
                  width_arg--;
                  if (ch != '$') {
                     //error
                  }
               }
               else {
                  width_arg = arg_count++;
                  format--;
               }
               width_value = (int)args[width_arg];
            }
            else if (isdigit(ch)) {
               width_value = 0;
               while (isdigit(ch)) {
                  width_value = width_value * 10 + (ch - '0');
                  ch = *format++;
               }
               format--;
            }
            else {
               //no width specified
               format--;
            }
            state = STATE_PRECISION;
            break;
         case STATE_PRECISION:
            if (ch == '.') {
               //have a precision
               ch = *format++;
               if (ch == '*') {
                  ch = *format++;
                  int prec_arg = 0;
                  if (isdigit(ch)) {
                     while (isdigit(ch)) {
                        prec_arg = prec_arg * 10 + (ch - '0');
                        ch = *format++;
                     }
                     prec_arg--;
                     if (ch != '$') {
                        //error
                     }
                  }
                  else {
                     prec_arg = arg_count++;
                     format--;
                  }
                  prec_value = (int)args[prec_arg];
               }
               else if (isdigit(ch)) {
                  prec_value = 0;
                  while (isdigit(ch)) {
                     prec_value = prec_value * 10 + (ch - '0');
                     ch = *format++;
                  }
                  format--;
               }
               else {
                  //no precision specified
                  format--;
               }
            }
            else {
               //no precision specified
               format--;
            }
            state = STATE_LENGTH;
            break;
         case STATE_LENGTH:
            switch (ch) {
               case 'h':
                  length = LENGTH_H;
                  if (*format == 'h') {
                     length++;
                     format++;
                  }
                  break;
               case 'l':
                  length = LENGTH_L;
                  if (*format == 'l') {
//                     length++;
                     format++;
                  }
                  break;
               case 'j':
                  length = LENGTH_J;
                  break;
               case 'z':
                  length = LENGTH_Z;
                  break;
               case 't':
                  length = LENGTH_T;
                  break;
               case 'L':
                  length = LENGTH_CAPL;
                  break;
               default:
                  format--;
                  break;
            }
            state = STATE_CONVERSION;
            break;
         case STATE_CONVERSION: {
            char num_buf[32];
            char *num_ptr;
            int use_caps = 1;
            int sign;
            int val;
            // long long llval;
            if (field_arg == -1) {
               field_arg = arg_count++;
            }
            switch (ch) {
               case 'd': case 'i': {
                  int len;
                  switch (length) {
                     case LENGTH_H:
                        val = (short)(int)args[field_arg];
                        sign = val < 0;
                        if (sign) {
                           val = -val;
                        }
                        num_ptr = r_utoa(val, num_buf);
                        break;
                     case LENGTH_HH:
                        val = (char)(int)args[field_arg];
                        sign = val < 0;
                        if (sign) {
                           val = -val;
                        }
                        num_ptr = r_utoa(val, num_buf);
                        break;
                     case LENGTH_L:
                     default:
                        val = (long)args[field_arg];
                        sign = val < 0;
                        if (sign) {
                           val = -val;
                        }
                        num_ptr = r_utoa(val, num_buf);
                        break;
                  }
                  len = num_ptr - num_buf + 1;
                  if (width_value == -1) {
                     //by default min length is the entire value
                     width_value = len;
                     if (sign || (flags & FLAGS_SIGN)) {
                        width_value++;
                     }
                  }
                  if (prec_value == -1) {
                     //by default max is entire value
                     prec_value = len;
                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {
                        //widen precision if necessary to pad to width with '0'
                        if (sign || (flags & FLAGS_SIGN)) {
                           prec_value = width_value - 1;
                        }
                        else {
                           prec_value = width_value;
                        }
                     }
                  }
                  else {
                     if (prec_value < len) {
                        prec_value = len;
                     }
                     //number won't need leading zeros
                     flags &= ~FLAGS_ZERO;
                  }
                  if (flags & FLAGS_LEFT) {
                     if (sign) {
                        func('-', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     else if ((flags & FLAGS_SIGN) != 0) {
                        func('+', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > (prec_value + 1)) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     if (sign) {
                        func('-', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     else if ((flags & FLAGS_SIGN) != 0) {
                        func('+', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     if (width_value > prec_value) {
                        func(' ', user, 0);
                        width_value--;
                     }                        
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'o': {
                  int len;
                  switch (length) {
                     case LENGTH_H:
                        num_ptr = r_otoa((unsigned short)(unsigned int)args[field_arg], num_buf);
                        break;
                     case LENGTH_HH:
                        num_ptr = r_otoa((unsigned char)(unsigned int)args[field_arg], num_buf);
                        break;
                     case LENGTH_L:
                     default:
                        num_ptr = r_otoa((unsigned long)args[field_arg], num_buf);
                        break;
                  }
                  if (flags & FLAGS_HASH) {
                     if (*num_ptr != '0') {
                        num_ptr++;
                        *num_ptr = '0';
                     }
                  }
                  len = num_ptr - num_buf + 1;
                  if (width_value == -1) {
                     //by default min length is the entire value
                     width_value = len;
                  }
                  if (prec_value == -1) {
                     //by default max is entire value
                     prec_value = len;
                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {
                        //widen precision if necessary to pad to width with '0'
                        prec_value = width_value;
                     }
                  }
                  else {
                     if (prec_value < len) {
                        prec_value = len;
                     }
                     flags &= ~FLAGS_ZERO;
                  }
                  if (flags & FLAGS_LEFT) {
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > prec_value) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'u': {
                  int len;
                  switch (length) {
                     case LENGTH_H:
                        num_ptr = r_utoa((unsigned short)(unsigned int)args[field_arg], num_buf);
                        break;
                     case LENGTH_HH:
                        num_ptr = r_utoa((unsigned char)(unsigned int)args[field_arg], num_buf);
                        break;
                     case LENGTH_L:
                     default:
                        num_ptr = r_utoa((unsigned long)args[field_arg], num_buf);
                        break;
                  }
                  len = num_ptr - num_buf + 1;
                  if (width_value == -1) {
                     //by default min length is the entire value
                     width_value = len;
                  }
                  if (prec_value == -1) {
                     //by default max is entire value
                     prec_value = len;
                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {
                        //widen precision if necessary to pad to width with '0'
                        prec_value = width_value;
                     }
                  }
                  else {
                     if (prec_value < len) {
                        prec_value = len;
                     }
                     flags &= ~FLAGS_ZERO;
                  }
                  if (flags & FLAGS_LEFT) {
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > prec_value) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'x':
                  use_caps = 0;  //now fall into X case
               case 'X': {
                  int len;
                  switch (length) {
                     case LENGTH_H:
                        num_ptr = r_xtoa((unsigned short)(unsigned int)args[field_arg], num_buf, use_caps);
                        break;
                     case LENGTH_HH:
                        num_ptr = r_xtoa((unsigned char)(unsigned int)args[field_arg], num_buf, use_caps);
                        break;
                     case LENGTH_L:
                     default:
                        num_ptr = r_xtoa((unsigned long)args[field_arg], num_buf, use_caps);
                        break;
                  }
                  len = num_ptr - num_buf + 1;
                  if (width_value == -1) {
                     //by default min length is the entire value
                     width_value = len;
                  }
                  if (prec_value == -1) {
                     //by default max is entire value
                     prec_value = len;
                     if ((flags & FLAGS_ZERO) != 0 && prec_value < width_value) {
                        //widen precision if necessary to pad to width with '0'
                        prec_value = width_value;
                     }
                  }
                  else {
                     if (prec_value < len) {
                        prec_value = len;
                     }
                     flags &= ~FLAGS_ZERO;
                  }
                  if (flags & FLAGS_LEFT) {
                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {
                        func('0', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                        func(use_caps ? 'X' : 'x', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > (prec_value + 2)) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     if (flags & FLAGS_HASH && (len != 1 || *num_ptr != '0')) {
                        func('0', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                        func(use_caps ? 'X' : 'x', user, 0);
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     else {
                        while (width_value > prec_value) {
                           func(' ', user, 0);
                           width_value--;
                        }
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'f': case 'F':
                  break;
               case 'e': case 'E':
                  break;
               case 'g': case 'G':
                  break;
               case 'a': case 'A':
                  break;
               case 'c': {
                  unsigned char ch = (unsigned char)(unsigned int)args[field_arg];
                  if (width_value == -1) {
                     width_value = 1;
                  }
                  if (flags & FLAGS_LEFT) {
                     func((char)ch, user, 0);
                     if (width_value > 0) {
                        width_value--;
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > 1) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     func(ch, user, 0);
                  }
                  break;
               }
               case 's': {
                  const char *s_arg = (const char *)args[field_arg];
                  int len = cgc_strlen(s_arg);
                  if (width_value == -1) {
                     //by default min length is the entire string
                     width_value = len;
                  }
                  if (prec_value == -1 || prec_value > len) {
                     //by default max is entire string but no less than width
                     prec_value = len;
                  }
                  if (flags & FLAGS_LEFT) {
                     while (prec_value != 0) {
                        func(*s_arg++, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > prec_value) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     while (prec_value != 0) {
                        func(*s_arg++, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'p': {
                  int len;
                  flags |= FLAGS_HASH;
                  num_ptr = r_xtoa((unsigned int)args[field_arg], num_buf, 0);
                  len = num_ptr - num_buf + 1;
                  if (prec_value == -1) {
                     //by default max is entire value
                     prec_value = len;
                  }
                  else {
                     if (prec_value < len) {
                        prec_value = len;
                     }
                     flags &= ~FLAGS_ZERO;
                  }
                  if (width_value == -1) {
                     //by default min length is the entire value
                     width_value = prec_value + 2;
                  }
                  if (flags & FLAGS_LEFT) {
                     func('0', user, 0);
                     if (width_value > 0) {
                        width_value--;
                     }
                     func('x', user, 0);
                     if (width_value > 0) {
                        width_value--;
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                        if (width_value > 0) {
                           width_value--;
                        }
                     }
                     while (width_value != 0) {
                        func(' ', user, 0);
                        width_value--;
                     }
                  }
                  else {
                     while (width_value > (prec_value + 2)) {
                        func(' ', user, 0);
                        width_value--;
                     }
                     func('0', user, 0);
                     if (width_value > 0) {
                        width_value--;
                     }
                     func('x', user, 0);
                     if (width_value > 0) {
                        width_value--;
                     }
                     while (prec_value > len) {
                        func('0', user, 0);
                        prec_value--;
                     }
                     while (prec_value != 0) {
                        func(*num_ptr--, user, 0);
                        prec_value--;
                     }
                  }
                  break;
               }
               case 'n': {
                  void *np = (void*)args[field_arg];
                  unsigned int len = func(0, user, 1);
                  switch (length) {
                     case LENGTH_HH:
                        *(unsigned char*)np = (unsigned char)len;
                        break;
                     case LENGTH_H:
                        *(unsigned short*)np = (unsigned short)len;
                        break;
                     case LENGTH_L:
                     default:
                        *(unsigned int*)np = len;
                        break;
                  }
                  break;
               }
               case 'C':
                  break;
               case 'S':
                  break;
               default:
                  break;
            }
            state = STATE_NORMAL;
            break;
         }
      }
   }
   func(0, user, 2);
}