commit efaf6124e55b6c02476f6f1b0d78d653dd3f5da1 Author: Bob Polis Date: Tue Sep 1 16:12:41 2020 +0200 first commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8f1a266 --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +BIN := $(shell basename $$(pwd)) + +MANSECTION := 1 +MANPAGE := $(BIN).$(MANSECTION) + +SRCS := $(wildcard *.cpp) +OBJS := $(subst .cpp,.o,$(SRCS)) +DEPS := $(subst .cpp,.d,$(SRCS)) + +CXX ?= g++ +PKG_CONFIG ?= pkg-config + +PREFIX ?= /usr/local +BINDIR ?= $(PREFIX)/bin +CONFIGDIR ?= $(PREFIX)/etc +DATADIR ?= $(PREFIX)/share +MANDIR ?= $(DATADIR)/man/man +DOCDIR ?= $(DATADIR)/$(BIN)/doc + +RM := /bin/rm -f +INSTALL := /usr/bin/install -c + +CXXFLAGS := $(CXXFLAGS) -Wshadow -Wall -Wpedantic -Wextra -g -fno-strict-aliasing -std=c++17 -pthread +ifeq ($(DEBUG),1) + CXXFLAGS += -D DEBUG -O0 +else + CXXFLAGS += -D NDEBUG -O3 +endif + +LDLIBS := -lm -lpthread -lcurl -lsclogging + +.PHONY: all clean install + +all: $(BIN) + +$(BIN): $(OBJS) $(DEPS) + $(CXX) $(OBJS) $(LDFLAGS) $(LDLIBS) -o $(BIN) + +%.o: %.cpp %.d Makefile + $(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $< + +-include *.d + +%.d: ; + +clean: + $(RM) $(OBJS) $(DEPS) $(BIN) + +install: $(BIN) + $(INSTALL) -d $(BINDIR) + $(INSTALL) $(BIN) $(BINDIR) + $(INSTALL) -d $(MANDIR)$(MANSECTION) + $(INSTALL) $(MANPAGE) $(MANDIR)$(MANSECTION) diff --git a/curly.1 b/curly.1 new file mode 100644 index 0000000..95c52f5 --- /dev/null +++ b/curly.1 @@ -0,0 +1,57 @@ +.Dd $Mdocdate$ +.Dt curly 1 +.Os +.Sh NAME +.Nm curly +.Nd one line about what it does +.\" .Sh LIBRARY +.\" For sections 2, 3, and 9 only. +.\" Not used in OpenBSD. +.Sh SYNOPSIS +.Nm +.Fl h | v +.Nm +.Op Ar +.Sh DESCRIPTION +The +.Nm +utility processes files ... +When no file arguments are given, +.Nm +will read from the standard input. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl h, \-help +Print help text and exit. +.It Fl v, \-version +Print version info and exit. +.El +.\" .Sh CONTEXT +.\" For section 9 functions only. +.\" .Sh IMPLEMENTATION NOTES +.\" Not used in OpenBSD. +.\" .Sh RETURN VALUES +.\" For sections 2, 3, and 9 function return values only. +.\" .Sh ENVIRONMENT +.\" For sections 1, 6, 7, and 8 only. +.\" .Sh FILES +.Sh EXIT STATUS +.\" For sections 1, 6, and 8 only. +.Nm +exits 0 on success, and 1 if an error occurs. +.\" .Sh EXAMPLES +.\" .Sh DIAGNOSTICS +.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only. +.\" .Sh ERRORS +.\" For sections 2, 3, 4, and 9 errno settings only. +.\" .Sh SEE ALSO +.\" .Xr foobar 1 +.\" .Sh STANDARDS +.\" .Sh HISTORY +.Sh AUTHORS +Bob Polis +.\" .Sh CAVEATS +.\" .Sh BUGS +.\" .Sh SECURITY CONSIDERATIONS +.\" Not used in OpenBSD. diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..28e1fc3 --- /dev/null +++ b/main.cpp @@ -0,0 +1,105 @@ +// +// main.cpp +// curly +// +// Created by Bob Polis at 2020-09-01 +// Copyright (c) 2020 SwiftCoder. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +sc::logger logger {"curly", sc::loglevel::info}; + +void print_help() { + std::cout << "usage: curly [-h|--version]\n"; + std::cout << " -h, --help show this help text and exit\n"; + std::cout << " --version show version number and exit\n"; +} + +void print_version() { + std::cout << "curly version 1.0\n"; +} + +size_t write_data(void* buf, size_t sz, size_t nmemb, void* userp) { + size_t realsize = sz * nmemb; + SCInfo(logger, "received ", realsize, " bytes"); + std::vector* dest {reinterpret_cast*>(userp)}; + size_t oldsize = dest->size(); + dest->resize(oldsize + realsize); + std::memcpy(dest->data() + oldsize, buf, realsize); + return realsize; +} + +int main(int argc, const char * argv[]) { + try { + int opt_char, opt_val; + struct option long_options[] = { + {"help", no_argument, nullptr, 'h'}, + {"version", no_argument, &opt_val, 1}, + {nullptr, 0, nullptr, 0} + }; + while ((opt_char = getopt_long(argc, const_cast(argv), "h", long_options, nullptr)) != -1) { + std::string arg {optarg ? optarg : ""}; + switch (opt_char) { + case 0: { + // handle long-only options here + switch (opt_val) { + case 1: + print_version(); + return EXIT_SUCCESS; + } + break; + } + case 'h': + print_help(); + return EXIT_SUCCESS; + case '?': + throw std::runtime_error("unrecognized option"); + } + } + if (optind == argc) { + // here when no file args + } + for (int i = optind; i < argc; ++i) { + try { + // process file argv[i] + } catch (const std::runtime_error& ex) { + std::cerr << "curly: " << ex.what() << '\n'; + } + } + std::cout << "hello, curly\n"; + + curl_global_init(CURL_GLOBAL_ALL); + auto easy_handle = curl_easy_init(); + curl_easy_setopt(easy_handle, CURLOPT_URL, "https://www.swiftcoder.nl/"); + curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, write_data); + std::vector buf; + curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &buf); + auto success = curl_easy_perform(easy_handle); + if (success != CURLE_OK) throw std::runtime_error("could not get remote data"); + + std::string text {buf.data(), buf.size()}; + std::cout << text << '\n'; + + curl_easy_setopt(easy_handle, CURLOPT_URL, "https://www.swiftcoder.nl/moneydance/"); + buf.clear(); + success = curl_easy_perform(easy_handle); + if (success != CURLE_OK) throw std::runtime_error("could not get remote data"); + + std::string page2 {buf.data(), buf.size()}; + std::cout << page2 << '\n'; + + } catch (const std::exception& ex) { + std::cerr << "curly: " << ex.what() << '\n'; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +}