Пример #1
0
/**
 * Calculates the HMAC of the given message, hashtype, and hashkey.
 * dest must be at least the hash length.
 */
int create_hmac(int hashtype, const unsigned char *key, unsigned int keylen,
                const unsigned char *src, unsigned int srclen,
                unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the hmac key each time.  Test to see if this
    // is quick enough or if we need to cache an imported hmac key.
    HCRYPTKEY hmackey;
    HCRYPTHASH hash;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    HMAC_INFO info;
    ALG_ID alg;
    int bloblen, hashlen, rval;
    DWORD _destlen;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);
    if (alg == 0) {
        log0(0, 0, 0, "Invalid hashtype");
        return 0;
    }

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RC2;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + hashlen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0,
                        CRYPT_IPSEC_HMAC_KEY, &hmackey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    if (!CryptCreateHash(base_prov, CALG_HMAC, hmackey, 0, &hash)) {
        mserror("CryptCreateHash failed");
        rval = 0;
        goto end1;
    }
    memset(&info, 0, sizeof(info));
    info.HashAlgid = alg;
    if (!CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&info, 0)) {
        mserror("CryptSetHashParam failed");
        rval = 0;
        goto end2;
    }
    if (!CryptHashData(hash, src, srclen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end2;
    }
    _destlen = hashlen;
    if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) {
        mserror("CryptGetHashParam failed");
        rval = 0;
        goto end2;
    }
    *destlen = _destlen;
    rval = 1;

