GithubHelp home page GithubHelp logo

devsolar / pdclib Goto Github PK

View Code? Open in Web Editor NEW
217.0 217.0 40.0 2.7 MB

The Public Domain C Library

Home Page: https://pdclib.rootdirectory.de

License: Creative Commons Zero v1.0 Universal

Makefile 0.12% C 95.62% CMake 1.78% C++ 2.48%

pdclib's People

Contributors

devsolar avatar thrimbor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pdclib's Issues

Compiling pdclib

I'm using an Ubuntu Linux machine, and I want to compile pdclib both as a static library and as part of my project.

I'm having trouble to understand QuickStart.txt, and I'd be really happy to have some clarifications.

Compile all the source files in 'functions' into a library (static or shared, your choice).

What is the way to compile it?

Define _PDCLIB_BUILD

Where does this definition should be?

Thank you

NULL is not detected as a sentinel

We came across this a while ago in XboxDev/nxdk#253.
Code can use a special attribute on gcc and clang that signals the compiler that it should check whether calls to the function use a sentinel value to properly end the parameter list.
This warning gets emitted when using PDCLib even when properly using NULL as a sentinel value, because NULL is defined as a zero literal:

#define _PDCLIB_NULL 0

clang has a test for this warning which indicates that it expects a pointer type: https://github.com/llvm-mirror/clang/blob/master/test/Sema/block-sentinel-attribute.c

The C11 standard says in 7.19:

NULL
which expands to an implementation-defined null pointer constant;

So I think replacing the above line with something #define _PDCLIB_NULL ((void *)0) should resolve that without any drawbacks regarding portability or standard compliance.

Definition of `EOF` macro might cause issues with existing code (missing parentheses)

This is the definition of EOF in pdclib:

#define EOF -1

it leads to issues with this code in jsoncpp: https://github.com/open-source-parsers/jsoncpp/blob/94cda30dbddc1859f111848fdd05dfb85d3287c7/src/lib_json/json_reader.cpp#L108

The error is:

/tmp/wdaoihs/jsoncpp/src/lib_json/json_reader.cpp:108:42: error: expected '(' after 'static_cast'
  std::getline(is, doc, static_cast<char> EOF);
                                         ^
                                         (

So this existing piece of (popular) code seems to assume that EOF will contain parentheses. I'm not sure if this is part of a C standard, a C++ standard, a convention / tradition, or a bug in my / our other toolchain components.
I also checked the standard and it merely seems to say that the EOF macro is a negative int number.

However, for comparison, my GNU libc installation has this:

#define EOF (-1)

I also checked newlib: https://www.sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/include/stdio.h;h=164d95bca4a1e3cc66cad9319f4925d168874e05;hb=5fcbbf7ead615c116f8e08047093232b1325faf4#l118 (also (-1))

I could imagine that there could also be potential operator precedence issues without the parantheses?

Public strtok_r

Hello,
In one of the project that I've been involved, I had the need to use strtok_r.
Since this function is private in pdclib, I had to use the one provided by Charlie Gordon (link for reference: https://groups.google.com/forum/#!msg/comp.lang.c/akY2fEnquSU/hGZkhrvssSoJ).

I'm opening this issue to ask about the possibility to have a public strtok_r in pdclib, so we can use the internal one.

Thanks

PS: adding @JayFoxRox to this ticket because we were following this issue toghether.

ungetc() not properly supported

I just realized there is a major muckup surrounding that ugly red-headed stepchild of <stdio.h>, ungetc(). (Which had been troubling me ever since I touched that header...)

As of now, ungetc() is not properly supported. As this is all kinds of "breaking", I will handle this issue with the utmost priority.

Improve handling of `strerror` messages

(This is a low priority issue, but ports would probably require updates, so it's good to fix this before a bad implementation propagates)

As also indicated by the comment, this function is not ideal:

/* TODO: Doing this via a static array is not the way to do it. */
char * strerror( int errnum )
{
if ( errnum >= _PDCLIB_ERRNO_MAX || errnum < 0 )
{
return _PDCLIB_EUNKNOWN_TEXT;
}
else
{
return _PDCLIB_lc_messages.errno_texts[errnum];
}
}

We actually discussed this briefly downstream in this conversation:

  • We have fairly large gaps in our error numbers / strings (so an array is not ideal).
  • There is some ambiguity wether the error message is "unknown error" from the host OS, or if it is "unknown error" from the pdclib error_readout tool.
  • There is no way to implement custom "unknown error"-messages algorithmically (for including the error number for example).

scanf crashes

This custom test case yields problems:

    int a, b, c;
    SCANF_TEST( 0, "foo 0", " %n%*s%n %n", &a, &b, &c );
    TESTCASE( a == 0 );
    TESTCASE( b == 3 );
    TESTCASE( c == 4 );

Here is some information from gdb:

Program received signal SIGSEGV, Segmentation fault.
0x00005555555645d3 in _PDCLIB_scan (spec=0x55555556732c "n", status=0x7fffffffe550) at pdclib/functions/_PDCLIB/_PDCLIB_scan.c:394
394	            *val = status->i;
(gdb) print val
$1 = (int *) 0x0
(gdb) print *status
$2 = {base = -1, flags = 0, n = 1, i = 4, current = 0, s = 0x0, width = 18446744073709551615, prec = 0, stream = 0x55555556b620 <_PDCLIB_sin>, arg = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fffffffe6b0, reg_save_area = 0x7fffffffe5f0}}}

Downstream issue where this affects a real application: XboxDev#16

_PDCLIB_Noreturn not effective in C++ code

In nxdk, we have been getting warnings when building libc++ about functions marked as noreturn supposedly returning. I have tracked this down to the function abort, which wasn't marked as noreturn when building C++ code. This is caused by the preprocessor code in _PDCLIB_internal.h (or _PDCLIB_aux.h in our case, we haven't rebased in a while), which relies on __STDC_VERSION__. Unfortunately, __STDC_VERSION__ is not defined in C++.

