summaryrefslogtreecommitdiffstats
path: root/main.c
blob: 6d3ea38d5cf8e2a67e7dea73968dd6ea0ecf7e3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*	Copyright (C) 2020 Gentoo-libre Install

	This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>//store if number is negative

//powq(): square roots
unsigned long powq(int number, int power)
{
unsigned long result = 1;//result int, 1 by default
if (!power){return 1;}//if to the power of 0, return 1
while(power)//loop until all powers have been calculated
        {
        result *= number;//in the end result=number*number*number*etc until power is reached
        --power;//--power since a power has been calculated
        }
return result;
}

//itoh(): Convert a string of decimal numbers to a string of hex. (No negative input num handling, no invalid char handling and ignores overflows)
void itoh(char s[], char *result)
{
int i;	//counter variable
for(i=0;i<16;++i){result[i]='0';}//zero out the result string (16 chars due to that being the size of unsigned long long int max)

int power = 0;	//int to store the power.
while(s[power] != '\0'){++power;}//increment power for however many non-null chars in the string.
--power;//The correct power is actually one less than above returns

unsigned long long integer = 0;	//the variable in which the integer result from the input string is stored.
i=0;//reset the counter int
while (s[i] != '\0')//convert the string of decimal numbers into a long long int
	{
	if (s[i] >= '0' && s[i] <= '9'){integer += ((s[i] - '0') * powq(10,power));}//integer = integer + ([char converted to number] * (10^[position of number in string]))

	++i;
	--power;//Deincrement the power. E.g. ([charvalue]*(10^3))+([nextcharvalue]*(10^2)) etc
	}

//convert the long long into a string of ASCII hex
i=15;//Write string right to left
int temp;
while(integer)
	{
	temp = (integer % 16);//temp = value to encode into ASCII char

	if ((temp>=0)&&(temp<=9)){result[i] = temp + '0'; goto skip;}//if temp is 0-9, convert that to a digit and skip checking for A-F
	if ((temp>=10)&&(temp<=15)){result[i] = temp + 55;}//if temp is 10-15, convert that to A-F

	skip: integer/=16;//divide integer by 16 to allow generating the next ASCII char
	--i;//write to the next digit to the left
	}
}



int main(int argc, char *argv[])
{
bool negative = false; //handle negative numbers
if (!argv[1]){goto stdinMode;}

	if (argv[1][1] == '-')
		{
		printf("Usage (stdin mode): %s\n", argv[0]);
		printf("Ctrl+D to exit\n");
		printf("Usage (cli args mode): %s [decnum]\n", argv[0]);
		printf("Licence: AGPLv3\n");
		return 0;
		}

	//result hex string, passed to itoh();
	char *cli = malloc(17*sizeof(char));
	if (!cli){printf("Malloc failed!\n"); return 1;}
	cli[16]='\0';//add null terminating char

	//strip out invalid chars from the input string
	if (argv[1][0] == '-'){negative = true;}//handle negative numbers
	int a,q;//counter variables
	for (a=0; argv[1][a] != '\0'; ++a)
	        {
	        if ((argv[1][a] < '0')||(argv[1][a] > '9'))//if argv[1][i] is a character to remove....
	                {
			q=a;
			while(argv[1][q] != '\0'){argv[1][q++] = argv[1][q+1];}//shift all characters above left, overwriting the character
			--a;//deincrement a, since the string was just shrunk by one and the one just above could indeed be a matching char
			}
			}



	itoh(argv[1], cli);
	if (negative){printf("-%s\n",cli); free(cli); return 0;}//handle negative numbers
	printf("%s\n",cli);//print string with all leading 0's

	free(cli);
	return 0;

stdinMode: ;
//input decimal string, by default 10 chars long
int size = 10;
char *input = malloc(size*sizeof(char));
if (!input){printf("Malloc failed!\n"); return 1;}

//result hex string
char *result = malloc(17*sizeof(char));
if (!result){printf("Malloc failed!\n"); return 1;}
result[16]='\0';//add null terminating char

int i;
nextnum: i=0;
char c;
while ((c=getchar())!='\n')
	{
	if (c==EOF){free(result); free(input); exit(0);}//exit if EOF
	if (i>size-2){size+=4; input=realloc(input,size*sizeof(char)); if (!input){printf("Realloc failed!\n"); return 1;}}//relloc if the input string is longer than size
	input[i]=c;//write c to the string
	++i;
	}
	input[i] = '\0'; //add NULL char for itoh


//strip out invalid chars from the input string
if (input[0] == '-'){negative = true;}//handle negative numbers
int j;//another counter variable
for (i=0; input[i] != '\0'; ++i)
        {
        if ((input[i] < '0')||(input[i] > '9'))//if input[i] is an invalid character
                {
                j=i;
                while(input[j] != '\0'){input[j++] = input[j+1];}//shift all characters above left, overwriting the character
                --i;//deincrement i, since the string was just shrunk by one and the one just above could indeed be a matching char
                }
        }

itoh(input, result);//itoh(): Given input string and a pointer to the result string


i=0;
while(result[i] == '0'){++i;}//increment i until a non-0 char is found
if (i == 16){--i;}//if all characters are 0, leave a 0 so the string isn't null
int x;//another counter variable
if (i){for(x=0;result[i-1]!='\0';++x){result[x]=result[i];++i;}}//copy non-0 characters to the left so there aren't any 0's in front of the output number. (Also don't do this if i=0 (there are no 0's))

if (negative){printf("Hexadecimal: -0x%s\n",result); negative = false; goto nextnum;}//handle negative numbers
printf("Hexadecimal: 0x%s\n",result);
goto nextnum; //process another number

//these won't be reached, but included anyway in case the above goto is removed
free(input);
free(result);

return 0;
}