end2:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
end1:
    if (!CryptDestroyKey(hmackey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
Пример #2
0
/**
 * Hashes a block of data and signs it with an RSA private key.
 * Output buffer must be at least the key size.
 */
int create_RSA_sig(RSA_key_t rsa, int hashtype,
                   const unsigned char *mes, unsigned int meslen,
                   unsigned char *sig, unsigned int *siglen)
{
    HCRYPTHASH hash;
    DWORD _siglen;
    int idx, found;
    ALG_ID alg;
    int hashlen, rval;
    unsigned int i;
    unsigned char *outsig;

    for (idx = 0, found = 0; (idx < MAXLIST) && (!found); idx++) {
        if (private_key_list[idx].key == rsa) {
            found = 1;
        }
    }
    if (!found) {
        log0(0, 0, 0, "Couldn't find provider for RSA key");
        return 0;
    }
    idx--;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);
    if (alg == 0) {
        log0(0, 0, 0, "Invalid hashtype");
        return 0;
    }

    if (!CryptCreateHash(private_key_list[idx].provider, alg, 0, 0, &hash)) {
        mserror("CryptCreateHash failed");
        return 0;
    }
    if (!CryptHashData(hash, mes, meslen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end;
    }

    _siglen = RSA_keylen(rsa);
    outsig = safe_calloc(_siglen, 1);
    if (!CryptSignHash(hash, AT_KEYEXCHANGE, NULL, 0, outsig, &_siglen)) {
        mserror("CryptSignHash failed");
        free(outsig);
        rval = 0;
        goto end;
    }
    *siglen = _siglen;
    // CryptoAPI returns signatures in little endian, so reverse the bytes
    for (i = 0; i < _siglen; i++) {
        sig[i] = outsig[_siglen - i - 1];
    }
    free(outsig);

    rval = 1;

end:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
    return rval;
}
    int
    test() {
        vi_t rin, rout;
        rin.resize(15);
        rin[0]  = 2;
        rin[1]  = 1;
        rin[2]  = 8;
        rin[3]  = 3;
        rin[4]  = 5;
        rin[5]  = 3;
        rin[6]  = 5;
        rin[7]  = 3;
        rin[8]  = 1;
        rin[9]  = 1;
        rin[10] = 1;
        rin[11] = 1;
        rin[12] = 3;
        rin[13] = 8;
        rin[14] = 6;

        compress_ranges(rin, rout);

        printf("Indexes: ");
        for (size_t i = 0; i < rin.size(); ++i) {
            printf("%4d", i);
        }
        printf("\n");

        printf("rin:     ");
        for (size_t i = 0; i < rin.size(); ++i) {
            printf("%4d", rin[i]);
        }
        printf("\n");

        printf("rout:    ");
        for (size_t i = 0; i < rout.size(); ++i) {
            printf("%4d", rout[i]);
        }
        printf("\n");

        printf("Ranges   ");
        for (size_t i = 0; i < rout.size(); ) {
            printf("%4d(%2d)", i, rout[i]-i);
            i = rout[i];
        }
        printf("%4d", rout.size());
        printf("\n");

        const char *s1 = "the quick brown fox huffs and puffs cats and runs and enthusiastically jumps over the lazy dogs";
        const char *s2 = "it's raining enthusiastically cats and dogs";
        vpii_t out;
        vpiui_t sh;
        int bsz = 12;

        find_matches(s1, s2, bsz, out, sh);

        for (size_t i = 0; i < out.size(); ++i) {
            printf("%.*s: %d, %d\n", bsz, s2+i, out[i].first, out[i].second);
        }

        printf("hash(e quick brow) == %u\n", get_hash("e quick brow", 12));
        printf("hash(enthusiastic) == %u\n", get_hash("enthusiastic", 12));
        return 0;
    }
Пример #4
0
            /**
             * Sets the merkle branch.
             * @param blk The block.
             */
            int set_merkle_branch(block * blk = 0)
            {
                if (globals::instance().is_client())
                {
                    if (m_block_hash == 0)
                    {
                        return 0;
                    }
                }
                else
                {
                    block blk_tmp;
                    
                    if (blk == 0)
                    {
                        /**
                         * Load the block this tx is in.
                         */
                        transaction_index tx_index;
                        
                        if (
                            db_tx("r").read_transaction_index(
                            get_hash(), tx_index) == false
                            )
                        {
                            return 0;
                        }
                        
                        if (
                            blk_tmp.read_from_disk(
                            tx_index.get_transaction_position().file_index(),
                            tx_index.get_transaction_position().block_position()
                            ) == false
                            )
                        {
                            return 0;
                        }
                        
                        blk = &blk_tmp;
                    }

                    /**
                     * Update the transaction's block hash.
                     */
                    m_block_hash = blk->get_hash();

                    /**
                     * Locate the transaction.
                     */
                    for (
                        m_index = 0; m_index < blk->transactions().size();
                        m_index++
                        )
                    {
                        if (
                            blk->transactions()[m_index] ==
                            *reinterpret_cast<transaction *>(this)
                            )
                        {
                            break;
                        }
                    }
                    
                    if (m_index == blk->transactions().size())
                    {
                        m_merkle_branch.clear();
                        
                        m_index = -1;
                        
                        log_error(
                            "Transaction merkle failed to set merkle branch, "
                            "unable to find transaction in block."
                        );

                        return 0;
                    }

                    /**
                     * Fill in the merkle branch.
                     */
                    m_merkle_branch = blk->get_merkle_branch(m_index);
                }

                /**
                 * Is the transaction in a block that's in the main chain?
                 */
                auto it = globals::instance().block_indexes().find(
                    m_block_hash
                );
                
                if (it == globals::instance().block_indexes().end())
                {
                    return 0;
                }

                if (!it->second || !it->second->is_in_main_chain())
                {
                    return 0;
                }
                
                return
                    stack_impl::get_block_index_best()->height() -
                    it->second->height() + 1
                ;
            }
Пример #5
0
int main(int argc, char *argv[])
{
	int rc;
	TSS_HCONTEXT    hContext;
	TSS_HTPM	hTPM;
	int i;
	unsigned int pcr_len = 0;
	unsigned char *pcr_value;
	unsigned char sha1[20];

	/* The argument being the executable */
	if (argc <= 1) {
		printf("Must give atleast one argument\n");
		exit(1);
	}

	/* Find out the currently running kernel and return its hash */
	rc = get_kernel(sha1);
	if (rc != 0) {
		printf("Kernel read failed\n");
		exit(1);
	}

	/* Start creating the TSS context */
	rc = Tspi_Context_Create(&hContext);
	if (rc != TSS_SUCCESS)
		printf("Context creation failed!\n");

	rc = Tspi_Context_Connect(hContext, NULL);
	if (rc != TSS_SUCCESS)
		printf("Context connection failed!\n");

	rc = Tspi_Context_GetTpmObject(hContext, &hTPM);
	if (rc != TSS_SUCCESS)
		printf("Getting TPM Object failed\n");

	rc = Tspi_TPM_PcrRead(hTPM, 16, &pcr_len, &pcr_value);
	printf("Length of data read: %d\n", pcr_len);
	for (i = 0; i < pcr_len; i++)
		printf("%x ", pcr_value[i]);
	printf("\n");

	/* Trousers wonkiness - have to pass SHA1 hash */
	rc = Tspi_TPM_PcrExtend(hTPM, 16, 20, sha1, NULL, 
			&pcr_len, &pcr_value);
	if (rc != TSS_SUCCESS) {
		printf("Kernel Extend failed : %d\n", rc);
	}

	/* argv[1] is the path to secure_daemon */
	rc = get_hash(argv[1], sha1);
	if (rc != 0)
		exit(1);

	rc = Tspi_TPM_PcrExtend(hTPM, 16, 20, sha1, NULL, 
			&pcr_len, &pcr_value);
	if (rc != TSS_SUCCESS) {
		printf("Secure Daemon Extend failed : %d\n", rc);
	} 

	printf("Length of extended PCR value: %d\n", pcr_len);
	for (i = 0; i < pcr_len; i++)
		printf("%x ", pcr_value[i]);
	printf("\n");

	free(pcr_value);
	Tspi_Context_Close(hContext);

	return 0;
}
Пример #6
0
void
getpw_lookup(nsc_return_t *out, int maxsize, nsc_call_t *in, time_t now)
{
	int		out_of_date;
	nsc_bucket_t	*retb;
	char 		**bucket;

	static time_t	lastmod;

	int bufferspace = maxsize - sizeof (nsc_return_t);

	if (current_admin.passwd.nsc_enabled == 0) {
		out->nsc_return_code = NOSERVER;
		out->nsc_bufferbytesused = sizeof (*out);
		return;
	}

	mutex_lock(&passwd_lock);

	if (current_admin.passwd.nsc_check_files) {
		struct stat buf;

		if (stat("/etc/passwd", &buf) < 0) {
			/*EMPTY*/;
		} else if (lastmod == 0) {
			lastmod = buf.st_mtime;
		} else if (lastmod < buf.st_mtime) {
			getpw_invalidate_unlocked();
			lastmod = buf.st_mtime;
		}
	}

	if (current_admin.debug_level >= DBG_ALL) {
		if (MASKUPDATEBIT(in->nsc_callnumber) == GETPWUID) {
			logit("getpw_lookup: looking for uid %d\n",
				in->nsc_u.uid);
		} else {
			logit("getpw_lookup: looking for name %s\n",
				in->nsc_u.name);
		}
	}

	for (;;) {
		if (MASKUPDATEBIT(in->nsc_callnumber) == GETPWUID) {
			bucket = get_hash(uid_hash, (char *)in->nsc_u.uid);
		} else { /* make reasonableness check here  */
			if (strlen(in->nsc_u.name) > NSCDMAXNAMELEN) {
				ucred_t *uc = NULL;

				if (door_ucred(&uc) != 0) {
					logit("getpw_lookup: Name too long, "
					    "but no user credential: %s\n",
					    strerror(errno));
				} else {

					logit("getpw_lookup: Name too long "
					    "from pid %d uid %d\n",
					    ucred_getpid(uc),
					    ucred_getruid(uc));
					ucred_free(uc);
				}


				out->nsc_errno = NSS_NOTFOUND;
				out->nsc_return_code = NOTFOUND;
				out->nsc_bufferbytesused = sizeof (*out);
				goto getout;
			}
			bucket = get_hash(nam_hash, in->nsc_u.name);
		}

		if (*bucket == (char *)-1) {	/* pending lookup */
			if (get_clearance(in->nsc_callnumber) != 0) {
				/* no threads available */
				out->nsc_return_code = NOSERVER;
				/* cannot process now */
				out->nsc_bufferbytesused = sizeof (*out);
				current_admin.passwd.nsc_throttle_count++;
				goto getout;
			}
			nscd_wait(&passwd_wait, &passwd_lock, bucket);
			release_clearance(in->nsc_callnumber);
			continue; /* go back and relookup hash bucket */
		}
		break;
	}

	/*
	 * check for no name_service mode
	 */

	if (*bucket == NULL && current_admin.avoid_nameservice) {
		out->nsc_return_code = NOTFOUND;
		out->nsc_bufferbytesused = sizeof (*out);
	} else if (*bucket == NULL ||
	    (in->nsc_callnumber & UPDATEBIT) ||
	    (out_of_date = (!current_admin.avoid_nameservice &&
		(current_admin.passwd.nsc_old_data_ok == 0) &&
		(((nsc_bucket_t *)*bucket)->nsc_timestamp < now)))) {
		/*
		 * time has expired
		 */
		int saved_errno;
		int saved_hits = 0;
		struct passwd *p;

		if (get_clearance(in->nsc_callnumber) != 0) {
			/* no threads available */
			out->nsc_return_code = NOSERVER;
			/* cannot process now */
			out->nsc_bufferbytesused = sizeof (*out);
			current_admin.passwd.nsc_throttle_count++;
			goto getout;
		}
		if (*bucket != NULL) {
			saved_hits = ((nsc_bucket_t *)*bucket)->nsc_hits;
		}

		/*
		 *  block any threads accessing this bucket if data
		 *  is non-existent or out of date
		 */

		if (*bucket == NULL || out_of_date) {
			update_pw_bucket((nsc_bucket_t **)bucket,
					(nsc_bucket_t *)-1,
					in->nsc_callnumber);
		} else {
			/*
			 * if still not -1 bucket we are doing
			 * update... mark to prevent pileups of threads if
			 * the name service is hanging..
			 */
			((nsc_bucket_t *)(*bucket))->nsc_status |=
				ST_UPDATE_PENDING;
			/* cleared by deletion of old data */
		}
		mutex_unlock(&passwd_lock);

		if (MASKUPDATEBIT(in->nsc_callnumber) == GETPWUID) {
			p = _uncached_getpwuid_r(in->nsc_u.uid, &out->nsc_u.pwd,
				out->nsc_u.buff+sizeof (struct passwd),
				bufferspace);
			saved_errno = errno;
		} else {
			p = _uncached_getpwnam_r(in->nsc_u.name,
				&out->nsc_u.pwd,
				out->nsc_u.buff+sizeof (struct passwd),
				bufferspace);
			saved_errno = errno;
		}

		mutex_lock(&passwd_lock);

		release_clearance(in->nsc_callnumber);

		if (p == NULL) { /* data not found */
			if (current_admin.debug_level >= DBG_CANT_FIND) {
				if (MASKUPDATEBIT(in->nsc_callnumber) ==
					GETPWUID) {
			logit("getpw_lookup: nscd COULDN'T FIND uid %d\n",
					in->nsc_u.uid);
				} else {
		logit("getpw_lookup: nscd COULDN'T FIND passwd name %s\n",
						in->nsc_u.name);
				}
			}

			if (!(UPDATEBIT & in->nsc_callnumber))
			    current_admin.passwd.nsc_neg_cache_misses++;

			retb = (nsc_bucket_t *)malloc(sizeof (nsc_bucket_t));

			retb->nsc_refcount = 1;
			retb->nsc_data.nsc_bufferbytesused =
				sizeof (nsc_return_t);
			retb->nsc_data.nsc_return_code = NOTFOUND;
			retb->nsc_data.nsc_errno = saved_errno;
			memcpy(out, &retb->nsc_data,
				retb->nsc_data.nsc_bufferbytesused);
			update_pw_bucket((nsc_bucket_t **)bucket, retb,
				in->nsc_callnumber);
			goto getout;
		} else {
			if (current_admin.debug_level >= DBG_ALL) {
				if (MASKUPDATEBIT(in->nsc_callnumber) ==
					GETPWUID) {
				logit("getpw_lookup: nscd FOUND uid %d\n",
						in->nsc_u.uid);
				} else {
			logit("getpw_lookup: nscd FOUND passwd name %s\n",
						in->nsc_u.name);
				}
			}
			if (!(UPDATEBIT & in->nsc_callnumber))
			    current_admin.passwd.nsc_pos_cache_misses++;

			retb = fixbuffer(out, bufferspace);
			update_pw_bucket((nsc_bucket_t **)bucket,
				retb, in->nsc_callnumber);
			if (saved_hits)
				retb->nsc_hits = saved_hits;
		}
	} else { 	/* found entry in cache */
		retb = (nsc_bucket_t *)*bucket;

		retb->nsc_hits++;

		memcpy(out, &(retb->nsc_data),
			retb->nsc_data.nsc_bufferbytesused);

		if (out->nsc_return_code == SUCCESS) {
			if (!(UPDATEBIT & in->nsc_callnumber))
			    current_admin.passwd.nsc_pos_cache_hits++;
			if (current_admin.debug_level >= DBG_ALL) {
				if (MASKUPDATEBIT(in->nsc_callnumber) ==
					GETPWUID) {
			logit("getpw_lookup: found uid %d in cache\n",
						in->nsc_u.uid);
				} else {
			logit("getpw_lookup: found name %s in cache\n",
						in->nsc_u.name);
				}
			}
		} else {
			if (!(UPDATEBIT & in->nsc_callnumber))
			    current_admin.passwd.nsc_neg_cache_hits++;
			if (current_admin.debug_level >= DBG_ALL) {
				if (MASKUPDATEBIT(in->nsc_callnumber) ==
					GETPWUID) {
		logit("getpw_lookup: %d marked as NOT FOUND in cache.\n",
						in->nsc_u.uid);
				} else {
		logit("getpw_lookup: %s marked as NOT FOUND in cache.\n",
						in->nsc_u.name);
				}
			}
		}

		if ((retb->nsc_timestamp < now) &&
			!(in->nsc_callnumber & UPDATEBIT) &&
			!(retb->nsc_status & ST_UPDATE_PENDING)) {
			logit("launch update since time = %d\n",
				retb->nsc_timestamp);
			retb->nsc_status |= ST_UPDATE_PENDING;
			/* cleared by deletion of old data */
			launch_update(in);
		}
	}

getout:

	mutex_unlock(&passwd_lock);

	/*
	 *	secure mode check - blank out passwd if call sucessfull
	 *	and caller != effective id
	 */
	if ((current_admin.passwd.nsc_secure_mode != 0) &&
		(out->nsc_return_code == SUCCESS) &&
		!(UPDATEBIT & in->nsc_callnumber)) {

		ucred_t *uc = NULL;

		if (door_ucred(&uc) != 0) {
			perror("door_ucred");
		} else {
			if (ucred_geteuid(uc) != out->nsc_u.pwd.pw_uid) {
				/*
				 *  write *NP* into passwd field if
				 *  not already that way... we fixed
				 *  the buffer code so there's always room.
				 */
				int len;

				char *foo = out->nsc_u.buff
					+ sizeof (struct passwd)
					+ (int)out->nsc_u.pwd.pw_passwd;

				len = strlen(foo);
				if (len > 0 &&
				    strcmp(foo, "*NP*") != 0 &&
				    strcmp(foo, "x") != 0) {
					if (len < 5)
						len = 5;
					strncpy(foo, "*NP*", len);
					/*
					 * strncpy will
					 * blank all
					 */
				}
			}
			ucred_free(uc);
		}
	}
}
Пример #7
0
/**
 * Returns whether a particular hash is supported
 */
int hash_supported(int hashtype)
{
    return (get_hash(hashtype) != NULL);
}
Пример #8
0
/**
 * Returns a linked list with the message id of a token.
 */
int get_data_pairs_sh(DB *dbp,char *token, linkedhashmap **pairslist){

    char *hashkey = get_hash(token);

    if(hashkey==NULL){
        wblprintf(LOG_CRITICAL,"LEARN_SPAMHUNTING","Could not compute message digest\n");                  
        return HASH_FAIL;
    }
    else{
        DBT key, data;

        memset(&key,0,sizeof(DBT));
        memset(&data,0,sizeof(DBT));

        key.data = hashkey;
        key.size = sizeof(char)*(strlen(hashkey)+1);

        DBC *cursor;
        int ret;
        dbp->cursor(dbp, NULL, &cursor,0 );

        if((ret=cursor->c_get(cursor,&key,&data,DB_SET))==DB_NOTFOUND){
            free(hashkey);
            return TOKEN_MISSING;
        }
        else{
            //ret=cursor->c_get(cursor,&key,&data,DB_SET)
            while (ret==0 /*&& !strcmp((char *)key.data,hashkey)*/)
            {
                //printf("DATO introducido en la lista %s\n",(char *)data.data);
                //printf("ENCONTRANDO EMAILS DEL TOKEN\n");
                //printf("TOKEN %s\n",(char *)key.data);
                //printf("EMAIL %s\n",(char *)data.data);
                //addorder(*pairslist,&data.data,&compare_pairs);
                any_t elem;
                //hashmap_iterate_elements(lh_gethashmap(*pairslist),&print,NULL);
                if(get_lh_element(*pairslist,(char *)data.data,(any_t *)&elem)==LH_MISSING){
                    //int *data=malloc(sizeof(int));
                    //*data=1;
                    //char * aux=malloc(sizeof(char)*strlen(data.data)+1);
                    //strcpy(aux,data.data);
                    messageoccur *msgoc=malloc(sizeof(messageoccur));
                    //msgoc->message_id=aux;
                    msgoc->message_id=malloc(sizeof(char)*strlen(data.data)+1);
                    strcpy(msgoc->message_id,data.data);
                    msgoc->occurrences=1;
                    //printf("Añadiendo nuevo email: %s\n",(char *)data.data);
                    //printf("AÑADIENDO EMAIL: %s\n",(char *)data.data);
                    //printf("\t KEY_EMAIL: %s\n",msgoc->message_id);
                    //printf("\t OCCURS_TOKEN_EMAIL: %d\n",msgoc->occurrences);
                    //printf("ADD NO EXISTE %d\n",add_lh_element(*pairslist,(char *)data.data,msgoc));
                    add_lh_element(*pairslist,msgoc->message_id,msgoc);
                }
                else{
                    //int *data=malloc(sizeof(int));
                    //*data++;
                    messageoccur *msgoc=(messageoccur *)elem;
                    msgoc->occurrences++;
                    //printf("sumando occur al email: %s\n",(char *)data.data);
                    //printf("EXISTE EMAIL: %s\n",(char *)data.data);
                    //printf("\t KEY_EMAIL: %s\n",msgoc->message_id);
                    //printf("\t OCCURS_TOKEN_EMAIL: %d\n",msgoc->occurrences);
                    //printf("ADD LH EXIST %d\n",add_lh_element(*pairslist,(char *)data.data,msgoc));
                    //add_lh_element(*pairslist,(char *)data.data,msgoc);
                }
                //printf("PROXIMA KEY REPETIDA %d\n",ret=cursor->c_get(cursor,&key,&data,DB_NEXT));
                ret=cursor->c_get(cursor,&key,&data,DB_NEXT_DUP);
                //printf("next_key: %s\n",key.data);
            }
            free(hashkey); //DAVID
            return TOKEN_FOUND;
        }
    }
}
Пример #9
0
token_t
primary(void)
{
    expr_t	*expr;
    entry_t	*entry;
    token_t	 token;
    int		 ch, lineno, column;

    if (ahead) {
        token = ahead->token;
        push_expr(ahead);
        ahead = NULL;
        return (token);
    }
    ch = skipws();
    lineno = parser.lineno;
    column = parser.column - 1;
    switch (ch) {
    case EOF:
        token = tok_eof;
        break;
    case '(':
        token = tok_oparen;
        break;
    case ')':
        token = tok_cparen;
        break;
    case '[':
        token = tok_obrack;
        break;
    case ']':
        token = tok_cbrack;
        break;
    case '{':
        token = tok_obrace;
        break;
    case '}':
        token = tok_cbrace;
        break;
    case ';':
        token = tok_semicollon;
        break;
    case ':':
        token = tok_collon;
        break;
    case ',':
        token = tok_comma;
        break;
    case '.':
        if ((ch = getch()) != '.') {
            ungetch(ch);
            token = tok_dot;
        }
        else if (getch() != '.')		error(NULL, "error near '..'");
        else				token = tok_ellipsis;
        break;
    case '=':
        if ((ch = getch()) == '=')		token = tok_eq;
        else {
            ungetch(ch);
            token = tok_set;
        }
        break;
    case '&':
        if ((ch = getch()) == '&')		token = tok_andand;
        else if (ch == '=')			token = tok_andset;
        else {
            ungetch(ch);
            token = tok_and;
        }
        break;
    case '|':
        if ((ch = getch()) == '|')		token = tok_oror;
        else if (ch == '=')			token = tok_orset;
        else {
            ungetch(ch);
            token = tok_or;
        }
        break;
    case '^':
        if ((ch = getch()) == '=')		token = tok_xorset;
        else {
            ungetch(ch);
            token = tok_xor;
        }
        break;
    case '<':
        if ((ch = getch()) == '=')		token = tok_le;
        else if (ch == '<') {
            if ((ch = getch()) == '=')	token = tok_lshset;
            else {
                ungetch(ch);
                token = tok_lsh;
            }
        }
        else {
            ungetch(ch);
            token = tok_lt;
        }
        break;
    case '>':
        if ((ch = getch()) == '=')		token = tok_ge;
        else if (ch == '>') {
            if ((ch = getch()) == '=')	token = tok_rshset;
            else {
                ungetch(ch);
                token = tok_rsh;
            }
        }
        else {
            ungetch(ch);
            token = tok_gt;
        }
        break;
    case '+':
        if ((ch = getch()) == '+')		token = tok_inc;
        else if (ch == '=')			token = tok_addset;
        else {
            ungetch(ch);
            token = tok_add;
        }
        break;
    case '-':
        if ((ch = getch()) == '-')		token = tok_dec;
        else if (ch == '=')			token = tok_subset;
        else if (ch == '>')			token = tok_arrow;
        else {
            ungetch(ch);
            token = tok_sub;
        }
        break;
    case '*':
        if ((ch = getch()) == '=')		token = tok_mulset;
        else {
            ungetch(ch);
            token = tok_mul;
        }
        break;
    case '/':
        if ((ch = getch()) == '=')		token = tok_divset;
        else {
            ungetch(ch);
            token = tok_div;
        }
        break;
    case '%':
        if ((ch = getch()) == '=')		token = tok_remset;
        else {
            ungetch(ch);
            token = tok_rem;
        }
        break;
    case '!':
        if ((ch = getch()) == '=')		token = tok_ne;
        else {
            ungetch(ch);
            token = tok_not;
        }
        break;
    case '~':
        token = tok_com;
        break;
    case '?':
        token = tok_question;
        break;
    case 'a' ... 'z':
    case 'A' ... 'Z':
    case '_':
        token = identifier(ch);
        break;
    case '0' ... '9':
        token = number(ch);
        break;
    case '"':
        token = string();
        break;
    case '\'':
        token = character();
        break;
    default:
        error(NULL, "syntax error");
    }

    parser.token = token;
    expr = new_expr(token, lineno, column);
    if (token == tok_string) {
        if ((entry = get_hash(strings, parser.string)) == NULL) {
            entry = (entry_t *)xmalloc(sizeof(entry_t));
            entry->name.string = xstrdup(parser.string);
            entry->value = entry->name.string;
            put_hash(strings, entry);
        }
        expr->data._unary.cp = entry->value;
    }
    else
        expr->data._unary = parser.value;
    push_expr(expr);

    return (token);
}
void single_sort(const char *dist_name, function_ptr dist_func, const char *sort_name, function_ptr sort_func, int runs /*, float percent, float offset*/)
{
	double cmean, csdev, tmean, tsdev, pmean, psdev;
	struct timespec t0, t1;
	int hash = 0;
	//std::cout << "percent=" << percent << "  offset=" << offset << "  ";

	int progress = (runs <= 10) ? 1 : runs / 10;
	std::cout << std::setprecision(0) << std::fixed;

	if (! verbose) {
		std::cout << dist_name << "  " << sort_name << "  " << std::flush;
	}

	for (int i = 1; i <= runs; i++) {
		random_seed(i);
		tcomp = tread = twrit = tpass = 0;
		(*dist_func)();

		if (verbose) {
			if (verbose == 1) {
				std::cout << "seed=" << i << "  ";
			}
			else {
				std::cout << "---------------- seed=" << i << '\n';
			}
			(*sort_func)();
			msec[i - 1] = 0;
		}
		else {
			if ((i % progress) == 0) {
				std::cout << '.' << std::flush;
			}
			//(*sort_func)();
			//update(percent, offset);
			clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t0);
			(*sort_func)();
			clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
			msec[i - 1] = (t1.tv_sec - t0.tv_sec) * 1000.0 + (t1.tv_nsec - t0.tv_nsec) * 0.000001;
		}

		comp[i - 1] = tcomp;
		pass[i - 1] = tpass;
		if (i == 1) {
			hash = get_hash();
		}
		else {
			hash ^= get_hash();
		}
		if (! is_spatially_sorted()) {
			std::cout << "result is not sorted!\n";
		}
	}

	if (verbose) {
		std::cout << dist_name << "  " << sort_name << "            ";
	}
	else {
		if (progress == 1) {
			for (int i = runs; i < 10; i++) {
				std::cout << ' ';
			}
		}
	}
	cmean = gsl_stats_mean(comp, 1, runs);
	csdev = gsl_stats_sd(comp, 1, runs);
	tmean = gsl_stats_mean(msec, 1, runs);
	tsdev = gsl_stats_sd(msec, 1, runs);
	pmean = gsl_stats_mean(pass, 1, runs);
	psdev = gsl_stats_sd(pass, 1, runs);
	std::cout << std::setw(12) << cmean << ' ' << std::setw(12) << csdev << ' ';
	std::cout << std::setprecision(2) << std::fixed;
	std::cout << std::setw(12) << tmean << ' ' << std::setw(12) << tsdev << ' ';
	std::cout << std::setw(12) << pmean << ' ' << std::setw(12) << psdev << "  ";
	std::cout << std::hex << hash << std::dec << '\n';
}
Пример #11
0
VALUE
rb_str_format(int argc, const VALUE *argv, VALUE fmt)
{
    enum {default_float_precision = 6};
    rb_encoding *enc;
    const char *p, *end;
    char *buf;
    long blen, bsiz;
    VALUE result;

    long scanned = 0;
    int coderange = ENC_CODERANGE_7BIT;
    int width, prec, flags = FNONE;
    int nextarg = 1;
    int posarg = 0;
    int tainted = 0;
    VALUE nextvalue;
    VALUE tmp;
    VALUE str;
    volatile VALUE hash = Qundef;

#define CHECK_FOR_WIDTH(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "width given twice");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "width after precision"); \
    }
#define CHECK_FOR_FLAGS(f)				 \
    if ((f) & FWIDTH) {					 \
	rb_raise(rb_eArgError, "flag after width");	 \
    }							 \
    if ((f) & FPREC0) {					 \
	rb_raise(rb_eArgError, "flag after precision"); \
    }

    ++argc;
    --argv;
    if (OBJ_TAINTED(fmt)) tainted = 1;
    StringValue(fmt);
    enc = rb_enc_get(fmt);
    fmt = rb_str_new4(fmt);
    p = RSTRING_PTR(fmt);
    end = p + RSTRING_LEN(fmt);
    blen = 0;
    bsiz = 120;
    result = rb_str_buf_new(bsiz);
    rb_enc_copy(result, fmt);
    buf = RSTRING_PTR(result);
    memset(buf, 0, bsiz);
    ENC_CODERANGE_SET(result, coderange);

    for (; p < end; p++) {
	const char *t;
	int n;
	VALUE sym = Qnil;

	for (t = p; t < end && *t != '%'; t++) ;
	PUSH(p, t - p);
	if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
	    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange);
	    ENC_CODERANGE_SET(result, coderange);
	}
	if (t >= end) {
	    /* end of fmt string */
	    goto sprint_exit;
	}
	p = t + 1;		/* skip `%' */

	width = prec = -1;
	nextvalue = Qundef;
      retry:
	switch (*p) {
	  default:
	    if (rb_enc_isprint(*p, enc))
		rb_raise(rb_eArgError, "malformed format string - %%%c", *p);
	    else
		rb_raise(rb_eArgError, "malformed format string");
	    break;

	  case ' ':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSPACE;
	    p++;
	    goto retry;

	  case '#':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FSHARP;
	    p++;
	    goto retry;

	  case '+':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FPLUS;
	    p++;
	    goto retry;

	  case '-':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FMINUS;
	    p++;
	    goto retry;

	  case '0':
	    CHECK_FOR_FLAGS(flags);
	    flags |= FZERO;
	    p++;
	    goto retry;

	  case '1': case '2': case '3': case '4':
	  case '5': case '6': case '7': case '8': case '9':
	    n = 0;
	    GETNUM(n, width);
	    if (*p == '$') {
		if (nextvalue != Qundef) {
		    rb_raise(rb_eArgError, "value given twice - %d$", n);
		}
		nextvalue = GETPOSARG(n);
		p++;
		goto retry;
	    }
	    CHECK_FOR_WIDTH(flags);
	    width = n;
	    flags |= FWIDTH;
	    goto retry;

	  case '<':
	  case '{':
	    {
		const char *start = p;
		char term = (*p == '<') ? '>' : '}';
		int len;

		for (; p < end && *p != term; ) {
		    p += rb_enc_mbclen(p, end, enc);
		}
		if (p >= end) {
		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
		}
#if SIZEOF_INT < SIZEOF_SIZE_T
		if ((size_t)(p - start) >= INT_MAX) {
		    const int message_limit = 20;
		    len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start);
		    rb_enc_raise(enc, rb_eArgError,
				 "too long name (%"PRIdSIZE" bytes) - %.*s...%c",
				 (size_t)(p - start - 2), len, start, term);
		}
#endif
		len = (int)(p - start + 1); /* including parenthesis */
		if (sym != Qnil) {
		    rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">",
				 len, start, rb_sym2str(sym));
		}
		CHECKNAMEARG(start, len, enc);
		get_hash(&hash, argc, argv);
		sym = rb_check_symbol_cstr(start + 1,
					   len - 2 /* without parenthesis */,
					   enc);
		if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
		if (nextvalue == Qundef) {
		    if (NIL_P(sym)) {
			sym = rb_sym_intern(start + 1,
					    len - 2 /* without parenthesis */,
					    enc);
		    }
		    nextvalue = rb_hash_default_value(hash, sym);
		    if (NIL_P(nextvalue)) {
			rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
		    }
		}
		if (term == '}') goto format_s;
		p++;
		goto retry;
	    }

	  case '*':
	    CHECK_FOR_WIDTH(flags);
	    flags |= FWIDTH;
	    GETASTER(width);
	    if (width < 0) {
		flags |= FMINUS;
		width = -width;
	    }
	    p++;
	    goto retry;

	  case '.':
	    if (flags & FPREC0) {
		rb_raise(rb_eArgError, "precision given twice");
	    }
	    flags |= FPREC|FPREC0;

	    prec = 0;
	    p++;
	    if (*p == '*') {
		GETASTER(prec);
		if (prec < 0) {	/* ignore negative precision */
		    flags &= ~FPREC;
		}
		p++;
		goto retry;
	    }

	    GETNUM(prec, precision);
	    goto retry;

	  case '\n':
	  case '\0':
	    p--;
	  case '%':
	    if (flags != FNONE) {
		rb_raise(rb_eArgError, "invalid format character - %%");
	    }
	    PUSH("%", 1);
	    break;

	  case 'c':
	    {
		VALUE val = GETARG();
		VALUE tmp;
		unsigned int c;
		int n;

		tmp = rb_check_string_type(val);
		if (!NIL_P(tmp)) {
		    if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) {
			rb_raise(rb_eArgError, "%%c requires a character");
		    }
		    c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc);
		    RB_GC_GUARD(tmp);
		}
		else {
		    c = NUM2INT(val);
		    n = rb_enc_codelen(c, enc);
		}
		if (n <= 0) {
		    rb_raise(rb_eArgError, "invalid character");
		}
		if (!(flags & FWIDTH)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
		else if ((flags & FMINUS)) {
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		    if (width > 1) FILL(' ', width-1);
		}
		else {
		    if (width > 1) FILL(' ', width-1);
		    CHECK(n);
		    rb_enc_mbcput(c, &buf[blen], enc);
		    blen += n;
		}
	    }
	    break;

	  case 's':
	  case 'p':
	  format_s:
	    {
		VALUE arg = GETARG();
		long len, slen;

		if (*p == 'p') {
		    str = rb_inspect(arg);
		}
		else {
		    str = rb_obj_as_string(arg);
		}
		if (OBJ_TAINTED(str)) tainted = 1;
		len = RSTRING_LEN(str);
		rb_str_set_len(result, blen);
		if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) {
		    int cr = coderange;
		    scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr);
		    ENC_CODERANGE_SET(result,
				      (cr == ENC_CODERANGE_UNKNOWN ?
				       ENC_CODERANGE_BROKEN : (coderange = cr)));
		}
		enc = rb_enc_check(result, str);
		if (flags&(FPREC|FWIDTH)) {
		    slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc);
		    if (slen < 0) {
			rb_raise(rb_eArgError, "invalid mbstring sequence");
		    }
		    if ((flags&FPREC) && (prec < slen)) {
			char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str),
					     prec, enc);
			slen = prec;
			len = p - RSTRING_PTR(str);
		    }
		    /* need to adjust multi-byte string pos */
		    if ((flags&FWIDTH) && (width > slen)) {
			width -= (int)slen;
			if (!(flags&FMINUS)) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			CHECK(len);
			memcpy(&buf[blen], RSTRING_PTR(str), len);
			RB_GC_GUARD(str);
			blen += len;
			if (flags&FMINUS) {
			    CHECK(width);
			    while (width--) {
				buf[blen++] = ' ';
			    }
			}
			rb_enc_associate(result, enc);
			break;
		    }
		}
		PUSH(RSTRING_PTR(str), len);
		RB_GC_GUARD(str);
		rb_enc_associate(result, enc);
	    }
	    break;

	  case 'd':
	  case 'i':
	  case 'o':
	  case 'x':
	  case 'X':
	  case 'b':
	  case 'B':
	  case 'u':
	    {
		volatile VALUE val = GETARG();
                int valsign;
		char nbuf[64], *s;
		const char *prefix = 0;
		int sign = 0, dots = 0;
		char sc = 0;
		long v = 0;
		int base, bignum = 0;
		int len;

		switch (*p) {
		  case 'd':
		  case 'i':
		  case 'u':
		    sign = 1; break;
		  case 'o':
		  case 'x':
		  case 'X':
		  case 'b':
		  case 'B':
		    if (flags&(FPLUS|FSPACE)) sign = 1;
		    break;
		}
		if (flags & FSHARP) {
		    switch (*p) {
		      case 'o':
			prefix = "0"; break;
		      case 'x':
			prefix = "0x"; break;
		      case 'X':
			prefix = "0X"; break;
		      case 'b':
			prefix = "0b"; break;
		      case 'B':
			prefix = "0B"; break;
		    }
		}

	      bin_retry:
		switch (TYPE(val)) {
		  case T_FLOAT:
		    if (FIXABLE(RFLOAT_VALUE(val))) {
			val = LONG2FIX((long)RFLOAT_VALUE(val));
			goto bin_retry;
		    }
		    val = rb_dbl2big(RFLOAT_VALUE(val));
		    if (FIXNUM_P(val)) goto bin_retry;
		    bignum = 1;
		    break;
		  case T_STRING:
		    val = rb_str_to_inum(val, 0, TRUE);
		    goto bin_retry;
		  case T_BIGNUM:
		    bignum = 1;
		    break;
		  case T_FIXNUM:
		    v = FIX2LONG(val);
		    break;
		  default:
		    val = rb_Integer(val);
		    goto bin_retry;
		}

		switch (*p) {
		  case 'o':
		    base = 8; break;
		  case 'x':
		  case 'X':
		    base = 16; break;
		  case 'b':
		  case 'B':
		    base = 2; break;
		  case 'u':
		  case 'd':
		  case 'i':
		  default:
		    base = 10; break;
		}

                if (base != 10) {
                    int numbits = ffs(base)-1;
                    size_t abs_nlz_bits;
                    size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits);
                    long i;
                    if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */
                        rb_raise(rb_eArgError, "size too big");
                    if (sign) {
                        if (numdigits == 0)
                            numdigits = 1;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        if (valsign < 0) {
                            sc = '-';
                            width--;
                        }
                        else if (flags & FPLUS) {
                            sc = '+';
                            width--;
                        }
                        else if (flags & FSPACE) {
                            sc = ' ';
                            width--;
                        }
                    }
                    else {
                        /* Following conditional "numdigits++" guarantees the
                         * most significant digit as
                         * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers
                         * - '0' for zero
                         * - not '0' for positive numbers.
                         *
                         * It also guarantees the most significant two
                         * digits will not be '11'(bin), '77'(oct), 'ff'(hex)
                         * or '00'.  */
                        if (numdigits == 0 ||
                                ((abs_nlz_bits != (size_t)(numbits-1) ||
                                  !rb_absint_singlebit_p(val)) &&
                                 (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val))))
                            numdigits++;
                        tmp = rb_str_new(NULL, numdigits);
                        valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp),
                                1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN);
                        for (i = 0; i < RSTRING_LEN(tmp); i++)
                            RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]];
                        s = RSTRING_PTR(tmp);
                        dots = valsign < 0;
                    }
                    len = rb_long2int(RSTRING_END(tmp) - s);
                }
                else if (!bignum) {
                    valsign = 1;
                    if (v < 0) {
                        v = -v;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
                    snprintf(nbuf, sizeof(nbuf), "%ld", v);
                    s = nbuf;
		    len = (int)strlen(s);
		}
		else {
                    tmp = rb_big2str(val, 10);
                    s = RSTRING_PTR(tmp);
                    valsign = 1;
                    if (s[0] == '-') {
                        s++;
                        sc = '-';
                        width--;
                        valsign = -1;
                    }
                    else if (flags & FPLUS) {
                        sc = '+';
                        width--;
                    }
                    else if (flags & FSPACE) {
                        sc = ' ';
                        width--;
                    }
		    len = rb_long2int(RSTRING_END(tmp) - s);
		}

		if (dots) {
		    prec -= 2;
		    width -= 2;
		}

		if (*p == 'X') {
		    char *pp = s;
		    int c;
		    while ((c = (int)(unsigned char)*pp) != 0) {
			*pp = rb_enc_toupper(c, enc);
			pp++;
		    }
		}
		if (prefix && !prefix[1]) { /* octal */
		    if (dots) {
			prefix = 0;
		    }
		    else if (len == 1 && *s == '0') {
			len = 0;
			if (flags & FPREC) prec--;
		    }
		    else if ((flags & FPREC) && (prec > len)) {
			prefix = 0;
		    }
		}
		else if (len == 1 && *s == '0') {
		    prefix = 0;
		}
		if (prefix) {
		    width -= (int)strlen(prefix);
		}
		if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) {
		    prec = width;
		    width = 0;
		}
		else {
		    if (prec < len) {
			if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0;
			prec = len;
		    }
		    width -= prec;
		}
		if (!(flags&FMINUS)) {
		    CHECK(width);
		    while (width-- > 0) {
			buf[blen++] = ' ';
		    }
		}
		if (sc) PUSH(&sc, 1);
		if (prefix) {
		    int plen = (int)strlen(prefix);
		    PUSH(prefix, plen);
		}
		CHECK(prec - len);
		if (dots) PUSH("..", 2);
		if (!sign && valsign < 0) {
		    char c = sign_bits(base, p);
		    while (len < prec--) {
			buf[blen++] = c;
		    }
		}
		else if ((flags & (FMINUS|FPREC)) != FMINUS) {
		    while (len < prec--) {
			buf[blen++] = '0';
		    }
		}
		PUSH(s, len);
		RB_GC_GUARD(tmp);
		CHECK(width);
		while (width-- > 0) {
		    buf[blen++] = ' ';
		}
	    }
	    break;

	  case 'f':
	    {
		VALUE val = GETARG(), num, den;
		int sign = (flags&FPLUS) ? 1 : 0, zero = 0;
		long len, done = 0;
		int prefix = 0;
		if (FIXNUM_P(val) || RB_TYPE_P(val, T_BIGNUM)) {
		    den = INT2FIX(1);
		    num = val;
		}
		else if (RB_TYPE_P(val, T_RATIONAL)) {
		    den = rb_rational_den(val);
		    num = rb_rational_num(val);
		}
		else {
		    nextvalue = val;
		    goto float_value;
		}
		if (!(flags&FPREC)) prec = default_float_precision;
		if (FIXNUM_P(num)) {
		    if ((SIGNED_VALUE)num < 0) {
			long n = -FIX2LONG(num);
			num = LONG2FIX(n);
			sign = -1;
		    }
		}
		else if (rb_num_negative_p(num)) {
		    sign = -1;
		    num = rb_funcallv(num, idUMinus, 0, 0);
		}
		if (den != INT2FIX(1) || prec > 1) {
		    const ID idDiv = rb_intern("div");
		    VALUE p10 = rb_int_positive_pow(10, prec);
		    VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2));
		    num = rb_funcallv(num, '*', 1, &p10);
		    num = rb_funcallv(num, '+', 1, &den_2);
		    num = rb_funcallv(num, idDiv, 1, &den);
		}
		else if (prec >= 0) {
		    zero = prec;
		}
		val = rb_obj_as_string(num);
		len = RSTRING_LEN(val) + zero;
		if (prec >= len) len = prec + 1; /* integer part 0 */
		if (sign || (flags&FSPACE)) ++len;
		if (prec > 0) ++len; /* period */
		CHECK(len > width ? len : width);
		if (sign || (flags&FSPACE)) {
		    buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' ';
		    prefix++;
		    done++;
		}
		len = RSTRING_LEN(val) + zero;
		t = RSTRING_PTR(val);
		if (len > prec) {
		    memcpy(&buf[blen], t, len - prec);
		    blen += len - prec;
		    done += len - prec;
		}
		else {
		    buf[blen++] = '0';
		    done++;
		}
		if (prec > 0) {
		    buf[blen++] = '.';
		    done++;
		}
		if (zero) {
		    FILL('0', zero);
		    done += zero;
		}
		else if (prec > len) {
		    FILL('0', prec - len);
		    memcpy(&buf[blen], t, len);
		    blen += len;
		    done += prec;
		}
		else if (prec > 0) {
		    memcpy(&buf[blen], t + len - prec, prec);
		    blen += prec;
		    done += prec;
		}
		if ((flags & FWIDTH) && width > done) {
		    int fill = ' ';
		    long shifting = 0;
		    if (!(flags&FMINUS)) {
			shifting = done;
			if (flags&FZERO) {
			    shifting -= prefix;
			    fill = '0';
			}
			blen -= shifting;
			memmove(&buf[blen + width - done], &buf[blen], shifting);
		    }
		    FILL(fill, width - done);
		    blen += shifting;
		}
		RB_GC_GUARD(val);
		break;
	    }
	  case 'g':
	  case 'G':
	  case 'e':
	  case 'E':
	    /* TODO: rational support */
	  case 'a':
	  case 'A':
	  float_value:
	    {
		VALUE val = GETARG();
		double fval;
		int i, need;
		char fbuf[32];

		fval = RFLOAT_VALUE(rb_Float(val));
		if (isnan(fval) || isinf(fval)) {
		    const char *expr;

		    if (isnan(fval)) {
			expr = "NaN";
		    }
		    else {
			expr = "Inf";
		    }
		    need = (int)strlen(expr);
		    if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
			need++;
		    if ((flags & FWIDTH) && need < width)
			need = width;

		    CHECK(need + 1);
		    snprintf(&buf[blen], need + 1, "%*s", need, "");
		    if (flags & FMINUS) {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen++] = '-';
			else if (flags & FPLUS)
			    buf[blen++] = '+';
			else if (flags & FSPACE)
			    blen++;
			memcpy(&buf[blen], expr, strlen(expr));
		    }
		    else {
			if (!isnan(fval) && fval < 0.0)
			    buf[blen + need - strlen(expr) - 1] = '-';
			else if (flags & FPLUS)
			    buf[blen + need - strlen(expr) - 1] = '+';
			else if ((flags & FSPACE) && need > width)
			    blen++;
			memcpy(&buf[blen + need - strlen(expr)], expr,
			       strlen(expr));
		    }
		    blen += strlen(&buf[blen]);
		    break;
		}

		fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec);
		need = 0;
		if (*p != 'e' && *p != 'E') {
		    i = INT_MIN;
		    frexp(fval, &i);
		    if (i > 0)
			need = BIT_DIGITS(i);
		}
		need += (flags&FPREC) ? prec : default_float_precision;
		if ((flags&FWIDTH) && need < width)
		    need = width;
		need += 20;

		CHECK(need);
		snprintf(&buf[blen], need, fbuf, fval);
		blen += strlen(&buf[blen]);
	    }
	    break;
	}
	flags = FNONE;
    }

  sprint_exit:
    RB_GC_GUARD(fmt);
    /* XXX - We cannot validate the number of arguments if (digit)$ style used.
     */
    if (posarg >= 0 && nextarg < argc) {
	const char *mesg = "too many arguments for format string";
	if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg);
	if (RTEST(ruby_verbose)) rb_warn("%s", mesg);
    }
    rb_str_resize(result, blen);

    if (tainted) OBJ_TAINT(result);
    return result;
}
Пример #12
0
LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void)
{
    return get_hash(0, 1);
}
Пример #13
0
int
new_solution (int (*board)[COL_MAX + 1], List* list)
{
    int i;
    int* hash;
    int hash_list[8];
    ListElmt *element;

    /* Go through all 8 board positions that arise through mirroring
     * the board.
     *
     * Important to get back to the starting position, because 'next_queen'
     * relies on using the same board position to carry
     * on the search for all solutions.
     */
    hash_list[0] = get_hash (board);
    board_mirror_row (board);
    hash_list[1] = get_hash (board);
    board_mirror_col (board);
    hash_list[2] = get_hash (board);
    board_mirror_row (board);
    hash_list[3] = get_hash (board);
    board_mirror_diagonal (board);
    hash_list[4] = get_hash (board);
    board_mirror_col (board);
    hash_list[5] = get_hash (board);
    board_mirror_row (board);
    hash_list[6] = get_hash (board);
    board_mirror_col (board);
    hash_list[7] = get_hash (board);
    board_mirror_diagonal (board);

    /* Traverse the linked list from the head to find
     * any item the same as in the hash list. */
    element = list_head (list);
    while (element != NULL) {
        for (i = 0; i < 8; i++) {
            if (*(int *) list_data (element) == hash_list[i])
                return false;
        }
        element = list_next (element);
    }

    /* for (i = 0; i < 8; i++) {  */
        /* printf ("hash[%d]=%d\n", i, hash_list[i]);  */
    /* }  */

    hash = malloc (sizeof(int));
    if (hash == NULL) {
        printf ("Out of memory\n");
        exit(1);
    }

    *hash = hash_list[0];
    element = list_tail (list);
    if (list_ins_next (list, element, hash) == -1) {
        printf ("out of memory\n");
        exit(1);
    }
    return true;
}
Пример #14
0
/*!
 *****************************************************************************
 *
 ****************************************************************************/
