Print functionality is now in place.
Fixed strange leading tab output. (Problem was in CommandParser.l todo with the ['"].*+['"] rule)
Added a .hgignore file to hopefully make management easier.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/.hgignore Fri Jul 03 11:21:44 2009 -0400
1.3 @@ -0,0 +1,18 @@
1.4 +syntax: glob
1.5 +
1.6 +# object files
1.7 +*.o
1.8 +CommandParser.tab.c
1.9 +CommandParser.tab.h
1.10 +CommandParser.yy.c
1.11 +
1.12 +# netbeans project files
1.13 +Makefile-hexciting.mk
1.14 +nbproject/*
1.15 +
1.16 +
1.17 +\.orig$
1.18 +\.orig\..*$
1.19 +\.chg\..*$
1.20 +\.rej$
1.21 +\.conflict\~$
2.1 --- a/Command.cpp Wed Jul 01 23:12:36 2009 -0400
2.2 +++ b/Command.cpp Fri Jul 03 11:21:44 2009 -0400
2.3 @@ -1,4 +1,5 @@
2.4 #include "Command.h"
2.5 +#include <cstring>
2.6 #include <stdio.h>
2.7 #include <stdlib.h>
2.8
2.9 @@ -23,25 +24,25 @@
2.10 printf("------\n");
2.11
2.12 printf("Mode:");
2.13 - switch(mode)
2.14 - {
2.15 - case PRINT:
2.16 - printf("Print");
2.17 - break;
2.18 - case XOR:
2.19 - printf("Xor");
2.20 - break;
2.21 - case OR:
2.22 - printf("Or");
2.23 - break;
2.24 - case AND:
2.25 - printf("And");
2.26 - break;
2.27 - case NOT:
2.28 - printf("Not");
2.29 - break;
2.30 - };
2.31 - printf("\n");
2.32 + switch(mode)
2.33 + {
2.34 + case PRINT:
2.35 + printf("Print");
2.36 + break;
2.37 + case XOR:
2.38 + printf("Xor");
2.39 + break;
2.40 + case OR:
2.41 + printf("Or");
2.42 + break;
2.43 + case AND:
2.44 + printf("And");
2.45 + break;
2.46 + case NOT:
2.47 + printf("Not");
2.48 + break;
2.49 + };
2.50 + printf("\n");
2.51
2.52 printf("Range: ");
2.53 if(range == true)
2.54 @@ -64,76 +65,152 @@
2.55
2.56 void processCommand(Command* command)
2.57 {
2.58 + std::ifstream ifs(command->filename, std::ifstream::in | std::ifstream::binary);
2.59
2.60 - switch(command->mode)
2.61 - {
2.62 - case PRINT:
2.63 - command->printOperation();
2.64 - break;
2.65 - case XOR:
2.66 - command->xorOperation();
2.67 - break;
2.68 - case OR:
2.69 - command->orOperation();
2.70 - break;
2.71 - case AND:
2.72 - command->andOperation();
2.73 - break;
2.74 - case NOT:
2.75 - command->notOperation();
2.76 - break;
2.77 - };
2.78 +
2.79 +
2.80 + // calculate the total file size
2.81 + ifs.seekg(0, std::ios::end);
2.82 + int fileSize = ifs.tellg();
2.83 +
2.84 + if(command->end > fileSize)
2.85 + command->end = fileSize;
2.86 + if(command->start > fileSize)
2.87 + {
2.88 + printf("Error. Start is past end of file.\n");
2.89 + return;
2.90 + }
2.91 + if(command->start > command->end)
2.92 + {
2.93 + printf("Error. Start is greater than end.\n");
2.94 + return;
2.95 + }
2.96 +
2.97 + ifs.close();
2.98 +
2.99 +
2.100 + switch(command->mode)
2.101 + {
2.102 + case PRINT:
2.103 + command->printOperation();
2.104 + break;
2.105 + case XOR:
2.106 + command->xorOperation();
2.107 + break;
2.108 + case OR:
2.109 + command->orOperation();
2.110 + break;
2.111 + case AND:
2.112 + command->andOperation();
2.113 + break;
2.114 + case NOT:
2.115 + command->notOperation();
2.116 + break;
2.117 + };
2.118 }
2.119
2.120
2.121 void Command::printOperation()
2.122 {
2.123 std::ifstream ifs(filename, std::ifstream::in | std::ifstream::binary);
2.124 -
2.125 - int length;
2.126
2.127 -
2.128 +
2.129 +
2.130 + // calculate the total file size
2.131 +
2.132 // calculate how many bytes we're printing
2.133 - length = end - start;
2.134 + int length = end - start;
2.135
2.136 // TODO: Optimise this for large files (>64 kb(?))
2.137
2.138 - char dataBuffer[length];
2.139 + unsigned char dataBuffer[length];
2.140 memset(dataBuffer, 0, length);
2.141
2.142 // seek to the start and scan in
2.143 ifs.seekg(start, std::ios::beg);
2.144 - ifs.read(dataBuffer, length);
2.145 + ifs.read((char*)dataBuffer, length);
2.146
2.147 int currentAddress = start;
2.148
2.149 - int asciiBuffer[0x10], hexBuffer[0x10];
2.150 + int hexBuffer[0x10];
2.151
2.152 for(int i = 0; i < 0x10; i++)
2.153 - {
2.154 - asciiBuffer[i] = 0;
2.155 - hexBuffer[i] = 0;
2.156 - }
2.157 + hexBuffer[i] = 0;
2.158 +
2.159 + // to prevent unwanted characters from being printed
2.160 + int numberCharsToPrint = 0;
2.161 + bool hasData = false;
2.162
2.163 for(int i = 0; i < length; i++)
2.164 {
2.165 - // we've filled our buffers, so print them out
2.166 - if(i % 0x10 == 0 && i != 0 || (i + 1) == length)
2.167 - {
2.168 - printf("\n%#x\t", currentAddress);
2.169 - currentAddress += 0x10;
2.170 + // new row, so print out the old data
2.171 + if(i % 0x10 == 0&& i != 0)
2.172 + {
2.173 + // print a row header
2.174 + printf("%#x:\t", currentAddress);
2.175 + currentAddress += 0x10;
2.176 +
2.177 + // print our hex data
2.178 + for(int j = 0; j < numberCharsToPrint; j++)
2.179 + printf("%02x ", hexBuffer[j]);
2.180 + for(int j = 0; j < numberCharsToPrint; j++)
2.181 + {
2.182 + if(checkCharacterBounds(hexBuffer[j]))
2.183 + printf("%c", hexBuffer[j]);
2.184 + else
2.185 + printf(".");
2.186 + }
2.187
2.188 - for(int j = 0; j < 0x10; j++)
2.189 - printf("%x ", hexBuffer[j]);
2.190 - printf(" ");
2.191 - for(int j = 0; j < 0x10; j++)
2.192 - printf("%c ", asciiBuffer[j]);
2.193 - }
2.194 - hexBuffer[i%16] = asciiBuffer[i%16] = dataBuffer[i];
2.195 + printf("\n");
2.196 + numberCharsToPrint = 0;
2.197 +
2.198 + hasData = false;
2.199 + }
2.200 +
2.201 +
2.202 + hexBuffer[i % 0x10] = dataBuffer[i];
2.203 + numberCharsToPrint++;
2.204 + hasData = true;
2.205 +
2.206 }
2.207 +
2.208 + // print any overflow data
2.209 + if(hasData == true)
2.210 + {
2.211 + // print a row header
2.212 + printf("%#x:\t", currentAddress);
2.213 + currentAddress += 0x10;
2.214 +
2.215 + // print our hex data
2.216 + for(int j = 0; j < 0x10; j++)
2.217 + {
2.218 + if(j < numberCharsToPrint)
2.219 + printf("%02x ", hexBuffer[j]);
2.220 + else
2.221 + printf(" ");
2.222 + }
2.223 +
2.224 + for(int j = 0; j < 0x10; j++)
2.225 + {
2.226 + if(j < numberCharsToPrint)
2.227 + printf("%c", hexBuffer[j]);
2.228 + else
2.229 + printf(" ");
2.230 + }
2.231 +
2.232 + printf("\n");
2.233 +
2.234 + }
2.235 }
2.236
2.237 void Command::xorOperation(){}
2.238 void Command::orOperation(){}
2.239 void Command::andOperation(){}
2.240 void Command::notOperation(){}
2.241 +
2.242 +bool checkCharacterBounds(char theChar)
2.243 +{
2.244 + if(theChar >= ' ' && theChar <= '~')
2.245 + return true;
2.246 + return false;
2.247 +}
2.248 \ No newline at end of file
3.1 --- a/Command.h Wed Jul 01 23:12:36 2009 -0400
3.2 +++ b/Command.h Fri Jul 03 11:21:44 2009 -0400
3.3 @@ -37,6 +37,7 @@
3.4
3.5 static Command* theCommand;
3.6
3.7 +bool checkCharacterBounds(char);
3.8
3.9 void processCommand(Command*);
3.10
4.1 --- a/CommandParser.l Wed Jul 01 23:12:36 2009 -0400
4.2 +++ b/CommandParser.l Fri Jul 03 11:21:44 2009 -0400
4.3 @@ -6,7 +6,15 @@
4.4
4.5 %%
4.6
4.7 -" \t\n" {
4.8 +\t {
4.9 + //printf("TAB!\n");
4.10 +}
4.11 +
4.12 +" " {
4.13 + //printf("SPACE!\n");
4.14 +}
4.15 +
4.16 +\n {
4.17 return;
4.18 }
4.19
4.20 @@ -47,17 +55,12 @@
4.21
4.22 [0-9]+ {
4.23 yylval.int_val = atoi(yytext);
4.24 - return NUMBER;
4.25 -}
4.26 -
4.27 -['"].*+['"] {
4.28 - yylval.string_val = strdup(yytext);
4.29 - return ARGUMENT;
4.30 + return NUMBER;
4.31 }
4.32
4.33 [^ \t\n]+ {
4.34 yylval.string_val = strdup(yytext);
4.35 - return ARGUMENT;
4.36 + return ARGUMENT;
4.37 }
4.38
4.39
4.40 @@ -65,9 +68,8 @@
4.41 void configBuffer(char* arguments)
4.42 {
4.43 #ifdef DEBUG
4.44 - printf("Given the buffer: %s\n", arguments);
4.45 + printf("Given the buffer: %s:\n", arguments);
4.46 #endif
4.47 yy_delete_buffer(YY_CURRENT_BUFFER);
4.48 -
4.49 yy_scan_string(arguments);
4.50 }
5.1 --- a/CommandParser.y Wed Jul 01 23:12:36 2009 -0400
5.2 +++ b/CommandParser.y Fri Jul 03 11:21:44 2009 -0400
5.3 @@ -57,7 +57,7 @@
5.4 theCommand->dataCount++;
5.5 theCommand->data.push_back($2);
5.6 }
5.7 -
5.8 + |
5.9 ;
5.10
5.11 mode:
5.12 @@ -85,7 +85,8 @@
5.13 destination:
5.14 range
5.15 |
5.16 - length
5.17 + length
5.18 + |
5.19 NUMBER {
5.20 }
5.21 ;
5.22 @@ -171,21 +172,24 @@
5.23
5.24 int main(int argc, char** argv)
5.25 {
5.26 - if(argc == 1)
5.27 - {
5.28 - printUsage();
5.29 - return 0;
5.30 - }
5.31 + if(argc == 1)
5.32 + {
5.33 + printUsage();
5.34 + return 0;
5.35 + }
5.36
5.37 // initialise our global
5.38 theCommand = new Command();
5.39
5.40 - // process our arguments
5.41 - parseArguments(argc, argv);
5.42 + // process our arguments
5.43 + parseArguments(argc, argv);
5.44
5.45 - // process the command
5.46 - processCommand(theCommand);
5.47 + // process the command
5.48 + processCommand(theCommand);
5.49
5.50 + #ifdef DEBUG
5.51 theCommand->print();
5.52 - return 0;
5.53 + #endif
5.54 +
5.55 + return 0;
5.56 }
6.1 --- a/makefile Wed Jul 01 23:12:36 2009 -0400
6.2 +++ b/makefile Fri Jul 03 11:21:44 2009 -0400
6.3 @@ -1,5 +1,5 @@
6.4 -$(CC) = g++ -g
6.5 -$(cc) = gcc -g
6.6 +$(CC) = g++ -g3 -gdwarf2
6.7 +$(cc) = gcc -g3 -gdwarf2
6.8
6.9 all: executable
6.10