Skip to content

Instantly share code, notes, and snippets.

@bathtime
Last active March 21, 2018 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bathtime/53fcc5c19157011f41d65ab03e457ab2 to your computer and use it in GitHub Desktop.
Save bathtime/53fcc5c19157011f41d65ab03e457ab2 to your computer and use it in GitHub Desktop.
// This program parses an online XML dictionary site and prints
// conjugated results for input terms.
//
// The goals of this project:
//
// 1. < 100 lines code
// 2. Simple & elegant coding
// 3. Fast & efficient execution.
//
// "Do one thing,
// and do it well."
//
// —Linux Credo
//
// Compile with:
// $ g++ -O3 -Wall latc.cpp -o latc -L/usr/include/curl/lib -lcurl
//
// Run with:
// $ latc quam totus amor
//
// Where 'quam', 'totus', and 'amor' are your search terms.
//
// Use with 'la' application to auto-conjugate and display results:
// $ la $(latc quam totus amor)
//
#include <iostream>
#include <string>
#include <curl/curl.h>
using namespace std;
string data; // Will hold the url's contents
size_t writeCallback(char* buf, size_t size, size_t nmemb, void* up)
{
for (unsigned int c = 0; c<size*nmemb; c++)
data.push_back(buf[c]);
return size*nmemb; // Tell curl how many bytes we handled
}
string findBetweenStr(string& trueText, string& strBegin, string& strEnd, int& pBegin)
{
std::size_t beginFound;
std::size_t tmpUnSigned = pBegin; // Can't compare signed and unsigned
// Do not start at position beyond end of string
if (tmpUnSigned + strBegin.length() + strEnd.length() > trueText.length()){
pBegin = -1;
return "";
}
beginFound = trueText.substr(pBegin).find(strBegin);
if (beginFound!=std::string::npos)
{
beginFound += pBegin + strBegin.length();
std::size_t endFound = trueText.substr(beginFound).find(strEnd);
if (endFound!=std::string::npos)
{
pBegin = beginFound + 1;
return trueText.substr(beginFound, endFound);
}
}
pBegin = -1;
return "";
}
int main(int argc, char* argv[])
{
// No search term entered. Bye!
if (!argv[1]) return 1;
int begin;
std::string text;
std::string sBegin = "entry=";
std::string sEnd = "-contents\');\n\">Lewis &amp; Short</a>";
// Go through all inputted command parameters
for(int keyNum = 1; keyNum < argc; keyNum++ )
{
data = ""; // reset or data appends for each iteration and creates double results
std::string charToStr(argv[keyNum]);
string URLkey="http://www.perseus.tufts.edu/hopper/morph?l=" + charToStr + "&la=la";
const char * keyChar = URLkey.c_str();
CURL* curl; // Our curl object
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, keyChar);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &writeCallback);
curl_easy_perform(curl);
begin = 0;
do{
text = findBetweenStr(data, sBegin , sEnd, begin);
if (begin != -1 && text.length() < 30)
std::cout << text << std::endl;
}while (begin != -1);
// Clean as we go: don't want any leaks!
curl_easy_cleanup(curl);
curl_global_cleanup();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment