Пример #1
0
int getAndRemoveFirstDigit(intmax_t *input) {
	int tmp = *input;

	if (tmp < 10) {
		*input = NULL;
		return tmp;
	}
	else {
		tmp = (int) (tmp / (intmax_t) pow(10,(countDigits(tmp) - 1)));
		*input = *input - tmp * pow(10,(countDigits(*input) - 1));
		return tmp;
	}
}
Пример #2
0
int isSatisfyingCondition(long long int n)
{
    int *arr,len,start,end,counter;
    long long int n1,n2,i;
    len=countDigits(n);
    arr=(int*)malloc(sizeof(int)*len);
    arr=formArray(n);
    bubbleSortDescending(arr,len);
    n2=formNumber(arr,len);
    bubbleSortAscending(arr,len);
    n1=formNumber(arr,len);
    free(arr);
    start=(int)pow(n1,1/3.0);
    start--;
    end=(int)pow(n2,1/3.0);
    end++;
    counter=0;
    for(i=start;i<=end;i++)
    {
        if(containsSameDigits(i*i*i,n) && isPerfectCube(i*i*i))
        {
            printf("%lld\n",(i*i*i));
            counter++;
        }
    }
    if(counter==5)
        return 1;
    return 0;
}
Пример #3
0
int main()
{
	int num = 3748;
	printf("Ingresa un numero: ");
	scanf("%d", &num);
	printf("El numero: %d tiene %d digitos.\n", num, countDigits(num));
	printf("El numero: %d sus numeros suman: %d\n", num, sumDigits(num));
	return 0;
}
Пример #4
0
bool DateComponents::parseTime(const String& src,
                               unsigned start,
                               unsigned& end) {
  int hour;
  if (!toInt(src, start, 2, hour) || hour < 0 || hour > 23)
    return false;
  unsigned index = start + 2;
  if (index >= src.length())
    return false;
  if (src[index] != ':')
    return false;
  ++index;

  int minute;
  if (!toInt(src, index, 2, minute) || minute < 0 || minute > 59)
    return false;
  index += 2;

  int second = 0;
  int millisecond = 0;
  // Optional second part.
  // Do not return with false because the part is optional.
  if (index + 2 < src.length() && src[index] == ':') {
    if (toInt(src, index + 1, 2, second) && second >= 0 && second <= 59) {
      index += 3;

      // Optional fractional second part.
      if (index < src.length() && src[index] == '.') {
        unsigned digitsLength = countDigits(src, index + 1);
        if (digitsLength > 0) {
          ++index;
          bool ok;
          if (digitsLength == 1) {
            ok = toInt(src, index, 1, millisecond);
            millisecond *= 100;
          } else if (digitsLength == 2) {
            ok = toInt(src, index, 2, millisecond);
            millisecond *= 10;
          } else {  // digitsLength >= 3
            ok = toInt(src, index, 3, millisecond);
          }
          DCHECK(ok);
          index += digitsLength;
        }
      }
    }
  }
  m_hour = hour;
  m_minute = minute;
  m_second = second;
  m_millisecond = millisecond;
  end = index;
  m_type = Time;
  return true;
}
Пример #5
0
char* intToCharTable(intmax_t input){
	int iter = countDigits(input);
	char result[iter];

	for(int i = 0; i < iter; i++) {
		result[iter-i-1] = input % 10;
		input /= 10;
	}

	return result;
}
Пример #6
0
int *formArray(long long int n)
{
    int len,*arr,i;
    len=countDigits(n);
    arr=(int*)malloc(sizeof(int)*len);
    for(i=len-1;i>=0;i--)
    {
        arr[i]=n%10;
        n/=10;
    }
    return arr;
}
Пример #7
0
bool validLastTwoNumbers(int initNumber, int lastLength, int nextToLastLength) {
  int number = initNumber;
  int last = cutLastDigits(number, lastLength),
    nextToLast = cutLastDigits(number, nextToLastLength);

  while (number != 0) {
    int expectedNext = last - nextToLast;

    if (countDigits(number) < countDigits(expectedNext)) {
      return false;
    } else {
      int actualNext = cutLastDigits(number, countDigits(expectedNext));
      if (expectedNext != actualNext) {
        return false;
      }
    }

    last = nextToLast;
    nextToLast = expectedNext;
  }
  return true;
}
bool DateComponents::parseYear(const String& src, unsigned start, unsigned& end)
{
    unsigned digitsLength = countDigits(src, start);
    // Needs at least 4 digits according to the standard.
    if (digitsLength < 4)
        return false;
    int year;
    if (!toInt(src, start, digitsLength, year))
        return false;
    if (year < minimumYear() || year > maximumYear())
        return false;
    m_year = year;
    end = start + digitsLength;
    return true;
}
Пример #9
0
bool isAggregated(int number) {
  if (number <= 0) {
    return false;
  }

  int nDigits = countDigits(number);
  for (int i = 1 ; i <= nDigits / 2 ; ++i) {
    for (int j = 1 ; (i + j) <= nDigits - 1 ; ++j) {
      if (validLastTwoNumbers(number, i, j)) {
        return true;
      }
    }
  }
  return false;
}
Пример #10
0
// processing lines with mismatches 
int extractMismatches(string reads, string baseQuals, int cov, 
                    string transcriptID, string mispos, string refbase, int qualThreshold, int &seqCount)
{
    string correctedReads; 
    string skip;
    int start = 0, end = 0, i = 0;
	char readPos;
	int current = 0;
    while (i < reads.length())
    {
		readPos = reads.at(i);
        if (reads[i] == '+' || reads[i] == '-')
        {
			i ++ ; 
			current = 0;
			while (isdigit(reads.at(i)))
			{
				current += current * 10 + (reads[i]-'0');
				i++;
			}
			i += current - countDigits(current) ;
        }
        else if (readPos == '^')
        {
            i ++;
            start = 1;
        }
        else if (readPos == '$')
        {
            end = 1;
        }
        else
        {
            correctedReads.push_back(reads[i]);
        }
		i++;
    }
    assert (correctedReads.size() == cov);
	seqCount ++;
	if (seqCount > 1 && seqCount % 10000 == 0)
	{
		cerr << "Processed " << seqCount << " alignments" <<endl;
	}
    printingTable(transcriptID, mispos, refbase, correctedReads, cov, baseQuals,start,end, qualThreshold);
    return 0;
}
Пример #11
0
/* Format a command according to the Redis protocol using an sds string and
 * sdscatfmt for the processing of arguments. This function takes the
 * number of arguments, an array with arguments and an array with their
 * lengths. If the latter is set to NULL, strlen will be used to compute the
 * argument lengths.
 */