void hashtable_entry_delete(void *h, const char *key)
{
        struct hash_table *ht = h;
        uint32_t i;

        if (key) {
                uint32_t hash = get_hash(key, ht->size);
                struct hash_table_entry *b = &ht->bucket[hash];
                struct hash_table_entry *p = b;
                printd(3, "Invalidating hash key %s in %p\n", key, ht);

                /* Search collision chain */
                while (p->next) {
                        struct hash_table_entry *prev = p;
                        p = p->next;
                        if (p->key && !strcmp(key, p->key)) {
                                if (p->user_data)
                                        ht->ops.free(p->user_data);
                                prev->next = p->next;
                                free(p->key);
                                free(p);
                                /* Entry purged. We can leave now. */
                                return;
                        }
                }

                /*
                 * Entry not found in collision chain.
                 * Most likely it is in the bucket, but double check.
                 */
                if (b->key && !strcmp(b->key, key)) {
                        /* Need to relink collision chain */
                        if (b->next) {
                                struct hash_table_entry *tmp = b->next;
                                if (b->user_data)
                                        ht->ops.free(b->user_data);
                                free(b->key);
                                memcpy(b, b->next,
                                            sizeof(struct hash_table_entry));
                                free(tmp);
                        } else {
                                ht->ops.free(b->user_data);
                                free(b->key);
                                memset(b, 0, sizeof(struct hash_table_entry));
                        }
                }
        } else {
                printd(3, "Invalidating all hash keys in %p\n", ht);
                for (i = 0; i < ht->size; i++) {
                        struct hash_table_entry *b = &ht->bucket[i];
                        struct hash_table_entry *next = b->next;

                        /* Search collision chain */
                        while (next) {
                                struct hash_table_entry *p = next;
                                next = p->next;
                                if (p->user_data)
                                        ht->ops.free(p->user_data);
                                free(p->key);
                                free(p);
                        }
                        if (b->user_data)
                                ht->ops.free(b->user_data);
                        free(b->key);
                        memset(b, 0, sizeof(struct hash_table_entry));
                }
        }
}
Пример #15
0
/**
 * Gets the length of the given hash
 */
