Git Product home page Git Product logo

likle / cargs Goto Github PK

View Code? Open in Web Editor NEW
146.0 7.0 16.0 114 KB

A lightweight cross-platform getopt alternative that is tested on Linux, Windows, FreeBSD and macOS. Command line argument parser library for C/C++. Can be used to parse argv and argc parameters.

Home Page: https://likle.github.io/cargs/

License: MIT License

CMake 10.75% C 71.29% Meson 0.80% C++ 17.16%
getopt getopt-long c cross-platform command-line-parser command-line arguments argument-parser windows macos

cargs's Issues

Non-option arguments

Thank you for this nice project.

Could you please add an example with non-option arguments and how to read them?

I guess the following example is self-explanatory, the src and dst arguments would be non-option file paths:

filecopy --recursive --overwrite=newer src dst

I've tried to understand the source code (quickly), but failed.

Thank you.

_Mark

Obsolete non-standard header memory.h?

cargs.c includes memory.h which is not a standard library header.

Is there are reason to use memory.h? Limiting the project to the standard headers would increase portability.

I removed the include and successfully built a test project with gcc 11 (Linux) and gcc 13 (Windows).

(libcargs v1.1.0)

`cag_option_print` not working in mingw64 (but works in msvc)

Hi,
Yesterday I was trying to use cargs. First I tried building with mingw gcc in windows. But everything went ok before testing help command. help command only printed "demonstra...." line and then paused for a second then stopped execution. But I tried doing this in wsl2 and msvc, and they worked perfectly there. Can you figure out the issue?

FWIW Include demo in default build

Update: added #11 for easier update

--- CMakeLists.org	2023-08-23 13:30:44.000000000 +0200
+++ CMakeLists.txt	2023-08-23 13:34:12.000000000 +0200
@@ -19,11 +19,15 @@
 
 # setup target and directory names
 set(LIBRARY_TARGET "cargs")
-set(TEST_TARGET "cargstest")
 set(INCLUDE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include")
 set(SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src")
+
+set(TEST_TARGET "cargstest")
 set(TEST_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/test")
 
+set(DEMO_TARGET "cargsdemo")
+set(DEMO_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/demo")
+
 # enable coverage if requested
 if(ENABLE_COVERAGE)
   message("-- Coverage enabled")
@@ -85,6 +89,12 @@
   enable_warnings(${TEST_TARGET})
 endif()
 
+if(ENABLE_DEMO)
+  message("-- Demo enabled")
+  add_executable(${DEMO_TARGET} "${DEMO_DIRECTORY}/main.c")
+  target_link_libraries(${DEMO_TARGET} PUBLIC ${LIBRARY_TARGET})
+endif()
+
 # version file
 configure_package_config_file("cmake/CargsConfig.cmake.in"
   ${CMAKE_CURRENT_BINARY_DIR}/CargsConfig.cmake

About code style

hi @likle,
There are a little suggestions about code style as follows:
1、I notice the maximum line width is 80 in most cases, but some is 100.
2、maybe use a .clang-format file to help people to make sure the code style fits the surrounding code. I notice there is a .clang-format file in the repo, but with too few constraints and terms in it.
Forgive me for my poor English. -:p

Fileles build option

Hi.

Are you interested following API change?

#ifndef NO_FILE_SUPPORT
CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
  FILE *destination);
#endif

typedef int(*cag_printer)(void *ctx, const char *fmt, ...);

CAG_PUBLIC void cag_option_print_cb(const cag_option* options, size_t option_count, cag_printer printer, void *ctx);

My embedded system does not have file support so I refactored API so that I could use callback to print help texts. Are you interested to receive PR ? I am too lazy to make it if you are not interested to extending API for embedded usage.

Get invalid option

Is there a way to get an invalid option, like an option that doesn't exist in array of cag_option?

while (cag_option_fetch(&context)) {
  ident = cag_option_get(&context);
  switch (ident) {
  case 'h':
    printf("%s\n", "Usage: program [-h]");
    exit(EXIT_SUCCESS);
    break;
  default:
    // here's where it handle invalid option; below is an example
    printf("Error: invalid option '%s'\n", cag_option_get_invalid(&context));
    exit(EXIT_FAILURE);
    break;
  }
}

Non-option arguments may be reordered

Hi,

I've been using cargs for a small project where I want to be cross-platform and still offer a reasonably full-featured command-line interface, and it's been working really well.

However, I seem to have a problem. If I compile this test program (foo.c):

#include <stdio.h>
#include "cargs.h"

static struct cag_option options[] = {
    { .identifier = 'h',
      .access_letters = "h",
      .access_name = "help",
      .description = "show this help and exit" },
};

int main(int argc, char *argv[]) {
    cag_option_context context;
    cag_option_prepare(&context, options, CAG_ARRAY_SIZE(options), argc, argv);
    while (cag_option_fetch(&context)) {
        char identifier = cag_option_get(&context);
        switch (identifier) {
            case 'h':
                printf("Help...\n");
                break;
            default:
                printf("?\n");
                break;
        }
    }
    for (int i = context.index; i < context.argc; ++i) {
        printf("arg %d: %s\n", i, context.argv[i]);
    }
}

the non-option arguments seem to be permuted inconsistently. Normally the order is preserved:

$ gcc -Wall foo.c cargs.c
$ ./a.out foo bar
arg 1: foo
arg 2: bar
$ ./a.out -h foo bar
Help...
arg 2: foo
arg 3: bar
$ ./a.out foo -h bar
Help...
arg 2: foo
arg 3: bar

but if I have an option as the last argument, things change:

$ ./a.out foo bar -h
Help...
arg 2: bar
arg 3: foo

arg 2 is now "bar", whereas it used to be "foo".

As my program is trying to accept two non-option arguments which are input and output files, this breaks things. Would it be possible to have the order of non-option arguments preserved in all cases please?

If you need any more information please let me know.

Thanks.

Steve

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.