int redisFormatSdsCommandArgv(sds *target, int argc, const char **argv,
                              const size_t *argvlen)
{
    sds cmd;
    unsigned long long totlen;
    int j;
    size_t len;

    /* Abort on a NULL target */
    if (target == NULL)
        return -1;

    /* Calculate our total size */
    totlen = 1+countDigits(argc)+2;
    for (j = 0; j < argc; j++) {
        len = argvlen ? argvlen[j] : strlen(argv[j]);
        totlen += bulklen(len);
    }

    /* Use an SDS string for command construction */
    cmd = sdsempty();
    if (cmd == NULL)
        return -1;

    /* We already know how much storage we need */
    cmd = sdsMakeRoomFor(cmd, totlen);
    if (cmd == NULL)
        return -1;

    /* Construct command */
    cmd = sdscatfmt(cmd, "*%i\r\n", argc);
    for (j=0; j < argc; j++) {
        len = argvlen ? argvlen[j] : strlen(argv[j]);
        cmd = sdscatfmt(cmd, "$%T\r\n", len);
        cmd = sdscatlen(cmd, argv[j], len);
        cmd = sdscatlen(cmd, "\r\n", sizeof("\r\n")-1);
    }

    assert(sdslen(cmd)==totlen);

    *target = cmd;
    return totlen;
}
int main()
{
  int max=0, max_palindrome=0;

  for (int i=999;i;--i)
  {
    for (int j=999;j;--j)
    {
      int candidate = i*j;
      int len = countDigits(candidate);

      if ((isPalindrome(candidate,len)) && (len >= max) && (candidate > max_palindrome)) 
      {
        max = len;
        max_palindrome = candidate;
      }
    }
  }
  std::cout << max_palindrome << std::endl;
}
Пример #13
0
int count(int n) {
	int ndigits = countDigits(n),
		n2s = 0,
		pow10 = 1;

	for (int i = 0 ; i < ndigits ; ++i) {

		n2s += pow10 * (n / (pow10 * 10));

		int remainder = n % (pow10 * 10);
		if (remainder / pow10 > 2) {
			n2s += pow10;
		} else if (remainder / pow10 == 2) {
			n2s += (remainder % pow10 + 1);
		}

		pow10 *= 10;
	}

	return n2s;
}
Пример #14
0
char *getDivide(long dividend, long divisor, unsigned long decimalPlace) {
    long a,b,c,d;
    bool h=false;
    bool r=false;
    long f=1;
    char *s = malloc(decimalPlace+countDigits(dividend/divisor)+2);
    while (dividend < divisor) {
        if (!r) {
            sprintf(s,"0.");
            h = r = true;
        } else {
            sprintf(s,"0");
            dividend = dividend * 10;
            f++;
        }
    }    a = dividend / divisor;
    if (!h)
        sprintf(s,"%ld.",a);
    else {
        sprintf(s,"%ld",a);
        f++;
    }
    b = dividend % divisor;
    while (f <= decimalPlace) {
        c = b * 10;
        while((c < divisor) && (f < decimalPlace)) {
            c = c * 10;
            sprintf(s,"0");
            f++;
        }
        d = c / divisor;
        sprintf(s,"%ld",d);
        b = c % divisor;
        f++;
    }
    
    return s;
}
Пример #15
0
/* Format a command according to the Redis protocol. This function takes the
 * number of arguments, an array with arguments and an array with their
 * lengths. If the latter is set to NULL, strlen will be used to compute the
 * argument lengths.
 */
