Skip to content

Commit

Permalink
upd progcalc
Browse files Browse the repository at this point in the history
  • Loading branch information
xMasterX committed Jan 5, 2024
1 parent 91e6e2e commit 9bb8658
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 112 deletions.
2 changes: 1 addition & 1 deletion non_catalog_apps/prog_calculator/application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ App(
fap_category="Tools",
fap_author="@armixz",
fap_weburl="https://github.com/armixz/Flipper-Zero-Programmer-Calculator",
fap_version="0.8",
fap_version="0.9",
fap_description="Calculator, for Programmers!",
)
108 changes: 54 additions & 54 deletions non_catalog_apps/prog_calculator/calculation_logic.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@ static const char* HEX_TO_BINARY_TABLE[16] = {
"1110",
"1111"};

bool decToBin(const char* decString, char* binaryResult, size_t resultSize) {
if(decString == NULL || binaryResult == NULL || resultSize < 2) {
return false; // Invalid pointers or insufficient result size
bool decToBin(const char* decString, char* decToBinResult, size_t resultSize) {
if(decString == NULL || decToBinResult == NULL || resultSize < 2) {
return false; // INVALID pointers or insufficient result size
}

char* end;
unsigned long num = strtoul(decString, &end, 10);
unsigned long long num = strtoull(decString, &end, 10);

if(*end != '\0' || *decString == '\0') {
return false; // Invalid decimal
return false; // INVALID decimal
}

// Calculate the number of bits
size_t bitsNeeded = 0;
unsigned long tempNum = num;
unsigned long long tempNum = num;
while(tempNum > 0) {
bitsNeeded++;
tempNum >>= 1;
Expand All @@ -48,7 +48,7 @@ bool decToBin(const char* decString, char* binaryResult, size_t resultSize) {
if(resultSize < 2) {
return false; // buffer
}
strcpy(binaryResult, "0");
strcpy(decToBinResult, "0");
return true;
}

Expand All @@ -57,32 +57,32 @@ bool decToBin(const char* decString, char* binaryResult, size_t resultSize) {
return false;
}

binaryResult[bitsNeeded] = '\0'; // Null-terminate the result
decToBinResult[bitsNeeded] = '\0'; // Null-terminate the result

// fill the binary string from the end
for(int i = bitsNeeded - 1; i >= 0; i--) {
binaryResult[i] = (num & 1) + '0'; // the least significant bit
decToBinResult[i] = (num & 1) + '0'; // the least significant bit
num >>= 1;
}

return true;
}

bool decToHex(const char* decString, char* hexResult, size_t resultSize) {
if(decString == NULL || hexResult == NULL || resultSize == 0) {
bool decToHex(const char* decString, char* decToHexResult, size_t resultSize) {
if(decString == NULL || decToHexResult == NULL || resultSize == 0) {
return false;
}

char* end;
unsigned long num = strtoul(decString, &end, 10);
unsigned long long num = strtoull(decString, &end, 10);

if(*end != '\0' || *decString == '\0') {
return false;
}

// buffer size
size_t requiredSize = 1;
unsigned long tempNum = num;
unsigned long long tempNum = num;

while(tempNum >= 16) {
requiredSize++;
Expand All @@ -93,31 +93,31 @@ bool decToHex(const char* decString, char* hexResult, size_t resultSize) {
return false;
}

hexResult[requiredSize] = '\0';
decToHexResult[requiredSize] = '\0';

// convert to hexadecimal in reverse order
do{
int remainder = num % 16;
hexResult[--requiredSize] = (remainder < 10) ? ('0' + remainder) : ('A' + (remainder - 10));
decToHexResult[--requiredSize] = (remainder < 10) ? ('0' + remainder) : ('A' + (remainder - 10));
num /= 16;
} while(num > 0);

return true;
}

bool decToChar(const char* decString, char* outChar) {
if(decString == NULL || outChar == NULL || *decString == '\0') {
bool decToChar(const char* decString, char* decToCharResult) {
if(decString == NULL || decToCharResult == NULL || *decString == '\0') {
return false;
}

char* end;
unsigned long num = strtoul(decString, &end, 10);
unsigned long long num = strtoull(decString, &end, 10);

if(*end != '\0' || num > 255) {
return false;
}

*outChar = (char)num;
*decToCharResult = (char)num;
return true;
}

Expand All @@ -140,8 +140,8 @@ bool hexDigitToBinary(char hexDigit, char* binary) {
}
}

bool hexToBin(const char* hexString, char* binaryResult, size_t resultSize) {
if(hexString == NULL || binaryResult == NULL || resultSize == 0) {
bool hexToBin(const char* hexString, char* hexToBinResult, size_t resultSize) {
if(hexString == NULL || hexToBinResult == NULL || resultSize == 0) {
return false;
}

Expand All @@ -165,22 +165,22 @@ bool hexToBin(const char* hexString, char* binaryResult, size_t resultSize) {
if(resultSize < 4) {
return false;
}
memcpy(binaryResult, hexToBinary, 4);
binaryResult += 4;
memcpy(hexToBinResult, hexToBinary, 4);
hexToBinResult += 4;
hexString++;
resultSize -= 4;
}

*binaryResult = '\0';
*hexToBinResult = '\0';
return true;
}

bool hexToDec(const char* hexString, int* outNum) {
if(hexString == NULL || outNum == NULL) {
bool hexToDec(const char* hexString, int* hexToDecResult) {
if(hexString == NULL || hexToDecResult == NULL) {
return false;
}

*outNum = 0;
*hexToDecResult = 0;
while(*hexString) {
char digit = *hexString;
int value;
Expand All @@ -195,31 +195,31 @@ bool hexToDec(const char* hexString, int* outNum) {
return false;
}

if(*outNum > INT_MAX / 16 || (*outNum == INT_MAX / 16 && value > INT_MAX % 16)) {
if(*hexToDecResult > INT_MAX / 16 || (*hexToDecResult == INT_MAX / 16 && value > INT_MAX % 16)) {
return false; // check overflow
}

*outNum = *outNum * 16 + value;
*hexToDecResult = *hexToDecResult * 16 + value;
hexString++;
}

return true;
}

bool binToDec(const char* binaryString, int* decResult) {
if(binaryString == NULL || decResult == NULL) {
bool binToDec(const char* binaryString, int* binToDecResult) {
if(binaryString == NULL || binToDecResult == NULL) {
return false;
}

*decResult = 0;
*binToDecResult = 0;
for(const char* p = binaryString; *p; ++p) {
if(*p != '0' && *p != '1') {
return false;
}
if(*decResult > INT_MAX / 2) {
if(*binToDecResult > INT_MAX / 2) {
return false; // check overflow
}
*decResult = (*decResult << 1) | (*p - '0');
*binToDecResult = (*binToDecResult << 1) | (*p - '0');
}

return true;
Expand All @@ -234,16 +234,16 @@ char binaryToHexDigit(const char* bin) {
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}

bool binToHex(const char* binaryString, char* hexResult, size_t resultSize) {
if(binaryString == NULL || hexResult == NULL || resultSize == 0) {
bool binToHex(const char* binaryString, char* binToHexResult, size_t resultSize) {
if(binaryString == NULL || binToHexResult == NULL || resultSize == 0) {
return false;
}

size_t binLength = strlen(binaryString);

for(size_t i = 0; i < binLength; ++i) {
if(binaryString[i] != '0' && binaryString[i] != '1') {
snprintf(hexResult, resultSize, "Invalid Binary");
snprintf(binToHexResult, resultSize, "INVALID Binary");
return false;
}
}
Expand All @@ -268,12 +268,12 @@ bool binToHex(const char* binaryString, char* hexResult, size_t resultSize) {
}

if(tempIndex == 4) {
hexResult[hexIndex++] = binaryToHexDigit(tempBin);
binToHexResult[hexIndex++] = binaryToHexDigit(tempBin);
tempIndex = 0;
}
}

hexResult[hexIndex] = '\0';
binToHexResult[hexIndex] = '\0';
return true;
}

Expand All @@ -287,51 +287,51 @@ void calculate(Calculator* calculator_state) {

switch(calculator_state->mode) {
case ModeDecToBin:
if(!decToBin(calculator_state->text, calculator_state->binaryResult, sizeof(calculator_state->binaryResult))) {
snprintf(calculator_state->binaryResult, sizeof(calculator_state->binaryResult), "Invalid Dec");
if(!decToBin(calculator_state->text, calculator_state->decToBinResult, sizeof(calculator_state->decToBinResult))) {
snprintf(calculator_state->decToBinResult, sizeof(calculator_state->decToBinResult), "INVALID D");
}
break;

case ModeDecToHex:
if(!decToHex(calculator_state->text, calculator_state->hexResult, sizeof(calculator_state->hexResult))) {
snprintf(calculator_state->hexResult, sizeof(calculator_state->hexResult), "Invalid Dec");
if(!decToHex(calculator_state->text, calculator_state->decToHexResult, sizeof(calculator_state->decToHexResult))) {
snprintf(calculator_state->decToHexResult, sizeof(calculator_state->decToHexResult), "INVALID D");
}
break;

case ModeDecToChar:
if(decToChar(calculator_state->text, &result)) {
calculator_state->charResult[0] = result;
calculator_state->charResult[1] = '\0';
calculator_state->decToCharResult[0] = result;
calculator_state->decToCharResult[1] = '\0';
} else {
snprintf(calculator_state->charResult, sizeof(calculator_state->charResult), "Invalid Dec");
snprintf(calculator_state->decToCharResult, sizeof(calculator_state->decToCharResult), "INVALID D");
}
break;

case ModeHexToBin:
if(!hexToBin(calculator_state->text, calculator_state->binaryResult, sizeof(calculator_state->binaryResult))) {
snprintf(calculator_state->binaryResult, sizeof(calculator_state->binaryResult), "Invalid Hex");
if(!hexToBin(calculator_state->text, calculator_state->hexToBinResult, sizeof(calculator_state->hexToBinResult))) {
snprintf(calculator_state->hexToBinResult, sizeof(calculator_state->hexToBinResult), "INVALID H");
}
break;

case ModeHexToDec:
if(hexToDec(calculator_state->text, &num)) {
snprintf(calculator_state->decResult, sizeof(calculator_state->decResult), "%d", num);
snprintf(calculator_state->hexToDecResult, sizeof(calculator_state->hexToDecResult), "%d", num);
} else {
snprintf(calculator_state->decResult, sizeof(calculator_state->decResult), "Invalid Hex");
snprintf(calculator_state->hexToDecResult, sizeof(calculator_state->hexToDecResult), "INVALID H");
}
break;

case ModeBinToDec:
if(binToDec(calculator_state->text, &num)) {
snprintf(calculator_state->decResult, sizeof(calculator_state->decResult), "%d", num);
snprintf(calculator_state->binToDecResult, sizeof(calculator_state->binToDecResult), "%d", num);
} else {
snprintf(calculator_state->decResult, sizeof(calculator_state->decResult), "Invalid Binary");
snprintf(calculator_state->binToDecResult, sizeof(calculator_state->binToDecResult), "INVALID B");
}
break;

case ModeBinToHex:
if(!binToHex(calculator_state->text, calculator_state->hexResult, sizeof(calculator_state->hexResult))) {
snprintf(calculator_state->hexResult, sizeof(calculator_state->hexResult), "Invalid Binary");
if(!binToHex(calculator_state->text, calculator_state->binToHexResult, sizeof(calculator_state->binToHexResult))) {
snprintf(calculator_state->binToHexResult, sizeof(calculator_state->binToHexResult), "INVALID B");
}
break;

Expand Down
4 changes: 2 additions & 2 deletions non_catalog_apps/prog_calculator/calculation_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include "calculator_state.h"

bool decToBin(const char* decString, char* binaryResult, size_t resultSize);
bool decToHex(const char* decString, char* hexResult, size_t resultSize);
bool decToBin(const char* decString, char* decToBinResult, size_t resultSize);
bool decToHex(const char* decString, char* decToHexResult, size_t resultSize);
bool decToChar(const char* decString, char* outChar);
bool hexToBin(const char* hexString, char* binaryResult, size_t resultSize);
bool hexToDec(const char* hexString, int* outNum);
Expand Down
20 changes: 12 additions & 8 deletions non_catalog_apps/prog_calculator/calculator_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#include <furi.h>
#include <stdbool.h>

#define MAX_TEXT_LENGTH 30
#define MAX_TEXT_LENGTH_INPUT 19
#define MAX_TEXT_LENGTH_RESULT 37

typedef enum {
ModeNone,
Expand All @@ -25,14 +26,17 @@ typedef struct {
typedef struct {
FuriMutex* mutex;
selectedPosition position;
char text[MAX_TEXT_LENGTH];
char originalInput[MAX_TEXT_LENGTH];
char binaryResult[MAX_TEXT_LENGTH];
char hexResult[MAX_TEXT_LENGTH];
char decResult[MAX_TEXT_LENGTH];
char charResult[MAX_TEXT_LENGTH];
char text[MAX_TEXT_LENGTH_INPUT];
char originalInput[MAX_TEXT_LENGTH_INPUT];
char decToBinResult[MAX_TEXT_LENGTH_RESULT];
char decToHexResult[MAX_TEXT_LENGTH_RESULT];
char decToCharResult[MAX_TEXT_LENGTH_RESULT];
char hexToBinResult[MAX_TEXT_LENGTH_RESULT];
char hexToDecResult[MAX_TEXT_LENGTH_RESULT];
char binToDecResult[MAX_TEXT_LENGTH_RESULT];
char binToHexResult[MAX_TEXT_LENGTH_RESULT];
short textLength;
char log[MAX_TEXT_LENGTH];
char log[MAX_TEXT_LENGTH_RESULT];
bool newInputStarted;
CalculatorMode mode;
} Calculator;
Expand Down
17 changes: 10 additions & 7 deletions non_catalog_apps/prog_calculator/input_handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void handle_long_press(Calculator* calculator_state, ViewPort* view_port, InputE
switch(event->key) {
case InputKeyOk:
if(calculator_state->position.x == 0 && calculator_state->position.y == 4) {
if(calculator_state->textLength < MAX_TEXT_LENGTH) {
if(calculator_state->textLength < MAX_TEXT_LENGTH_INPUT) {
calculator_state->text[calculator_state->textLength++] = ')';
calculator_state->text[calculator_state->textLength] = '\0';
}
Expand All @@ -101,7 +101,7 @@ void handle_key_press(Calculator* calculator_state, char key) {
switch(key) {
case '=':
// Logic for '=' key
strncpy(calculator_state->originalInput, calculator_state->text, MAX_TEXT_LENGTH);
strncpy(calculator_state->originalInput, calculator_state->text, MAX_TEXT_LENGTH_INPUT);
calculate(calculator_state);
// calculator_state->text[0] = '\0';
calculator_state->textLength = 0;
Expand All @@ -110,10 +110,13 @@ void handle_key_press(Calculator* calculator_state, char key) {
// Logic for 'R' key, typically 'Clear'
calculator_state->text[0] = '\0';
calculator_state->textLength = 0;
calculator_state->binaryResult[0] = '\0'; // Clear binary result
calculator_state->decResult[0] = '\0'; // Clear binary result
calculator_state->charResult[0] = '\0'; // Clear binary result
calculator_state->hexResult[0] = '\0'; // Clear hex result
calculator_state->decToBinResult[0] = '\0';
calculator_state->decToHexResult[0] = '\0';
calculator_state->decToCharResult[0] = '\0';
calculator_state->hexToBinResult[0] = '\0';
calculator_state->hexToDecResult[0] = '\0';
calculator_state->binToDecResult[0] = '\0';
calculator_state->binToHexResult[0] = '\0';
calculator_state->newInputStarted = false;
break;
case '<':
Expand All @@ -132,7 +135,7 @@ void handle_key_press(Calculator* calculator_state, char key) {
calculator_state->newInputStarted = false;
}
// Add the new character to the text, respecting the maximum text length
if(calculator_state->textLength < MAX_TEXT_LENGTH - 1) {
if(calculator_state->textLength < MAX_TEXT_LENGTH_INPUT - 1) {
calculator_state->text[calculator_state->textLength++] = key;
calculator_state->text[calculator_state->textLength] = '\0';
}
Expand Down
Loading

0 comments on commit 9bb8658

Please sign in to comment.