Пример #1
0
int main(int argc, char** argv)
{
  int i=0;
  int tailleO=0;
  int *ptrT=&tailleO;
  char **tabCodes;

  if (argc<2){
    printf("erreur"); /*aide();*/
    return 0;
  }

  tabCodes=getCodes(argv[1],ptrT);
  
  printf("taille originale du fichier a décomprésser:%d\n",tailleO);
  for (i=0;i<256;i++){
    if(tabCodes[i]!=NULL)
      printf("%d:%s\n",i,tabCodes[i]);
  }

  decompresser(argv[1],tabCodes, ptrT);
   
  
  for(i=0;i<256;i++) {
    free(tabCodes[i]);
  }
  free(tabCodes);
  return 0;
}
Пример #2
0
const LCDbTest::MachineDef * LCDbTest::findMachineDef( int buddyID ) const
{
	const LCDbAnalysers & machines = LCDbAnalysers::records();
	if( buddyID == 0 )
		buddyID = machines.getCurrentID();

	const MachineDef * found = NULL;
	const std::set< int > allIDs = machines.getMachineIDs( buddyID );
	for( Range< MachineDef > mi = getCodes(); mi.isValid(); ++ mi )
	{
		if( allIDs.count( mi -> getMachineID() ) != 0 )
		{
			// give preference to local definition against clusters'
			if( found == NULL || (mi -> getMachineID() == buddyID
							&& found -> getMachineID() != buddyID) )
				found = &(*mi);

			// but don't return anything if the definition's ambiguous
			else if( found -> getProtocol() != mi -> getProtocol()
				  || found -> getTestOrder() != mi -> getTestOrder()
				  || found -> getCode() != mi -> getCode() )
			{
				return NULL;
			}
		}
	}
	return found;
}
Пример #3
0
/* Compress file */
void compressFile(FILE *fin, FILE *fout){
	 	/* Create Huffman tree - indexed */
		uint32_t numberOfChars = 0;
		queue *Huffman = HuffmanTree(fin, &numberOfChars);
		uint16_t numberOfNodes = countNodes(Huffman);
		treeIndexing(Huffman);
		/* Create TagHuffmanNode array */
		createTagHuffmanVector(Huffman);
		/* Get codes for each character */
		getCodes(Huffman, 0);
		/* Write in binary file - number of characters and number of nodes */
		fwrite(&numberOfChars, sizeof(uint32_t), 1, fout);
		fwrite(&numberOfNodes, sizeof(uint16_t), 1, fout);
		/* Prase file */
		unsigned char c;
		rewind(fin);
		int i, j;
		/* Write TagHuffmanNode array */
		for(i = 0; i < indexTagHuffman; i++)
			fwrite(&vectorTagHuffman[i], sizeof(TagHuffmanNode), 1, fout);
		/* Parse file and binary compression */
		char code = 0;
		int bitCount = 0; // number of bits
		while(fscanf(fin, "%c", &c) && !feof(fin)){
			/* Search for character code */
			for(i = 0; i < huffCodesCount; i++){
				if (huffCode[i].caracter == c){
					/* Write in file according to the code */
					for(j = 0; j < huffCode[i].length; j++){
						if(huffCode[i].code[j] == 0)
							code = code << 1;
						else
							code = (code << 1) | 1;
						bitCount++;
						/* Write in file when 8 bits are counted */
						if(bitCount == 8){
							fwrite(&code, sizeof(char), 1, fout);
							bitCount = 0;
						}
					}
					break;
				}
			}
		}
		/* Bits left */
		if(bitCount != 0){
			while(bitCount != 8){
				code = code << 1;
				bitCount++;
			}
			fwrite(&code, sizeof(char), 1, fout);
		}
		/* Eliberare arbore */
		freeTree(Huffman);
}
Пример #4
0
std::string LCDbTest::findTestCode( const std::set< int > & machines, short protocol ) const
{
	std::set< std::string > codes;
	for( Range< LCDbTest::MachineDef > mi = getCodes(); mi.isValid(); ++ mi )
		if( mi -> getProtocol() == protocol && machines.count( mi -> getMachineID() ) != 0 )
			codes.insert( mi -> getCode() );

	if( codes.size() == 1 )
		return *(codes.begin());
	else
		return "";
}
Пример #5
0
void getCodes(queue *root, int length){
	/* Leaf node -> obtained code */
	if(root->left == NULL && root->right == NULL){
		huffCode[huffCodesCount].length = length;
		huffCode[huffCodesCount].caracter = root->value.caracter;
		huffCodesCount++;
		int i;
		/* Copy previous path in the new code */
		for(i = 0; i < huffCode[huffCodesCount - 1].length; i++)
			huffCode[huffCodesCount].code[i] = huffCode[huffCodesCount - 1].code[i];
	}
	/* Generate code left */
	if(root->left){
		huffCode[huffCodesCount].code[length] = 0;
		getCodes(root->left, length + 1);
	}
	/* Generate code right */
	if(root->right){
		huffCode[huffCodesCount].code[length] = 1;
		getCodes(root->right, length + 1);
	}
}
Пример #6
0
void
loop ()
{
  // event interface
  int fd = -1;			/* the file descriptor for the device */
  int i;			/* loop counter */
  size_t read_bytes;		/* how many bytes were read */
  struct input_event ev[64];	/* the events (up to 64 at once) */
  int key;			/*key code */
  /* used if event hit fn */
  int hasSomething;

#ifdef HAVE_LIBXOSD
  // prepare queue handling
  int flag = 0, brightness = 0, sound = 0;
  createqueue ();
#endif
  
  if (strcasecmp(devinput,"AUTO")==0) { // try to figure out rigth event value for keyboard
	  snprintf(devinput,MAX_DEVINPUT_SIZE,"/dev/input/event%d",getItemEvent(DEFAULT_KEYBOARD_NAME));
	  syslog(LOG_INFO,"autodevice determines %s as keyboard event",devinput);
  }
  
  if ((fd = open (devinput, O_RDONLY)) < 0)
    {
      syslog (LOG_CRIT,"event interface (%s) open failed: %m",devinput);
      // shoot auto as LAST chance
      snprintf(devinput,MAX_DEVINPUT_SIZE,"/dev/input/event%d",getItemEvent(DEFAULT_KEYBOARD_NAME));
      syslog(LOG_CRIT,"autodevice determines %s as a last chance keyboard event",devinput);
      if ((fd = open (devinput, O_RDONLY)) < 0)
        {
	      syslog(LOG_CRIT,"Event interface (%s) open failed: %m",devinput);
              cleanExit(EXIT_FAILURE);
	}
    }

  /* handle important signal */
  if (signal(SIGTERM,signal_handler) < 0)
    {
      perror("signal");
      exit(EXIT_FAILURE);
    }
  if (signal(SIGHUP,signal_handler) < 0)
    {
      perror("signal");
      exit(EXIT_FAILURE);
    }

  syslog(LOG_INFO,"fsfn loaded");


  while (1)
    {				/* loop */
      hasSomething = 0;		/* nothing yet */

      /*
       * read the event interface 
       */
      if ( (read_bytes = read (fd, ev, sizeof (struct input_event) * 64))==-1) {
	      //fprintf(stderr,"Error: %d\n",errno);
	      if (errno==ENODEV) { // event is now invalid ? must be back from sleep...
		      syslog(LOG_NOTICE,"Start sleeping...");
		      sleep(10);		      
		      syslog(LOG_NOTICE,"End sleeping...");

		      close(fd); // is this needed ??
		      
		      syslog(LOG_NOTICE,"Input device changed, back from suspend ?: %m");
		      
		      // get new event
		      snprintf(devinput,MAX_DEVINPUT_SIZE,"/dev/input/event%d",getItemEvent(DEFAULT_KEYBOARD_NAME));
      		      syslog(LOG_NOTICE,"autodevice determines %s as new event",devinput);
		      
		      // reopen - seems to be problems after a hibernate :(
      		      if ((fd = open (devinput, O_RDONLY)) < 0)
        	        {
				syslog(LOG_CRIT,"New event interface (%s) open failed: %m",devinput); 
				cleanExit(EXIT_FAILURE);
			}
		      // read it
		      if ((read_bytes = read (fd, ev, sizeof (struct input_event) * 64))==-1) 
		        {
				syslog(LOG_CRIT,"Reading new device (%s) failed: %m",devinput);
				cleanExit(EXIT_FAILURE);
		        }
	      }
	      else {
		      syslog(LOG_CRIT,"Input device reading failed: %m");
		      cleanExit(EXIT_FAILURE);
	      }
	}
      	
      if (read_bytes < (int) sizeof (struct input_event))
	{
	  syslog (LOG_CRIT,"short read: %m");
	  cleanExit(EXIT_FAILURE);
	}
      
      /*
       * Loop for all readed events until we have something
       * interesting.. 
       */
      for (i = 0;
	   !hasSomething
	   && (i < (int) (read_bytes / sizeof (struct input_event))); i++)
	{
	  hasSomething = (ev[i].type == FN_INPUT_TYPE)
	    && (ev[i].code == FN_INPUT_CODE)
	    && (ev[i].value == FN_INPUT_VALUE);
	}
      
      /*
       * If we got a FN event, plz do something... 
       */
      if (hasSomething && (key = getCodes ()))
	{
	  if ((key & FN_F5) == FN_F5)
	    { 
	      	// check config
	      	if (!checkConfig("F5_CMD"))
		  {
	      		// lower brightness
#ifdef HAVE_LIBXOSD
	      		flag = MOD_BRIGHTNESS;
	      		brightness = setBrightness (getBrightness () - 1);
	      		sendmsg (flag, brightness, sound);
			sendcmd (FN_F5);
#else
	      		setBrightness (getBrightness () - 1);
#endif
		  }
	    }
	  if ((key & FN_F6) == FN_F6)
	    {
	    	// check config
		if (!checkConfig("F6_CMD")) 
		  {
		  	
	    		// higher brightness
#ifdef HAVE_LIBXOSD
	      		flag = MOD_BRIGHTNESS;
	      		brightness = setBrightness (getBrightness () + 1);
	      		sendmsg (flag, brightness, sound);
			sendcmd (FN_F6);
#else
	      		setBrightness (getBrightness () + 1);
#endif
		  }
	    }

	  if ((key & FN_F2) == FN_F2)
	    {
		// check config
		if (!checkConfig("F2_CMD"))
		  {
#ifdef HAVE_LIBXOSD
	      		flag = MOD_SOUND;
	      		sound = mute (SOUND_STEP);
	      		sendmsg (flag, brightness, sound);
			sendcmd(FN_F2);
#else
	      		mute (SOUND_STEP);			
#endif
		  }
	    }
	  if ((key & FN_F3) == FN_F3)
	    {
		if (!checkConfig("F3_CMD"))
	          {
#ifdef HAVE_LIBXOSD
	      		flag = MOD_SOUND;
	      		sound = volume_down (SOUND_STEP);	//mod by SilSha
	      		sendmsg (flag, brightness, sound);
			sendcmd(FN_F3);
#else
	      		volume_down (SOUND_STEP);
#endif
		  }
	    }
	  if ((key & FN_F4) == FN_F4)
	    {
	       if (!checkConfig("F4_CMD"))
	         {
#ifdef HAVE_LIBXOSD
	      		flag = MOD_SOUND;
	      		sound = volume_up (SOUND_STEP);		//mod by SilSha
	      		sendmsg (flag, brightness, sound);
			sendcmd(FN_F4);
#else
	      		volume_up (SOUND_STEP);
#endif
		 }	
	    }
	 /* NO built in commands */
	  if ((key & FN_F7) == FN_F7)
	    {
#ifdef HAVE_LIBXOSD
	      if (!checkConfig("F7_CMD"))
		sendcmd(FN_F7);
#else
	      sendcmd(FN_F7);
#endif
	    }
	  if ((key & FN_F10) == FN_F10)
	    {
#ifdef HAVE_LIBXOSD
	      if(!checkConfig("F10_CMD"))
		sendcmd(FN_F10);
#else
	      sendcmd(FN_F10);
#endif
	    }
	  if ((key & FN_F12) == FN_F12)
	    {
#ifdef HAVE_LIBXOSD
	      if (!checkConfig("F12_CMD"))
		sendcmd(FN_F12);
#else
	      checkConfig("F12_CMD");
#endif
	    }
	  if (( key & S1_BTN) == S1_BTN) 
	    {
#ifdef HAVE_LIBXOSD
	      if (!checkConfig("S1_CMD"))
		sendcmd(S1_BTN);
#else
	      checkConfig("S1_CMD");
#endif
	    }
	  if (( key & S2_BTN) == S2_BTN)
	    {
#ifdef HAVE_LIBXOSD
	      if (!checkConfig("S2_CMD"))
		sendcmd(S2_BTN);
#else
	      checkConfig("S2_CMD");
#endif
	    }		  
	}
    }// while
}
Пример #7
0
// main and loop
int main(int argc, char **argv) {
    // event interface
    int fd = -1;                /* the file descriptor for the device */
    int i;                      /* loop counter */
    size_t read_bytes;          /* how many bytes were read */
    struct input_event ev[64];  /* the events (up to 64 at once) */
      
    /* key code */
    int key;

    /* used if event hit fn */
    int hasSomething;
    
    /* Volume */
    int value = 0;

    fileops(0, 0);

    /* open event interface*/
    if (argc != 2) {
        /* i don't like outputs...
        fprintf(stderr, "Using /dev/input/event1 for input\n");
        fprintf(stderr, "Overide with %s event-device\n", argv[0]);
        */
        if ((fd = open("/dev/input/event1", O_RDONLY)) < 0) {
            perror("event interface open failed");
            exit(1);
        }
    } else {   
        if ((fd = open(argv[1], O_RDONLY)) < 0) {
            perror("event interface open failed");
            exit(1);
        }
    }

    nice(10); // be a nice dirty code (less dirty but keep nice)

    while(1) {          /* loop */
        hasSomething=0; /* nothing yet */
      
        /* read the event interface */
        read_bytes = read(fd, ev, sizeof(struct input_event) * 64);
      
        if (read_bytes < (int) sizeof(struct input_event)) {
            perror("sonyfn: short read");
            exit (1);
        }

        /* Loop for all readed events until we have something interesting.. */
        for (i = 0;! hasSomething && ( i < (int) (read_bytes /
                                sizeof(struct input_event)) ); i++) {
            hasSomething= (ev[i].type == FN_INPUT_TYPE)
                && (ev[i].code == FN_INPUT_CODE)
                && (ev[i].value == FN_INPUT_VALUE);
          }

        /* If we got a FN event, plz do something...*/
        if ( hasSomething && (key=getCodes()) ) {
            if ((key & FN_F5)==FN_F5) { // lower brightness
                setBrightness(getBrightness()-1);
                fileops(FN_F5, getBrightness());
            }
            if ((key & FN_F6)==FN_F6) { // higher brightness
                setBrightness(getBrightness()+1);
                fileops(FN_F6, getBrightness());
            }
            if ((key & FN_F2)==FN_F2){
                mute();
                fileops(FN_F2, 0);
            }
            if ((key & FN_F3)==FN_F3) {
                volume_down();
                get_volume(&value);
                fileops(FN_F3, value);
            }
            if ((key & FN_F4)==FN_F4) {
                volume_up();
                get_volume(&value);
                fileops(FN_F4, value);
            }
            if ((key & FN_F7)==FN_F7) {
                fileops(FN_F7, 0);
		usleep(100000);
                fileops(0, 0);
            }
            if ((key & FN_F10)==FN_F10) {
                fileops(FN_F10, 0);
		usleep(100000);
                fileops(0, 0);
            }
            if ((key & FN_F12)==FN_F12) {
                fileops(FN_F12, 0);
		usleep(100000);
                fileops(0, 0);
            }     
        }
    }// while
   
    close(fd);
    return 0;
} 
Пример #8
0
//--------------------------------------------------------------------------------------------------
void TestInteractivele_sim_Authentication()
{
    le_result_t     res;
    bool            ready=false;
    int32_t         initTries=0;
    int32_t         tries=0;
    le_sim_ObjRef_t simRef;
    uint32_t        i=1;
    bool            pinReq=true;
    char            internalPin[2][16];
    le_sim_States_t state;

    getCodes();

    do
    {
        fprintf(stderr, "\nTake off, then insert SIM card.%d, wait for +WIND:1 (approx. 2s) and then press enter \n", i);
        while ( getchar() != '\n' );

        simRef = le_sim_Create(i);
        CU_ASSERT_PTR_NOT_NULL(simRef);

        state = le_sim_GetState(simRef);
        displaySIMState(state, i);
        fprintf(stderr, "\nPress enter to continue...\n");
        while ( getchar() != '\n' );

        strcpy((char*)&internalPin[i-1][0], (char*)&PIN_TEST[i-1][0]);

        // Enter PIN
        if(state == LE_SIM_READY)
        {
            pinReq=false;
            // Lock PIN
            res = le_sim_Lock(simRef, PIN_TOO_LONG_TEST);
            CU_ASSERT_EQUAL(res, LE_OVERFLOW);
            res = le_sim_Lock(simRef, PIN_TOO_SHORT_TEST);
            CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
            res = le_sim_Lock(simRef, FAIL_PIN_TEST);
            CU_ASSERT_EQUAL(res, LE_NOT_POSSIBLE);
            res = le_sim_Lock(simRef, (char*)&internalPin[i-1][0]);
            CU_ASSERT_EQUAL(res, LE_OK);
            fprintf(stderr, "\nle_sim_Lock, res.%d  (should be LE_OK=0)\n", res);
            fprintf(stderr, "\nTake off, then insert SIM card.%d, wait for +WIND:1 (approx. 2s) and then press enter \n", i);
            while ( getchar() != '\n' );
        }

        initTries=le_sim_GetRemainingPINTries(simRef);
        res = le_sim_EnterPIN(simRef, PIN_TOO_LONG_TEST);
        CU_ASSERT_EQUAL(res, LE_OVERFLOW);
        res = le_sim_EnterPIN(simRef, PIN_TOO_SHORT_TEST);
        CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
        res = le_sim_EnterPIN(simRef, FAIL_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_NOT_POSSIBLE);

        tries=le_sim_GetRemainingPINTries(simRef);
        CU_ASSERT_TRUE((initTries-tries == 1));

        ready=le_sim_IsReady(simRef);
        CU_ASSERT_FALSE(ready);

        res = le_sim_EnterPIN(simRef, (char*)&internalPin[i-1][0]);
        CU_ASSERT_EQUAL(res, LE_OK);

        ready=le_sim_IsReady(simRef);
        CU_ASSERT_TRUE(ready);
#if 0
        if (ready != true)
        {
            LE_FATAL("SIM card.%d NOT READY ! check it, test exits !", i);
        }
#endif
        fprintf(stderr, "\nle_sim_EnterPIN, res.%d (should be LE_OK=0) \n", res);
        fprintf(stderr, "\nWait for SIM card.%d answer (+CREG: 1, approx. 2s) and then press enter \n", i);
        while ( getchar() != '\n' );

        // Change PIN
        res = le_sim_ChangePIN(simRef, PIN_TOO_LONG_TEST, NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_OVERFLOW);
        res = le_sim_ChangePIN(simRef, (char*)&internalPin[i-1][0], PIN_TOO_LONG_TEST);
        CU_ASSERT_EQUAL(res, LE_OVERFLOW);
        res = le_sim_ChangePIN(simRef, PIN_TOO_SHORT_TEST, NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
        res = le_sim_ChangePIN(simRef, (char*)&internalPin[i-1][0], PIN_TOO_SHORT_TEST);
        CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
        res = le_sim_ChangePIN(simRef, FAIL_PIN_TEST, NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_NOT_POSSIBLE);
        res = le_sim_ChangePIN(simRef, (char*)&internalPin[i-1][0], NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_OK);

        fprintf(stderr, "\nle_sim_ChangePIN, res.%d (should be LE_OK=0)\n", res);
        fprintf(stderr, "\nTake off, then insert SIM card.%d, wait for +WIND:1 (approx. 2s) and then press enter \n", i);
        while ( getchar() != '\n' );

        // Unblock PIN
        while((initTries=le_sim_GetRemainingPINTries(simRef))>0)
        {
            res = le_sim_EnterPIN(simRef, FAIL_PIN_TEST);
        }

        if(initTries < 0)
        {
            fprintf(stderr, "\nle_sim_GetRemainingPINTries error, res.%d (should be >=0)\n", initTries);
        }

        res = le_sim_Unblock(simRef, (char*)&PUK_TEST[i-1][0], PIN_TOO_LONG_TEST);
        CU_ASSERT_EQUAL(res, LE_OVERFLOW);
        res = le_sim_Unblock(simRef, (char*)&PUK_TEST[i-1][0], PIN_TOO_SHORT_TEST);
        CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
        res = le_sim_Unblock(simRef, PUK_BAD_LENGTH_TEST, NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_OUT_OF_RANGE);
        res = le_sim_Unblock(simRef, FAIL_PUK_TEST, NEW_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_NOT_POSSIBLE);
        res = le_sim_Unblock(simRef, (char*)&PUK_TEST[i-1][0], (char*)&internalPin[i-1][0]);
        CU_ASSERT_EQUAL(res, LE_OK);

        fprintf(stderr, "\nle_sim_Unblock, res.%d  (should be LE_OK=0), press enter to continue \n", res);
        while ( getchar() != '\n' );

        // Unlock PIN
        res = le_sim_Unlock(simRef, PIN_TOO_LONG_TEST);
        CU_ASSERT_EQUAL(res, LE_OVERFLOW);
        res = le_sim_Unlock(simRef, PIN_TOO_SHORT_TEST);
        CU_ASSERT_EQUAL(res, LE_UNDERFLOW);
        res = le_sim_Unlock(simRef, FAIL_PIN_TEST);
        CU_ASSERT_EQUAL(res, LE_NOT_POSSIBLE);
        res = le_sim_Unlock(simRef, (char*)&internalPin[i-1][0]);
        CU_ASSERT_EQUAL(res, LE_OK);

        fprintf(stderr, "\nle_sim_Unlock, res.%d  (should be LE_OK=0), press enter to continue  \n", res);
        while ( getchar() != '\n' );

        // Re-lock the SIM card
        if (pinReq)
        {
            res = le_sim_Lock(simRef, (char*)&internalPin[i-1][0]);
            CU_ASSERT_EQUAL(res, LE_OK);
        }

        le_sim_Delete(simRef);
        i++;
    } while (i<=le_sim_CountSlots());

    // Test case for SIM card absent: executed only on first slot
    simRef = le_sim_Create(1);
    CU_ASSERT_PTR_NOT_NULL(simRef);

    fprintf(stderr, "Take off SIM card.1 and then press enter \n");
    while ( getchar() != '\n' );

    // Enter PIN
    initTries=le_sim_GetRemainingPINTries(simRef);
    CU_ASSERT_TRUE((initTries == LE_NOT_FOUND) || (initTries == LE_NOT_POSSIBLE));

    res = le_sim_EnterPIN(simRef, PIN_TEMP);
    CU_ASSERT_TRUE((res == LE_NOT_FOUND) || (res == LE_NOT_POSSIBLE));

    ready=le_sim_IsReady(simRef);
    CU_ASSERT_FALSE(ready);

    // Change PIN
    res = le_sim_ChangePIN(simRef, PIN_TEMP, NEW_PIN_TEST);
    CU_ASSERT_TRUE((res == LE_NOT_FOUND) || (res == LE_NOT_POSSIBLE));

    // Unblock PIN
    res = le_sim_Unblock(simRef, (char*)&PUK_TEST[0][0], PIN_TEMP);
    CU_ASSERT_TRUE((res == LE_NOT_FOUND) || (res == LE_NOT_POSSIBLE));

    // Unlock PIN
    res = le_sim_Unlock(simRef, PIN_TEMP);
    CU_ASSERT_TRUE((res == LE_NOT_FOUND) || (res == LE_NOT_POSSIBLE));

    le_sim_Delete(simRef);

    fprintf(stderr, "Insert SIM card.1, wait for +WIND:1 (approx. 2s) and then press enter \n");
    while ( getchar() != '\n' );
}
Пример #9
0
c_exp c_exp::fromLispExp(lisp_exp exp, QHash<QString, DataType> dataTypes, QHash<QString, QString> wireNames) {
    if (exp.isLeaf()) {
        if (wireNames.contains(exp.value())) {
            DataType dt = dataTypes.value(exp.value());
            QString wireName = wireNames.value(exp.value());
            return c_exp(wireName, dt);
        } else {
            bool success;
            exp.value().toInt(&success);
            if (success) {
                return c_exp(exp.value(), DATATYPE_INT);
            } else {
                exp.value().toFloat(&success);
                if (success) {
                    return c_exp(exp.value(), DATATYPE_FLOAT);
                } else {
                    return c_exp(); // error condition
                }
            }
        }
    } else {
        QString theOperator = exp.element(0).value();
        if (theOperator == "+" || theOperator == "-") {
            QList<c_exp> results = evaluateArguments(exp, dataTypes, wireNames);
            DataType mostGeneralType = getMostGeneralType(results);
            DataType resultType;
            if (mostGeneralType.isAFP()) {
                resultType = DATATYPE_AFP(mostGeneralType.afpPrecision() - intLog2(results.size()));
            } else {
                resultType = mostGeneralType;
            }
            QList<QString> conversionCodes = getConversionCodes(results, resultType);
            QString code = conversionCodes.join(" " + theOperator + " ");
            return c_exp(code, resultType);
        } else if (theOperator == "*") {
            QList<c_exp > results = evaluateArguments(exp, dataTypes, wireNames);
            DataType mostGeneralType = getMostGeneralType(results);
            if (mostGeneralType.isAFP()) {
                QString lastCode = "(int64_t)(" + results[0].code() + ")";
                DataType lastType = results[0].type();
                for (int i = 1; i < results.size(); i++) {
                    c_exp result = results[i];
                    if (! result.isValid()) {
                        lastType = DataType();
                    }
                    lastCode = "(" + lastCode + ") * (" + result.code() + ")";
                    lastCode = "(" + lastCode + ") >> 32";
                    int lastAFPPrecision = lastType.isAFP() ? lastType.afpPrecision() : 0;
                    int resultAFPPrecision = result.type().isAFP() ? result.type().afpPrecision() : 0;
                    if (lastType.isValid()) {
                        lastType = DATATYPE_AFP(32 - ((32 - lastAFPPrecision) + (32 - resultAFPPrecision)));
                    }
                }
                lastCode = "(int)(" + lastCode + ")";
                return c_exp(lastCode, lastType);
            } else {
                DataType resultType = mostGeneralType;
                QList<QString> codes = getCodes(results);
                QString code = codes.join(" * ");
                return c_exp(code, resultType);
            }
        } else if (theOperator == "/") {
            return c_exp();
        } else if (theOperator == "//") {
            return c_exp();
        } else if (theOperator == "%") {
            return c_exp();
        } else if (theOperator == "mod") {
            return c_exp();
        } else if (theOperator == "if") {
            c_exp condResult = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames);
            c_exp ifTrueResult = c_exp::fromLispExp(exp.element(2), dataTypes, wireNames);
            c_exp ifFalseResult = c_exp::fromLispExp(exp.element(3), dataTypes, wireNames);
            DataType resultType = moreGeneralType(ifTrueResult.type(), ifFalseResult.type());
            QString code = "(" + condResult.code() + ") ? (" + ifTrueResult.conversionTo(resultType).code() + ") : (" + ifFalseResult.conversionTo(resultType).code() + ")";
            return c_exp(code, resultType);
        } else if (theOperator == ">" || theOperator == "<" || theOperator == ">=" || theOperator == "<=" || theOperator == "==" || theOperator == "!=") {
            c_exp leftOperand = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames);
            c_exp rightOperand = c_exp::fromLispExp(exp.element(2), dataTypes, wireNames);
            DataType resultType = moreGeneralType(leftOperand.type(), rightOperand.type());
            QString code = "(" + leftOperand.conversionTo(resultType).code() + ") " + theOperator + " (" + rightOperand.conversionTo(resultType).code() + ")";
            return c_exp(code, resultType);
        } else if (theOperator == "sqrt") {
            c_exp operand = c_exp::fromLispExp(exp.element(1), dataTypes, wireNames);
            QString code = "sqrt(" + operand.code() + ")";
            return c_exp(code, DATATYPE_FLOAT);
        } else if (theOperator == "read_adc") {
            QString code = "((int)read_adc(" + c_exp::fromLispExp(exp.element(1), dataTypes, wireNames).conversionTo(DATATYPE_INT).code() + ") << 16)";
            return c_exp(code, DATATYPE_AFP(27));
        } else {
            return c_exp(); // error condition
        }
    }
}