int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) {
    char *cmd = NULL; /* final command */
    int pos; /* position in final command */
    size_t len;
    int totlen, j;

    /* Abort on a NULL target */
    if (target == NULL)
        return -1;

    /* Calculate number of bytes needed for the command */
    totlen = 1+countDigits(argc)+2;
    for (j = 0; j < argc; j++) {
        len = argvlen ? argvlen[j] : strlen(argv[j]);
        totlen += bulklen(len);
    }

    /* Build the command at protocol level */
    cmd = malloc(totlen+1);
    if (cmd == NULL)
        return -1;

    pos = sprintf(cmd,"*%d\r\n",argc);
    for (j = 0; j < argc; j++) {
        len = argvlen ? argvlen[j] : strlen(argv[j]);
        pos += sprintf(cmd+pos,"$%zu\r\n",len);
        memcpy(cmd+pos,argv[j],len);
        pos += len;
        cmd[pos++] = '\r';
        cmd[pos++] = '\n';
    }
    assert(pos == totlen);
    cmd[pos] = '\0';

    *target = cmd;
    return totlen;
}
Пример #16
0
_Bool writePid(intmax_t inputPid, int desc){
	intmax_t buffSize = 32768, fileLength = 0;
	int descriptor = desc;

	if (descriptor < 0) {
		printf("Open Err\n");
		return false;
	}
	
	char *buf = malloc(buffSize);

	int tmp = 0;

	buffSize =countDigits(inputPid) + 1;
	buf = realloc(buf, buffSize * sizeof(char));
	
	char *pidTmp = intToCharTable(inputPid);
	int pidTmpSize = sizeof(pidTmp) / sizeof(pidTmp[0]);


	for (int i = 0; i < pidTmpSize; i ++) buf[i] = (char) pidTmp[i] + '0';

	buf[buffSize - 1] = (char) '\n';
	
	if(write(descriptor, buf, buffSize) == -1) {
		printf("Write Err\n");
		return false;
	}
	
	if(close(descriptor)) {
		printf("Close Err\n");
		return false;
	}

	return true;
}
Пример #17
0
int concat(int a,int b){
	int digits=countDigits(b);
	a*=pow(10,digits);
	a+=b;
	return a;
}
Пример #18
0
Grid<double> createRandomMaze(int size) {
    Grid<double> maze(size, size, kMazeFloor);
    BasicGraph* graph = gridToGraph(maze, mazeCost);
    
    // assign random weights to the edges
    // give each edge a 'random' weight;
    // put all edges into a priority queue, sorted by weight
    Set<Edge*> edgeSet = graph->getEdgeSet();
    int edgeCount = edgeSet.size();
    for (Edge* edge : edgeSet) {
        int weight = randomInteger(1, edgeCount * 1000);
        edge->cost = weight;
    }
    
    // run the student's Kruskal algorithm to get a minimum spanning tree (MST)
    Set<Edge*> mst = kruskal(*graph);
    
    // convert the MST/graph back into a maze grid
    // (insert a 'wall' between any neighbors that do not have a connecting edge)
    graph->clearEdges();
    for (Edge* edge : mst) {
        graph->addEdge(edge->start, edge->finish);
        graph->addEdge(edge->finish, edge->start);
    }

    // physical <-> logical size; a maze of size MxN has 2M-1 x 2N-1 grid cells.
    // cells in row/col 0, 2, 4, ... are open squares (floors), and cells in 
    // row/col 1, 3, 5, ... are blocked (walls).
    int digits = countDigits(size);
    int worldSize = size * 2 - 1;
    Grid<double> world(worldSize, worldSize, kMazeWall);
    for (int row = 0; row < worldSize; row++) {
        for (int col = 0; col < worldSize; col++) {
            if (row % 2 == 0 && col % 2 == 0) {
                world[row][col] = kMazeFloor;
            }
        }
    }
    
    for (int row = 0; row < size; row++) {
        int gridRow = row * 2;
        for (int col = 0; col < size; col++) {
            int gridCol = col * 2;
            string name = vertexName(row, col, digits);
            
            // decide whether to put open floor between neighbors
            // (if there is an edge between them)
            for (int dr = -1; dr <= 1; dr++) {
                int nr = row + dr;
                int gridNr = gridRow + dr;
                for (int dc = -1; dc <= 1; dc++) {
                    int nc = col + dc;
                    int gridNc = gridCol + dc;
                    if ((nr != row && nc != col)
                            || (nr == row && nc == col)
                            || !world.inBounds(gridNr, gridNc)) {
                        continue;
                    }
                    string neighborName = vertexName(nr, nc, digits);
                    if (graph->containsEdge(name, neighborName)) {
                        world[gridNr][gridNc] = kMazeFloor;
                    }
                }
            }
        }
    }
    
    delete graph;
    return world;
}
Пример #19
0
int main(void)
{
    long long cardNum;
    int currProduct;
    int currTotal = 0;
    int digits;
    //prompt user to enter a credit card 
    printf("Please Enter Your Card Number\n");

    cardNum = GetLongLong();

    //lets count the number of digits 
    digits = countDigits(cardNum);
    
    //printf("%d count \n", digits);
    if(digits == 13 || digits == 15 || digits == 16)
    {
        //lets check validity
        int last = 1;
        char* card_string = calloc(digits, sizeof(char));
        //use this to loop through above array
        int pos = digits;
        

        //multiply every other number by two
        while (cardNum > 0) {
            int currDigit = cardNum % 10;
            card_string[pos] = (char)currDigit;
            pos --;
            //this means we are at the last and we can use this as an interval for the next iteration
            if(last == 0)
            {
                currProduct =  currDigit * 2;
                //run this loop again to get the digits of the result
                while(currProduct > 0 )
                {
                    int currInnerDigit = currProduct % 10;
                    currTotal += currInnerDigit;
                    //get the next inner digit
                    currProduct /= 10;
                }
                //switch indicator for next iteration
                last = 1;
            }
            else
            {
               //add to the total since we didnt multiply it by e 
               currTotal += currDigit;
               //switch the indicator of positions
               last = 0;
            }
            
            //get the next digit 
            cardNum /= 10;
        }
        
        int validity = currTotal % 10;
        
        // convert card num to string 
        
        //sprintf(card_string, "%llu", cardNum);
        //ltoa(cardNum,card_string,10);
        
        printf("Card String %s\n", card_string);
        
        if(validity != 0)
        {
            printf("INVALID\n");
        }
        else
        {
            //check the number of digits to show you card type check  valid cart prefixes
            if ( digits == 15 )
            {
                if(startsWith("34", card_string) || startsWith("37", card_string))
                {
                    printf("AMEX\n");
                }
                else
                {
                    printf("INVALID\n");
                }
            }
            else if ( digits == 16 )
            {
                if (startsWith("51", card_string) || startsWith("52", card_string) || startsWith("53", card_string) || startsWith("54", card_string) || startsWith("55", card_string))
                {
                    printf("MASTERCARD\n");
                }
                else if (startsWith("4", card_string))
                {
                    printf("VISA\n");
                }
                else
                {
                    printf("INVALID\n");
                }
            }
             else if (startsWith("4", card_string) )
            {
                    printf("VISA\n");
            }
            else 
            {
               printf("INVALID\n");
            }
            
            
        }
        
        
        
    }
    else
    {
        printf("INVALID\n");
    }
    return 0;
}
Пример #20
0
string vertexName(int r, int c, const Grid<double>& world) {
    // zero-pad the number of rows/cols for better alphabetic sorting
    int rowCols = max(world.numRows(), world.numCols());
    return vertexName(r, c, countDigits(rowCols));
}
static void onlineClusterKNN_cluster(t_onlineClusterKNN *x, t_symbol *s, int argc, t_atom *argv)
{
    int i, j, k, instanceIdx, listLength;
    float min_dist,dist;
    
	instanceIdx = x->numInstances;
	listLength = argc;
	//s=s; // to get rid of 'unused variable' warning
    //post("list length: %i", listLength);
    
    if((x->featureLength>0) && (x->featureLength != listLength))
	{
        post("received list of length %i and expected %i", listLength, x->featureLength); 
        return;
    }    
    
	x->instances = (t_instance *)t_resizebytes_(x->instances, x->numInstances * sizeof(t_instance), (x->numInstances+1) * sizeof(t_instance));
	x->instanceFeatureLengths = (int *)t_resizebytes_(x->instanceFeatureLengths, x->numInstances * sizeof(int), (x->numInstances+1) * sizeof(int));
	
	x->instanceFeatureLengths[instanceIdx] = listLength;
	x->instances[instanceIdx].instance = (float *)t_getbytes_(listLength * sizeof(float));    
    
	x->numInstances++;
	//post("no. of instances: %i", x->numInstances);          
    
    
    //get the data
	for(i=0; i<listLength; i++)
		x->instances[instanceIdx].instance[i] = atom_getfloat(argv+i);
    
    //test if received element is zeros vector
    if (test_zero(x->instances[instanceIdx].instance,listLength) == 0)
    {
        //post("instance cannot be zeros vector");
        //rollback
        t_freebytes_(x->instances[instanceIdx].instance, x->instanceFeatureLengths[instanceIdx]*sizeof(float));
        x->instances = (t_instance *)t_resizebytes_(x->instances, x->numInstances * sizeof(t_instance), (x->numInstances-1) * sizeof(t_instance));
        x->instanceFeatureLengths = (int *)t_resizebytes_(x->instanceFeatureLengths, x->numInstances * sizeof(int), (x->numInstances-1) * sizeof(int)); 
        
        x->numInstances--;
        
    }
    else 
    {
        
        if(instanceIdx == 0)
        {
            x->featureInput = (float *)t_resizebytes_(x->featureInput, x->featureLength * sizeof(float), listLength * sizeof(float));		
            x->featureLength = listLength;  
            
            x->num = (int *)t_resizebytes_(x->num, 0 * sizeof(int), x->numClusters * sizeof(int));
            
            // initialize means randomly for each cluster        
            for(i=0; i<x->numClusters; i++)
            {
                x->means = (t_instance *)t_resizebytes_(x->means, i * sizeof(t_instance), (i+1) * sizeof(t_instance));
                x->means[i].instance = (float *)t_getbytes_(listLength * sizeof(float)); 
                
                if (x->randomFlag == 1)
                {
                    for(j=0; j<listLength; j++)
                    {
                        srand(i*j+i+j+1);
                        x->means[i].instance[j] = (float)rand()/(float)RAND_MAX;            
                    }
                }
            }                
            // initialize number of instances for each cluster
            for(i=0; i<x->numClusters; i++)
                x->num[i] = 0;
        };
        
        
        //normalize the data to be 0-1
        for(i=0; i<listLength; i++)
            if (x->instances[instanceIdx].instance[i]>1)
            {            
                x->instances[instanceIdx].instance[i] = x->instances[instanceIdx].instance[i] * pow(10,-countDigits((int)(x->instances[instanceIdx].instance[i])));
            }
        
        //////////////ONLINE CLUSTERING
        
        //initialize means with the first instances if random==0
        if ((x->randomFlag == 0) && (instanceIdx < x->numClusters))
        {
            for(j=0; j<listLength; j++)
            {
                x->means[instanceIdx].instance[j] =  x->instances[instanceIdx].instance[j];
            }
            x->instances[instanceIdx].cluster = instanceIdx;
            x->num[instanceIdx] = 1;
        }
        else
        {        
            //compute distances to the means and determine the closest cluster 
            min_dist = 99999999;
            k = -1;
            for(i=0; i<x->numClusters; i++)
            { 
                dist = squared_euclid(x->means[i].instance,x->instances[instanceIdx].instance,listLength);
                //post("%6.20f", dist);
                if (dist < min_dist)
                {
                    min_dist = dist;
                    k = i;
                }
            }   
            
            //add the new instance to the found cluster
            //post("cluster %i", k);
            if (k != -1)
            {
                x->num[k] = x->num[k] + 1;
                compute_mean(x, k, x->instances[instanceIdx]);
                x->instances[instanceIdx].cluster = k;     
            }  
        }
        
        outlet_int(x->id, x->instances[instanceIdx].cluster);    
    }
}
Пример #22
0
void WorldMaze::createRandomMaze(WorldSize size) {
    clearSelection(/* redraw */ false);
    
    int rowsCols = getRowsCols(size) / 2 + 1;
    worldGrid.resize(rowsCols, rowsCols);
    worldGrid.fill(MAZE_FLOOR);
    graph = gridToGraph(worldGrid);
    
    // assign random weights to the edges
    // give each edge a 'random' weight;
    // put all edges into a priority queue, sorted by weight
    Set<Edge*> edgeSet = graph->getEdgeSet();
    int edgeCount = edgeSet.size();
    for (Edge* edge : edgeSet) {
        int weight = randomInteger(1, edgeCount * 1000);
        edge->cost = weight;
    }
    
    // run the student's Kruskal algorithm to get a minimum spanning tree (MST)
    Set<Edge*> mst = kruskal(*graph);
    
    // convert the MST/graph back into a maze grid
    // (insert a 'wall' between any neighbors that do not have a connecting edge)
    graph->clearEdges();
    for (Edge* edge : mst) {
        graph->addEdge(edge->start, edge->finish);
        graph->addEdge(edge->finish, edge->start);
    }

    // physical <-> logical size; a maze of size MxN has 2M-1 x 2N-1 grid cells.
    // cells in row/col 0, 2, 4, ... are open squares (floors), and cells in 
    // row/col 1, 3, 5, ... are blocked (walls).
    int digits = countDigits(rowsCols);
    int worldSize = rowsCols * 2 - 1;
    worldGrid.resize(worldSize, worldSize);
    worldGrid.fill(MAZE_WALL);
    
    pxPerWidth = (double) windowWidth / worldSize;
    pxPerHeight = (double) windowHeight / worldSize;
    
    for (int row = 0; row < worldSize; row++) {
        for (int col = 0; col < worldSize; col++) {
            if (row % 2 == 0 && col % 2 == 0) {
                worldGrid.set(row, col, MAZE_FLOOR);
            }
        }
    }
    
    for (int row = 0; row < rowsCols; row++) {
        int gridRow = row * 2;
        for (int col = 0; col < rowsCols; col++) {
            int gridCol = col * 2;
            std::string name = vertexName(row, col, digits);
            
            // decide whether to put open floor between neighbors
            // (if there is an edge between them)
            for (int dr = -1; dr <= 1; dr++) {
                int nr = row + dr;
                int gridNr = gridRow + dr;
                for (int dc = -1; dc <= 1; dc++) {
                    int nc = col + dc;
                    int gridNc = gridCol + dc;
                    if ((nr != row && nc != col)
                            || (nr == row && nc == col)
                            || !worldGrid.inBounds(gridNr, gridNc)) {
                        continue;
                    }
                    std::string neighborName = vertexName(nr, nc, digits);
                    if (graph->containsEdge(name, neighborName)) {
                        worldGrid.set(gridNr, gridNc, MAZE_FLOOR);
                    }
                }
            }
        }
    }
    
    delete graph;
    graph = gridToGraph(worldGrid);
}
Пример #23
0
int redisvFormatCommand(char **target, const char *format, va_list ap) {
    const char *c = format;
    char *cmd = NULL; /* final command */
    int pos; /* position in final command */
    sds curarg, newarg; /* current argument */
    int touched = 0; /* was the current argument touched? */
    char **curargv = NULL, **newargv = NULL;
    int argc = 0;
    int totlen = 0;
    int error_type = 0; /* 0 = no error; -1 = memory error; -2 = format error */
    int j;

    /* Abort if there is not target to set */
    if (target == NULL)
        return -1;

    /* Build the command string accordingly to protocol */
    curarg = sdsempty();
    if (curarg == NULL)
        return -1;

    while(*c != '\0') {
        if (*c != '%' || c[1] == '\0') {
            if (*c == ' ') {
                if (touched) {
                    newargv = realloc(curargv,sizeof(char*)*(argc+1));
                    if (newargv == NULL) goto memory_err;
                    curargv = newargv;
                    curargv[argc++] = curarg;
                    totlen += bulklen(sdslen(curarg));

                    /* curarg is put in argv so it can be overwritten. */
                    curarg = sdsempty();
                    if (curarg == NULL) goto memory_err;
                    touched = 0;
                }
            } else {
                newarg = sdscatlen(curarg,c,1);
                if (newarg == NULL) goto memory_err;
                curarg = newarg;
                touched = 1;
            }
        } else {
            char *arg;
            size_t size;

            /* Set newarg so it can be checked even if it is not touched. */
            newarg = curarg;

            switch(c[1]) {
            case 's':
                arg = va_arg(ap,char*);
                size = strlen(arg);
                if (size > 0)
                    newarg = sdscatlen(curarg,arg,size);
                break;
            case 'b':
                arg = va_arg(ap,char*);
                size = va_arg(ap,size_t);
                if (size > 0)
                    newarg = sdscatlen(curarg,arg,size);
                break;
            case '%':
                newarg = sdscat(curarg,"%");
                break;
            default:
                /* Try to detect printf format */
                {
                    static const char intfmts[] = "diouxX";
                    static const char flags[] = "#0-+ ";
                    char _format[16];
                    const char *_p = c+1;
                    size_t _l = 0;
                    va_list _cpy;

                    /* Flags */
                    while (*_p != '\0' && strchr(flags,*_p) != NULL) _p++;

                    /* Field width */
                    while (*_p != '\0' && isdigit(*_p)) _p++;

                    /* Precision */
                    if (*_p == '.') {
                        _p++;
                        while (*_p != '\0' && isdigit(*_p)) _p++;
                    }

                    /* Copy va_list before consuming with va_arg */
                    va_copy(_cpy,ap);

                    /* Integer conversion (without modifiers) */
                    if (strchr(intfmts,*_p) != NULL) {
                        va_arg(ap,int);
                        goto fmt_valid;
                    }

                    /* Double conversion (without modifiers) */
                    if (strchr("eEfFgGaA",*_p) != NULL) {
                        va_arg(ap,double);
                        goto fmt_valid;
                    }

                    /* Size: char */
                    if (_p[0] == 'h' && _p[1] == 'h') {
                        _p += 2;
                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
                            va_arg(ap,int); /* char gets promoted to int */
                            goto fmt_valid;
                        }
                        goto fmt_invalid;
                    }

                    /* Size: short */
                    if (_p[0] == 'h') {
                        _p += 1;
                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
                            va_arg(ap,int); /* short gets promoted to int */
                            goto fmt_valid;
                        }
                        goto fmt_invalid;
                    }

                    /* Size: long long */
                    if (_p[0] == 'l' && _p[1] == 'l') {
                        _p += 2;
                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
                            va_arg(ap,long long);
                            goto fmt_valid;
                        }
                        goto fmt_invalid;
                    }

                    /* Size: long */
                    if (_p[0] == 'l') {
                        _p += 1;
                        if (*_p != '\0' && strchr(intfmts,*_p) != NULL) {
                            va_arg(ap,long);
                            goto fmt_valid;
                        }
                        goto fmt_invalid;
                    }

                fmt_invalid:
                    va_end(_cpy);
                    goto format_err;

                fmt_valid:
                    _l = (_p+1)-c;
                    if (_l < sizeof(_format)-2) {
                        memcpy(_format,c,_l);
                        _format[_l] = '\0';
                        newarg = sdscatvprintf(curarg,_format,_cpy);

                        /* Update current position (note: outer blocks
                         * increment c twice so compensate here) */
                        c = _p-1;
                    }

                    va_end(_cpy);
                    break;
                }
            }

            if (newarg == NULL) goto memory_err;
            curarg = newarg;

            touched = 1;
            c++;
        }
        c++;
    }

    /* Add the last argument if needed */
    if (touched) {
        newargv = realloc(curargv,sizeof(char*)*(argc+1));
        if (newargv == NULL) goto memory_err;
        curargv = newargv;
        curargv[argc++] = curarg;
        totlen += bulklen(sdslen(curarg));
    } else {
        sdsfree(curarg);
    }

    /* Clear curarg because it was put in curargv or was free'd. */
    curarg = NULL;

    /* Add bytes needed to hold multi bulk count */
    totlen += 1+countDigits(argc)+2;

    /* Build the command at protocol level */
    cmd = malloc(totlen+1);
    if (cmd == NULL) goto memory_err;

    pos = sprintf(cmd,"*%d\r\n",argc);
    for (j = 0; j < argc; j++) {
        pos += sprintf(cmd+pos,"$%zu\r\n",sdslen(curargv[j]));
        memcpy(cmd+pos,curargv[j],sdslen(curargv[j]));
        pos += sdslen(curargv[j]);
        sdsfree(curargv[j]);
        cmd[pos++] = '\r';
        cmd[pos++] = '\n';
    }
    assert(pos == totlen);
    cmd[pos] = '\0';

    free(curargv);
    *target = cmd;
    return totlen;

format_err:
    error_type = -2;
    goto cleanup;

memory_err:
    error_type = -1;
    goto cleanup;

cleanup:
    if (curargv) {
    while(argc--)
        sdsfree(curargv[argc]);
    free(curargv);
    }

        sdsfree(curarg);

    /* No need to check cmd since it is the last statement that can fail,
     * but do it anyway to be as defensive as possible. */
    if (cmd != NULL)
        free(cmd);

    return error_type;
}
Пример #24
0
/* Helper that calculates the bulk length given a certain string length. */
static size_t bulklen(size_t len) {
    return 1+countDigits(len)+2+len+2;
}
Пример #25
0
/** @fn int countColWidth ( double num, int decimals )
	@brief calculates the width in characters the number will occupy
	@param num [in] number to count column width for
	@param decimals [in] number of decimals 
	@return width of space the number will take */
int countColWidth(double num, int decimals) {
	int digitsCount = countDigits(num);
	if (!decimals)
		--decimals; // remove extra space for a period if no decimals
	return digitsCount + (digitsCount / 3) + decimals + 2; //digits, commas, decimals, period, possible minus sign
}
Пример #26
0
int cmpDigits(uint32_t a, uint32_t b){
	countDigits(a, digitsa);
	countDigits(b, digitsb);
	return memcmp(digitsa, digitsb, 10*sizeof(uint8_t));
}