User Guide
FAQ

FAQ

Missing <regex.h>

CPLib depends on the regex.h header file from the C POSIX Library (opens in a new tab). If you are using a standard library outside of a POSIX environment (such as MinGW on Windows or the default standard library used by MSVC), it is likely that this file does not exist or is corrupted. You can solve this problem by using the musl regex.h standalone (opens in a new tab) project.

You can obtain a single-header regex.h implementation from the GitHub repository (opens in a new tab) of this project. You can place it in the system's include folder or replace the existing and corrupted regex.h.

Regular Expression Too Big

If you use a regular expression like [a-z]{1,1000000} to match strings with lengths between 11 and 10610^6, the program will quit with an "Internal Error", along with an error message such as pattern constructor failed: Invalid contents of {} or pattern constructor failed: Regular expression too big. This is because most regular expression libraries based on NFA (opens in a new tab) have a space complexity of O(SR)O(|S| \cdot R) and a time complexity of O(STR)O(|S| \cdot |T| \cdot R) when matching a pattern string SS against a text string TT. Here, RR represents the sum of values in the interval repetition syntax {n}, {n,}, {,m}, or {n,m} within SS. When RR is very large, the pattern construction may fail, and even if it succeeds in some environments, it can result in very slow matching efficiency. Therefore, if you want to match long texts using regular expressions, do not check the length of the string within the regular expression. The following example shows how to correctly read and check a long string:

// Wrong
// auto pat = Pattern("[a-z]{1,1000000}");
 
// Right
auto pat = Pattern("[a-z]+");
auto str = some_reader.read(cplib::var::String(pat));
if (str.size() > 1000000) {
  // handle error
}

License Agreement

CPLib is licensed under the LGPL-3.0-or-later (opens in a new tab) license. This license is relatively permissive compared to the GPL license. You can use CPLib in any software, including proprietary software, without the need to disclose your own source code.

What you are required to do

When you distribute software that uses CPLib, the LGPL requires you to:

  • Indicate somewhere that the software uses CPLib, and that CPLib is licensed under the LGPL.
  • Provide a link to the LGPL license text.

However, you don't need to worry about this, as when using the DefaultInitializer, the program written using CPLib will automatically output the relevant information when called with the --help command-line argument.

Without constituting a fork, the LGPL license is almost entirely equivalent to the 2-clause BSD license. This will be explained further in the following.

Forking

Forking CPLib means modifying CPLib itself and distributing software based on the modified CPLib. In this case, there are additional requirements:

  • If you want to distribute software based on the modified CPLib, you must provide the modified CPLib under the LGPL license.
  • The only content you must provide under the LGPL is the modified CPLib. You still do not need to provide any other software under the LGPL, not even software that uses CPLib or your modified CPLib.

Simply using CPLib in your software does not constitute a fork. Forking CPLib involves modifying the CPLib files themselves in some way. The LGPL also explicitly states (in Section 0) that subclassing CPLib classes (also known as inheriting from CPLib classes, such as customizing the initializer) does not constitute a fork.

Why is CPLib, a header-only library, compatible with LGPL?

This question has been addressed in the LGPL version 3. The relevant part is in Section 3.

Linking, whether static or not, does not apply to CPLib, as it only contains header files. In CPLib, there is no linkable content.