Introduction
C is a general purpose programming language developed in the late 1960s for the creation of the Unix operating system. Its use for writing systems explains why it relates closely to the way machines work. Programming in C is much lower-level than working with Java or Python. For example, understanding how computer memory is allocated is an important aspect of programming in C. Although C can be considered “hard to learn”, it is actually a very simple language. Even with modern languages such as Java, Python, Go, and R, learning C is an important skill for systems work as it allows access to the hardware of a computer. It is essential for writing device drivers, operating systems, and ultra-fast code for data processing.
C is a very common language, and it is the language in many applications, systems, and even other languages are built. For example, Windows and MacOS are both written in C, the Python and R interpreters are written in C, the Git version control system is written in C, to name a few.
C is a compiled language - which means that in order to run it, the compiler (e.g., gcc) must transform the code that we wrote to machine language and create an executable program file. This file can then be executed from the command line (or, as it’s often called, the shell, the CLI, or the terminal).
Edit-Compile-Run Cycle
Writing a program in C requires several steps and is similar to other compiled languages but different from interpreted languages such as Python and R. The steps are:
Write the source code for the program in an editor. On Linux, the simplest editor to use in vi or its improved version vim. For Windows and MacOS one can also use a development environment such as Eclipse.
Compile the source code into assembly code using a compiler such as gcc or g++. Most C compilers are actually C++ compilers as C++ is a superset of C.
After compilation, the code must be transformed into an executable using a linker. The linker is generally invoked by the compiler after compilation is complete.
Once the code is linked with all external libraries, the program is now executable and can be run from the terminal shell.
Editing with vi and vim
For more information on how to edit text files with vi and vim, consult:
Example
Use an editor such as vim to type in the program below and save it under the name “hello.c”.
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("Hello World\n");
return 0;
}
In Linux, compile the program from the shell using the command:
% gcc hello.c -o hello
In the shell command above, the % is used to indicate the command prompt; it may differ on your system. Do not type it in.
The option -o hello specifies the name of the executable program. If it is not specified, it will default to a.out.
To run, type in
% ./hello
The ./ is required as the current directory is generally not in the searched path for programs in Linux.
Program Structure
A C program is a collection of functions located in one or more source files. Source files are text files with the .c extension. They are compiled separately and then linked together with libraries that contain external functions provided by third-parties. The names of the functions must be unique and conform to the rules for naming identifiers (start with letter or underscore and then have any number of letters, digits, and underscores)
Every C program must have a function call main. Execution of the program starts with the first statement in main. The main function is called by the operating system when the process in which the program runs is created. As programs are generally run from the command line (shell or terminal), they can take parameters as input, which is the reason why main has two arguments: the number of arguments passed by the command line and an array of strings corresponding to the arguments.
Let’s take a look at each line in the program below.
#include <stdio.h>
int main(int argc, char* argv[]) {
printf("Hello World\n");
return 0;
}
Line 1: Includes the source code contained in another file that is compiled as part of this program. Called an include or header file. Headers files with a .h extension (by convention) contain function definitions and are often used for external libraries. In this program, the stdio.h header file includes the definitions of input/output functions.
Line 3: The definition of the main function where execution starts. The body of the function is between { and }.
Line 4: Call to the function printf which outputs the text to the console. The \n is a newline character to advance the cursor to the next line on the console device (normally a terminal screen but can also be a file).
Line 5: Explicit return from the function with the value 0. The value is returned to the shell so that the program can be used within shell scripts. If there is no return statement, then the return is implicit but the return value is not defined and should only be used for functions with a return type of void.
Note that every statement must be terminated by a semi-colon (;). Statements may span several lines.
Never put a semi-colon before the start of a block ({) or after a }. This is the source of many sleepless nights for C/C++ (and even Java) programmers.
Variables
Variables are memory allocated to hold values. They are of a specific type which determines what values can be stored in the variable. All variables must be declared with a type and an identifier. Variables can have a default value.
int counter;
char ioByte = 0;
In original C, all variables must be declared at the beginning of a block before any statements. This is not true for C++ and, consequently, most modern C programs.
Types
C has several data types and additional user data types can be defined through struct definitions.
The table below summarizes commonly used types in C programming. The column for “Format Specifier” is useful for printing or displaying variables using printf()
.
int |
between 2 and 4 |
%d, %i |
char |
1 |
%c |
float |
4 |
%f |
double |
8 |
%lf |
short int |
2 usually |
%hd |
unsigned int |
at least 2, usually 4 |
%u |
long int |
at least 4, usually 8 |
%ld, %li |
long long int |
at least 8 |
%lld, %lli |
unsigned long int |
at least 4 |
%lu |
unsigned long long int |
at least 8 |
%llu |
signed char |
1 |
%c |
unsigned char |
1 |
%c |
long double |
at least 10, usually 12 or 16 |
%Lf |
You can get the exact number of bytes used to store a variable’s value using the sizeof()
function.
int i;
printf("size in bytes of i = %d", sizeof(i));
There are modifiers for variables including extern, register, static, and volatile. They are directives for the compiler on how to (or not to) optimize the code. These are less commonly used unless one works with systems code. Here is what they mean:
extern – the variable is defined in a library or some other source file but is used in this source file; variables can only be defined once but must be declared wherever they are used so the compiler can perform type checking; does not result in the allocation of memory, just the declaration of the identifier and its type
register – the variable should be kept in a CPU register for fast processing
static – the value of the variable does not change and its memory should be allocated from the static block rather than the stack
volatile - the variable can be modified outside of the program code (e.g., through and interrupt handler) and the compiler should always reload the value before using and not cache any values or optimize out the variable
In addition, there are derived types, including pointers and bool.
Default Values
Variables in C do not have a default value, so they must be initialized to a value prior to use. Do not assume that the default value is 0 as is common in other programming languages. To be more exact, local variables are uninitialized, while global and static variables of type integer or pointer are initialized to 0. However, it is a best practice not to rely on language defaults or compiler specific initialization and to always initialize variables after definition.
Memory Allocation and Overflows
C does not perform type checking, so it is the responsibility of the programmer to ensure that the variable has sufficient memory allocated to hold the value assigned to the variable. For example, assigning a 32-bit (4 byte) integer to a variable of type char (an 8-bit or 1 byte character) would cause an overflow. The assignment is still done and four bytes are copied to memory reserved for one byte cause the remaining 3 bytes to overflow into the next three bytes in memory, potentially overwriting other variables. A common source of headaches for programmers. Modern compilers will “lint” the code and point out such issues.
Identifiers
An identifier is the name given to entities such as variables, functions, structures, etc. Identifiers must be unique within a program block (its scope). Identifier are used to refer to a memory object.
For example, in the code fragment below, amount and accountBalance are identifiers:
int amount;
double accountBalance;
Identifier names must be different from keywords. For example, you cannot use int as an identifier because int is a keyword. A list of all C keywords is below. Note that most modern C compilers are actually C++ compilers and C++ has additional keywords. Most editors are syntax-aware and will tag keywords in different colors.
Identifier Naming Rules
A valid identifier can have letters (both uppercase and lowercase), digits and underscores (_). The first letter of an identifier must be either a letter or an underscore. You cannot use keywords like int, for, etc. as identifiers. There is no rule on how long an identifier can be, but you may run into problems with some compilers when the identifier is longer than 31 characters. You can choose any name as an identifier as long as you follow the above rules. However, use meaningful names to variables and function that represent what they contain; it makes programs more readable and easier to understand and debug.
Keywords
Identifiers cannot be reserved keywords. The list below are all the keywords of C. Most C compilers are actually C++ compilers and thus have additional keywords, such as class or virtual.
## Command Line Arguments
C (and C++) programs can run from the command line (terminal or shell) as can take arguments. The main
function takes two parameters – argc
and argv
– that are used to retrieve the command line arguments.
The example below prints out the values of the arguments, although that is no that practical.
Note that the first argument (argv[0]
) is the name of the executable program.
#include <stdio.h>
int main(int argc, char* argv[])
{
for (int i = 0; i < argc; ++i) {
printf("%i | %s\n", i, argv[i]);
}
return 0;
}
Tutorial
Watch and follow along with the narrated tutorial of a code walk below.
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIEMgUHJvZ3JhbW1pbmciCnBhcmFtczoKICBjYXRlZ29yeTogOAogIG51bWJlcjogMTAwCiAgdGltZTogNjAKICBsZXZlbDogYmVnaW5uZXIKICB0YWdzOiAiYyxnY2MscmVwbC5pdCIKICBkZXNjcmlwdGlvbjogIkludHJvZHVjZXMgYmFzaWMgc3RydWN0dXJlIG9mIGEgQyBwcm9ncmFtLiBTaG93cwogICAgICAgICAgICAgICAgaG93IHRvIGNvbXBpbGUsIGxpbmssIGFuZCBydW4gYSBDIHByb2dyYW0gdXNpbmcgZ2NjCiAgICAgICAgICAgICAgICBhbmQgb25saW5lIHVzaW5nIHJlcGwuaXQuIgpkYXRlOiAiPHNtYWxsPmByIFN5cy5EYXRlKClgPC9zbWFsbD4iCmF1dGhvcjogIjxzbWFsbD5NYXJ0aW4gU2NoZWRsYmF1ZXI8L3NtYWxsPiIKZW1haWw6ICJtLnNjaGVkbGJhdWVyQG5ldS5lZHUiCmFmZmlsaXRhdGlvbjogIk5vcnRoZWFzdGVybiBVbml2ZXJzaXR5IgpvdXRwdXQ6IAogIGJvb2tkb3duOjpodG1sX2RvY3VtZW50MjoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogc3BhY2VsYWIKICAgIGhpZ2hsaWdodDogdGFuZ28KLS0tCgotLS0KdGl0bGU6ICI8c21hbGw+YHIgcGFyYW1zJGNhdGVnb3J5YC5gciBwYXJhbXMkbnVtYmVyYDwvc21hbGw+PGJyLz48c3BhbiBzdHlsZT0nY29sb3I6ICMyRTQwNTM7IGZvbnQtc2l6ZTogMC45ZW0nPmByIHJtYXJrZG93bjo6bWV0YWRhdGEkdGl0bGVgPC9zcGFuPiIKLS0tCgpgYGB7ciBjb2RlPXhmdW46OnJlYWRfdXRmOChwYXN0ZTAoaGVyZTo6aGVyZSgpLCcvUi9faW5zZXJ0MkRCLlInKSksIGluY2x1ZGUgPSBGQUxTRX0KYGBgCgojIyBJbnRyb2R1Y3Rpb24KCkMgaXMgYSBnZW5lcmFsIHB1cnBvc2UgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgZGV2ZWxvcGVkIGluIHRoZSBsYXRlIDE5NjBzIGZvciB0aGUgY3JlYXRpb24gb2YgdGhlIFVuaXggb3BlcmF0aW5nIHN5c3RlbS4gSXRzIHVzZSBmb3Igd3JpdGluZyBzeXN0ZW1zIGV4cGxhaW5zIHdoeSBpdCByZWxhdGVzIGNsb3NlbHkgdG8gdGhlIHdheSBtYWNoaW5lcyB3b3JrLiBQcm9ncmFtbWluZyBpbiBDIGlzIG11Y2ggbG93ZXItbGV2ZWwgdGhhbiB3b3JraW5nIHdpdGggSmF2YSBvciBQeXRob24uIEZvciBleGFtcGxlLCB1bmRlcnN0YW5kaW5nIGhvdyBjb21wdXRlciBtZW1vcnkgaXMgYWxsb2NhdGVkIGlzIGFuIGltcG9ydGFudCBhc3BlY3Qgb2YgcHJvZ3JhbW1pbmcgaW4gQy4gQWx0aG91Z2ggQyBjYW4gYmUgY29uc2lkZXJlZCAiaGFyZCB0byBsZWFybiIsIGl0IGlzIGFjdHVhbGx5IGEgdmVyeSBzaW1wbGUgbGFuZ3VhZ2UuIEV2ZW4gd2l0aCBtb2Rlcm4gbGFuZ3VhZ2VzIHN1Y2ggYXMgSmF2YSwgUHl0aG9uLCBHbywgYW5kIFIsIGxlYXJuaW5nIEMgaXMgYW4gaW1wb3J0YW50IHNraWxsIGZvciBzeXN0ZW1zIHdvcmsgYXMgaXQgYWxsb3dzIGFjY2VzcyB0byB0aGUgaGFyZHdhcmUgb2YgYSBjb21wdXRlci4gSXQgaXMgZXNzZW50aWFsIGZvciB3cml0aW5nIGRldmljZSBkcml2ZXJzLCBvcGVyYXRpbmcgc3lzdGVtcywgYW5kIHVsdHJhLWZhc3QgY29kZSBmb3IgZGF0YSBwcm9jZXNzaW5nLgoKQyBpcyBhIHZlcnkgY29tbW9uIGxhbmd1YWdlLCBhbmQgaXQgaXMgdGhlIGxhbmd1YWdlIGluIG1hbnkgYXBwbGljYXRpb25zLCBzeXN0ZW1zLCBhbmQgZXZlbiBvdGhlciBsYW5ndWFnZXMgYXJlIGJ1aWx0LiBGb3IgZXhhbXBsZSwgV2luZG93cyBhbmQgTWFjT1MgYXJlIGJvdGggd3JpdHRlbiBpbiBDLCB0aGUgUHl0aG9uIGFuZCBSIGludGVycHJldGVycyBhcmUgd3JpdHRlbiBpbiBDLCB0aGUgR2l0IHZlcnNpb24gY29udHJvbCBzeXN0ZW0gaXMgd3JpdHRlbiBpbiBDLCB0byBuYW1lIGEgZmV3LgoKQyBpcyBhIGNvbXBpbGVkIGxhbmd1YWdlIC0gd2hpY2ggbWVhbnMgdGhhdCBpbiBvcmRlciB0byBydW4gaXQsIHRoZSBjb21waWxlciAoKmUuZy4qLCAqZ2NjKikgbXVzdCB0cmFuc2Zvcm0gdGhlIGNvZGUgdGhhdCB3ZSB3cm90ZSB0byBtYWNoaW5lIGxhbmd1YWdlIGFuZCBjcmVhdGUgYW4gZXhlY3V0YWJsZSBwcm9ncmFtIGZpbGUuIFRoaXMgZmlsZSBjYW4gdGhlbiBiZSBleGVjdXRlZCBmcm9tIHRoZSBjb21tYW5kIGxpbmUgKG9yLCBhcyBpdCdzIG9mdGVuIGNhbGxlZCwgdGhlIHNoZWxsLCB0aGUgQ0xJLCBvciB0aGUgdGVybWluYWwpLgoKIyMgRWRpdC1Db21waWxlLVJ1biBDeWNsZQoKV3JpdGluZyBhIHByb2dyYW0gaW4gQyByZXF1aXJlcyBzZXZlcmFsIHN0ZXBzIGFuZCBpcyBzaW1pbGFyIHRvIG90aGVyIGNvbXBpbGVkIGxhbmd1YWdlcyBidXQgZGlmZmVyZW50IGZyb20gaW50ZXJwcmV0ZWQgbGFuZ3VhZ2VzIHN1Y2ggYXMgUHl0aG9uIGFuZCBSLiBUaGUgc3RlcHMgYXJlOgoKMS4gIFdyaXRlIHRoZSBzb3VyY2UgY29kZSBmb3IgdGhlIHByb2dyYW0gaW4gYW4gZWRpdG9yLiBPbiBMaW51eCwgdGhlIHNpbXBsZXN0IGVkaXRvciB0byB1c2UgaW4gKnZpKiBvciBpdHMgaW1wcm92ZWQgdmVyc2lvbiAqdmltKi4gRm9yIFdpbmRvd3MgYW5kIE1hY09TIG9uZSBjYW4gYWxzbyB1c2UgYSBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCBzdWNoIGFzICpFY2xpcHNlKi4KCjIuICBDb21waWxlIHRoZSBzb3VyY2UgY29kZSBpbnRvIGFzc2VtYmx5IGNvZGUgdXNpbmcgYSBjb21waWxlciBzdWNoIGFzICpnY2MqIG9yICpnKysqLiBNb3N0IEMgY29tcGlsZXJzIGFyZSBhY3R1YWxseSBDKysgY29tcGlsZXJzIGFzIEMrKyBpcyBhIHN1cGVyc2V0IG9mIEMuCgozLiAgQWZ0ZXIgY29tcGlsYXRpb24sIHRoZSBjb2RlIG11c3QgYmUgdHJhbnNmb3JtZWQgaW50byBhbiBleGVjdXRhYmxlIHVzaW5nIGEgbGlua2VyLiBUaGUgbGlua2VyIGlzIGdlbmVyYWxseSBpbnZva2VkIGJ5IHRoZSBjb21waWxlciBhZnRlciBjb21waWxhdGlvbiBpcyBjb21wbGV0ZS4KCjQuICBPbmNlIHRoZSBjb2RlIGlzIGxpbmtlZCB3aXRoIGFsbCBleHRlcm5hbCBsaWJyYXJpZXMsIHRoZSBwcm9ncmFtIGlzIG5vdyBleGVjdXRhYmxlIGFuZCBjYW4gYmUgcnVuIGZyb20gdGhlIHRlcm1pbmFsIHNoZWxsLgoKIyMgRWRpdGluZyB3aXRoICp2aSogYW5kICp2aW0qCgpGb3IgbW9yZSBpbmZvcm1hdGlvbiBvbiBob3cgdG8gZWRpdCB0ZXh0IGZpbGVzIHdpdGggKnZpKiBhbmQgKnZpbSosIGNvbnN1bHQ6CgotICAgW0NsYXNzaWMgU3lzQWRtaW46IFZpbSAxMDE6IEEgQmVnaW5uZXIncyBHdWlkZSB0byBWaW1dKGh0dHBzOi8vbGludXhmb3VuZGF0aW9uLm9yZy9ibG9nL2NsYXNzaWMtc3lzYWRtaW4tdmltLTEwMS1hLWJlZ2lubmVycy1ndWlkZS10by12aW0pCi0gICBbVkkgRWRpdG9yXShodHRwczovL3d3dy5ndXJ1OTkuY29tL3RoZS12aS1lZGl0b3IuaHRtbCkKCiMjIEV4YW1wbGUKClVzZSBhbiBlZGl0b3Igc3VjaCBhcyAqdmltKiB0byB0eXBlIGluIHRoZSBwcm9ncmFtIGJlbG93IGFuZCBzYXZlIGl0IHVuZGVyIHRoZSBuYW1lICJoZWxsby5jIi4KCmBgYHtSY3BwIGV2YWw9Rn0KI2luY2x1ZGUgPHN0ZGlvLmg+CgppbnQgbWFpbihpbnQgYXJnYywgY2hhciogYXJndltdKSB7CiAgcHJpbnRmKCJIZWxsbyBXb3JsZFxuIik7CiAgcmV0dXJuIDA7Cn0KYGBgCgpJbiBMaW51eCwgY29tcGlsZSB0aGUgcHJvZ3JhbSBmcm9tIHRoZSBzaGVsbCB1c2luZyB0aGUgY29tbWFuZDoKCmBgYCAgICAgICAgIAolIGdjYyBoZWxsby5jIC1vIGhlbGxvCmBgYAoKSW4gdGhlIHNoZWxsIGNvbW1hbmQgYWJvdmUsIHRoZSAqJSogaXMgdXNlZCB0byBpbmRpY2F0ZSB0aGUgY29tbWFuZCBwcm9tcHQ7IGl0IG1heSBkaWZmZXIgb24geW91ciBzeXN0ZW0uIERvIG5vdCB0eXBlIGl0IGluLgoKVGhlIG9wdGlvbiAqLW8gaGVsbG8qIHNwZWNpZmllcyB0aGUgbmFtZSBvZiB0aGUgZXhlY3V0YWJsZSBwcm9ncmFtLiBJZiBpdCBpcyBub3Qgc3BlY2lmaWVkLCBpdCB3aWxsIGRlZmF1bHQgdG8gKmEub3V0Ki4KClRvIHJ1biwgdHlwZSBpbgoKYGBgICAgICAgICAgCiUgLi9oZWxsbwpgYGAKClRoZSAqLi8qIGlzIHJlcXVpcmVkIGFzIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpcyBnZW5lcmFsbHkgbm90IGluIHRoZSBzZWFyY2hlZCBwYXRoIGZvciBwcm9ncmFtcyBpbiBMaW51eC4KCiMjIFByb2dyYW0gU3RydWN0dXJlCgpBIEMgcHJvZ3JhbSBpcyBhIGNvbGxlY3Rpb24gb2YgZnVuY3Rpb25zIGxvY2F0ZWQgaW4gb25lIG9yIG1vcmUgc291cmNlIGZpbGVzLiBTb3VyY2UgZmlsZXMgYXJlIHRleHQgZmlsZXMgd2l0aCB0aGUgKi5jKiBleHRlbnNpb24uIFRoZXkgYXJlIGNvbXBpbGVkIHNlcGFyYXRlbHkgYW5kIHRoZW4gbGlua2VkIHRvZ2V0aGVyIHdpdGggbGlicmFyaWVzIHRoYXQgY29udGFpbiBleHRlcm5hbCBmdW5jdGlvbnMgcHJvdmlkZWQgYnkgdGhpcmQtcGFydGllcy4gVGhlIG5hbWVzIG9mIHRoZSBmdW5jdGlvbnMgbXVzdCBiZSB1bmlxdWUgYW5kIGNvbmZvcm0gdG8gdGhlIHJ1bGVzIGZvciBuYW1pbmcgaWRlbnRpZmllcnMgKHN0YXJ0IHdpdGggbGV0dGVyIG9yIHVuZGVyc2NvcmUgYW5kIHRoZW4gaGF2ZSBhbnkgbnVtYmVyIG9mIGxldHRlcnMsIGRpZ2l0cywgYW5kIHVuZGVyc2NvcmVzKQoKRXZlcnkgQyBwcm9ncmFtIG11c3QgaGF2ZSBhIGZ1bmN0aW9uIGNhbGwgKm1haW4qLiBFeGVjdXRpb24gb2YgdGhlIHByb2dyYW0gc3RhcnRzIHdpdGggdGhlIGZpcnN0IHN0YXRlbWVudCBpbiAqbWFpbiouIFRoZSAqbWFpbiogZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IHRoZSBvcGVyYXRpbmcgc3lzdGVtIHdoZW4gdGhlIHByb2Nlc3MgaW4gd2hpY2ggdGhlIHByb2dyYW0gcnVucyBpcyBjcmVhdGVkLiBBcyBwcm9ncmFtcyBhcmUgZ2VuZXJhbGx5IHJ1biBmcm9tIHRoZSBjb21tYW5kIGxpbmUgKHNoZWxsIG9yIHRlcm1pbmFsKSwgdGhleSBjYW4gdGFrZSBwYXJhbWV0ZXJzIGFzIGlucHV0LCB3aGljaCBpcyB0aGUgcmVhc29uIHdoeSAqbWFpbiogaGFzIHR3byBhcmd1bWVudHM6IHRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHBhc3NlZCBieSB0aGUgY29tbWFuZCBsaW5lIGFuZCBhbiBhcnJheSBvZiBzdHJpbmdzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGFyZ3VtZW50cy4KCkxldCdzIHRha2UgYSBsb29rIGF0IGVhY2ggbGluZSBpbiB0aGUgcHJvZ3JhbSBiZWxvdy4KCmBgYHtSY3BwIGV2YWw9RiwgYXR0ci5zb3VyY2U9Jy5udW1iZXJMaW5lcyd9CiNpbmNsdWRlIDxzdGRpby5oPgoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkgewogIHByaW50ZigiSGVsbG8gV29ybGRcbiIpOwogIHJldHVybiAwOwp9CmBgYAoKKipMaW5lIDEqKjogSW5jbHVkZXMgdGhlIHNvdXJjZSBjb2RlIGNvbnRhaW5lZCBpbiBhbm90aGVyIGZpbGUgdGhhdCBpcyBjb21waWxlZCBhcyBwYXJ0IG9mIHRoaXMgcHJvZ3JhbS4gQ2FsbGVkIGFuIGluY2x1ZGUgb3IgaGVhZGVyIGZpbGUuIEhlYWRlcnMgZmlsZXMgd2l0aCBhICouaCogZXh0ZW5zaW9uIChieSBjb252ZW50aW9uKSBjb250YWluIGZ1bmN0aW9uIGRlZmluaXRpb25zIGFuZCBhcmUgb2Z0ZW4gdXNlZCBmb3IgZXh0ZXJuYWwgbGlicmFyaWVzLiBJbiB0aGlzIHByb2dyYW0sIHRoZSAqc3RkaW8uaCogaGVhZGVyIGZpbGUgaW5jbHVkZXMgdGhlIGRlZmluaXRpb25zIG9mIGlucHV0L291dHB1dCBmdW5jdGlvbnMuCgoqKkxpbmUgMyoqOiBUaGUgZGVmaW5pdGlvbiBvZiB0aGUgKm1haW4qIGZ1bmN0aW9uIHdoZXJlIGV4ZWN1dGlvbiBzdGFydHMuIFRoZSBib2R5IG9mIHRoZSBmdW5jdGlvbiBpcyBiZXR3ZWVuICp7KiBhbmQgKn0qLgoKKipMaW5lIDQqKjogQ2FsbCB0byB0aGUgZnVuY3Rpb24gKnByaW50Ziogd2hpY2ggb3V0cHV0cyB0aGUgdGV4dCB0byB0aGUgY29uc29sZS4gVGhlICpcXG4qIGlzIGEgbmV3bGluZSBjaGFyYWN0ZXIgdG8gYWR2YW5jZSB0aGUgY3Vyc29yIHRvIHRoZSBuZXh0IGxpbmUgb24gdGhlIGNvbnNvbGUgZGV2aWNlIChub3JtYWxseSBhIHRlcm1pbmFsIHNjcmVlbiBidXQgY2FuIGFsc28gYmUgYSBmaWxlKS4KCioqTGluZSA1Kio6IEV4cGxpY2l0IHJldHVybiBmcm9tIHRoZSBmdW5jdGlvbiB3aXRoIHRoZSB2YWx1ZSAqMCouIFRoZSB2YWx1ZSBpcyByZXR1cm5lZCB0byB0aGUgc2hlbGwgc28gdGhhdCB0aGUgcHJvZ3JhbSBjYW4gYmUgdXNlZCB3aXRoaW4gc2hlbGwgc2NyaXB0cy4gSWYgdGhlcmUgaXMgbm8gKnJldHVybiogc3RhdGVtZW50LCB0aGVuIHRoZSByZXR1cm4gaXMgaW1wbGljaXQgYnV0IHRoZSByZXR1cm4gdmFsdWUgaXMgbm90IGRlZmluZWQgYW5kIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIGZ1bmN0aW9ucyB3aXRoIGEgcmV0dXJuIHR5cGUgb2YgKnZvaWQqLgoKTm90ZSB0aGF0IGV2ZXJ5IHN0YXRlbWVudCBtdXN0IGJlIHRlcm1pbmF0ZWQgYnkgYSBzZW1pLWNvbG9uICg7KS4gU3RhdGVtZW50cyBtYXkgc3BhbiBzZXZlcmFsIGxpbmVzLgoKPiBOZXZlciBwdXQgYSBzZW1pLWNvbG9uIGJlZm9yZSB0aGUgc3RhcnQgb2YgYSBibG9jayAoeykgb3IgYWZ0ZXIgYSB9LiBUaGlzIGlzIHRoZSBzb3VyY2Ugb2YgbWFueSBzbGVlcGxlc3MgbmlnaHRzIGZvciBDL0MrKyAoYW5kIGV2ZW4gSmF2YSkgcHJvZ3JhbW1lcnMuCgojIyBWYXJpYWJsZXMKClZhcmlhYmxlcyBhcmUgbWVtb3J5IGFsbG9jYXRlZCB0byBob2xkIHZhbHVlcy4gVGhleSBhcmUgb2YgYSBzcGVjaWZpYyB0eXBlIHdoaWNoIGRldGVybWluZXMgd2hhdCB2YWx1ZXMgY2FuIGJlIHN0b3JlZCBpbiB0aGUgdmFyaWFibGUuIEFsbCB2YXJpYWJsZXMgbXVzdCBiZSBkZWNsYXJlZCB3aXRoIGEgdHlwZSBhbmQgYW4gaWRlbnRpZmllci4gVmFyaWFibGVzIGNhbiBoYXZlIGEgZGVmYXVsdCB2YWx1ZS4KCmBgYHtSY3BwIGV2YWw9Rn0KaW50IGNvdW50ZXI7CmNoYXIgaW9CeXRlID0gMDsKYGBgCgpJbiBvcmlnaW5hbCBDLCBhbGwgdmFyaWFibGVzIG11c3QgYmUgZGVjbGFyZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBhIGJsb2NrIGJlZm9yZSBhbnkgc3RhdGVtZW50cy4gVGhpcyBpcyBub3QgdHJ1ZSBmb3IgQysrIGFuZCwgY29uc2VxdWVudGx5LCBtb3N0IG1vZGVybiBDIHByb2dyYW1zLgoKIyMjIFR5cGVzCgpDIGhhcyBzZXZlcmFsIGRhdGEgdHlwZXMgYW5kIGFkZGl0aW9uYWwgdXNlciBkYXRhIHR5cGVzIGNhbiBiZSBkZWZpbmVkIHRocm91Z2ggKnN0cnVjdCogZGVmaW5pdGlvbnMuCgpUaGUgdGFibGUgYmVsb3cgc3VtbWFyaXplcyBjb21tb25seSB1c2VkIHR5cGVzIGluIEMgcHJvZ3JhbW1pbmcuIFRoZSBjb2x1bW4gZm9yICJGb3JtYXQgU3BlY2lmaWVyIiBpcyB1c2VmdWwgZm9yIHByaW50aW5nIG9yIGRpc3BsYXlpbmcgdmFyaWFibGVzIHVzaW5nIGBwcmludGYoKWAuCgp8ICAgICAgICAgIFR5cGUgICAgICAgICAgfCBTaXplIChieXRlcykgICAgICAgICAgICAgICAgICB8IEZvcm1hdCBTcGVjaWZpZXIgfAp8Oi0tLS0tLS0tLS0tLS0tLS0tLS0tLS06fDotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Oi0tLS0tLS0tLS0tLS0tLS06fAp8ICAgICAgICAgIGludCAgICAgICAgICAgfCBiZXR3ZWVuIDIgYW5kIDQgICAgICAgICAgICAgICB8ICAgICAgJWQsICVpICAgICAgfAp8ICAgICAgICAgIGNoYXIgICAgICAgICAgfCAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAlYyAgICAgICAgfAp8ICAgICAgICAgZmxvYXQgICAgICAgICAgfCA0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAlZiAgICAgICAgfAp8ICAgICAgICAgZG91YmxlICAgICAgICAgfCA4ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICVsZiAgICAgICAgfAp8ICAgICAgIHNob3J0IGludCAgICAgICAgfCAyIHVzdWFsbHkgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICVoZCAgICAgICAgfAp8ICAgICAgdW5zaWduZWQgaW50ICAgICAgfCBhdCBsZWFzdCAyLCB1c3VhbGx5IDQgICAgICAgICB8ICAgICAgICAldSAgICAgICAgfAp8ICAgICAgICBsb25nIGludCAgICAgICAgfCBhdCBsZWFzdCA0LCB1c3VhbGx5IDggICAgICAgICB8ICAgICAlbGQsICVsaSAgICAgfAp8ICAgICBsb25nIGxvbmcgaW50ICAgICAgfCBhdCBsZWFzdCA4ICAgICAgICAgICAgICAgICAgICB8ICAgICVsbGQsICVsbGkgICAgfAp8ICAgdW5zaWduZWQgbG9uZyBpbnQgICAgfCBhdCBsZWFzdCA0ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICVsdSAgICAgICAgfAp8IHVuc2lnbmVkIGxvbmcgbG9uZyBpbnQgfCBhdCBsZWFzdCA4ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICVsbHUgICAgICAgfAp8ICAgICAgc2lnbmVkIGNoYXIgICAgICAgfCAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAlYyAgICAgICAgfAp8ICAgICB1bnNpZ25lZCBjaGFyICAgICAgfCAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAlYyAgICAgICAgfAp8ICAgICAgbG9uZyBkb3VibGUgICAgICAgfCBhdCBsZWFzdCAxMCwgdXN1YWxseSAxMiBvciAxNiB8ICAgICAgICVMZiAgICAgICAgfAoKWW91IGNhbiBnZXQgdGhlIGV4YWN0IG51bWJlciBvZiBieXRlcyB1c2VkIHRvIHN0b3JlIGEgdmFyaWFibGUncyB2YWx1ZSB1c2luZyB0aGUgYHNpemVvZigpYCBmdW5jdGlvbi4KCmBgYHtSY3BwIGV2YWw9Rn0KaW50IGk7CgpwcmludGYoInNpemUgaW4gYnl0ZXMgb2YgaSA9ICVkIiwgc2l6ZW9mKGkpKTsKYGBgCgpUaGVyZSBhcmUgbW9kaWZpZXJzIGZvciB2YXJpYWJsZXMgaW5jbHVkaW5nICpleHRlcm4qLCAqcmVnaXN0ZXIqLCAqc3RhdGljKiwgYW5kICp2b2xhdGlsZSouIFRoZXkgYXJlIGRpcmVjdGl2ZXMgZm9yIHRoZSBjb21waWxlciBvbiBob3cgdG8gKG9yIG5vdCB0bykgb3B0aW1pemUgdGhlIGNvZGUuIFRoZXNlIGFyZSBsZXNzIGNvbW1vbmx5IHVzZWQgdW5sZXNzIG9uZSB3b3JrcyB3aXRoIHN5c3RlbXMgY29kZS4gSGVyZSBpcyB3aGF0IHRoZXkgbWVhbjoKCi0gICAqKmV4dGVybioqIC0tIHRoZSB2YXJpYWJsZSBpcyBkZWZpbmVkIGluIGEgbGlicmFyeSBvciBzb21lIG90aGVyIHNvdXJjZSBmaWxlIGJ1dCBpcyB1c2VkIGluIHRoaXMgc291cmNlIGZpbGU7IHZhcmlhYmxlcyBjYW4gb25seSBiZSBkZWZpbmVkIG9uY2UgYnV0IG11c3QgYmUgZGVjbGFyZWQgd2hlcmV2ZXIgdGhleSBhcmUgdXNlZCBzbyB0aGUgY29tcGlsZXIgY2FuIHBlcmZvcm0gdHlwZSBjaGVja2luZzsgZG9lcyBub3QgcmVzdWx0IGluIHRoZSBhbGxvY2F0aW9uIG9mIG1lbW9yeSwganVzdCB0aGUgZGVjbGFyYXRpb24gb2YgdGhlIGlkZW50aWZpZXIgYW5kIGl0cyB0eXBlCgotICAgKipyZWdpc3RlcioqIC0tIHRoZSB2YXJpYWJsZSBzaG91bGQgYmUga2VwdCBpbiBhIENQVSByZWdpc3RlciBmb3IgZmFzdCBwcm9jZXNzaW5nCgotICAgKipzdGF0aWMqKiAtLSB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIGRvZXMgbm90IGNoYW5nZSBhbmQgaXRzIG1lbW9yeSBzaG91bGQgYmUgYWxsb2NhdGVkIGZyb20gdGhlIHN0YXRpYyBibG9jayByYXRoZXIgdGhhbiB0aGUgc3RhY2sKCi0gICAqKnZvbGF0aWxlKiogLSB0aGUgdmFyaWFibGUgY2FuIGJlIG1vZGlmaWVkIG91dHNpZGUgb2YgdGhlIHByb2dyYW0gY29kZSAoKmUuZy4qLCB0aHJvdWdoIGFuZCBpbnRlcnJ1cHQgaGFuZGxlcikgYW5kIHRoZSBjb21waWxlciBzaG91bGQgYWx3YXlzIHJlbG9hZCB0aGUgdmFsdWUgYmVmb3JlIHVzaW5nIGFuZCBub3QgY2FjaGUgYW55IHZhbHVlcyBvciBvcHRpbWl6ZSBvdXQgdGhlIHZhcmlhYmxlCgpJbiBhZGRpdGlvbiwgdGhlcmUgYXJlIGRlcml2ZWQgdHlwZXMsIGluY2x1ZGluZyBwb2ludGVycyBhbmQgKmJvb2wqLgoKIyMjIERlZmF1bHQgVmFsdWVzCgpWYXJpYWJsZXMgaW4gQyBkbyBub3QgaGF2ZSBhIGRlZmF1bHQgdmFsdWUsIHNvIHRoZXkgbXVzdCBiZSBpbml0aWFsaXplZCB0byBhIHZhbHVlIHByaW9yIHRvIHVzZS4gRG8gbm90IGFzc3VtZSB0aGF0IHRoZSBkZWZhdWx0IHZhbHVlIGlzIDAgYXMgaXMgY29tbW9uIGluIG90aGVyIHByb2dyYW1taW5nIGxhbmd1YWdlcy4gVG8gYmUgbW9yZSBleGFjdCwgbG9jYWwgdmFyaWFibGVzIGFyZSB1bmluaXRpYWxpemVkLCB3aGlsZSBnbG9iYWwgYW5kIHN0YXRpYyB2YXJpYWJsZXMgb2YgdHlwZSBpbnRlZ2VyIG9yIHBvaW50ZXIgYXJlIGluaXRpYWxpemVkIHRvIDAuIEhvd2V2ZXIsIGl0IGlzIGEgYmVzdCBwcmFjdGljZSBub3QgdG8gcmVseSBvbiBsYW5ndWFnZSBkZWZhdWx0cyBvciBjb21waWxlciBzcGVjaWZpYyBpbml0aWFsaXphdGlvbiBhbmQgdG8gYWx3YXlzIGluaXRpYWxpemUgdmFyaWFibGVzIGFmdGVyIGRlZmluaXRpb24uCgojIyMgTWVtb3J5IEFsbG9jYXRpb24gYW5kIE92ZXJmbG93cwoKQyBkb2VzIG5vdCBwZXJmb3JtIHR5cGUgY2hlY2tpbmcsIHNvIGl0IGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiB0aGUgcHJvZ3JhbW1lciB0byBlbnN1cmUgdGhhdCB0aGUgdmFyaWFibGUgaGFzIHN1ZmZpY2llbnQgbWVtb3J5IGFsbG9jYXRlZCB0byBob2xkIHRoZSB2YWx1ZSBhc3NpZ25lZCB0byB0aGUgdmFyaWFibGUuIEZvciBleGFtcGxlLCBhc3NpZ25pbmcgYSAzMi1iaXQgKDQgYnl0ZSkgaW50ZWdlciB0byBhIHZhcmlhYmxlIG9mIHR5cGUgKmNoYXIqIChhbiA4LWJpdCBvciAxIGJ5dGUgY2hhcmFjdGVyKSB3b3VsZCBjYXVzZSBhbiBvdmVyZmxvdy4gVGhlIGFzc2lnbm1lbnQgaXMgc3RpbGwgZG9uZSBhbmQgZm91ciBieXRlcyBhcmUgY29waWVkIHRvIG1lbW9yeSByZXNlcnZlZCBmb3Igb25lIGJ5dGUgY2F1c2UgdGhlIHJlbWFpbmluZyAzIGJ5dGVzIHRvIG92ZXJmbG93IGludG8gdGhlIG5leHQgdGhyZWUgYnl0ZXMgaW4gbWVtb3J5LCBwb3RlbnRpYWxseSBvdmVyd3JpdGluZyBvdGhlciB2YXJpYWJsZXMuIEEgY29tbW9uIHNvdXJjZSBvZiBoZWFkYWNoZXMgZm9yIHByb2dyYW1tZXJzLiBNb2Rlcm4gY29tcGlsZXJzIHdpbGwgImxpbnQiIHRoZSBjb2RlIGFuZCBwb2ludCBvdXQgc3VjaCBpc3N1ZXMuCgojIyMgSWRlbnRpZmllcnMKCkFuIGlkZW50aWZpZXIgaXMgdGhlIG5hbWUgZ2l2ZW4gdG8gZW50aXRpZXMgc3VjaCBhcyB2YXJpYWJsZXMsIGZ1bmN0aW9ucywgc3RydWN0dXJlcywgKmV0Yy4qIElkZW50aWZpZXJzIG11c3QgYmUgdW5pcXVlIHdpdGhpbiBhIHByb2dyYW0gYmxvY2sgKGl0cyAqc2NvcGUqKS4gSWRlbnRpZmllciBhcmUgdXNlZCB0byByZWZlciB0byBhIG1lbW9yeSBvYmplY3QuCgpGb3IgZXhhbXBsZSwgaW4gdGhlIGNvZGUgZnJhZ21lbnQgYmVsb3csICphbW91bnQqIGFuZCAqYWNjb3VudEJhbGFuY2UqIGFyZSBpZGVudGlmaWVyczoKCmBgYHtSY3BwIGV2YWw9Rn0KaW50IGFtb3VudDsKZG91YmxlIGFjY291bnRCYWxhbmNlOwpgYGAKCklkZW50aWZpZXIgbmFtZXMgbXVzdCBiZSBkaWZmZXJlbnQgZnJvbSBrZXl3b3Jkcy4gRm9yIGV4YW1wbGUsIHlvdSBjYW5ub3QgdXNlICppbnQqIGFzIGFuIGlkZW50aWZpZXIgYmVjYXVzZSAqaW50KiBpcyBhIGtleXdvcmQuIEEgbGlzdCBvZiBhbGwgQyBrZXl3b3JkcyBpcyBiZWxvdy4gTm90ZSB0aGF0IG1vc3QgbW9kZXJuIEMgY29tcGlsZXJzIGFyZSBhY3R1YWxseSBDKysgY29tcGlsZXJzIGFuZCBDKysgaGFzIGFkZGl0aW9uYWwga2V5d29yZHMuIE1vc3QgZWRpdG9ycyBhcmUgc3ludGF4LWF3YXJlIGFuZCB3aWxsIHRhZyBrZXl3b3JkcyBpbiBkaWZmZXJlbnQgY29sb3JzLgoKIyMjIyBJZGVudGlmaWVyIE5hbWluZyBSdWxlcwoKQSB2YWxpZCBpZGVudGlmaWVyIGNhbiBoYXZlIGxldHRlcnMgKGJvdGggdXBwZXJjYXNlIGFuZCBsb3dlcmNhc2UpLCBkaWdpdHMgYW5kIHVuZGVyc2NvcmVzIChcXykuIFRoZSBmaXJzdCBsZXR0ZXIgb2YgYW4gaWRlbnRpZmllciBtdXN0IGJlIGVpdGhlciBhIGxldHRlciBvciBhbiB1bmRlcnNjb3JlLiBZb3UgY2Fubm90IHVzZSBrZXl3b3JkcyBsaWtlICppbnQqLCAqZm9yKiwgKmV0Yy4qIGFzIGlkZW50aWZpZXJzLiBUaGVyZSBpcyBubyBydWxlIG9uIGhvdyBsb25nIGFuIGlkZW50aWZpZXIgY2FuIGJlLCBidXQgeW91IG1heSBydW4gaW50byBwcm9ibGVtcyB3aXRoIHNvbWUgY29tcGlsZXJzIHdoZW4gdGhlIGlkZW50aWZpZXIgaXMgbG9uZ2VyIHRoYW4gMzEgY2hhcmFjdGVycy4gWW91IGNhbiBjaG9vc2UgYW55IG5hbWUgYXMgYW4gaWRlbnRpZmllciBhcyBsb25nIGFzIHlvdSBmb2xsb3cgdGhlIGFib3ZlIHJ1bGVzLiBIb3dldmVyLCB1c2UgbWVhbmluZ2Z1bCBuYW1lcyB0byB2YXJpYWJsZXMgYW5kIGZ1bmN0aW9uIHRoYXQgcmVwcmVzZW50IHdoYXQgdGhleSBjb250YWluOyBpdCBtYWtlcyBwcm9ncmFtcyBtb3JlIHJlYWRhYmxlIGFuZCBlYXNpZXIgdG8gdW5kZXJzdGFuZCBhbmQgZGVidWcuCgojIyMgS2V5d29yZHMKCklkZW50aWZpZXJzIGNhbm5vdCBiZSByZXNlcnZlZCBrZXl3b3Jkcy4gVGhlIGxpc3QgYmVsb3cgYXJlIGFsbCB0aGUga2V5d29yZHMgb2YgQy4gTW9zdCBDIGNvbXBpbGVycyBhcmUgYWN0dWFsbHkgQysrIGNvbXBpbGVycyBhbmQgdGh1cyBoYXZlIGFkZGl0aW9uYWwga2V5d29yZHMsIHN1Y2ggYXMgKmNsYXNzKiBvciAqdmlydHVhbCouCgohW0tleXdvcmRzIGluIENdKGltYWdlcy9rZXl3b3Jkcy1pbi1jLmpwZyl7d2lkdGg9Ijc1JSJ9IFwjIyBDb21tYW5kIExpbmUgQXJndW1lbnRzCgpDIChhbmQgQysrKSBwcm9ncmFtcyBjYW4gcnVuIGZyb20gdGhlIGNvbW1hbmQgbGluZSAodGVybWluYWwgb3Igc2hlbGwpIGFzIGNhbiB0YWtlIGFyZ3VtZW50cy4gVGhlIGBtYWluYCBmdW5jdGlvbiB0YWtlcyB0d28gcGFyYW1ldGVycyAtLSBgYXJnY2AgYW5kIGBhcmd2YCAtLSB0aGF0IGFyZSB1c2VkIHRvIHJldHJpZXZlIHRoZSBjb21tYW5kIGxpbmUgYXJndW1lbnRzLgoKVGhlIGV4YW1wbGUgYmVsb3cgcHJpbnRzIG91dCB0aGUgdmFsdWVzIG9mIHRoZSBhcmd1bWVudHMsIGFsdGhvdWdoIHRoYXQgaXMgbm8gdGhhdCBwcmFjdGljYWwuCgpOb3RlIHRoYXQgdGhlIGZpcnN0IGFyZ3VtZW50IChgYXJndlswXWApIGlzIHRoZSBuYW1lIG9mIHRoZSBleGVjdXRhYmxlIHByb2dyYW0uCgpgYGB7UmNwcCBldmFsPUZ9CiNpbmNsdWRlIDxzdGRpby5oPgoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIqIGFyZ3ZbXSkKewogIGZvciAoaW50IGkgPSAwOyBpIDwgYXJnYzsgKytpKSB7CiAgICBwcmludGYoIiVpIHwgJXNcbiIsIGksIGFyZ3ZbaV0pOwogIH0KCiAgcmV0dXJuIDA7Cn0KYGBgCgojIyMgVHV0b3JpYWwKCldhdGNoIGFuZCBmb2xsb3cgYWxvbmcgd2l0aCB0aGUgbmFycmF0ZWQgdHV0b3JpYWwgb2YgYSBjb2RlIHdhbGsgYmVsb3cuCgo8aWZyYW1lIHNyYz0iaHR0cHM6Ly9wbGF5ZXIudmltZW8uY29tL3ZpZGVvLzc0NzYyMTAxMT9oPTQ0NWYyMDAwNDgiIHdpZHRoPSIzMjAiIGhlaWdodD0iMTgwIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImF1dG9wbGF5OyBmdWxsc2NyZWVuOyBwaWN0dXJlLWluLXBpY3R1cmUiIGFsbG93ZnVsbHNjcmVlbiBkYXRhLWV4dGVybmFsPSIxIj4KCjwvaWZyYW1lPgoKIyMgRmlsZXMgJiBSZXNvdXJjZXMKCmBgYHtyIHppcEZpbGVzLCBlY2hvPUZBTFNFfQp6aXBOYW1lID0gc3ByaW50ZigiTGVzc29uRmlsZXMtJXMtJXMuemlwIiwgCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LAogICAgICAgICAgICAgICAgIHBhcmFtcyRudW1iZXIpCgp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIAogICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksIi4iLHBhcmFtcyRudW1iZXIpCgojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlIKa25pdHI6OnJhd19odG1sKGRvd25sb2FkRmlsZXNMaW5rKCIuIiwgemlwTmFtZSwgdGV4dEFMaW5rKSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIFJlZmVyZW5jZXMKCktlcm5pZ2hhbiwgQi4gVy4sICYgUml0Y2hpZSwgRC4gTS4gKDE5ODgpLiAqVGhlIEMgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UqLiBQZWFyc29uIEVkdWNhdGlvbgoKW1JpdGNoaWUsIEQuIE0uICgxOTkzKS4gVGhlIGRldmVsb3BtZW50IG9mIHRoZSBDIGxhbmd1YWdlLiBBQ00gU2lncGxhbiBOb3RpY2VzLCAyOCgzKSwgMjAxLTIwOC5dKGh0dHBzOi8vd3d3LmJlbGwtbGFicy5jb20vdXNyL2Rtci93d3cvY2hpc3QucGRmKQoKIyMgRXJyYXRhCgpbTGV0IHVzIGtub3ddKGh0dHBzOi8vZm9ybS5qb3Rmb3JtLmNvbS8yMTIxODcwNzI3ODQxNTcpe3RhcmdldD0iX2JsYW5rIn0uCg==