This is the problematic part:

#if __STDC_VERSION__ < 201112L
#define _PDCLIB_Noreturn
#else
#define _PDCLIB_Noreturn _Noreturn
#endif

I checked how the compiler handles this, and it evaluates the __STDC_VERSION__ < 201112L condition to true, thereby not marking the functions as noreturn despite the compiler supporting it.

I replaced it with the following code, which fixes the warnings mentioned above:

#if defined(__cplusplus) && __cplusplus >= 201103L
#define _PDCLIB_Noreturn [[noreturn]]
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define _PDCLIB_Noreturn _Noreturn
#else
#define _PDCLIB_Noreturn
#endif

There are other uses of __STD_VERSION__ in PDCLib that might need similar treatment.

Design flaw / logic error in _PDCLIB_seek

This was found on pdclib for nxdk (homebrew toolchain for the original Xbox). The nxdk pdclib is very close to the example reference implementation, so I believe the following is a flaw in the pdclib design, not in our implementation.

Here's code which triggers the bug:

(I'll refer to the machines kernel / filesystem driver as "platform backend")

#include <stdio.h>

#ifdef NXDK
// Hack for original Xbox: Use a framebuffer draw instead of stdout
#include <xboxrt/debug.h>
#define printf(fmt, ...) debugPrint(fmt, __VA_ARGS__)
#endif

int main() {

  FILE* f = fopen("default.xbe" ,"rb");
  // platform backend at offset 0
  // pdclib at offset 0

  char buf[10];
  fread(buf, 1, 10, f);
  // platform backend was forced to fill the entire buffer, so platform backend is at 1024 (_PDCLIB_BUFSIZ)
  // pdclib has 1024 buffer, and knows platform backend is at 1024, but, correctly, pdclib only moves to offset 10 in that buffer

  size_t a = ftell(f);
  printf("A: %zu\n", a);
  // Still returns 10 (handled internally by pdclib; recovered by doing a bit of math with known values)

  // !!! The state is still good

  fseek(f, 0, SEEK_CUR);
  // platform backend reports new offset as 1024
  // pdclib trusts this and is now also at offset 1024 (should be at 10)

  // !!! The state is now broken

  size_t b = ftell(f);
  printf("B: %zu\n", b);
  // Suddenly returns 1024

  
  while(1);


  return 0;
}

Explanation:

  • When reading, this remembers how much of the buffer it read so pdclib knows the real offset in the file (so even if pdclib buffers 1024 bytes, it knows it is still at offset 0; and if it reads X bytes of the buffer, it's at offset X). Meanwhile, the underlying platform backend (kernel / filesystem driver) will have seeked.

  • When doing a relative seek, the platform backend only knows about its own information. It will have it's own cursor at the end of where pdclib stopped filling the buffer from. That will be returned from here (Something like _PDCLIB_BUFSIZ = 1024) and used for relative seeks. As far as the platform backend is concerned this is the current cursor position.

  • When the platform code returns, pdclib will forget about its own buffer offset and accept the platform backend cursor as true fact. pdclib has now accidentally moved from knowing where it is in the buffer, to another location behind the buffer.


I hope this will be reviewed / addressed soon.

I did not check wether this also affects other functions, like unget, write, ..; I also did not think about other cases like SEEK_SET or SEEK_END yet.

Can't find "pdclib/_PDCLIB_config.h"

I create a C source in this repo "\include" folder and compile it:

#include ".\stdio.h"
int main()
{
    printf("Hello, PDCLib!");
    return 0;
}

And Compiler (MinGW-w64) says,

E:\source\repos\pdclib\include\pdclib_PDCLIB_int.h|19|fatal error: pdclib/_PDCLIB_config.h: No such file or directory|

I see "_PDCLIB_int.h", in Line 19:
#include "pdclib/_PDCLIB_config.h"
I can't find "pdclib/_PDCLIB_config.h" in this repo. Where is "pdclib/_PDCLIB_config.h"?

Move "Status" section out of "Get the Source" wiki article

https://rootdirectory.ddns.net/dokuwiki/doku.php?id=pdclib:source#status should be moved to either of those:

The implementation status is not really related to "Get the Source" - it is "What is PDCLib" (which is what pdclib:start should be).


Minor related issues:

  • The "Get the Source" link also shouldn't be in the "Status" section of pdclib:start, and be more prominent elsewhere in that article.
  • The GitHub "Wiki" (along with "Projects") should be disabled in the GitHub settings: Those navigation links are dead for non-owners and mislead users into thinking the main wiki is on GitHub.

_PDCLIB_Noreturn does nothing in C++11

The current code for PDCLIB_Noreturn seems to define it as an empty macro when building with a C++ compiler. This causes warning: function declared 'noreturn' should not return [-Winvalid-noreturn] warnings when building libc++, as it expects abort(), which is called in functions marked [[noreturn]], to come with the C++11 [[noreturn]] attribute.

I experimented with adding the following code in line 59 of _PDCLIB_int.h:

#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define _PDCLIB_Noreturn [[noreturn]]
#endif

It fixed the warnings in my tests while not negatively impacting compilation of other code.

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.