We use only spaces for indentation, never TABs. We use two spaces for each new
open brace.
- if(something_is_true) {
- while(second_statement == fine) {
- moo();
- }
- }
+```c
+if(something_is_true) {
+ while(second_statement == fine) {
+ moo();
+ }
+}
+```
## Comments
Since we write C89 code, **//** comments are not allowed. They weren't
introduced in the C standard until C99. We use only **/* comments */**.
- /* this is a comment */
+```c
+/* this is a comment */
+```
## Long lines
the keyword and we then set the closing brace on the same indentation level as
the initial keyword. Like this:
- if(age < 40) {
- /* clearly a youngster */
- }
+```c
+if(age < 40) {
+ /* clearly a youngster */
+}
+```
You may omit the braces if they would contain only a one-line statement:
- if(!x)
- continue;
+```c
+if(!x)
+ continue;
+```
For functions the opening brace should be on a separate line:
- int main(int argc, char **argv)
- {
- return 1;
- }
+```c
+int main(int argc, char **argv)
+{
+ return 1;
+}
+```
## 'else' on the following line
When adding an **else** clause to a conditional expression using braces, we
add it on a new line after the closing brace. Like this:
- if(age < 40) {
- /* clearly a youngster */
- }
- else {
- /* probably grumpy */
- }
+```c
+if(age < 40) {
+ /* clearly a youngster */
+}
+else {
+ /* probably grumpy */
+}
+```
## No space before parentheses
When writing expressions using if/while/do/for, there shall be no space
between the keyword and the open parenthesis. Like this:
- while(1) {
- /* loop forever */
- }
+```c
+while(1) {
+ /* loop forever */
+}
+```
## Use boolean conditions
pointer against NULL or != NULL and an int against zero or not zero in
if/while conditions we prefer:
- result = do_something();
- if(!result) {
- /* something went wrong */
- return result;
- }
+```c
+result = do_something();
+if(!result) {
+ /* something went wrong */
+ return result;
+}
+```
## No assignments in conditions
To increase readability and reduce complexity of conditionals, we avoid
assigning variables within if/while conditions. We frown upon this style:
- if((ptr = malloc(100)) == NULL)
- return NULL;
+```c
+if((ptr = malloc(100)) == NULL)
+ return NULL;
+```
and instead we encourage the above version to be spelled out more clearly:
- ptr = malloc(100);
- if(!ptr)
- return NULL;
+```c
+ptr = malloc(100);
+if(!ptr)
+ return NULL;
+```
## New block on a new line
We never write multiple statements on the same source line, even for very
short if() conditions.
- if(a)
- return TRUE;
- else if(b)
- return FALSE;
+```c
+if(a)
+ return TRUE;
+else if(b)
+ return FALSE;
+```
and NEVER:
- if(a) return TRUE;
- else if(b) return FALSE;
+```c
+if(a) return TRUE;
+else if(b) return FALSE;
+```
## Space around operators
Examples:
- bla = func();
- who = name[0];
- age += 1;
- true = !false;
- size += -2 + 3 * (a + b);
- ptr->member = a++;
- struct.field = b--;
- ptr = &address;
- contents = *pointer;
- complement = ~bits;
- empty = (!*string) ? TRUE : FALSE;
+```c
+bla = func();
+who = name[0];
+age += 1;
+true = !false;
+size += -2 + 3 * (a + b);
+ptr->member = a++;
+struct.field = b--;
+ptr = &address;
+contents = *pointer;
+complement = ~bits;
+empty = (!*string) ? TRUE : FALSE;
+```
## No parentheses for return values
We use the 'return' statement without extra parentheses around the value:
- int works(void)
- {
- return TRUE;
- }
+```c
+int works(void)
+{
+ return TRUE;
+}
+```
## Parentheses for sizeof arguments
When using the sizeof operator in code, we prefer it to be written with
parentheses around its argument:
- int size = sizeof(int);
+```c
+int size = sizeof(int);
+```
## Column alignment
cases follow the 2-space indent guideline. Here are some examples from
libcurl:
- if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
- (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
- (handle->set.httpreq == HTTPREQ_GET ||
- handle->set.httpreq == HTTPREQ_HEAD))
- /* didn't ask for HTTP/1.0 and a GET or HEAD */
- return TRUE;
+```c
+if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
+ (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
+ (handle->set.httpreq == HTTPREQ_GET ||
+ handle->set.httpreq == HTTPREQ_HEAD))
+ /* didn't ask for HTTP/1.0 and a GET or HEAD */
+ return TRUE;
+```
If no parenthesis, use the default indent:
- data->set.http_disable_hostname_check_before_authentication =
- (0 != va_arg(param, long)) ? TRUE : FALSE;
+```c
+data->set.http_disable_hostname_check_before_authentication =
+ (0 != va_arg(param, long)) ? TRUE : FALSE;
+```
Function invoke with an open parenthesis:
- if(option) {
- result = parse_login_details(option, strlen(option),
- (userp ? &user : NULL),
- (passwdp ? &passwd : NULL),
- NULL);
- }
+```c
+if(option) {
+ result = parse_login_details(option, strlen(option),
+ (userp ? &user : NULL),
+ (passwdp ? &passwd : NULL),
+ NULL);
+}
+```
Align with the "current open" parenthesis:
- DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
- "server response left\n",
- (int)clipamount));
+```c
+DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
+ "server response left\n",
+ (int)clipamount));
+```
## Platform dependent code
seamless. Like this example where the **magic()** function works differently
depending on a build-time conditional:
- #ifdef HAVE_MAGIC
- void magic(int a)
- {
- return a + 2;
- }
- #else
- #define magic(x) 1
- #endif
+```c
+#ifdef HAVE_MAGIC
+void magic(int a)
+{
+ return a + 2;
+}
+#else
+#define magic(x) 1
+#endif
- int content = magic(3);
+int content = magic(3);
+```
## No typedefed structs
Use structs by all means, but do not typedef them. Use the `struct name` way
of identifying them:
- struct something {
- void *valid;
- size_t way_to_write;
- };
- struct something instance;
+```c
+struct something {
+ void *valid;
+ size_t way_to_write;
+};
+struct something instance;
+```
**Not okay**:
- typedef struct {
- void *wrong;
- size_t way_to_write;
- } something;
- something instance;
+```c
+typedef struct {
+ void *wrong;
+ size_t way_to_write;
+} something;
+something instance;
+```
## init
- void Curl_dyn_init(struct dynbuf *s, size_t toobig);
+```c
+void Curl_dyn_init(struct dynbuf *s, size_t toobig);
+```
This inits a struct to use for dynbuf and it can't fail. The `toobig` value
**must** be set to the maximum size we allow this buffer instance to grow to.
## free
- void Curl_dyn_free(struct dynbuf *s);
+```c
+void Curl_dyn_free(struct dynbuf *s);
+```
Free the associated memory and clean up. After a free, the `dynbuf` struct can
be re-used to start appending new data to.
## addn
- CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len);
+```c
+CURLcode Curl_dyn_addn(struct dynbuf *s, const void *mem, size_t len);
+```
Append arbitrary data of a given length to the end of the buffer.
## add
- CURLcode Curl_dyn_add(struct dynbuf *s, const char *str);
+```c
+CURLcode Curl_dyn_add(struct dynbuf *s, const char *str);
+```
Append a C string to the end of the buffer.
## addf
- CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...);
+```c
+CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...);
+```
Append a `printf()`-style string to the end of the buffer.
## vaddf
- CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap);
+```c
+CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap);
+```
Append a `vprintf()`-style string to the end of the buffer.
## reset
- void Curl_dyn_reset(struct dynbuf *s);
+```c
+void Curl_dyn_reset(struct dynbuf *s);
+```
Reset the buffer length, but leave the allocation.
## tail
- CURLcode Curl_dyn_tail(struct dynbuf *s, size_t length)
+```c
+CURLcode Curl_dyn_tail(struct dynbuf *s, size_t length);
+```
Keep `length` bytes of the buffer tail (the last `length` bytes of the
buffer). The rest of the buffer is dropped. The specified `length` must not be
## ptr
- char *Curl_dyn_ptr(const struct dynbuf *s);
+```c
+char *Curl_dyn_ptr(const struct dynbuf *s);
+```
Returns a `char *` to the buffer if it has a length, otherwise a NULL. Since
the buffer may be reallocated, this pointer should not be trusted or used
## uptr
- unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
+```c
+unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
+```
Returns an `unsigned char *` to the buffer if it has a length, otherwise a
NULL. Since the buffer may be reallocated, this pointer should not be trusted
## len
- size_t Curl_dyn_len(const struct dynbuf *s);
+```c
+size_t Curl_dyn_len(const struct dynbuf *s);
+```
Returns the length of the buffer in bytes. Does not include the terminating
zero byte.
Make sure that MinGW32's bin dir is in the search path, for example:
- set PATH=c:\mingw32\bin;%PATH%
+```cmd
+set PATH=c:\mingw32\bin;%PATH%
+```
then run `mingw32-make mingw32` in the root dir. There are other
make targets available to build libcurl with more features, use:
adjust as necessary. It is also possible to override these paths with
environment variables, for example:
- set ZLIB_PATH=c:\zlib-1.2.8
- set OPENSSL_PATH=c:\openssl-1.0.2c
- set LIBSSH2_PATH=c:\libssh2-1.6.0
+```cmd
+set ZLIB_PATH=c:\zlib-1.2.8
+set OPENSSL_PATH=c:\openssl-1.0.2c
+set LIBSSH2_PATH=c:\libssh2-1.6.0
+```
It is also possible to build with other LDAP SDKs than MS LDAP; currently
it is possible to build with native Win32 OpenLDAP, or with the Novell CLDAP
SDK. If you want to use these you need to set these vars:
- set LDAP_SDK=c:\openldap
- set USE_LDAP_OPENLDAP=1
+```cmd
+set LDAP_SDK=c:\openldap
+set USE_LDAP_OPENLDAP=1
+```
or for using the Novell SDK:
- set USE_LDAP_NOVELL=1
+```cmd
+set USE_LDAP_NOVELL=1
+```
If you want to enable LDAPS support then set LDAPS=1.
commands in curl's directory in the shell will build the code such that it
will run on cats as old as OS X 10.6 ("Snow Leopard") (using bash):
- export MACOSX_DEPLOYMENT_TARGET="10.6"
- ./configure --with-secure-transport
- make
+```bash
+export MACOSX_DEPLOYMENT_TARGET="10.6"
+./configure --with-secure-transport
+make
+```
# Android
launching `configure`. On macOS, those variables could look like this to compile
for `aarch64` and API level 29:
- export NDK=~/Library/Android/sdk/ndk/20.1.5948944
- export HOST_TAG=darwin-x86_64
- export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
- export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
- export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
- export CC=$TOOLCHAIN/bin/aarch64-linux-android29-clang
- export CXX=$TOOLCHAIN/bin/aarch64-linux-android29-clang++
- export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
- export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
- export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
+```bash
+export NDK=~/Library/Android/sdk/ndk/20.1.5948944
+export HOST_TAG=darwin-x86_64
+export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
+export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
+export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
+export CC=$TOOLCHAIN/bin/aarch64-linux-android29-clang
+export CXX=$TOOLCHAIN/bin/aarch64-linux-android29-clang++
+export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
+export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
+export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
+```
When building on Linux or targeting other API levels or architectures, you need
to adjust those variables accordingly. After that you can build curl like this:
example of cross-compiling for the IBM 405GP PowerPC processor using the
toolchain from MonteVista for Hardhat Linux.
- #! /bin/sh
-
- export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
- export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
- export AR=ppc_405-ar
- export AS=ppc_405-as
- export LD=ppc_405-ld
- export RANLIB=ppc_405-ranlib
- export CC=ppc_405-gcc
- export NM=ppc_405-nm
-
- ./configure --target=powerpc-hardhat-linux
- --host=powerpc-hardhat-linux
- --build=i586-pc-linux-gnu
- --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
- --exec-prefix=/usr/local
+```bash
+#! /bin/sh
+
+export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin
+export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include"
+export AR=ppc_405-ar
+export AS=ppc_405-as
+export LD=ppc_405-ld
+export RANLIB=ppc_405-ranlib
+export CC=ppc_405-gcc
+export NM=ppc_405-nm
+
+./configure --target=powerpc-hardhat-linux
+ --host=powerpc-hardhat-linux
+ --build=i586-pc-linux-gnu
+ --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local
+ --exec-prefix=/usr/local
+```
You may also need to provide a parameter like `--with-random=/dev/urandom` to
configure as it cannot detect the presence of a random number generating
Add a line in your application code:
- `curl_dbg_memdebug("dump");`
+```c
+ curl_dbg_memdebug("dump");
+```
This will make the malloc debug system output a full trace of all resource
using functions to the given file name. Make sure you rebuild your program
(page located at `http://www.formpost.com/getthis/`)
- <form action="post.cgi" method="post">
- <input name=user size=10>
- <input name=pass type=password size=10>
- <input name=id type=hidden value="blablabla">
- <input name=ding value="submit">
- </form>
+```html
+<form action="post.cgi" method="post">
+<input name=user size=10>
+<input name=pass type=password size=10>
+<input name=id type=hidden value="blablabla">
+<input name=ding value="submit">
+</form>
+```
We want to enter user 'foobar' with password '12345'.
If you've received a page from a server that contains a header like:
- Set-Cookie: sessionid=boo123; path="/foo";
+```http
+Set-Cookie: sessionid=boo123; path="/foo";
+```
it means the server wants that first pair passed on when we get anything in a
path beginning with "/foo".
A GET-form uses the method GET, as specified in HTML like:
- <form method="GET" action="junk.cgi">
- <input type=text name="birthyear">
- <input type=submit name=press value="OK">
- </form>
+```html
+<form method="GET" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value="OK">
+</form>
+```
In your favorite browser, this form will appear with a text box to fill in
and a press-button labeled "OK". If you fill in '1905' and press the OK
The form would look very similar to the previous one:
- <form method="POST" action="junk.cgi">
- <input type=text name="birthyear">
- <input type=submit name=press value=" OK ">
- </form>
+```html
+<form method="POST" action="junk.cgi">
+ <input type=text name="birthyear">
+ <input type=submit name=press value=" OK ">
+</form>
+```
And to use curl to post this form with the same data filled in as before, we
could do it like:
This method is mainly designed to better support file uploads. A form that
allows a user to upload a file could be written like this in HTML:
- <form method="POST" enctype='multipart/form-data' action="upload.cgi">
- <input type=file name=upload>
- <input type=submit name=press value="OK">
- </form>
+```html
+<form method="POST" enctype='multipart/form-data' action="upload.cgi">
+ <input type=file name=upload>
+ <input type=submit name=press value="OK">
+</form>
+```
This clearly shows that the Content-Type about to be sent is
`multipart/form-data`.
A similar example form with one visible field, one hidden field and one
submit button could look like:
- <form method="POST" action="foobar.cgi">
- <input type=text name="birthyear">
- <input type=hidden name="person" value="daniel">
- <input type=submit name="press" value="OK">
- </form>
+```html
+<form method="POST" action="foobar.cgi">
+ <input type=text name="birthyear">
+ <input type=hidden name="person" value="daniel">
+ <input type=submit name="press" value="OK">
+</form>
+```
To POST this with curl, you won't have to think about if the fields are
hidden or not. To curl they're all the same:
may require its own user and password to allow the client to get through to
the Internet. To specify those with curl, run something like:
- curl --proxy-user proxyuser:proxypassword curl.se
+ curl --proxy-user proxyuser:proxypassword curl.se
If your proxy requires the authentication to be done using the NTLM method,
use [`--proxy-ntlm`](https://curl.se/docs/manpage.html#--proxy-ntlm), if
numbering scheme that can be used for comparison. The version number is
defined as:
- #define LIBCURL_VERSION_NUM 0xXXYYZZ
+```c
+#define LIBCURL_VERSION_NUM 0xXXYYZZ
+```
Where XX, YY and ZZ are the main version, release and patch numbers in
hexadecimal. All three number fields are always represented using two digits