219 lines
8.7 KiB
C++
219 lines
8.7 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Tyler Perkins
|
|
// 7-23-21
|
|
// options implementation
|
|
//
|
|
|
|
#include "options.hpp"
|
|
|
|
void help(char* progName){
|
|
std::cout << "Usage: " << progName << " [-u FEED_URI] [CHANNEL FLAGS] ";
|
|
std::cout << "[-i ITEM_INDEX] [ITEM FLAGS]\n";
|
|
std::cout << "Options:\n";
|
|
std::cout << "Required Options:\n";
|
|
std::cout << " [-u, --uri] URI URI of the rss stream\n\n";
|
|
|
|
std::cout << "Channel information:\n";
|
|
std::cout << " [-t, --title] Get title of channel\n";
|
|
std::cout << " [-l, --link] Get link to channel\n";
|
|
std::cout << " [-d, --description] Get description of channel\n";
|
|
std::cout << " [-e, --language] Get language code of channel\n";
|
|
std::cout << " [-m, --webmaster] Get webMaster's email\n";
|
|
std::cout << " [-c, --copyright] Get copyright\n";
|
|
std::cout << " [-p, --pubdate] Get publishing date\n";
|
|
std::cout << " [-q, --managingeditor] Get managing editor\n";
|
|
std::cout << " [-g, --generator] Get generator of this feed\n";
|
|
std::cout << " [-o, --docs] Get link to RSS documentation\n";
|
|
std::cout << " [-w, --ttl] Get ttl, time that channel can be\n";
|
|
std::cout << " cached before being updated\n";
|
|
std::cout << " [-b, --builddate] Get last time the channel's\n";
|
|
std::cout << " content changed\n";
|
|
std::cout << " [-i, --item] INDEX Provide index of item to display\n";
|
|
std::cout << " If no index is provided, assume the first\n";
|
|
std::cout << " item in the feed. All following flags will\n";
|
|
std::cout << " be parsed as item options, till another\n";
|
|
std::cout << " item is provided\n\n";
|
|
|
|
std::cout << "Item options:\n";
|
|
std::cout << " [-t, --title] Get title of item\n";
|
|
std::cout << " [-l, --link] Get link\n";
|
|
std::cout << " [-d, --description] Get description\n";
|
|
std::cout << " [-a, --author] Get author\n";
|
|
std::cout << " [-z, --category] Get category list\n";
|
|
std::cout << " [-f, --comments] Get link to comments\n";
|
|
std::cout << " [-j, --guid] Get GUID\n";
|
|
std::cout << " [-p, --pubdate] Get publishing date\n";
|
|
std::cout << " [-s, --source] Get source of item\n\n";
|
|
|
|
std::cout << "General options:\n";
|
|
std::cout << " [-h, --help] Show this message\n\n";
|
|
|
|
std::cout << "For more information, refer to the RSS 2.0 documentation\n";
|
|
std::cout << "https://validator.w3.org/feed/docs/rss2.html\n";
|
|
|
|
exit(1);
|
|
}
|
|
|
|
option_flags* parse_options(int argc, char** argv) {
|
|
int option_index = 0;
|
|
int c;
|
|
|
|
item_flags* current_item = nullptr;
|
|
option_flags* ret = new option_flags;
|
|
|
|
ret->item_count = 0;
|
|
ret->items = nullptr;
|
|
|
|
while(true){
|
|
c = getopt_long(argc, argv, optarg_string,
|
|
long_options, &option_index);
|
|
if(c == -1)
|
|
break;
|
|
|
|
switch(c){
|
|
case 'u':
|
|
ret->uri = std::string(optarg);
|
|
break;
|
|
case 't':
|
|
if(current_item == nullptr)
|
|
ret->title ^= 1;
|
|
else
|
|
current_item->title ^= 1;
|
|
break;
|
|
case 'l':
|
|
if(current_item == nullptr)
|
|
ret->link ^= 1;
|
|
else
|
|
current_item->link ^= 1;
|
|
break;
|
|
case 'd':
|
|
if(current_item == nullptr)
|
|
ret->description ^= 1;
|
|
else
|
|
current_item->description ^= 1;
|
|
break;
|
|
case 'e':
|
|
ret->language ^= 1;
|
|
break;
|
|
case 'm':
|
|
ret->webmaster ^= 1;
|
|
break;
|
|
case 'c':
|
|
ret->copyright ^= 1;
|
|
break;
|
|
case 'p':
|
|
if(current_item == nullptr)
|
|
ret->pubdate ^= 1;
|
|
else
|
|
current_item->pubdate ^= 1;
|
|
break;
|
|
case 'q':
|
|
ret->managingeditor ^= 1;
|
|
break;
|
|
case 'g':
|
|
ret->generator ^= 1;
|
|
break;
|
|
case 'o':
|
|
ret->docs ^= 1;
|
|
break;
|
|
case 'w':
|
|
ret->ttl ^= 1;
|
|
break;
|
|
case 'b':
|
|
ret->builddate ^= 1;
|
|
break;
|
|
case 'i':
|
|
if(ret->items == nullptr){
|
|
ret->items = new item_flags[ret->item_count + 1];
|
|
current_item = &(ret->items[0]);
|
|
ret->item_count++;
|
|
current_item->index = optarg ? atoi(optarg) : 0;
|
|
} else {
|
|
item_flags* new_flags = new item_flags[ret->item_count + 1];
|
|
for(unsigned int i=0;i<ret->item_count;++i)
|
|
new_flags[i] = ret->items[i];
|
|
delete ret->items;
|
|
ret->items = new_flags;
|
|
current_item = &(ret->items[ret->item_count]);
|
|
ret->item_count++;
|
|
current_item->index = optarg ? atoi(optarg) : 0;
|
|
}
|
|
break;
|
|
case 'a':
|
|
if(current_item == nullptr){
|
|
std::cerr << "Invalid option in this context: [-a --author]" << std::endl;
|
|
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
|
} else
|
|
current_item->author ^= 1;
|
|
break;
|
|
case 'z':
|
|
if(current_item == nullptr){
|
|
std::cerr << "Invalid option in this context: [-z --category]" << std::endl;
|
|
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
|
} else
|
|
current_item->category ^= 1;
|
|
break;
|
|
case 'f':
|
|
if(current_item == nullptr){
|
|
std::cerr << "Invalid option in this context: [-f --comments]" << std::endl;
|
|
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
|
} else
|
|
current_item->comments ^= 1;
|
|
break;
|
|
case 'j':
|
|
if(current_item == nullptr){
|
|
std::cerr << "Invalid option in this context: [-j --guid]" << std::endl;
|
|
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
|
} else
|
|
current_item->guid ^= 1;
|
|
break;
|
|
case 's':
|
|
if(current_item == nullptr){
|
|
std::cerr << "Invalid option in this context: [-s --source]" << std::endl;
|
|
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
|
} else
|
|
current_item->source ^= 1;
|
|
break;
|
|
case ':': //go here if flag that requires argument is passed, but no arg given
|
|
switch(optopt){
|
|
case 'i':
|
|
if(ret->items == nullptr){
|
|
ret->item_count++;
|
|
ret->items = new item_flags[ret->item_count];
|
|
current_item = &(ret->items[0]);
|
|
current_item->index = 1;
|
|
} else {
|
|
item_flags* new_flags = new item_flags[ret->item_count + 1];
|
|
for(unsigned int i=0;i<ret->item_count;++i)
|
|
new_flags[i] = ret->items[i];
|
|
delete ret->items;
|
|
ret->items = new_flags;
|
|
current_item = &(ret->items[ret->item_count]);
|
|
ret->item_count++;
|
|
current_item->index = 1;
|
|
}
|
|
break;
|
|
default:
|
|
std::cerr << "Invalid use: option -" << (char)optopt
|
|
<< " requires an argument" << std::endl;
|
|
break;
|
|
}
|
|
break;
|
|
case '?':
|
|
std::cerr << "Unknown option: " << (char)optopt << std::endl;
|
|
case 'h':
|
|
help(argv[0]);
|
|
break;
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
|
|
if(ret->uri == ""){
|
|
std::cerr << "Missing required option! -u/--uri" << std::endl;
|
|
exit(-1);
|
|
}
|
|
return ret;
|
|
}
|
|
|