int get_hash_len(int hashtype)
{
    const EVP_MD *hashptr = get_hash(hashtype);

    return EVP_MD_size(hashptr);
}
Пример #16
0
int
filehash_get(const unsigned char *path, unsigned char *val)
{
  unsigned long p_hash;
  unsigned int idx, i, min_i;
  struct hash_entry *p, *q;
  FILE *f = 0;
  unsigned min_tick;

  ASSERT(path);
  p_hash = get_hash(path);

  idx = p_hash % HASH_SIZE;
  while (hash_table[idx] && hash_table[idx]->path_hash == p_hash
         && strcmp(hash_table[idx]->path, path) != 0) {
    idx = (idx + HASH_STEP) % HASH_SIZE;
  }
  if (hash_table[idx] && hash_table[idx]->path_hash == p_hash) {
    // hit!
    if (!file_stamp_is_updated(path, hash_table[idx]->stamp)) {
      info("entry <%s> is in hash table and is not changed", path);
      memcpy(val, hash_table[idx]->sha1_hash, SHA1_SIZE);
      hash_table[idx]->tick = cur_tick++;
      return 0;
    }
    // update the hash code, maybe removing an item
    info("entry <%s> is in hash table and is CHANGED!", path);
    hash_table[idx]->stamp = file_stamp_update(path, hash_table[idx]->stamp);
    if (!hash_table[idx]->stamp || !(f = fopen(path, "rb"))
        || sha_stream(f, hash_table[idx]->sha1_hash)) {
      // file no longer exists or I/O error
      if (f) fclose(f);
      p = remove_hash_item(idx);
      free_hash_item(p);
      hash_use--;
      return -1;
    }
    // recalculate the hash
    fclose(f);
    memcpy(val, hash_table[idx]->sha1_hash, SHA1_SIZE);
    hash_table[idx]->tick = cur_tick++;
    return 0;
  }

  // no entry in the hash table
  XCALLOC(p, 1);
  if (!(p->stamp = file_stamp_get(path))
      || !(f = fopen(path, "rb"))
      || sha_stream(f, p->sha1_hash)) {
    if (f) fclose(f);
    free_hash_item(p);
    return -1;
  }
  fclose(f);
  p->path_hash = p_hash;
  p->path = xstrdup(path);
  p->tick = cur_tick++;
  memcpy(val, p->sha1_hash, SHA1_SIZE);
  if (hash_use < HASH_CAP) {
    info("entry <%s> is not in the hash table - adding", path);
    add_hash_item(p);
    hash_use++;
    return 0;
  }

  // find the least recently used entry and remove it
  info("entry <%s> is not in the hash table - REPLACING", path);
  min_i = -1;
  min_tick = cur_tick;
  for (i = 0; i < HASH_SIZE; i++)
    if (hash_table[i] && hash_table[i]->tick < min_tick) {
      min_i = i;
      min_tick = hash_table[i]->tick;
    }
  ASSERT(min_i >= 0);
  q = remove_hash_item(min_i);
  free_hash_item(q);
  add_hash_item(p);
  return 0;
}
Пример #17
0
	/// Erzeugt aus dem Schedule einen eindeutigen Hashwert.
	/// Der Hashwert wird dabei nur einmal ermittelt. D.h. werden 
	/// weitere Operationen angefuegt, dann ändert sich der Hashwert nicht.
	long get_hash() {
		if (Hash==-1) {
			Hash=get_hash(Schedule);
		}
		return Hash;
	}
