Commit 2ac4da773dcc1f487ab4b941809dce6e85259671
- Diff rendering mode:
- inline
- side by side
Makefile
(2 / 2)
|   | |||
| 1 | 1 | all: bs_grep | |
| 2 | 2 | ||
| 3 | bs_grep: bs_grep.cpp | ||
| 4 | g++ -o bs_grep bs_grep.cpp | ||
| 3 | bs_grep: bs_grep.cpp main.cpp bs_grep.h | ||
| 4 | g++ -o bs_grep bs_grep.cpp main.cpp |
bs_grep.cpp
(47 / 89)
|   | |||
| 10 | 10 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
| 11 | 11 | */ | |
| 12 | 12 | ||
| 13 | #include "bs_grep.h" | ||
| 14 | |||
| 13 | 15 | #include <algorithm> | |
| 14 | 16 | #include <fstream> | |
| 15 | 17 | #include <sstream> | |
| … | … | ||
| 25 | 25 | ||
| 26 | 26 | using namespace std; | |
| 27 | 27 | ||
| 28 | int64_t fieldValue(char* line, int fieldNumber); | ||
| 29 | |||
| 30 | int main(int argc, char** argv) | ||
| 28 | void reverse(char* data, int bytes) | ||
| 31 | 29 | { | |
| 32 | char buffer[1024 * 1024]; | ||
| 33 | int argument; | ||
| 34 | int fieldNumber = -1; | ||
| 35 | int64_t startValue = - 1; | ||
| 36 | int64_t endValue = -1; | ||
| 37 | bool reverse = false; | ||
| 38 | bool badArgument = false; | ||
| 30 | for(int i = 0; i < (bytes / 2); ++i) | ||
| 31 | { | ||
| 32 | const int other = bytes - (i + 1); | ||
| 33 | data[i] ^= data[other]; | ||
| 34 | data[other] ^= data[i]; | ||
| 35 | data[i] ^= data[other]; | ||
| 36 | } | ||
| 37 | } | ||
| 39 | 38 | ||
| 40 | while((argument = ::getopt(argc, argv, "f:s:e:r")) != -1) | ||
| 39 | int64_t fieldValue(char* line, int fieldNumber) | ||
| 40 | { | ||
| 41 | std::string dump; | ||
| 42 | int64_t value = ~0; // to help debugging | ||
| 43 | const size_t count = ::strlen(line); | ||
| 44 | if(fieldNumber > 0) | ||
| 41 | 45 | { | |
| 42 | switch(argument) | ||
| 46 | // from left | ||
| 47 | istringstream stream(line); | ||
| 48 | for(int i = 1; i < fieldNumber; ++i) | ||
| 43 | 49 | { | |
| 44 | case 'f': | ||
| 45 | fieldNumber = atoi(::optarg); | ||
| 46 | break; | ||
| 47 | case 's': | ||
| 48 | startValue = atoll(::optarg); | ||
| 49 | break; | ||
| 50 | case 'e': | ||
| 51 | endValue = atoll(::optarg); | ||
| 52 | break; | ||
| 53 | case 'r': | ||
| 54 | reverse = true; | ||
| 55 | break; | ||
| 56 | case '?': | ||
| 57 | badArgument = true; | ||
| 58 | break; | ||
| 59 | default: | ||
| 60 | break; | ||
| 50 | stream >> dump; | ||
| 61 | 51 | } | |
| 52 | stream >> value; | ||
| 62 | 53 | } | |
| 63 | if(fieldNumber == -1 || (startValue == -1 && endValue == -1) || argc - ::optind != 1 || badArgument) | ||
| 54 | else | ||
| 64 | 55 | { | |
| 65 | cerr << "Syntax: " << argv[0] << " [-r] -f FIELDNUMBER [-s start [-e end] | -e end] FILE" << endl; | ||
| 66 | cerr << "\t-r Count FIELDNUMBER from the end of each line, not the start" << endl; | ||
| 67 | cerr << "\t-f The field number to use for the binary search" << endl; | ||
| 68 | cerr << "\t-s Start value" << endl; | ||
| 69 | cerr << "\t-e End value" << endl; | ||
| 70 | return 1; | ||
| 56 | // from right | ||
| 57 | // reverse the string | ||
| 58 | // FIXME: 8bit | ||
| 59 | reverse(line, count); | ||
| 60 | { | ||
| 61 | istringstream stream(line); | ||
| 62 | for(int i = -1; i >= fieldNumber; --i) | ||
| 63 | { | ||
| 64 | stream >> dump; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | const char* internal = dump.c_str(); | ||
| 68 | size_t length = strlen(internal); | ||
| 69 | char buffer[length]; | ||
| 70 | ::memcpy(buffer, internal, length); | ||
| 71 | reverse(buffer, length); | ||
| 72 | value = atoll(buffer); | ||
| 73 | reverse(line, count); | ||
| 71 | 74 | } | |
| 75 | return value; | ||
| 76 | } | ||
| 77 | |||
| 78 | int bs_grep(const char* filename, int fieldNumber, int64_t startValue, int64_t endValue, bool reverse) | ||
| 79 | { | ||
| 80 | char buffer[1024 * 1024]; | ||
| 72 | 81 | if(reverse) | |
| 73 | 82 | { | |
| 74 | 83 | fieldNumber = -fieldNumber; | |
| 75 | 84 | } | |
| 76 | const char* const filename = argv[::optind]; | ||
| 77 | 85 | ||
| 78 | 86 | struct stat fileStat; | |
| 79 | 87 | const int result = ::stat(filename, &fileStat); | |
| … | … | ||
| 301 | 301 | } | |
| 302 | 302 | ||
| 303 | 303 | return 0; | |
| 304 | } | ||
| 305 | |||
| 306 | void reverse(char* data, int bytes); | ||
| 307 | |||
| 308 | int64_t fieldValue(char* line, int fieldNumber) | ||
| 309 | { | ||
| 310 | std::string dump; | ||
| 311 | int64_t value = ~0; // to help debugging | ||
| 312 | const size_t count = ::strlen(line); | ||
| 313 | if(fieldNumber > 0) | ||
| 314 | { | ||
| 315 | // from left | ||
| 316 | istringstream stream(line); | ||
| 317 | for(int i = 1; i < fieldNumber; ++i) | ||
| 318 | { | ||
| 319 | stream >> dump; | ||
| 320 | } | ||
| 321 | stream >> value; | ||
| 322 | } | ||
| 323 | else | ||
| 324 | { | ||
| 325 | // from right | ||
| 326 | // reverse the string | ||
| 327 | // FIXME: 8bit | ||
| 328 | reverse(line, count); | ||
| 329 | { | ||
| 330 | istringstream stream(line); | ||
| 331 | for(int i = -1; i >= fieldNumber; --i) | ||
| 332 | { | ||
| 333 | stream >> dump; | ||
| 334 | } | ||
| 335 | } | ||
| 336 | const char* internal = dump.c_str(); | ||
| 337 | size_t length = strlen(internal); | ||
| 338 | char buffer[length]; | ||
| 339 | ::memcpy(buffer, internal, length); | ||
| 340 | reverse(buffer, length); | ||
| 341 | value = atoll(buffer); | ||
| 342 | reverse(line, count); | ||
| 343 | } | ||
| 344 | return value; | ||
| 345 | } | ||
| 346 | |||
| 347 | void reverse(char* data, int bytes) | ||
| 348 | { | ||
| 349 | for(int i = 0; i < (bytes / 2); ++i) | ||
| 350 | { | ||
| 351 | const int other = bytes - (i + 1); | ||
| 352 | data[i] ^= data[other]; | ||
| 353 | data[other] ^= data[i]; | ||
| 354 | data[i] ^= data[other]; | ||
| 355 | } | ||
| 356 | 304 | } |