Пример #18
0
/** Author: Xiaoman Xu
 *	Server side data link layer
 *	receives frames and 
 * 	reassembles it into a packet
 *	and forward to to server netword layer
 **/
int datalink_recv(unsigned short sock, packet_t* packet, FILE* &outlog)
{
	int frame_num = 0;
	size_t recv_at = 0;
	int recv_size = 0;
	frame_t frame, ack_frame;;
    bool valid, repeat = false; 

	size_t packet_size = sizeof(packet_t);

	//while still more to receive
	while(recv_at < packet_size)
	{
		uint16_t frame_expected;
		frame_expected = ack_frame_send_seq;
        valid = false;

        //if the data frame received is not valid,
        //keep receiving
        while (!valid) {
            if((recv_size = physical_recv(sock, & frame)) != sizeof(frame_t))
            {
                DieWithError("Server DataLink: Physical layer receive different size %d than expected", recv_size);
            }

            //if the data frame seq num is the frame expected, 
            //then copy the data from the payload
            if(frame.sequence_num == frame_expected)
            {
            	
            	repeat = false;
            	memcpy(((char*)packet) + recv_at, frame.payload, frame.length);
            	
            }

            //selse the data frame is repeated.
            else
            {
            	repeat = true;
            }
            // check whether the data frame is valid
            valid = frame.check == get_hash(&frame);
            if(!valid)
            	fprintf(outlog, "Server data link layer: data frame %d of packet %d received in error (frame %d)\n",
            		frame_num, packet_sent, frame_expected);
        }

        //open the log file if not already
        if(outlog == NULL)
        {
        	char logname [20];
        	sprintf(logname, "server_%c.log", packet->filename[0]);
        	outlog = fopen(logname, "w");
        }
		ack_frame.type = FRAME_ACK;
		ack_frame.length = 0;
		ack_frame.sequence_num = ack_frame_send_seq;
	    ack_frame.check = get_hash(&ack_frame);
	    //send the ACK frame to client
		if(!repeat)
		{
			frame_num ++;
			fprintf(outlog, "Server Data Link: data frame %d of packet %d received.(frame %d)\n",
        		frame_num, packet_sent, frame_expected);
			recv_at += frame.length;
			flip_frame(&ack_frame);
			ack_frame_send_seq++;

		}
		else
		{
			fprintf(outlog, "Server data link: data frame %d of packet %d repeated!(frame %d)\n",
				frame_num, packet_sent, frame_expected);
		}
		
		datalink_send_ACK(sock, &ack_frame);
		fprintf(outlog, "Server data link layer: ACK frame %d of packet %d sent.(frame %d)\n",
			frame_num, packet_sent, frame_expected);

		if(frame.is_end&&repeat)
		{
			return 0;
		}	
	}
	packet_sent++;
    
	return sizeof(packet_t);
}
Пример #19
0
static bool cmp_hash(char hash[HASH_SIZE],char * str,int len) {
	char hexstring[41];
	get_hash(hexstring,str,len);
	return (strncmp(hash,hexstring,HASH_SIZE) == 0);
}