WONKY



LOG | FILES | OVERVIEW


F diff --git a/.exrc b/.exrc new file mode 100644 --- /dev/null +++ b/.exrc
+ if &cp | set nocp | endif
+ let s:cpo_save=&cpo
+ set cpo&vim
+ vmap gx <Plug>NetrwBrowseXVis
+ nmap gx <Plug>NetrwBrowseX
+ vnoremap <silent> <Plug>NetrwBrowseXVis :call netrw#BrowseXVis()
+ nnoremap <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>')),netrw#CheckIfRemote())
+ map <F4> :r !timestamp<NL>
+ map <F6> :set keymap=<NL>
+ map <F5> :set keymap=bulgarian-phonetic<NL>
+ imap  l <F6>
+ imap  ; <F5>
+ let &cpo=s:cpo_save
+ unlet s:cpo_save
+ set background=dark
+ set backspace=indent,eol,start
+ set cindent
+ set fileencodings=ucs-bom,utf-8,default,latin1
+ set helplang=en
+ set nomodeline
+ set printoptions=paper:letter
+ set ruler
+ set runtimepath=~/.vim,/var/lib/vim/addons,/usr/share/vim/vimfiles,/usr/share/vim/vim81,/usr/share/vim/vimfiles/after,/var/lib/vim/addons/after,~/.vim/after
+ set suffixes=.bak,~,.swp,.o,.info,.aux,.log,.dvi,.bbl,.blg,.brf,.cb,.ind,.idx,.ilg,.inx,.out,.toc
+ " vim: set ft=vim :
F diff --git a/C89.txt b/C89.txt new file mode 100644 --- /dev/null +++ b/C89.txt
+
+ American National Standard Programming Language C specifies the
+ syntax and semantics of programs written in the C programming
+ language. It specifies the C program's interactions with the
+ execution environment via input and output data. It also specifies
+ restrictions and limits imposed upon conforming implementations of C
+ language translators.
+
+ The standard was developed by the X3J11 Technical Committee on the
+ C Programming Language under project 381-D by American National
+ Standards Committee on Computers and Information Processing (X3).
+ SPARC document number 83-079 describes the purpose of this project to
+ ``provide an unambiguous and machine-independent definition of the
+ language C.''
+
+ The need for a single clearly defined standard had arisen in the C
+ community due to a rapidly expanding use of the C programming language
+ and the variety of differing translator implementations that had been
+ and were being developed. The existence of similar but incompatible
+ implementations was a serious problem for program developers who
+ wished to develop code that would compile and execute as expected in
+ several different environments.
+
+ Part of this problem could be traced to the fact that implementors
+ did not have an adequate definition of the C language upon which to
+ base their implementations. The de facto C programming language
+ standard, The C Programming Language by Brian W. Kernighan and Dennis
+ M. Ritchie, is an excellent book; however, it is not precise or
+ complete enough to specify the C language fully. In addition, the
+ language has grown over years of use to incorporate new ideas in
+ programming and to address some of the weaknesses of the original
+ language.
+
+ American National Standard Programming Language C addresses the
+ problems of both the program developer and the translator implementor
+ by specifying the C language precisely.
+
+ The work of X3J11 began in the summer of 1983, based on the several
+ documents that were made available to the Committee (see $1.5, Base
+ Documents). The Committee divided the effort into three pieces: the
+ environment, the language, and the library. A complete specification
+ in each of these areas is necessary if truly portable programs are to
+ be developed. Each of these areas is addressed in the Standard. The
+ Committee evaluated many proposals for additions, deletions, and
+ changes to the base documents during its deliberations. A concerted
+ effort was made to codify existing practice wherever unambiguous and
+ consistent practice could be identified. However, where no consistent
+ practice could be identified, the Committee worked to establish clear
+ rules that were consistent with the overall flavor of the language.
+
+ This document was approved as an American National Standard by the
+ American National Standards Institute (ANSI) on DD MM, 1988.
+ Suggestions for improvement of this Standard are welcome. They should
+ be sent to the American National Standards Institute, 1430 Broadway,
+ New York, NY 10018.
+
+ The Standard was processed and approved for submittal to ANSI by
+ the American National Standards Committee on Computers and Information
+ Processing, X3. Committee approval of the Standard does not
+ necessarily imply that all members voted for its approval. At the
+ time that it approved this Standard, the X3 Committee had the
+ following members:
+
+ Organization Name of Representative=20
+ (To be completed on approval of the Standard.)
+
+ Technical Committee X3J11 on the C Programming Language had the
+ following members at the time they forwarded this document to X3 for
+ processing as an American National Standard:
+
+ Chair
+ Jim Brodie
+
+ Vice-Chair
+ Thomas Plum Plum Hall Secretary
+ P. J. Plauger Whitesmiths, Ltd.
+
+ International Representative
+ P. J. Plauger Whitesmiths, Ltd.
+ Steve Hersee Lattice, Inc.
+
+ Vocabulary Representative
+ Andrew Johnson Prime Computer=20
+
+ Environment Subcommittee Chairs
+ Ralph Ryan Microsoft
+ Ralph Phraner Phraner Associates
+
+ Language Subcommittee Chair
+ Lawrence Rosler AT&amp;T
+
+ Library Subcommittee Chair
+ P. J. Plauger Whitesmiths, Ltd.
+
+ Draft Redactor
+ David F. Prosser AT&amp;T
+ Lawrence Rosler AT&amp;T
+
+ Rationale Redactor
+ Randy Hudson Intermetrics, Inc. =20
+
+ In the following list, unmarked names denote principal members and *
+ denotes alternate members.
+
+ David F. Prosser, AT&amp;T
+ Steven J. Adamski, AT&amp;T* (X3H2 SQL liaison)
+ Bob Gottlieb, Alliant Computer Systems
+ Kevin Brosnan, Alliant Computer Systems
+ Neal Weidenhofer, Amdahl
+ Philip C. Steel, American Cimflex
+ Eric McGlohon, American Cimflex*
+ Stephen Kafka, Analog Devices
+ Kevin Leary, Analog Devices*
+ Gordon Sterling, Analog Devices*
+ John Peyton, Apollo Computer
+ Elizabeth Crockett, Apple Computers
+ Ed Wells, Arinc
+ Tom Ketterhagen, Arinc*
+ Vaughn Vernon, Aspen Scientific
+ Craig Bordelon, Bell Communications Research
+ Steve Carter, Bell Communications Research*
+ William Puig, Bell Communications Research*
+ Bob Jervis, Borland International
+ Yom-Tov Meged, Boston Systems Office
+ Rose Thomson, Boston Systems Office*
+ Maurice Fathi, COSMIC
+ John Wu, Charles River Data Systems
+ Daniel Mickey, Chemical Abstracts Service
+ Thomas Mimlitch, Chemical Abstracts Service*
+ Alan Losoff, Chicago Research &amp; Trading Group
+ Edward Briggs, Citibank
+ Firmo Freire, Cobra S/A
+ Jim Patterson, Cognos
+ Bruce Tetelman, Columbia U. Center for Computing
+ Terry Moore, CompuDas
+ Mark Barrenechea, Computer Associates
+ George Eberhardt, Computer Innovations
+ Dave Neathery, Computer Innovations*
+ Joseph Bibbo, Computrition
+ Steve Davies, Concurrent Computer Corporation
+ Don Fosbury, Control Data
+ George VandeBunte, Control Data*
+ Lloyd Irons, Cormorant Communications
+ Tom MacDonald, Cray Research
+ Lynne Johnson, Cray Research*
+ Dave Becker, Cray Research*
+ Jean Risley, Custom Development Environments
+ Rex Jaeschke, DEC Professional
+ Mike Terrazas, DECUS Representative
+ Michael Meissner, Data General
+ Mark Harris, Data General*
+ Leonard Ohmes, Datapoint
+ James Stanley, Data Systems Analysts
+ Samuel J. Kendall, Delft Consulting
+ Randy Meyers, Digital Equipment Corporation
+ Art Bjork, Digital Equipment Corporation*
+ Lu Anne Van de Pas, Digital Equipment Corporation*
+ Ben Patel, EDS
+ Richard Relph, EPI
+ Graham Andrews, Edinburgh Portable Compilers
+ Colin McPhail, Edinburgh Portable Compilers*
+ J. Stephen Adamczyk, Edison Design Group
+ Eric Schwarz, Edison Design Group*
+ Dmitry Lenkov, Everest Solutions
+ Frank Farance, Farance Inc.
+ Peter Hayes, Farance Inc.*
+ Florin Jordan, Floradin
+ Philip Provin, General Electric Information Services
+ Liz Sanville, Gould CSD
+ Tina Aleksa, Gould CSD*
+ Thomas Kelly, HCR Corporation
+ Paul Jackson, HCR Corporation*
+ Gary Jeter, Harris Computer Systems
+ Sue Meloy, Hewlett Packard
+ Larry Rosler, Hewlett Packard*
+ Michelle Ruscetta, Hewlett Packard*
+ Thomas E. Osten, Honeywell Information Systems
+ David Kayden, Honeywell Information Systems*
+ Shawn Elliott, IBM
+ Larry Breed, IBM*
+ Mel Goldberg, IBM*
+ Mike Banahan, Instruction Set
+ Clark Nelson, Intel
+ Dan Lau, Intel*
+ John Wolfe, InterACT
+ Lillian Toll, InterACT*
+ Randy Hudson, Intermetrics
+ Keith Winter, International Computers Ltd.
+ Honey M. Schrecker, International Computers Ltd.*
+ Jim Brodie, J. Brodie &amp; Associates
+ Jacklin Kotikian, Kendall Square Research
+ W. Peter Hesse, LSI Logic Europe Ltd.
+ John Kaminski, Language Processors Inc.
+ David Yost, Laurel Arts
+ Mike Branstetter, Lawrence Livermore National Laboratory
+ Bob Weaver, Los Alamos National Laboratory
+ Lidia Eberhart, Modcomp
+ Robert Sherry, Manx Software
+ Courtney Meissen, Mark Williams Co.
+ Patricia Jenkins, Masscomp
+ Dave Hinman, Masscomp*
+ Michael Kearns, MetaLink
+ Tom Pennello, MetaWare Incorporated
+ David F. Weil, Microsoft
+ Mitch Harder, Microsoft*
+ Kim Kempf, Microware Systems
+ Shane McCarron, Minnesota Educational Computing
+ Bruce Olsen, Mosaic Technologies
+ Michael Paton, Motorola
+ Rick Schubert, NCR
+ Brian Johnson, NCR*
+ Joseph Mueller, National Semiconductor
+ Derek Godfrey, National Semiconductor*
+ Jim Upperman, National Bureau of Standards
+ James W. Williams, Naval Research Laboratory
+ Lisa Simon, OCLC
+ Paul Amaranth, Oakland University
+ August R. Hansen, Omniware
+ Michael Rolle, Oracle
+ Carl Ellis, Oregon Software
+ Barry Hedquist, Perennial
+ Sassan Hazeghi, Peritus International
+ James Holmlund, Peritus International*
+ Thomas Plum, Plum Hall
+ Christopher Skelly, Plum Hall*
+ Andrew Johnson, Prime Computer
+ Fran Litterio, Prime Computer*
+ Daniel J. Conrad, Prismatics
+ David Fritz, Production Languages
+ Kenneth Pugh, Pugh
+ Killeen Ed Ramsey, Purdue University
+ Stephen Roberts, Purdue University*
+ Kevin Nolan, Quantitative Technology Corp.
+ Robert Mueller, Quantitative Technology Corp.*
+ Chris DeVoney, Que Corporation
+ Jon Tulk, Rabbit Software
+ Terry Colligan, Rational Systems
+ Daniel Saks, Saks &amp; Associates
+ Nancy Saks, Saks &amp; Associates*
+ Oliver Bradley, SAS Institute
+ Alan Beale, SAS Institute*
+ Larry Jones, SDRC
+ Donald Kossman, SEI Information Technology
+ Kenneth Harrenstien, SRI International
+ Larry Rosenthal, Sierra Systems
+ Phil Hempfner, Southern Bell Telephone
+ Purshotam Rajani, Spruce Technology
+ Savu Savulescu, Stagg Systems
+ Peter Darnell, Stellar Computer
+ Lee W. Cooprider, Stellar Computer*
+ Paul Gilmartin, Storage Technology Corp.
+ Steve Muchnick, Sun Microsystems
+ Chuck Rasbold, Supercomputer Systems, Inc.
+ Kelly O'Hair, Supercomputer Systems, Inc.*
+ Henry Richardson, Tandem
+ John M. Hausman, Tandem*
+ Samuel Harbison, Tartan Laboratories
+ Michael S. Ball, TauMetric
+ Carl Sutton, Tektronix
+ Jim Besemer, Tektronix*
+ Reid Tatge, Texas Instruments
+ Ed Brower, Tokheim
+ Robert Mansfield, Tokheim*
+ Monika Khushf, Tymlabs
+ Morgan Jones, Tymlabs*
+ Don Bixler, Unisys
+ Steve Bartels, Unisys*
+ Glenda Berkheimer, Unisys*
+ Annice Jackson, Unisys*
+ Fred Blonder, University of Maryland
+ Fred Schwarz, University of Michigan
+ R. Jordan Kreindler, University of Southern California CTC
+ Mike Carmody, University of Waterloo
+ Douglas Gwyn, US Army BRL (IEEE P1003 liaison)
+ C. Dale Pierce, US Army Management Engineering*
+ John C. Black, VideoFinancial
+ Joseph Musacchia, Wang Labs
+ Fred Rozakis, Wang Labs*
+ P. J. Plauger, Whitesmiths, Ltd.
+ Kim Leeper, Wick Hill
+ Mark Wittenberg, Zehntel
+ Jim Balter
+ Robert Bradbury
+ Edward Chin
+ Neil Daniels
+ Stephen Desofi
+ Michael Duffy
+ Phillip Escue
+ Ralph Phraner
+ D. Hugh Redelmeier
+ Arnold Davi
+ Robbins Roger
+ Wilks Michael
+ J. Young
+
+
+ purpose: 1.1
+ scope: 1.2
+ references: 1.3
+ organization of the document: 1.4
+ base documents: 1.5
+ definitions of terms: 1.6
+ compliance: 1.7
+ translation environment: 2.
+ execution environment: 2.
+ separate compilation: 2.1.1.1
+ separate translation: 2.1.1.1
+ source file: 2.1.1.1
+ translation unit: 2.1.1.1
+ program execution: 2.1.2.3
+ side effects: 2.1.2.3
+ sequence point: 2.1.2.3
+ character set: 2.2.1
+ signals: 2.2.3
+ interrupts: 2.2.3
+ syntax notation: 3.
+ lexical elements: 3.1
+ comment: 3.1
+ white space: 3.1
+ list of keywords: 3.1.1
+ reserved words: 3.1.1
+ underscore character: 3.1.2
+ enumeration constant: 3.1.2
+ length of names: 3.1.2
+ internal name, length of: 3.1.2
+ external name, length of: 3.1.2
+ function name, length of: 3.1.2
+ scopes: 3.1.2.1
+ prototype, function: 3.1.2.1
+ function scope: 3.1.2.1
+ file scope: 3.1.2.1
+ block scope: 3.1.2.1
+ block structure: 3.1.2.1
+ function prototype scope: 3.1.2.1
+ linkage: 3.1.2.2
+ external linkage: 3.1.2.2
+ internal linkage: 3.1.2.2
+ no linkage: 3.1.2.2
+ name spaces: 3.1.2.3
+ named label: 3.1.2.3
+ structure tag: 3.1.2.3
+ union tag: 3.1.2.3
+ enumeration tag: 3.1.2.3
+ structure member name: 3.1.2.3
+ union member name: 3.1.2.3
+ storage duration: 3.1.2.4
+ static storage duration: 3.1.2.4
+ automatic storage duration: 3.1.2.4
+ types: 3.1.2.5
+ object types: 3.1.2.5
+ function types: 3.1.2.5
+ incomplete types: 3.1.2.5
+ char type: 3.1.2.5
+ signed character: 3.1.2.5
+ signed char type: 3.1.2.5
+ short type: 3.1.2.5
+ long type: 3.1.2.5
+ unsigned type: 3.1.2.5
+ float type: 3.1.2.5
+ double type: 3.1.2.5
+ long double type: 3.1.2.5
+ basic types: 3.1.2.5
+ character types: 3.1.2.5
+ enumerated type: 3.1.2.5
+ void type: 3.1.2.5
+ derived types: 3.1.2.5
+ integral types: 3.1.2.5
+ arithmetic types: 3.1.2.5
+ scalar types: 3.1.2.5
+ aggregate types: 3.1.2.5
+ constants: 3.1.3
+ floating constant: 3.1.3.1
+ double constant: 3.1.3.1
+ integer constant: 3.1.3.2
+ decimal constant: 3.1.3.2
+ octal constant: 3.1.3.2
+ hexadecimal constant: 3.1.3.2
+ unsigned constant: 3.1.3.2
+ long constant: 3.1.3.2
+ enumeration constant: 3.1.3.3
+ character constant: 3.1.3.4
+ backslash character: 3.1.3.4=20
+ escape character: 3.1.3.4
+ escape sequence: 3.1.3.4
+ string literal: 3.1.4
+ character string: 3.1.4
+ operator: 3.1.5
+ evaluation: 3.1.5
+ operand: 3.1.5
+ punctuator: 3.1.6
+ character-integer conversion: 3.2.1.1
+ integer-character conversion: 3.2.1.1
+ integral promotions: 3.2.1.1
+ integer-long conversion: 3.2.1.1
+ signed character: 3.2.1.1
+ unsigned-integer conversion: 3.2.1.2
+ integer-unsigned conversion: 3.2.1.2
+ long-unsigned conversion: 3.2.1.2
+ long-integer conversion: 3.2.1.2
+ floating-integer conversion: 3.2.1.3
+ integer-floating conversion: 3.2.1.3
+ float-double conversion: 3.2.1.4
+ double-float conversion: 3.2.1.4
+ arithmetic conversions: 3.2.1.5
+ type conversion rules: 3.2.1.5
+ lvalue: 3.2.2.1
+ function designator: 3.2.2.1
+ conversion of array: 3.2.2.1
+ conversion of function name: 3.2.2.1
+ void type: 3.2.2.2
+ pointer-pointer conversion: 3.2.2.3
+ integer-pointer conversion: 3.2.2.3
+ null pointer: 3.2.2.3
+ expression: 3.3
+ precedence of operators: 3.3
+ associativity of operators: 3.3
+ order of evaluation of expressions: 3.3
+ order of evaluation: 3.3
+ bitwise operators: 3.3
+ exceptions: 3.3
+ primary expression: 3.3.1
+ type of string: 3.3.1
+ parenthesized expression: 3.3.1
+ subscript operator: 3.3.2
+ function call: 3.3.2
+ structure member operator: 3.3.2
+ structure pointer operator: 3.3.2
+ ++ increment operator: 3.3.2
+ -- decrement operator: 3.3.2
+ array, explanation of subscripting: 3.3.2.1
+ subscripting, explanation of: 3.3.2.1
+ multi-dimensional array: 3.3.2.1
+ storage order of array: 3.3.2.1
+ function call: 3.3.2.2
+ implicit declaration of function: 3.3.2.2
+ function argument: 3.3.2.2
+ call by value: 3.3.2.2
+ recursion: 3.3.2.2
+ structure reference: 3.3.2.3
+ union reference: 3.3.2.3
+ common initial sequence: 3.3.2.3
+ postfix ++ and --: 3.3.2.4
+ -- decrement operator: 3.3.2.4
+ unary expression: 3.3.3
+ ++ increment operator: 3.3.3
+ -- decrement operator: 3.3.3
+ sizeof operator: 3.3.3
+ &amp; address operator: 3.3.3
+ * indirection operator: 3.3.3
+ + unary plus operator: 3.3.3
+ - unary minus operator: 3.3.3
+ ~ bitwise complement operator: 3.3.3
+ ! logical negation operator: 3.3.3
+ ++ increment operator: 3.3.3.1
+ prefix ++ and --: 3.3.3.1
+ -- decrement operator: 3.3.3.1
+ + unary plus operator: 3.3.3.3
+ - unary minus operator: 3.3.3.3
+ ~ bitwise complement operator: 3.3.3.3
+ ! logical negation operator: 3.3.3.3
+ byte: 3.3.3.4
+ storage allocator: 3.3.3.4
+ cast expression: 3.3.4
+ cast operator: 3.3.4
+ explicit conversion operator: 3.3.4
+ cast operator: 3.3.4
+ pointer conversion: 3.3.4
+ explicit conversion operator: 3.3.4
+ pointer-integer conversion: 3.3.4
+ integer-pointer conversion: 3.3.4
+ alignment restriction: 3.3.4
+ arithmetic operators: 3.3.5
+ multiplicative operators: 3.3.5
+ * multiplication operator: 3.3.5
+ / division operator: 3.3.5
+ % modulus operator: 3.3.5
+ additive operators: 3.3.6
+ + addition operator: 3.3.6
+ - subtraction operator: 3.3.6
+ pointer arithmetic: 3.3.6
+ pointer arithmetic: 3.3.6
+ shift operators: 3.3.7
+ &lt;&lt; left shift operator: 3.3.7
+ &gt;&gt; right shift operator: 3.3.7
+ relational operators: 3.3.8
+ &lt; less than operator: 3.3.8
+ &gt; greater than operator: 3.3.8
+ &lt;=3D less than or equal to operator: 3.3.8
+ &gt;=3D greater than or equal to operator: 3.3.8
+ pointer comparison: 3.3.8
+ equality operators: 3.3.9
+ =3D=3D equality operator: 3.3.9
+ !=3D inequality operator: 3.3.9
+ &amp; bitwise AND operator: 3.3.10
+ ^ bitwise exclusive OR operator: 3.3.11
+ | bitwise inclusive OR operator: 3.3.12
+ &amp;&amp; logical AND operator: 3.3.13
+ || logical OR operator: 3.3.14
+ ?: conditional expression: 3.3.15
+ assignment operators: 3.3.16
+ assignment expression: 3.3.16
+ simple assignment: 3.3.16.1
+ conversion by assignment: 3.3.16.1
+ compound assignment: 3.3.16.2
+ comma operator: 3.3.17
+ constant expression: 3.4
+ permitted form of initializer: 3.4
+ declarations: 3.5
+ storage-class specifier: 3.5.1
+ storage-class declaration: 3.5.1
+ typedef declaration: 3.5.1
+ extern storage class: 3.5.1
+ static storage class: 3.5.1
+ auto storage class: 3.5.1
+ register storage class: 3.5.1
+ type specifier: 3.5.2
+ void type: 3.5.2
+ char type: 3.5.2
+ short type: 3.5.2
+ int type: 3.5.2
+ long type: 3.5.2
+ float type: 3.5.2
+ double type: 3.5.2
+ signed type: 3.5.2
+ unsigned type: 3.5.2
+ structure declaration: 3.5.2.1
+ union declaration: 3.5.2.1
+ bit-field declaration: 3.5.2.1
+ bit-field: 3.5.2.1
+ member alignment: 3.5.2.1
+ enumeration: 3.5.2.2
+ enum-specifier: 3.5.2.2
+ enumerator: 3.5.2.2
+ structure tag: 3.5.2.3
+ union tag: 3.5.2.3
+ structure content: 3.5.2.3
+ union content: 3.5.2.3
+ enumeration content: 3.5.2.3
+ self-referential structure: 3.5.2.3
+ type qualifier: 3.5.3
+ const type qualifier: 3.5.3
+ volatile type qualifier: 3.5.3
+ declarator: 3.5.4
+ type declaration: 3.5.4
+ declaration of pointer: 3.5.4.1
+ array declaration: 3.5.4.2
+ declaration of function: 3.5.4.3
+ type names: 3.5.5
+ abstract declarator: 3.5.5
+ typedef declaration: 3.5.6
+ initialization: 3.5.7
+ initialization of statics: 3.5.7
+ implicit initialization: 3.5.7
+ default initialization: 3.5.7
+ initialization of automatics: 3.5.7
+ aggregate initialization: 3.5.7
+ array initialization: 3.5.7
+ structure initialization: 3.5.7
+ character array initialization: 3.5.7
+ wchar_t array initialization: 3.5.7
+ statements: 3.6
+ sequencing of statements: 3.6
+ full expression: 3.6
+ labeled statement: 3.6.1
+ named label: 3.6.1
+ case label: 3.6.1
+ default label: 3.6.1
+ compound statement: 3.6.2
+ block: 3.6.2
+ block structure: 3.6.2
+ initialization in blocks: 3.6.2
+ expression statement: 3.6.3
+ null statement: 3.6.3
+ empty statement: 3.6.3
+ if-else statement: 3.6.4.1
+ switch statement: 3.6.4.2
+ switch body: 3.6.4.2
+ loop body: 3.6.5
+ while statement: 3.6.5.1
+ do statement: 3.6.5.2
+ for statement: 3.6.5.3
+ goto statement: 3.6.6.1
+ continue statement: 3.6.6.2
+ break statement: 3.6.6.3
+ return statement: 3.6.6.4
+ type conversion by return: 3.6.6.4
+ conversion by return: 3.6.6.4
+ external definition: 3.7
+ function definition: 3.7.1
+ parameter: 3.7.1
+ array argument: 3.7.1
+ function name argument: 3.7.1
+ pointer to function: 3.7.1
+ object definitions: 3.7.2
+ scope of externals: 3.7.2
+ tentative definition: 3.7.2
+ preprocessing directives: 3.8
+ macro preprocessor: 3.8
+ preprocessing directive lines: 3.8
+ conditional inclusion: 3.8.1
+ #if: 3.8.1
+ #elif 3.8.1
+ #ifdef: 3.8.1
+ #ifndef: 3.8.1
+ #else: 3.8.1
+ #endif: 3.8.1
+ #include: 3.8.2
+ source file inclusion: 3.8.2
+ macro replacement: 3.8.3
+ object-like macro: 3.8.3
+ function-like macro: 3.8.3
+ macro name: 3.8.3
+ #define: 3.8.3
+ macro parameters: 3.8.3
+ macro invocation: 3.8.3
+ argument substitution: 3.8.3.1
+ # operator: 3.8.3.2
+ ## operator: 3.8.3.3
+ rescanning and replacement: 3.8.3.4
+ macro definition scope: 3.8.3.5
+ #undef: 3.8.3.5
+ #line: 3.8.4
+ error directive: 3.8.5
+ pragma directive: 3.8.6
+ null directive: 3.8.7
+ introduction: 4.1
+ string definition: 4.1.1
+ letter definition: 4.1.1
+ decimal-point definition: 4.1.1
+ reserved identifier: 4.1.2
+ printing character: 4.3
+ control character: 4.3
+ variable arguments: 4.8
+ unbuffered stream: 4.9.3
+ fully buffered stream: 4.9.3
+ line buffered stream: 4.9.3
+ appendices: A.
+ language syntax summary: A.1
+ sequence points: A.2
+ library summary: A.3
+ implementation limits: A.4
+ warnings: A.5
+ portability: A.6
+ order of evaluation: A.6.1
+ machine dependency: A.6.3
+ restrictions on registers: A.6.3.7
+ function pointer casts: A.6.5.7
+ bit-field types: A.6.5.8
+ fortran keyword: A.6.5.9
+ asm keyword: A.6.5.10
+ multiple external definitions: A.6.5.11
+ empty macro arguments: A.6.5.12
+ predefined macro names: A.6.5.13
+ signal handler arguments: A.6.5.14
+ stream types: A.6.5.15
+ file-opening modes: A.6.5.15
+ file position indicator: A.6.5.16
+ foreword: A.7
+
+
+ 1. INTRODUCTION
+
+ 1.1 PURPOSE
+
+ This Standard specifies the form and establishes the interpretation
+ of programs written in the C programming language./1/
+
+ 1.2 SCOPE
+
+ This Standard specifies:=20
+
+ * the representation of C programs;=20
+
+ * the syntax and constraints of the C language;=20
+
+ * the semantic rules for interpreting C programs;=20
+
+ * the representation of input data to be processed by C programs;=20
+
+ * the representation of output data produced by C programs;=20
+
+ * the restrictions and limits imposed by a conforming implementation of C.=
+ =20
+
+
+ This Standard does not specify:=20
+
+ * the mechanism by which C programs are transformed for use by a
+ data-processing system;
+
+ * the mechanism by which C programs are invoked for use by a
+ data-processing system;
+
+ * the mechanism by which input data are transformed for use by a C program=
+ ;=20
+
+ * the mechanism by which output data are transformed after being
+ produced by a C program;
+
+ * the size or complexity of a program and its data that will exceed
+ the capacity of any specific data-processing system or the capacity of
+ a particular processor;
+
+ * all minimal requirements of a data-processing system that is
+ capable of supporting a conforming implementation.
+
+
+ 1.3 REFERENCES
+
+ 1. ``The C Reference Manual'' by Dennis M. Ritchie, a version of
+ which was published in The C Programming Language by Brian
+ W. Kernighan and Dennis M. Ritchie, Prentice-Hall, Inc., (1978).
+ Copyright owned by AT&amp;T.
+
+ 2. 1984 /usr/group Standard by the /usr/group Standards Committee,
+ Santa Clara, California, USA (November, 1984).
+
+ 3. American National Dictionary for Information Processing Systems,
+ Information Processing Systems Technical Report ANSI X3/TR-1-82 (1982).
+
+ 4. ISO 646-1983 Invariant Code Set. =20
+
+ 5. IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1=
+ 985). =20
+
+ 6. ISO 4217 Codes for the Representation of Currency and Funds. =20
+
+
+ 1.4 ORGANIZATION OF THE DOCUMENT
+
+ This document is divided into four major sections:=20
+
+ 1. this introduction;=20
+
+ 2. the characteristics of environments that translate and execute C progra=
+ ms;=20
+
+ 3. the language syntax, constraints, and semantics;=20
+
+ 4. the library facilities. =20
+
+ Examples are provided to illustrate possible forms of the
+ constructions described. Footnotes are provided to emphasize
+ consequences of the rules described in the section or elsewhere in the
+ Standard. References are used to refer to other related sections. A
+ set of appendices summarizes information contained in the Standard.
+ The abstract, the foreword, the examples, the footnotes, the
+ references, and the appendices are not part of the Standard.
+
+ 1.5 BASE DOCUMENTS
+
+ The language section ($3) is derived from ``The C Reference
+ Manual'' by Dennis M. Ritchie, a version of which was published as
+ Appendix A of The C Programming Language by Brian W. Kernighan and
+ Dennis M. Ritchie, Prentice-Hall, Inc., 1978; copyright owned by AT&amp;T.
+
+ The library section ($4) is based on the 1984 /usr/group Standard by
+ the /usr/group Standards Committee, Santa Clara, California, USA
+ (November 14, 1984).
+
+ 1.6 DEFINITIONS OF TERMS
+
+ In this Standard, ``shall'' is to be interpreted as a requirement
+ on an implementation or on a program; conversely, ``shall not'' is to
+ be interpreted as a prohibition.
+
+ The following terms are used in this document:=20
+
+ * Implementation --- a particular set of software, running in a
+ particular translation environment under particular control options,
+ that performs translation of programs for, and supports execution of
+ functions in, a particular execution environment.
+
+ * Bit --- the unit of data storage in the execution environment large
+ enough to hold an object that may have one of two values. It need not
+ be possible to express the address of each individual bit of an
+ object.
+
+ * Byte --- the unit of data storage in the execution environment
+ large enough to hold any member of the basic character set of the
+ execution environment. It shall be possible to express the address of
+ each individual byte of an object uniquely. A byte is composed of a
+ contiguous sequence of bits, the number of which is
+ implementation-defined. The least significant bit is called the
+ low-order bit; the most significant bit is called the high-order bit.
+
+ * Object --- a region of data storage in the execution environment,
+ the contents of which can represent values. Except for bit-fields,
+ objects are composed of contiguous sequences of one or more bytes, the
+ number, order, and encoding of which are either explicitly specified
+ or implementation-defined.
+
+ * Character --- a single byte representing a member of the basic
+ character set of either the source or the execution environment.
+
+ * Multibyte character --- a sequence of one or more bytes
+ representing a member of the extended character set of either the
+ source or the execution environment. The extended character set is a
+ superset of the basic character set.
+
+ * Alignment --- a requirement that objects of a particular type be
+ located on storage boundaries with addresses that are particular
+ multiples of a byte address.
+
+ * Argument --- an expression in the comma-separated list bounded by
+ the parentheses in a function call expression, or a sequence of
+ preprocessing tokens in the comma-separated list bounded by the
+ parentheses in a function-like macro invocation. Also known as
+ ``actual argument'' or ``actual parameter.''
+
+ * Parameter --- an object declared as part of a function declaration
+ or definition that acquires a value on entry to the function, or an
+ identifier from the comma-separated list bounded by the parentheses
+ immediately following the macro name in a function-like macro
+ definition. Also known as ``formal argument'' or ``formal
+ parameter.''
+
+ * Unspecified behavior --- behavior, for a correct program construct
+ and correct data, for which the Standard imposes no requirements.
+
+ * Undefined behavior --- behavior, upon use of a nonportable or
+ erroneous program construct, of erroneous data, or of
+ indeterminately-valued objects, for which the Standard imposes no
+ requirements. Permissible undefined behavior ranges from ignoring the
+ situation completely with unpredictable results, to behaving during
+ translation or program execution in a documented manner characteristic
+ of the environment (with or without the issuance of a diagnostic
+ message), to terminating a translation or execution (with the issuance
+ of a diagnostic message).
+
+ If a ``shall'' or ``shall not'' requirement that appears outside of
+ a constraint is violated, the behavior is undefined. Undefined=20
+ behavior is otherwise indicated in this Standard by the words
+ ``undefined behavior'' or by the omission of any explicit definition
+ of behavior. There is no difference in emphasis among these three;
+ they all describe ``behavior that is undefined.''
+
+ * Implementation-defined behavior --- behavior, for a correct program
+ construct and correct data, that depends on the characteristics of the
+ implementation and that each implementation shall document.
+
+ * Locale-specific behavior --- behavior that depends on local
+ conventions of nationality, culture, and language that each
+ implementation shall document.
+
+ * Diagnostic message --- a message belonging to an
+ implementation-defined subset of the implementation's message output.
+
+ * Constraints --- syntactic and semantic restrictions by which the
+ exposition of language elements is to be interpreted.
+
+ * Implementation limits --- restrictions imposed upon programs by the
+ implementation.
+
+ * Forward references --- references to later sections of the Standard
+ that contain additional information relevant to this section.
+
+ Other terms are defined at their first appearance, indicated by italic
+ type. Terms explicitly defined in this Standard are not to be
+ presumed to refer implicitly to similar terms defined elsewhere.
+
+ Terms not defined in this Standard are to be interpreted according to
+ the American National Dictionary for Information Processing Systems,
+ Information Processing Systems Technical Report ANSI X3/TR-1-82 (1982).
+
+ Forward references: localization ($4.4). =20
+
+ "Examples"
+
+ An example of unspecified behavior is the order in which the
+ arguments to a function are evaluated.
+
+ An example of undefined behavior is the behavior on integer overflow.
+
+ An example of implementation-defined behavior is the propagation of
+ the high-order bit when a signed integer is shifted right.
+
+ An example of locale-specific behavior is whether the islower
+ function returns true for characters other than the 26 lower-case
+ English letters.
+
+ Forward references: bitwise shift operators ($3.3.7), expressions
+ ($3.3), function calls ($3.3.2.2), the islower function ($4.3.1.6).
+
+
+ 1.7 COMPLIANCE
+
+ A strictly conforming program shall use only those features of the
+ language and library specified in this Standard. It shall not produce
+ output dependent on any unspecified, undefined, or
+ implementation-defined behavior, and shall not exceed any minimum
+ implementation limit.
+
+ The two forms of conforming implementation are hosted and
+ freestanding. A conforming hosted implementation shall accept any
+ strictly conforming program. A conforming freestanding implementation
+ shall accept any strictly conforming program in which the use of the
+ features specified in the library section ($4) is confined to the
+ contents of the standard headers &lt;float.h&gt; , &lt;limits.h&gt; , &lt;s=
+ tdarg.h&gt; ,
+ and &lt;stddef.h&gt; . A conforming implementation may have extensions
+ (including additional library functions), provided they do not alter
+ the behavior of any strictly conforming program.
+
+ A conforming program is one that is acceptable to a conforming
+ implementation./2/
+
+ An implementation shall be accompanied by a document that defines
+ all implementation-defined characteristics and all extensions.
+
+ Forward references: limits &lt;float.h&gt; and &lt;limits.h&gt; ($4.1.4), v=
+ ariable
+ arguments &lt;stdarg.h&gt; ($4.8), common definitions &lt;stddef.h&gt; ($4.=
+ 1.5).
+
+
+ 1.8 FUTURE DIRECTIONS
+
+ With the introduction of new devices and extended character sets,
+ new features may be added to the Standard. Subsections in the
+ language and library sections warn implementors and programmers of
+ usages which, though valid in themselves, may conflict with future
+ additions.
+
+ Certain features are obsolescent , which means that they may be
+ considered for withdrawal in future revisions of the Standard. They
+ are retained in the Standard because of their widespread use, but
+ their use in new implementations (for implementation features) or new
+ programs (for language or library features) is discouraged.
+
+ Forward references: future language directions ($3.9.9), future
+ library directions ($4.13).
+
+ 1.9 ABOUT THIS DRAFT
+
+ Symbols in the right margin mark substantive differences between
+ this draft and its predecessor (ANSI X3J11/88-001, January 11, 1988).
+ A plus sign indicates an addition, a minus sign a deletion, and a
+ vertical bar a replacement.
+
+ This section and the difference marks themselves will not appear in
+ the published document.
+
+
+ 2. ENVIRONMENT
+
+ An implementation translates C source files and executes C programs
+ in two data-processing-system environments, which will be called the
+ translation environment and the execution environment in this
+ Standard. Their characteristics define and constrain the results of
+ executing conforming C programs constructed according to the syntactic
+ and semantic rules for conforming implementations.
+
+ Forward references: In the environment section ($2), only a few of
+ many possible forward references have been noted.
+
+
+ 2.1 CONCEPTUAL MODELS
+
+ 2.1.1 Translation environment
+
+ 2.1.1.1 Program structure
+
+ A C program need not all be translated at the same time. The text
+ of the program is kept in units called source files in this Standard.
+ A source file together with all the headers and source files included
+ via the preprocessing directive #include , less any source lines
+ skipped by any of the conditional inclusion preprocessing directives,
+ is called a translation unit. Previously translated translation units
+ may be preserved individually or in libraries. The separate
+ translation units of a program communicate by (for example) calls to
+ functions whose identifiers have external linkage, by manipulation of
+ objects whose identifiers have external linkage, and by manipulation
+ of data files. Translation units may be separately translated and
+ then later linked to produce an executable program.
+
+ Forward references: conditional inclusion ($3.8.1), linkages of
+ identifiers ($3.1.2.2), source file inclusion ($3.8.2).
+
+ 2.1.1.2 Translation phases
+
+ The precedence among the syntax rules of translation is specified
+ by the following phases./3/
+
+ 1. Physical source file characters are mapped to the source character
+ set (introducing new-line characters for end-of-line indicators) if
+ necessary. Trigraph sequences are replaced by corresponding
+ single-character internal representations.
+
+ 2. Each instance of a new-line character and an immediately preceding
+ backslash character is deleted, splicing physical source lines to form
+ logical source lines. A source file that is not empty shall end in a
+ new-line character, which shall not be immediately preceded by a
+ backslash character.
+
+ 3. The source file is decomposed into preprocessing tokens/4/ and
+ sequences of white-space characters (including comments). A source
+ file shall not end in a partial preprocessing token or comment. Each
+ comment is replaced by one space character. New-line characters are
+ retained. Whether each nonempty sequence of other white-space
+ characters is retained or replaced by one space character is
+ implementation-defined.
+
+ 4. Preprocessing directives are executed and macro invocations are
+ expanded. A #include preprocessing directive causes the named header
+ or source file to be processed from phase 1 through phase 4,
+ recursively.
+
+ 5. Each escape sequence in character constants and string literals is
+ converted to a member of the execution character set.
+
+ 6. Adjacent character string literal tokens are concatenated and
+ adjacent wide string literal tokens are concatenated.
+
+ 7. White-space characters separating tokens are no longer
+ significant. Preprocessing tokens are converted into tokens. The
+ resulting tokens are syntactically and semantically analyzed and
+ translated.
+
+ 8. All external object and function references are resolved. Library
+ components are linked to satisfy external references to functions and
+ objects not defined in the current translation. All such translator
+ output is collected into a program image which contains information
+ needed for execution in its execution environment.
+
+ Forward references: lexical elements ($3.1), preprocessing directives
+ ($3.8), trigraph sequences ($2.2.1.1).
+
+ 2.1.1.3 Diagnostics
+
+ A conforming implementation shall produce at least one diagnostic
+ message (identified in an implementation-defined manner) for every
+ translation unit that contains a violation of any syntax rule or
+ constraint. Diagnostic messages need not be produced in other
+ circumstances.
+
+ 2.1.2 Execution environments
+
+ Two execution environments are defined: freestanding and hosted.
+ In both cases, program startup occurs when a designated C function
+ is called by the execution environment. All objects in static storage
+ shall be initialized (set to their initial values) before program
+ startup. The manner and timing of such initialization are otherwise
+ unspecified. Program termination returns control to the execution
+ environment.
+
+ Forward references: initialization ($3.5.7). =20
+
+ 2.1.2.1 Freestanding environment
+
+ In a freestanding environment (in which C program execution may
+ take place without any benefit of an operating system), the name and
+ type of the function called at program startup are
+ implementation-defined. There are otherwise no reserved external
+ identifiers. Any library facilities available to a freestanding
+ program are implementation-defined.
+
+ The effect of program termination in a freestanding environment is
+ implementation-defined.
+
+ 2.1.2.2 Hosted environment
+
+ A hosted environment need not be provided, but shall conform to the
+ following specifications if present.
+
+ "Program startup"
+
+ The function called at program startup is named main . The
+ implementation declares no prototype for this function. It can be
+ defined with no parameters:
+
+ int main(void) { /*...*/ }
+
+ or with two parameters (referred to here as argc and argv , though any
+ names may be used, as they are local to the function in which they are
+ declared):
+
+ int main(int argc, char *argv[]) { /*...*/ }
+
+
+ If they are defined, the parameters to the main function shall obey
+ the following constraints:
+
+ * The value of argc shall be nonnegative. =20
+
+ * argv[argc] shall be a null pointer. =20
+
+ * If the value of argc is greater than zero, the array members
+ argv[0] through argv[argc-1] inclusive shall contain pointers to
+ strings, which are given implementation-defined values by the host
+ environment prior to program startup. The intent is to supply to the
+ program information determined prior to program startup from elsewhere
+ in the hosted environment. If the host environment is not capable of
+ supplying strings with letters in both upper-case and lower-case, the
+ implementation shall ensure that the strings are received in
+ lower-case.
+
+ * If the value of argc is greater than zero, the string pointed to by
+ argv[0] represents the program name ;argv[0][0] shall be the null
+ character if the program name is not available from the host
+ environment. If the value of argc is greater than one, the strings
+ pointed to by argv[1] through argv[argc-1] represent the program
+ parameters .
+
+ * The parameters argc and argv and the strings pointed to by the argv
+ array shall be modifiable by the program, and retain their last-stored
+ values between program startup and program termination.
+
+ "Program execution"
+
+ In a hosted environment, a program may use all the functions,
+ macros, type definitions, and objects described in the library section ($4)=
+ .
+
+ "Program termination"
+
+ A return from the initial call to the main function is equivalent
+ to calling the exit function with the value returned by the main
+ function as its argument. If the main function executes a return that
+ specifies no value, the termination status returned to the host
+ environment is undefined.
+
+ Forward references: definition of terms ($4.1.1), the exit function
+ ($4.10.4.3).
+
+
+ 2.1.2.3 Program execution
+
+ The semantic descriptions in this Standard describe the behavior of
+ an abstract machine in which issues of optimization are irrelevant.
+
+ Accessing a volatile object, modifying an object, modifying a file,
+ or calling a function that does any of those operations are all side
+ effects ,which are changes in the state of the execution environment.
+ Evaluation of an expression may produce side effects. At certain
+ specified points in the execution sequence called sequence points, all
+ side effects of previous evaluations shall be complete and no side
+ effects of subsequent evaluations shall have taken place.
+
+ In the abstract machine, all expressions are evaluated as specified
+ by the semantics. An actual implementation need not evaluate part of
+ an expression if it can deduce that its value is not used and that no
+ needed side effects are produced (including any caused by calling a
+ function or accessing a volatile object).
+
+ When the processing of the abstract machine is interrupted by
+ receipt of a signal, only the values of objects as of the previous
+ sequence point may be relied on. Objects that may be modified between
+ the previous sequence point and the next sequence point need not have
+ received their correct values yet.
+
+ An instance of each object with automatic storage duration is
+ associated with each entry into a block. Such an object exists and
+ retains its last-stored value during the execution of the block and
+ while the block is suspended (by a call of a function or receipt of a
+ signal).
+
+ The least requirements on a conforming implementation are:=20
+
+ * At sequence points, volatile objects are stable in the sense that
+ previous evaluations are complete and subsequent evaluations have not
+ yet occurred.
+
+ * At program termination, all data written into files shall be
+ identical to the result that execution of the program according to the
+ abstract semantics would have produced.
+
+ * The input and output dynamics of interactive devices shall take
+ place as specified in $4.9.3. The intent of these requirements is
+ that unbuffered or line-buffered output appear as soon as possible, to
+ ensure that prompting messages actually appear prior to a program
+ waiting for input.
+
+ What constitutes an interactive device is implementation-defined.
+
+ More stringent correspondences between abstract and actual
+ semantics may be defined by each implementation.
+
+ "Examples"
+
+ An implementation might define a one-to-one correspondence between
+ abstract and actual semantics: at every sequence point, the values of
+ the actual objects would agree with those specified by the abstract
+ semantics. The keyword volatile would then be redundant.
+
+ Alternatively, an implementation might perform various
+ optimizations within each translation unit, such that the actual
+ semantics would agree with the abstract semantics only when making
+ function calls across translation unit boundaries. In such an
+ implementation, at the time of each function entry and function return
+ where the calling function and the called function are in different
+ translation units, the values of all externally linked objects and of
+ all objects accessible via pointers therein would agree with the
+ abstract semantics. Furthermore, at the time of each such function
+ entry the values of the parameters of the called function and of all
+ objects accessible via pointers therein would agree with the abstract
+ semantics. In this type of implementation, objects referred to by
+ interrupt service routines activated by the signal function would
+ require explicit specification of volatile storage, as well as other
+ implementation-defined restrictions.
+
+ In executing the fragment=20
+
+ char c1, c2;
+ /*...*/
+ c1 =3D c1 + c2;
+
+ the ``integral promotions'' require that the abstract machine promote
+ the value of each variable to int size and then add the two int s and
+ truncate the sum. Provided the addition of two char s can be done
+ without creating an overflow exception, the actual execution need only
+ produce the same result, possibly omitting the promotions.
+
+ Similarly, in the fragment=20
+
+ float f1, f2;
+ double d;
+ /*...*/
+ f1 =3D f2 * d;
+
+ the multiplication may be executed using single-precision arithmetic
+ if the implementation can ascertain that the result would be the same
+ as if it were executed using double-precision arithmetic (for example,
+ if d were replaced by the constant 2.0, which has type double ).
+ Alternatively, an operation involving only int s or float s may be
+ executed using double-precision operations if neither range nor
+ precision is lost thereby.
+
+ Forward references: compound statement, or block ($3.6.2), files
+ ($4.9.3), sequence points ($3.3, $3.6), the signal function ($4.7),
+ type qualifiers ($3.5.3).
+
+
+ 2.2 ENVIRONMENTAL CONSIDERATIONS
+
+ 2.2.1 Character sets
+
+ Two sets of characters and their associated collating sequences
+ shall be defined: the set in which source files are written, and the
+ set interpreted in the execution environment. The values of the
+ members of the execution character set are implementation-defined; any
+ additional members beyond those required by this section are
+ locale-specific.
+
+ In a character constant or string literal, members of the execution
+ character set shall be represented by corresponding members of the
+ source character set or by escape sequences consisting of the
+ backslash \ followed by one or more characters. A byte with all bits
+ set to 0, called the null character, shall exist in the basic
+ execution character set; it is used to terminate a character string
+ literal.
+
+ Both the basic source and basic execution character sets shall have
+ at least the following members: the 26 upper-case letters of the
+ English alphabet
+
+ A B C D E F G H I J K L M
+ N O P Q R S T U V W X Y Z
+
+ the 26 lower-case letters of the English alphabet=20
+
+ a b c d e f g h i j k l m
+ n o p q r s t u v w x y z
+
+ the 10 decimal digits=20
+
+ 0 1 2 3 4 5 6 7 8 9
+
+ the following 29 graphic characters=20
+
+ ! " # % &amp; ' ( ) * + , - . / :
+ ; &lt; =3D &gt; ? [ \ ] ^ _ { | } ~
+
+ the space character, and control characters representing horizontal
+ tab, vertical tab, and form feed. In both the source and execution
+ basic character sets, the value of each character after 0 in the above
+ list of decimal digits shall be one greater than the value of the
+ previous. In source files, there shall be some way of indicating the
+ end of each line of text; this Standard treats such an end-of-line
+ indicator as if it were a single new-line character. In the execution
+ character set, there shall be control characters representing alert,
+ backspace, carriage return, and new line. If any other characters are
+ encountered in a source file (except in a preprocessing token that is
+ never converted to a token, a character constant, a string literal, or
+ a comment), the behavior is undefined.
+
+ Forward references: character constants ($3.1.3.4), preprocessing
+ directives ($3.8), string literals ($3.1.4), comments ($3.1.9).
+
+
+ 2.2.1.1 Trigraph sequences
+
+ All occurrences in a source file of the following sequences of
+ three characters (called trigraph sequences /5/)are replaced with the
+ corresponding single character.
+
+ ??=3D #
+ ??( [
+ ??/ \
+ ??) ]
+ ??' ^
+ ??&lt; {
+ ??! |
+ ??&gt; }
+ ??- ~
+
+ No other trigraph sequences exist. Each ? that does not begin one of
+ the trigraphs listed above is not changed.
+
+ Example
+
+ The following source line=20
+
+ printf("Eh???/n");
+
+ becomes (after replacement of the trigraph sequence ??/ )=20
+
+ printf("Eh?\n");
+
+
+ 2.2.1.2 Multibyte characters
+
+ The source character set may contain multibyte characters, used to
+ represent members of the extended character set. The execution
+ character set may also contain multibyte characters, which need not
+ have the same encoding as for the source character set. For both
+ character sets, the following shall hold:
+
+ * The single-byte characters defined in $2.2.1 shall be present. =20
+
+ * The presence, meaning, and representation of any additional members
+ is locale-specific.
+
+ * A multibyte character may have a state-dependent encoding ,wherein
+ each sequence of multibyte characters begins in an initial shift state
+ and enters other implementation-defined shift states when specific
+ multibyte characters are encountered in the sequence. While in the
+ initial shift state, all single-byte characters retain their usual
+ interpretation and do not alter the shift state. The interpretation
+ for subsequent bytes in the sequence is a function of the current
+ shift state.
+
+ * A byte with all bits zero shall be interpreted as a null character
+ independent of shift state.
+
+ * A byte with all bits zero shall not occur in the second or
+ subsequent bytes of a multibyte character.
+
+ For the source character set, the following shall hold:=20
+
+ * A comment, string literal, character constant, or header name shall
+ begin and end in the initial shift state.
+
+ * A comment, string literal, character constant, or header name shall
+ consist of a sequence of valid multibyte characters.
+
+
+ 2.2.2 Character display semantics
+
+ The active position is that location on a display device where the
+ next character output by the fputc function would appear. The intent
+ of writing a printable character (as defined by the isprint function)
+ to a display device is to display a graphic representation of that
+ character at the active position and then advance the active position
+ to the next position on the current line. The direction of printing
+ is locale-specific. If the active position is at the final position
+ of a line (if there is one), the behavior is unspecified.
+
+ Alphabetic escape sequences representing nongraphic characters in
+ the execution character set are intended to produce actions on display
+ devices as follows: ( alert ) Produces an audible or visible alert.
+ The active position shall not be changed. ( backspace ) Moves the
+ active position to the previous position on the current line. If the
+ active position is at the initial position of a line, the behavior is
+ unspecified. ( "form feed" ) Moves the active position to the initial
+ position at the start of the next logical page. ( "new line" ) Moves
+ the active position to the initial position of the next line. =20
+ ( "carriage return" ) Moves the active position to the initial position
+ of the current line. ( "horizontal tab" ) Moves the active position
+ to the next horizontal tabulation position on the current line. If
+ the active position is at or past the last defined horizontal
+ tabulation position, the behavior is unspecified. ( "vertical tab" )
+ Moves the active position to the initial position of the next vertical
+ tabulation position. If the active position is at or past the last
+ defined vertical tabulation position, the behavior is unspecified.
+
+ Each of these escape sequences shall produce a unique
+ implementation-defined value which can be stored in a single char
+ object. The external representations in a text file need not be
+ identical to the internal representations, and are outside the scope
+ of this Standard.
+
+ Forward references: the fputc function ($4.9.7.3), the isprint
+ function ($4.3.1.7).
+
+
+ 2.2.3 Signals and interrupts
+
+ Functions shall be implemented such that they may be interrupted at
+ any time by a signal, or may be called by a signal handler, or both,
+ with no alteration to earlier, but still active, invocations' control
+ flow (after the interruption), function return values, or objects with
+ automatic storage duration. All such objects shall be maintained
+ outside the function image (the instructions that comprise the
+ executable representation of a function) on a per-invocation basis.
+
+ The functions in the standard library are not guaranteed to be
+ reentrant and may modify objects with static storage duration.
+
+
+ 2.2.4 Environmental limits
+
+ Both the translation and execution environments constrain the
+ implementation of language translators and libraries. The following
+ summarizes the environmental limits on a conforming implementation.
+
+
+ 2.2.4.1 Translation limits
+
+ The implementation shall be able to translate and execute at least
+ one program that contains at least one instance of every one of the
+ following limits:/6/
+
+ * 15 nesting levels of compound statements, iteration control
+ structures, and selection control structures
+
+ * 8 nesting levels of conditional inclusion=20
+
+ * 12 pointer, array, and function declarators (in any combinations)
+ modifying an arithmetic, a structure, a union, or an incomplete type
+ in a declaration
+
+ * 31 declarators nested by parentheses within a full declarator=20
+
+ * 32 expressions nested by parentheses within a full expression=20
+
+ * 31 significant initial characters in an internal identifier or a
+ macro name
+
+ * 6 significant initial characters in an external identifier=20
+
+ * 511 external identifiers in one translation unit=20
+
+ * 127 identifiers with block scope declared in one block=20
+
+ * 1024 macro identifiers simultaneously defined in one translation unit=20
+
+ * 31 parameters in one function definition=20
+
+ * 31 arguments in one function call=20
+
+ * 31 parameters in one macro definition=20
+
+ * 31 arguments in one macro invocation=20
+
+ * 509 characters in a logical source line=20
+
+ * 509 characters in a character string literal or wide string literal
+ (after concatenation)
+
+ * 32767 bytes in an object (in a hosted environment only)=20
+
+ * 8 nesting levels for #include'd files=20
+
+ * 257 case labels for a switch statement (excluding those for any
+ nested switch statements)
+
+ * 127 members in a single structure or union=20
+
+ * 127 enumeration constants in a single enumeration=20
+
+ * 15 levels of nested structure or union definitions in a single
+ struct-declaration-list
+
+
+ 2.2.4.2 Numerical limits
+
+ A conforming implementation shall document all the limits specified
+ in this section, which shall be specified in the headers &lt;limits.h&gt;
+ and &lt;float.h&gt; .
+
+ "Sizes of integral types &lt;limits.h&gt;"
+
+ The values given below shall be replaced by constant expressions
+ suitable for use in #if preprocessing directives. Their
+ implementation-defined values shall be equal or greater in magnitude
+ (absolute value) to those shown, with the same sign.
+
+ * maximum number of bits for smallest object that is not a bit-field (byte=
+ )=20
+ CHAR_BIT 8=20
+
+ * minimum value for an object of type signed char=20
+ SCHAR_MIN -127=20
+
+ * maximum value for an object of type signed char=20
+ SCHAR_MAX +127=20
+
+ * maximum value for an object of type unsigned char=20
+ UCHAR_MAX 255=20
+
+ * minimum value for an object of type char=20
+ CHAR_MIN see below=20
+
+ * maximum value for an object of type char=20
+ CHAR_MAX see below=20
+
+ * maximum number of bytes in a multibyte character, for any supported loca=
+ le=20
+ MB_LEN_MAX 1=20
+
+ * minimum value for an object of type short int=20
+ SHRT_MIN -32767=20
+
+ * maximum value for an object of type short int=20
+ SHRT_MAX +32767=20
+
+ * maximum value for an object of type unsigned short int=20
+ USHRT_MAX 65535=20
+
+ * minimum value for an object of type int=20
+ INT_MIN -32767=20
+
+ * maximum value for an object of type int=20
+ INT_MAX +32767=20
+
+ * maximum value for an object of type unsigned int=20
+ UINT_MAX 65535=20
+
+ * minimum value for an object of type long int=20
+ LONG_MIN -2147483647=20
+
+ * maximum value for an object of type long int=20
+ LONG_MAX +2147483647=20
+
+ * maximum value for an object of type unsigned long int=20
+ ULONG_MAX 4294967295
+
+ If the value of an object of type char sign-extends when used in an
+ expression, the value of CHAR_MIN shall be the same as that of
+ SCHAR_MIN and the value of CHAR_MAX shall be the same as that of
+ SCHAR_MAX . If the value of an object of type char does not
+ sign-extend when used in an expression, the value of CHAR_MIN shall be
+ 0 and the value of CHAR_MAX shall be the same as that of UCHAR_MAX
+ ./7/
+
+ "Characteristics of floating types &lt;float.h&gt;"
+
+ delim $$ The characteristics of floating types are defined in terms
+ of a model that describes a representation of floating-point numbers
+ and values that provide information about an implementation's
+ floating-point arithmetic. The following parameters are used to
+ define the model for each floating-point type:
+
+ A normalized floating-point number x ($f sub 1$ &gt; 0 if x is defined
+ by the following model:/8/ $x~=3D~s~times~b sup e~times~sum from k=3D1 to
+ p~f sub k~times~b sup -k~,~~~e sub min~&lt;=3D~e~&lt;=3D~e sub max$
+
+ Of the values in the &lt;float.h&gt; header, FLT_RADIX shall be a
+ constant expression suitable for use in #if preprocessing directives;
+ all other values need not be constant expressions. All except
+ FLT_RADIX and FLT_ROUNDS have separate names for all three
+ floating-point types. The floating-point model representation is
+ provided for all values except FLT_ROUNDS .
+
+ The rounding mode for floating-point addition is characterized by
+ the value of FLT_ROUNDS : -1 indeterminable, 0 toward zero, 1 to nearest,
+ 2 toward positive infinity, 3 toward negative infinity. All other values
+ for FLT_ROUNDS characterize implementation-defined rounding behavior.
+
+ The values given in the following list shall be replaced by
+ implementation-defined expressions that shall be equal or greater in
+ magnitude (absolute value) to those shown, with the same sign.
+
+ * radix of exponent representation, b=20
+ FLT_RADIX 2=20
+
+ * number of base- FLT_RADIX digits in the floating-point mantissa, p=20
+
+ FLT_MANT_DIG
+ DBL_MANT_DIG
+ LDBL_MANT_DIG
+
+
+
+ * number of decimal digits of precision, $left floor~(p~-~1)~times~{
+ log sub 10 } b~right floor ~+~ left { lpile { 1 above 0 } ~~ lpile {
+ roman "if " b roman " is a power of 10" above roman otherwise }$
+
+ FLT_DIG 6
+ DBL_DIG 10
+ LDBL_DIG 10
+
+
+
+ * minimum negative integer such that FLT_RADIX raised to that power
+ minus 1 is a normalized floating-point number, $e sub min$
+
+ FLT_MIN_EXP
+ DBL_MIN_EXP
+ LDBL_MIN_EXP
+
+
+
+ * minimum negative integer such that 10 raised to that power is in
+ the range of normalized floating-point numbers,
+
+ FLT_MIN_10_EXP -37
+ DBL_MIN_10_EXP -37
+ LDBL_MIN_10_EXP -37
+
+
+
+ * maximum integer such that FLT_RADIX raised to that power minus 1 is
+ a representable finite floating-point number, $e sub max$
+
+ FLT_MAX_EXP
+ DBL_MAX_EXP
+ LDBL_MAX_EXP
+
+
+
+ * maximum integer such that 10 raised to that power is in the range
+ of representable finite floating-point numbers,
+
+ FLT_MAX_10_EXP +37
+ DBL_MAX_10_EXP +37
+ LDBL_MAX_10_EXP +37
+
+
+ The values given in the following list shall be replaced by
+ implementation-defined expressions with values that shall be equal to
+ or greater than those shown.
+
+ * maximum representable finite floating-point number,=20
+
+ FLT_MAX 1E+37
+ DBL_MAX 1E+37
+ LDBL_MAX 1E+37
+
+
+ The values given in the following list shall be replaced by
+ implementation-defined expressions with values that shall be equal to
+ or smaller than those shown.
+
+ * minimum positive floating-point number x such that 1.0 + x=20
+
+ FLT_EPSILON 1E-5
+ DBL_EPSILON 1E-9
+ LDBL_EPSILON 1E-9
+
+
+
+ * minimum normalized positive floating-point number, $b sup { e sub
+ min - 1 }$
+
+ FLT_MIN 1E-37
+ DBL_MIN 1E-37
+ LDBL_MIN 1E-37
+
+
+
+ Examples
+
+ The following describes an artificial floating-point representation
+ that meets the minimum requirements of the Standard, and the
+ appropriate values in a &lt;float.h&gt; header for type float :
+ $x~=3D~s~times~16 sup e~times~sum from k=3D1 to 6~f sub k~times~16 sup
+ -k~,~~~-31~&lt;=3D~e~&lt;=3D~+32$
+ =20
+
+ FLT_RADIX 16
+ FLT_MANT_DIG 6
+ FLT_EPSILON 9.53674316E-07F
+ FLT_DIG 6
+ FLT_MIN_EXP -31
+ FLT_MIN 2.93873588E-39F
+ FLT_MIN_10_EXP -38
+ FLT_MAX_EXP +32
+ FLT_MAX 3.40282347E+38F
+ FLT_MAX_10_EXP +38
+
+
+ The following describes floating-point representations that also
+ meet the requirements for single-precision and double-precision
+ normalized numbers in the IEEE Standard for Binary Floating-Point
+ Arithmetic (ANSI/IEEE Std 754-1985),/9/ b and the appropriate values
+ in a &lt;float.h&gt; header for types float and double : $x sub
+ f~=3D~s~times~2 sup e~times~{ sum from k=3D1 to 24~f sub k~times~2 sup -k
+ },~~~-125~&lt;=3D~e~&lt;=3D~+128$ $x sub d~=3D~s~times~2 sup e~times~{ sum =
+ from
+ k=3D1 to 53~f sub k~times~2 sup -k },~~~-1021~&lt;=3D~e~&lt;=3D~+1024$
+ =20
+
+ FLT_RADIX 2
+ FLT_MANT_DIG 24
+ FLT_EPSILON 1.19209290E-07F
+ FLT_DIG 6
+ FLT_MIN_EXP -125
+ FLT_MIN 1.17549435E-38F
+ FLT_MIN_10_EXP -37
+ FLT_MAX_EXP +128
+ FLT_MAX 3.40282347E+38F
+ FLT_MAX_10_EXP +38
+ DBL_MANT_DIG 53
+ DBL_EPSILON 2.2204460492503131E-16
+ DBL_DIG 15
+ DBL_MIN_EXP -1021
+ DBL_MIN 2.2250738585072016E-308
+ DBL_MIN_10_EXP -307
+ DBL_MAX_EXP +1024
+ DBL_MAX 1.7976931348623157E+308
+ DBL_MAX_10_EXP +308
+
+
+ The values shown above for FLT_EPSILON and DBL_EPSILON are
+ appropriate for the ANSI/IEEE Std 754-1985 default rounding mode (to
+ nearest). Their values may differ for other rounding modes.
+
+ Forward references: conditional inclusion ($3.8.1). conditional
+ inclusion ($3.8.1).
+
+
+ 3. LANGUAGE
+
+ In the syntax notation used in the language section ($3), syntactic
+ categories (nonterminals) are indicated by italic type, and literal
+ words and character set members (terminals) by bold type. A colon (:)
+ following a nonterminal introduces its definition. Alternative
+ definitions are listed on separate lines, except when prefaced by the
+ words ``one of.'' An optional symbol is indicated by the so that
+
+ { expression&lt;opt&gt; }
+
+ indicates an optional expression enclosed in braces. =20
+
+ 3.1 LEXICAL ELEMENTS
+
+
+ Syntax
+
+ token:
+ keyword
+ identifier
+ constant
+ string-literal
+ operator
+ punctuator
+
+ preprocessing-token:
+ header-name
+ identifier
+ pp-number
+ character-constant
+ string-literal
+ operator
+ punctuator
+ each non-white-space character that cannot be one of
+ the above
+
+
+
+ Constraints
+
+ Each preprocessing token that is converted to a token shall have
+ the lexical form of a keyword, an identifier, a constant, a string
+ literal, an operator, or a punctuator.
+
+ Semantics
+
+ A token is the minimal lexical element of the language in
+ translation phases 7 and 8. The categories of tokens are: keywords,
+ identifiers, constants, string literals, operators, and punctuators.
+ A preprocessing token is the minimal lexical element of the language
+ in translation phases 3 through 6. The categories of preprocessing
+ token are: header names, identifiers, preprocessing numbers,
+ character constants, string literals, operators, punctuators, and
+ single non-white-space characters that do not lexically match the
+ other preprocessing token categories. If a ' or a " character matches
+ the last category, the behavior is undefined. Comments (described
+ later) and the characters space, horizontal tab, new-line, vertical
+ tab, and form-feed---collectively called white space ---canseparate
+ preprocessing tokens. As described in $3.8, in certain circumstances
+ during translation phase 4, white space (or the absence thereof)
+ serves as more than preprocessing token separation. White space may
+ appear within a preprocessing token only as part of a header name or
+ between the quotation characters in a character constant or string
+ literal.
+
+ If the input stream has been parsed into preprocessing tokens up to
+ a given character, the next preprocessing token is the longest
+ sequence of characters that could constitute a preprocessing token.
+
+ Examples
+
+ The program fragment 1Ex is parsed as a preprocessing number token
+ (one that is not a valid floating or integer constant token), even
+ though a parse as the pair of preprocessing tokens 1 and Ex might
+ produce a valid expression (for example, if Ex were a macro defined as
+ +1 ). Similarly, the program fragment 1E1 is parsed as a
+ preprocessing number (one that is a valid floating constant token),
+ whether or not E is a macro name.
+
+ The program fragment x+++++y is parsed as x ++ ++ + y, which
+ violates a constraint on increment operators, even though the parse x
+ ++ + ++ y might yield a correct expression.
+
+ Forward references: character constants ($3.1.3.4), comments ($3.1.9),
+ expressions ($3.3), floating constants ($3.1.3.1), header names
+ ($3.1.7), macro replacement ($3.8.3), postfix increment and decrement
+ operators ($3.3.2.4), prefix increment and decrement operators
+ ($3.3.3.1), preprocessing directives ($3.8), preprocessing numbers
+ ($3.1.8), string literals ($3.1.4).
+
+
+ 3.1.1 Keywords
+
+ Syntax
+
+ keyword: one of
+
+ auto double int struct
+ break else long switch
+ case enum register typedef
+ char extern return union
+ const float short unsigned
+ continue for signed void
+ default goto sizeof volatile
+ do if static while
+
+
+
+ Semantics
+
+ The above tokens (entirely in lower-case) are reserved (in
+ translation phases 7 and 8) for use as keywords, and shall not be used
+ otherwise.
+
+
+ 3.1.2 Identifiers
+
+ Syntax
+
+ identifier:
+ nondigit
+ identifier nondigit
+ identifier digit
+
+
+
+ nondigit: one of
+ _ a b c d e f g h i j k l m
+ n o p q r s t u v w x y z
+ A B C D E F G H I J K L M
+ N O P Q R S T U V W X Y Z
+
+
+
+ digit: one of
+ 0 1 2 3 4 5 6 7 8 9
+
+
+
+ Description
+
+ An identifier is a sequence of nondigit characters (including the
+ underscore _ and the lower-case and upper-case letters) and digits.
+ The first character shall be a nondigit character.
+
+ Constraints
+
+ In translation phases 7 and 8, an identifier shall not consist of
+ the same sequence of characters as a keyword.
+
+ Semantics
+
+ An identifier denotes an object, a function, or one of the
+ following entities that will be described later: a tag or a member of
+ a structure, union, or enumeration; a typedef name; a label name; a
+ macro name; or a macro parameter. A member of an enumeration is
+ called an enumeration constant. Macro names and macro parameters are
+ not considered further here, because prior to the semantic phase of
+ program translation any occurrences of macro names in the source file
+ are replaced by the preprocessing token sequences that constitute
+ their macro definitions.
+
+ There is no specific limit on the maximum length of an identifier. =20
+
+ "Implementation limits"
+
+ The implementation shall treat at least the first 31 characters of
+ an internal name (a macro name or an identifier that does not have
+ external linkage) as significant. Corresponding lower-case and
+ upper-case letters are different. The implementation may further
+ restrict the significance of an external name (an identifier that has
+ external linkage) to six characters and may ignore distinctions of
+ alphabetical case for such names./10/ These limitations on identifiers
+ are all implementation-defined.
+
+ Any identifiers that differ in a significant character are
+ different identifiers. If two identifiers differ in a non-significant
+ character, the behavior is undefined.
+
+ Forward references: linkages of identifiers ($3.1.2.2), macro
+ replacement ($3.8.3).
+
+
+ 3.1.2.1 Scopes of identifiers
+
+ An identifier is visible (i.e., can be used) only within a region
+ of program text called its scope . There are four kinds of scopes:
+ function, file, block, and function prototype. (A function prototype
+ is a declaration of a function that declares the types of its
+ parameters.)
+
+ A label name is the only kind of identifier that has function scope.
+ It can be used (in a goto statement) anywhere in the function in
+ which it appears, and is declared implicitly by its syntactic
+ appearance (followed by a : and a statement). Label names shall be
+ unique within a function.
+
+ Every other identifier has scope determined by the placement of its
+ declaration (in a declarator or type specifier). If the declarator or
+ type specifier that declares the identifier appears outside of any
+ block or list of parameters, the identifier has file scope, which
+ terminates at the end of the translation unit. If the declarator or
+ type specifier that declares the identifier appears inside a block or
+ within the list of parameter declarations in a function definition,
+ the identifier has block scope, which terminates at the } that closes
+ the associated block. If the declarator or type specifier that
+ declares the identifier appears within the list of parameter
+ declarations in a function prototype (not part of a function
+ definition), the identifier has function prototype scope ,which
+ terminates at the end of the function declarator. If an outer
+ declaration of a lexically identical identifier exists in the same
+ name space, it is hidden until the current scope terminates, after
+ which it again becomes visible.
+
+ Structure, union, and enumeration tags have scope that begins just
+ after the appearance of the tag in a type specifier that declares the
+ tag. Each enumeration constant has scope that begins just after the
+ appearance of its defining enumerator in an enumerator list. Any
+ other identifier has scope that begins just after the completion of
+ its declarator.
+
+ Forward references: compound statement, or block ($3.6.2),
+ declarations ($3.5), enumeration specifiers ($3.5.2.2), function calls
+ ($3.3.2.2), function declarators (including prototypes) ($3.5.4.3),
+ function definitions ($3.7.1), the goto statement ($3.6.6.1), labeled
+ statements ($3.6.1), name spaces of identifiers ($3.1.2.3), scope of
+ macro definitions ($3.8.3.5), source file inclusion ($3.8.2), tags
+ ($3.5.2.3), type specifiers ($3.5.2).
+
+ 3.1.2.2 Linkages of identifiers
+
+ An identifier declared in different scopes or in the same scope
+ more than once can be made to refer to the same object or function by
+ a process called linkage . There are three kinds of linkage: external,
+ internal, and none.
+
+ In the set of translation units and libraries that constitutes an
+ entire program, each instance of a particular identifier with external
+ linkage denotes the same object or function. Within one translation
+ unit, each instance of an identifier with internal linkage denotes the
+ same object or function. Identifiers with no linkage denote unique
+ entities.
+
+ If the declaration of an identifier for an object or a function has
+ file scope and contains the storage-class specifier static, the
+ identifier has internal linkage.
+
+ If the declaration of an identifier for an object or a function
+ contains the storage-class specifier extern , the identifier has the
+ same linkage as any visible declaration of the identifier with file
+ scope. If there is no visible declaration with file scope, the
+ identifier has external linkage.
+
+ If the declaration of an identifier for a function has no
+ storage-class specifier, its linkage is determined exactly as if it
+ were declared with the storage-class specifier extern . If the
+ declaration of an identifier for an object has file scope and no
+ storage-class specifier, its linkage is external.
+
+ The following identifiers have no linkage: an identifier declared
+ to be anything other than an object or a function; an identifier
+ declared to be a function parameter; an identifier declared to be an
+ object inside a block without the storage-class specifier extern.
+
+ If, within a translation unit, the same identifier appears with
+ both internal and external linkage, the behavior is undefined.
+
+ Forward references: compound statement, or block ($3.6.2),
+ declarations ($3.5), expressions ($3.3), external definitions ($3.7).
+
+
+ 3.1.2.3 Name spaces of identifiers
+
+ If more than one declaration of a particular identifier is visible
+ at any point in a translation unit, the syntactic context
+ disambiguates uses that refer to different entities. Thus, there are
+ separate name spaces for various categories of identifiers, as
+ follows:
+
+ * label names (disambiguated by the syntax of the label declaration
+ and use);
+
+ * the tags of structures, unions, and enumerations (disambiguated by
+ following any/11/ of the keywords struct , union , or enum );
+
+ * the members of structures or unions; each structure or union has a
+ separate name space for its members (disambiguated by the type of the
+ expression used to access the member via the . or -&gt; operator);
+
+ * all other identifiers, called ordinary identifiers (declared in
+ ordinary declarators or as enumeration constants).
+
+ Forward references: declarators ($3.5.4), enumeration specifiers
+ ($3.5.2.2), labeled statements ($3.6.1), structure and union
+ specifiers ($3.5.2.1), structure and union members ($3.3.2.3), tags
+ ($3.5.2.3).
+
+
+ 3.1.2.4 Storage durations of objects
+
+ An object has a storage duration that determines its lifetime.
+ There are two storage durations: static and automatic.
+
+ An object declared with external or internal linkage, or with the
+ storage-class specifier static has static storage duration. For such
+ an object, storage is reserved and its stored value is initialized
+ only once, prior to program startup. The object exists and retains
+ its last-stored value throughout the execution of the entire
+ program./12/
+
+ An object declared with no linkage and without the storage-class
+ specifier static has automatic storage duration. Storage is guaranteed
+ to be reserved for a new instance of such an object on each normal
+ entry into the block in which it is declared, or on a jump from
+ outside the block to a label in the block or in an enclosed block. If
+ an initialization is specified for the value stored in the object, it
+ is performed on each normal entry, but not if the block is entered by
+ a jump to a label. Storage for the object is no longer guaranteed to
+ be reserved when execution of the block ends in any way. (Entering an
+ enclosed block suspends but does not end execution of the enclosing
+ block. Calling a function that returns suspends but does not end
+ execution of the block containing the call.) The value of a pointer
+ that referred to an object with automatic storage duration that is no
+ longer guaranteed to be reserved is indeterminate.
+
+ Forward references: compound statement, or block ($3.6.2), function
+ calls ($3.3.2.2), initialization ($3.5.7).
+
+
+ 3.1.2.5 Types
+
+ The meaning of a value stored in an object or returned by a
+ function is determined by the type of the expression used to access
+ it. (An identifier declared to be an object is the simplest such
+ expression; the type is specified in the declaration of the
+ identifier.) Types are partitioned into object types (types that
+ describe objects), function types (types that describe functions), and
+ incomplete types (types that describe objects but lack information
+ needed to determine their sizes).
+
+ An object declared as type char is large enough to store any member
+ of the basic execution character set. If a member of the required
+ source character set enumerated in $2.2.1 is stored in a char object,
+ its value is guaranteed to be positive. If other quantities are
+ stored in a char object, the behavior is implementation-defined: the
+ values are treated as either signed or nonnegative integers.
+
+ There are four signed integer types, designated as signed char,=20
+ short int, int, and long int. (The signed integer and other types
+ may be designated in several additional ways, as described in $3.5.2.)
+
+ An object declared as type signed char occupies the same amount of
+ storage as a ``plain'' char object. A ``plain'' int object has the
+ natural size suggested by the architecture of the execution
+ environment (large enough to contain any value in the range INT_MIN to
+ INT_MAX as defined in the header &lt;limits.h&gt; ). In the list of signed
+ integer types above, the range of values of each type is a subrange of
+ the values of the next type in the list.
+
+ For each of the signed integer types, there is a corresponding (but
+ different) unsigned integer type (designated with the keyword unsigned)=20
+ that uses the same amount of storage (including sign information)
+ and has the same alignment requirements. The range of nonnegative
+ values of a signed integer type is a subrange of the corresponding
+ unsigned integer type, and the representation of the same value in
+ each type is the same. A computation involving unsigned operands can
+ never overflow, because a result that cannot be represented by the
+ resulting unsigned integer type is reduced modulo the number that is
+ one greater than the largest value that can be represented by the
+ resulting unsigned integer type.
+
+ There are three floating types, designated as float , double , and
+ long double . The set of values of the type float is a subset of the
+ set of values of the type double ; the set of values of the type
+ double is a subset of the set of values of the type long double.
+
+ The type char, the signed and unsigned integer types, and the
+ floating types are collectively called the basic types. Even if the
+ implementation defines two or more basic types to have the same
+ representation, they are nevertheless different types.
+
+ There are three character types, designated as char , signed char ,
+ and unsigned char.
+
+ An enumeration comprises a set of named integer constant values.
+ Each distinct enumeration constitutes a different enumerated type.
+
+ The void type comprises an empty set of values; it is an incomplete
+ type that cannot be completed.
+
+ Any number of derived types can be constructed from the basic,
+ enumerated, and incomplete types, as follows:
+
+ * An array type describes a contiguously allocated set of objects
+ with a particular member object type, called the element type .Array
+ types are characterized by their element type and by the number of
+ members of the array. An array type is said to be derived from its
+ element type, and if its element type is T , the array type is
+ sometimes called ``array of T .'' The construction of an array type
+ from an element type is called ``array type derivation.''
+
+ * A structure type describes a sequentially allocated set of member
+ objects, each of which has an optionally specified name and possibly
+ distinct type.
+
+ * A union type describes an overlapping set of member objects, each
+ of which has an optionally specified name and possibly distinct type.
+
+ * A function type describes a function with specified return type. A=20
+ function type is characterized by its return type and the number and
+ types of its parameters. A function type is said to be derived from
+ its return type, and if its return type is T , the function type is
+ sometimes called ``function returning T.'' The construction of a
+ function type from a return type is called ``function type
+ derivation.''
+
+ * A pointer type may be derived from a function type, an object type,
+ or an incomplete type, called the referenced type. A pointer type
+ describes an object whose value provides a reference to an entity of
+ the referenced type. A pointer type derived from the referenced type
+ T is sometimes called ``pointer to T .'' The construction of a pointer
+ type from a referenced type is called ``pointer type derivation.''
+
+ These methods of constructing derived types can be applied
+ recursively.
+
+ The type char, the signed and unsigned integer types, and the
+ enumerated types are collectively called integral types. The
+ representations of integral types shall define values by use of a pure
+ binary numeration system./13/ American National Dictionary for
+ Information Processing Systems.) The representations of floating types
+ are unspecified.
+
+ Integral and floating types are collectively called arithmetic
+ types. Arithmetic types and pointer types are collectively called
+ scalar types. Array and structure types are collectively called
+ aggregate types. /14/
+
+ A pointer to void shall have the same representation and alignment
+ requirements as a pointer to a character type. Other pointer types
+ need not have the same representation or alignment requirements.
+
+ An array type of unknown size is an incomplete type. It is
+ completed, for an identifier of that type, by specifying the size in a
+ later declaration (with internal or external linkage). A structure or
+ union type of unknown content (as described in $3.5.2.3) is an
+ incomplete type. It is completed, for all declarations of that type,
+ by declaring the same structure or union tag with its defining content
+ later in the same scope.
+
+ Array, function, and pointer types are collectively called derived
+ declarator types. A declarator type derivation from a type T is the
+ construction of a derived declarator type from T by the application of
+ an array, a function, or a pointer type derivation to T.
+
+ A type is characterized by its top type, which is either the first
+ type named in describing a derived type (as noted above in the
+ construction of derived types), or the type itself if the type
+ consists of no derived types.
+
+ A type has qualified type if its top type is specified with a type
+ qualifier; otherwise it has unqualified type. The type qualifiers
+ const and volatile respectively designate const-qualified type and
+ volatile-qualified type. /15/ For each qualified type there is an
+ unqualified type that is specified the same way as the qualified type,
+ but without any type qualifiers in its top type. This type is known
+ as the unqualified version of the qualified type. Similarly, there
+ are appropriately qualified versions of types (such as a
+ const-qualified version of a type), just as there are appropriately
+ non-qualified versions of types (such as a non-const-qualified version
+ of a type).
+
+ Examples
+
+ The type designated as ``float *'' is called ``pointer to float''
+ and its top type is a pointer type, not a floating type. The
+ const-qualified version of this type is designated as ``float * const''
+ whereas the type designated as `` const float * '' is not a
+ qualified type --- it is called ``pointer to const float '' and is a
+ pointer to a qualified type.
+
+ Finally, the type designated as `` struct tag (*[5])(float) '' is
+ called ``array of pointer to function returning struct tag.'' Its top
+ type is array type. The array has length five and the function has a
+ single parameter of type float.=20
+
+ Forward references: character constants ($3.1.3.4), declarations
+ ($3.5), tags ($3.5.2.3), type qualifiers ($3.5.3).
+
+
+ 3.1.2.6 Compatible type and composite type
+
+ Two types have compatible type if their types are the same.
+ Additional rules for determining whether two types are compatible are
+ described in $3.5.2 for type specifiers, in $3.5.3 for type
+ qualifiers, and in $3.5.4 for declarators. /16/ Moreover, two
+ structure, union, or enumeration types declared in separate
+ translation units are compatible if they have the same number of
+ members, the same member names, and compatible member types; for two
+ structures, the members shall be in the same order; for two
+ enumerations, the members shall have the same values.
+
+ All declarations that refer to the same object or function shall
+ have compatible type; otherwise the behavior is undefined.
+
+ A composite type can be constructed from two types that are
+ compatible; it is a type that is compatible with both of the two types
+ and has the following additions:
+
+ * If one type is an array of known size, the composite type is an
+ array of that size.
+
+ * If only one type is a function type with a parameter type list (a
+ function prototype), the composite type is a function prototype with
+ the parameter type list.
+
+ * If both types have parameter type lists, the type of each parameter
+ in the composite parameter type list is the composite type of the
+ corresponding parameters.
+
+ These rules apply recursively to the types from which the two types
+ are derived.
+
+ For an identifier with external or internal linkage declared in the
+ same scope as another declaration for that identifier, the type of the
+ identifier becomes the composite type.
+
+ Example
+
+ Given the following two file scope declarations:=20
+
+ int f(int (*)(), double (*)[3]);
+ int f(int (*)(char *), double (*)[]);
+
+ The resulting composite type for the function is:=20
+
+ int f(int (*)(char *), double (*)[3]);
+
+ Forward references: declarators ($3.5.4), enumeration specifiers
+ ($3.5.2.2), structure and union specifiers ($3.5.2.1), type
+ definitions ($3.5.6), type qualifiers ($3.5.3), type specifiers
+ ($3.5.2).
+
+
+ 3.1.3 Constants
+
+ Syntax
+
+ constant:
+ floating-constant
+ integer-constant
+ enumeration-constant
+ character-constant
+
+ Constraints
+
+ The value of a constant shall be in the range of representable
+ values for its type.
+
+ Semantics
+
+ Each constant has a type, determined by its form and value, as
+ detailed later.
+
+
+ 3.1.3.1 Floating constants
+
+ Syntax
+
+ floating-constant:
+ fractional-constant exponent-part&lt;opt&gt; floating-suf=
+ fix&lt;opt&gt;
+ digit-sequence exponent-part floating-suffix&lt;opt&gt;
+
+ fractional-constant:
+ digit-sequence&lt;opt&gt;.digit-sequence
+ digit-sequence.
+
+ exponent-part:
+ e sign&lt;opt&gt; digit-sequence
+ E sign&lt;opt&gt; digit-sequence
+
+ sign: one of
+ + -
+
+ digit-sequence:
+ digit
+ digit-sequence digit
+
+ floating-suffix: one of
+ f l F L
+
+ Description
+
+ A floating constant has a value part that may be followed by an
+ exponent part and a suffix that specifies its type. The components of
+ the value part may include a digit sequence representing the
+ whole-number part, followed by a period (.), followed by a digit
+ sequence representing the fraction part. The components of the
+ exponent part are an e or E followed by an exponent consisting of an
+ optionally signed digit sequence. Either the whole-number part or the
+ fraction part shall be present; either the period or the exponent part
+ shall be present.
+
+ Semantics
+
+ The value part is interpreted as a decimal rational number; the
+ digit sequence in the exponent part is interpreted as a decimal
+ integer. The exponent indicates the power of 10 by which the value
+ part is to be scaled. If the scaled value is in the range of
+ representable values (for its type) but cannot be represented exactly,
+ the result is either the nearest higher or nearest lower value, chosen
+ in an implementation-defined manner.
+
+ An unsuffixed floating constant has type double. If suffixed by
+ the letter f or F, it has type float. If suffixed by the letter l
+ or L, it has type long double.
+
+
+ 3.1.3.2 Integer constants
+
+ Syntax
+
+ integer-constant:
+ decimal-constant integer-suffix&lt;opt&gt;
+ octal-constant integer-suffix&lt;opt&gt;
+ hexadecimal-constant integer-suffix&lt;opt&gt;
+
+ decimal-constant:
+ nonzero-digit
+ decimal-constant digit
+
+ octal-constant:
+ 0=20
+ octal-constant octal-digit
+
+ hexadecimal-constant:
+ 0x hexadecimal-digit
+ 0X hexadecimal-digit
+ hexadecimal-constant hexadecimal-digit
+
+ nonzero-digit: one of
+ 1 2 3 4 5 6 7 8 9
+
+ octal-digit: one of
+ 0 1 2 3 4 5 6 7
+
+ hexadecimal-digit: one of
+ 0 1 2 3 4 5 6 7 8 9
+ a b c d e f
+ A B C D E F
+
+ integer-suffix:
+ unsigned-suffix long-suffix&lt;opt&gt;
+ long-suffix unsigned-suffix&lt;opt&gt;
+
+ unsigned-suffix: one of
+ u U
+
+ long-suffix: one of
+ l L
+
+ Description
+
+ An integer constant begins with a digit, but has no period or
+ exponent part. It may have a prefix that specifies its base and a
+ suffix that specifies its type.
+
+ A decimal constant begins with a nonzero digit and consists of a
+ sequence of decimal digits. An octal constant consists of the prefix
+ 0 optionally followed by a sequence of the digits 0 through 7 only. A
+ hexadecimal constant consists of the prefix 0x or 0X followed by a
+ sequence of the decimal digits and the letters a (or A ) through f (or
+ F) with values 10 through 15 respectively.
+
+ Semantics
+
+ The value of a decimal constant is computed base 10; that of an
+ octal constant, base 8; that of a hexadecimal constant, base 16. The
+ lexically first digit is the most significant.
+
+ The type of an integer constant is the first of the corresponding
+ list in which its value can be represented. Unsuffixed decimal: int,
+ long int, unsigned long int; unsuffixed octal or hexadecimal: int,
+ unsigned int, long int, unsigned long int; suffixed by the letter u
+ or U: unsigned int, unsigned long int; suffixed by the letter l or
+ L: long int, unsigned long int; suffixed by both the letters u or U
+ and l or L: unsigned long int .
+
+
+ 3.1.3.3 Enumeration constants
+
+ Syntax
+
+ enumeration-constant:
+ identifier
+
+ Semantics
+
+ An identifier declared as an enumeration constant has type int. =20
+
+ Forward references: enumeration specifiers ($3.5.2.2). =20
+
+
+ 3.1.3.4 Character constants
+
+ Syntax
+
+ character-constant:
+ ' c-char-sequence'=20
+ L' c-char-sequence'=20
+
+ c-char-sequence:
+ c-char
+ c-char-sequence c-char
+
+ c-char:
+ any member of the source character set except
+ the single-quote ', backslash \, or new-line character
+ escape-sequence
+
+ escape-sequence:
+ simple-escape-sequence
+ octal-escape-sequence
+ hexadecimal-escape-sequence
+
+ simple-escape-sequence: one of
+ \' \" \? \\
+ \a \b \f \n \r \t \v
+
+ octal-escape-sequence:
+ \ octal-digit
+ \ octal-digit octal-digit
+ \ octal-digit octal-digit octal-digit
+
+ hexadecimal-escape-sequence:
+ \x hexadecimal-digit
+ hexadecimal-escape-sequence hexadecimal-digit
+
+
+
+ Description
+
+ An integer character constant is a sequence of one or more
+ multibyte characters enclosed in single-quotes, as in 'x' or 'ab'. A
+ wide character constant is the same, except prefixed by the letter L .
+ With a few exceptions detailed later, the elements of the sequence are
+ any members of the source character set; they are mapped in an
+ implementation-defined manner to members of the execution character
+ set.
+
+ The single-quote ', the double-quote , the question-mark ?, the
+ backslash \ , and arbitrary integral values, are representable
+ according to the following table of escape sequences:
+
+ single-quote ' \'
+ double-quote " \"
+ question-mark ? \?
+ backslash \ \\
+ octal integer \ octal digits
+ hexadecimal integer \x hexadecimal digits
+
+ The double-quote and question-mark ? are representable either by
+ themselves or by the escape sequences \" and \? respectively, but the
+ single-quote ' and the backslash \ shall be represented, respectively,
+ by the escape sequences \' and \\ .
+
+ The octal digits that follow the backslash in an octal escape
+ sequence are taken to be part of the construction of a single
+ character for an integer character constant or of a single wide
+ character for a wide character constant. The numerical value of the
+ octal integer so formed specifies the value of the desired character.
+
+ The hexadecimal digits that follow the backslash and the letter x
+ in a hexadecimal escape sequence are taken to be part of the
+ construction of a single character for an integer character constant
+ or of a single wide character for a wide character constant. The
+ numerical value of the hexadecimal integer so formed specifies the
+ value of the desired character.
+
+ Each octal or hexadecimal escape sequence is the longest sequence
+ of characters that can constitute the escape sequence.
+
+ In addition, certain nongraphic characters are representable by
+ escape sequences consisting of the backslash \ followed by a
+ lower-case letter: \a , \b , \f , \n , \r , \t , and \v ./17/ If any
+ other escape sequence is encountered, the behavior is undefined./18/
+
+ Constraints
+
+ The value of an octal or hexadecimal escape sequence shall be in
+ the range of representable values for the unsigned type corresponding
+ to its type.
+
+ Semantics
+
+ An integer character constant has type int. The value of an
+ integer character constant containing a single character that maps
+ into a member of the basic execution character set is the numerical
+ value of the representation of the mapped character interpreted as an
+ integer. The value of an integer character constant containing more
+ than one character, or containing a character or escape sequence not
+ represented in the basic execution character set, is
+ implementation-defined. In particular, in an implementation in which
+ type char has the same range of values as signed char, the high-order
+ bit position of a single-character integer character constant is
+ treated as a sign bit.
+
+ A wide character constant has type wchar_t , an integral type
+ defined in the &lt;stddef.h&gt; header. The value of a wide character
+ constant containing a single multibyte character that maps into a
+ member of the extended execution character set is the wide character
+ (code) corresponding to that multibyte character, as defined by the
+ mbtowc function, with an implementation-defined current locale. The
+ value of a wide character constant containing more than one multibyte
+ character, or containing a multibyte character or escape sequence not
+ represented in the extended execution character set, is
+ implementation-defined.
+
+ Examples
+
+ The construction '\0' is commonly used to represent the null character.
+
+ Consider implementations that use two's-complement representation
+ for integers and eight bits for objects that have type char. In an
+ implementation in which type char has the same range of values as
+ signed char, the integer character constant '\xFF' has the value if
+ type char has the same range of values as unsigned char, the
+ character constant '\xFF' has the value
+
+ Even if eight bits are used for objects that have type char , the
+ construction '\x123' specifies an integer character constant
+ containing only one character. (The value of this single-character
+ integer character constant is implementation-defined and violates the
+ above constraint.) To specify an integer character constant containing
+ the two characters whose values are 0x12 and '3', the construction
+ '\0223' may be used, since a hexadecimal escape sequence is terminated
+ only by a non-hexadecimal character. (The value of this two-character
+ integer character constant is implementation-defined also.)
+
+ Even if 12 or more bits are used for objects that have type wchar_t,
+ the construction L'\1234' specifies the implementation-defined value
+ that results from the combination of the values 0123 and '4'.
+
+ Forward references: characters and integers ($3.2.1.1) common
+ definitions &lt;stddef.h&gt; ($4.1.5), the mbtowc function ($4.10.7.2).
+
+
+ 3.1.4 String literals
+
+ Syntax
+
+ string-literal:
+ " s-char-sequence&lt;opt&gt;"
+ L" s-char-sequence&lt;opt&gt;"
+
+ s-char-sequence:
+ s-char
+ s-char-sequence s-char
+
+ s-char:
+ any member of the source character set except
+ the double-quote ", backslash \, or new-line character
+ escape-sequence
+
+ Description
+
+ A character string literal is a sequence of zero or more multibyte
+ characters enclosed in double-quotes, as in xyz. A wide string
+ literal is the same, except prefixed by the letter L.
+
+ The same considerations apply to each element of the sequence in a
+ character string literal or a wide string literal as if it were in an
+ integer character constant or a wide character constant, except that
+ the single-quote ' is representable either by itself or by the escape
+ sequence \', but the double-quote shall be represented by the escape
+ sequence \.
+
+ Semantics
+
+ A character string literal has static storage duration and type
+ ``array of char ,'' and is initialized with the given characters. A
+ wide string literal has static storage duration and type ``array of
+ wchar_t,'' and is initialized with the wide characters corresponding
+ to the given multibyte characters. Character string literals that are
+ adjacent tokens are concatenated into a single character string
+ literal. A null character is then appended. /19/ Likewise, adjacent
+ wide string literal tokens are concatenated into a single wide string
+ literal to which a code with value zero is then appended. If a
+ character string literal token is adjacent to a wide string literal
+ token, the behavior is undefined.
+
+ Identical string literals of either form need not be distinct. If
+ the program attempts to modify a string literal of either form, the
+ behavior is undefined.
+
+ Example
+
+ This pair of adjacent character string literals=20
+
+ "\x12" "3"
+
+ produces a single character string literal containing the two
+ characters whose values are \x12 and '3', because escape sequences are
+ converted into single members of the execution character set just
+ prior to adjacent string literal concatenation.
+
+ Forward references: common definitions &lt;stddef.h&gt; ($4.1.5). =20
+
+
+ 3.1.5 Operators
+
+ Syntax
+
+ operator: one of
+ [ ] ( ) . -&gt;
+ ++ -- &amp; * + - ~ ! sizeof
+ / % &lt;&lt; &gt;&gt; &lt; &gt; &lt;=3D &gt;=3D =
+ =3D=3D !=3D ^ | &amp;&amp; ||
+ ? :
+ =3D *=3D /=3D %=3D +=3D -=3D &lt;&lt;=3D &gt;&gt;=
+ =3D &amp;=3D ^=3D |=3D
+ , # ##
+
+ Constraints
+
+ The operators [ ] , ( ) , and ? : shall occur in pairs, possibly
+ separated by expressions. The operators # and ## shall occur in
+ macro-defining preprocessing directives only.
+
+ Semantics
+
+ An operator specifies an operation to be performed (an evaluation )
+ that yields a value, or yields a designator, or produces a side
+ effect, or a combination thereof. An operand is an entity on which an
+ operator acts.
+
+ Forward references: expressions ($3.3), macro replacement ($3.8.3). =20
+
+ 3.1.6 Punctuators
+
+
+ Syntax
+
+ punctuator: one of
+ [ ] ( ) { } * , : =3D ; ... #
+
+ Constraints
+
+ The punctuators [ ] , ( ) , and { } shall occur in pairs, possibly
+ separated by expressions, declarations, or statements. The punctuator
+ # shall occur in preprocessing directives only.
+
+ Semantics
+
+ A punctuator is a symbol that has independent syntactic and
+ semantic significance but does not specify an operation to be
+ performed that yields a value. Depending on context, the same symbol
+ may also represent an operator or part of an operator.
+
+ Forward references: expressions ($3.3), declarations ($3.5),
+ preprocessing directives ($3.8), statements ($3.6).
+
+ 3.1.7 Header names
+
+ Syntax
+
+ header-name:
+ &lt; h-char-sequence&gt;
+ " q-char-sequence"
+
+ h-char-sequence:
+ h-char
+ h-char-sequence h-char
+
+ h-char:
+ any member of the source character set except
+ the new-line character and &gt;
+
+ q-char-sequence:
+ q-char
+ q-char-sequence q-char
+
+ q-char:
+ any member of the source character set except
+ the new-line character and "
+
+
+ Constraints
+
+ Header name preprocessing tokens shall only appear within a
+ #include preprocessing directive.
+
+ Semantics
+
+ The sequences in both forms of header names are mapped in an
+ implementation-defined manner to headers or external source file names
+ as specified in $3.8.2.
+
+ If the characters ', \ , , or /* occur in the sequence between the
+ &lt; and &gt; delimiters, the behavior is undefined. Similarly, if the
+ characters ', \ , or /* occur in the sequence between the " delimiters,
+ the behavior is undefined. /20/
+
+ Example
+
+ The following sequence of characters:=20
+
+ 0x3&lt;1/a.h&gt;1e2
+ #include &lt;1/a.h&gt;
+ #define const.member@$
+
+ forms the following sequence of preprocessing tokens (with each
+ individual preprocessing token delimited by a { on the left and a } on
+ the right).
+
+ {0x3}{&lt;}{1}{/}{a}{.}{h}{&gt;}{1e2}
+ {#}{include} {&lt;1/a.h&gt;}
+ {#}{define} {const}{.}{member}{@}{$}
+
+ Forward references: source file inclusion ($3.8.2). =20
+
+
+ 3.1.8 Preprocessing numbers
+
+ Syntax
+
+ pp-number:
+ digit
+ . digit
+ pp-number digit
+ pp-number nondigit
+ pp-number e sign
+ pp-number E sign
+ pp-number .
+
+ Description
+
+ A preprocessing number begins with a digit optionally preceded by a
+ period (.) and may be followed by letters, underscores, digits,
+ periods, and e+, e-, E+, or E- character sequences.
+
+ Preprocessing number tokens lexically include all floating and
+ integer constant tokens.
+
+ Semantics
+
+ A preprocessing number does not have type or a value; it acquires
+ both after a successful conversion (as part of translation phase 7) to
+ a floating constant token or an integer constant token.
+
+
+ 3.1.9 Comments
+
+ Except within a character constant, a string literal, or a comment,
+ the characters /* introduce a comment. The contents of a comment are
+ examined only to identify multibyte characters and to find the
+ characters */ that terminate it. /21/
+
+
+ 3.2 CONVERSIONS
+
+ Several operators convert operand values from one type to another
+ automatically. This section specifies the result required from such
+ an implicit conversion, as well as those that result from a cast
+ operation (an explicit conversion). The list in $3.2.1.5 summarizes
+ the conversions performed by most ordinary operators; it is
+ supplemented as required by the discussion of each operator in $3.3.
+
+ Conversion of an operand value to a compatible type causes no change. =
+ =20
+
+ Forward references: cast operators ($3.3.4). =20
+
+
+ 3.2.1 Arithmetic operands
+
+ 3.2.1.1 Characters and integers
+
+ A char, a short int, or an int bit-field, or their signed or
+ unsigned varieties, or an object that has enumeration type, may be
+ used in an expression wherever an int or unsigned int may be used. If
+ an int can represent all values of the original type, the value is
+ converted to an int; otherwise it is converted to an unsigned int.
+ These are called the integral promotions.
+
+ The integral promotions preserve value including sign. As
+ discussed earlier, whether a ``plain'' char is treated as signed is
+ implementation-defined.
+
+ Forward references: enumeration specifiers ($3.5.2.2), structure and
+ union specifiers ($3.5.2.1).
+
+
+ 3.2.1.2 Signed and unsigned integers
+
+ When an unsigned integer is converted to another integral type, if
+ the value can be represented by the new type, its value is unchanged.
+
+ When a signed integer is converted to an unsigned integer with
+ equal or greater size, if the value of the signed integer is
+ nonnegative, its value is unchanged. Otherwise: if the unsigned
+ integer has greater size, the signed integer is first promoted to the
+ signed integer corresponding to the unsigned integer; the value is
+ converted to unsigned by adding to it one greater than the largest
+ number that can be represented in the unsigned integer type. /22/
+
+ When an integer is demoted to an unsigned integer with smaller
+ size, the result is the nonnegative remainder on division by the
+ number one greater than the largest unsigned number that can be
+ represented in the type with smaller size. When an integer is demoted
+ to a signed integer with smaller size, or an unsigned integer is
+ converted to its corresponding signed integer, if the value cannot be
+ represented the result is implementation-defined.
+
+
+ 3.2.1.3 Floating and integral
+
+ When a value of floating type is converted to integral type, the
+ fractional part is discarded. If the value of the integral part
+ cannot be represented by the integral type, the behavior is
+ undefined. /23/
+
+ When a value of integral type is converted to floating type, if the
+ value being converted is in the range of values that can be
+ represented but cannot be represented exactly, the result is either
+ the nearest higher or nearest lower value, chosen in an
+ implementation-defined manner.
+
+
+ 3.2.1.4 Floating types
+
+ When a float is promoted to double or long double , or a double is
+ promoted to long double , its value is unchanged.
+
+ When a double is demoted to float or a long double to double or
+ float, if the value being converted is outside the range of values
+ that can be represented, the behavior is undefined. If the value
+ being converted is in the range of values that can be represented but
+ cannot be represented exactly, the result is either the nearest higher
+ or nearest lower value, chosen in an implementation-defined manner.
+
+
+ 3.2.1.5 Usual arithmetic conversions
+
+ Many binary operators that expect operands of arithmetic type cause
+ conversions and yield result types in a similar way. The purpose is
+ to yield a common type, which is also the type of the result. This
+ pattern is called the usual arithmetic conversions: First, if either
+ operand has type long double, the other operand is converted to long
+ double . Otherwise, if either operand has type double, the other
+ operand is converted to double. Otherwise, if either operand has
+ type float, the other operand is converted to float. Otherwise, the
+ integral promotions are performed on both operands. Then the
+ following rules are applied: If either operand has type unsigned long
+ int, the other operand is converted to unsigned long int.
+ Otherwise, if one operand has type long int and the other has type
+ unsigned int, if a long int can represent all values of an unsigned
+ int, the operand of type unsigned int is converted to long int ; if a
+ long int cannot represent all the values of an unsigned int, both
+ operands are converted to unsigned long int. Otherwise, if either
+ operand has type long int, the other operand is converted to long int.
+ Otherwise, if either operand has type unsigned int, the other
+ operand is converted to unsigned int. Otherwise, both operands have
+ type int.
+
+ The values of operands and of the results of expressions may be
+ represented in greater precision and range than that required by the
+ type; the types are not changed thereby.
+
+
+ 3.2.2 Other operands
+
+ 3.2.2.1 Lvalues and function designators
+
+ An lvalue is an expression (with an object type or an incomplete
+ type other than void) that designates an object. /24/ When an object
+ is said to have a particular type, the type is specified by the lvalue
+ used to designate the object. A modifiable lvalue is an lvalue that
+ does not have array type, does not have an incomplete type, does not
+ have a const-qualified type, and if it is a structure or union, does
+ not have any member (including, recursively, any member of all
+ contained structures or unions) with a const-qualified type.
+
+ Except when it is the operand of the sizeof operator, the unary &amp;
+ operator, the ++ operator, the -- operator, or the left operand of the .
+ operator or an assignment operator, an lvalue that does not have
+ array type is converted to the value stored in the designated object
+ (and is no longer an lvalue). If the lvalue has qualified type, the
+ value has the unqualified version of the type of the lvalue; otherwise
+ the value has the type of the lvalue. If the lvalue has an incomplete
+ type and does not have array type, the behavior is undefined.
+
+ Except when it is the operand of the sizeof operator or the unary &amp;
+ operator, or is a character string literal used to initialize an array
+ of character type, or is a wide string literal used to initialize an
+ array with element type compatible with wchar_t, an lvalue that has
+ type ``array of type '' is converted to an expression that has type
+ ``pointer to type '' that points to the initial member of the array
+ object and is not an lvalue.
+
+ A function designator is an expression that has function type.
+ Except when it is the operand of the sizeof operator /25/ or the unary
+ &amp; operator, a function designator with type ``function returning type
+ '' is converted to an expression that has type ``pointer to function
+ returning type .''
+
+ Forward references: address and indirection operators ($3.3.3.2),
+ assignment operators ($3.3.16), common definitions &lt;stddef.h&gt;
+ ($4.1.5), initialization ($3.5.7), postfix increment and decrement
+ operators ($3.3.2.4), prefix increment and decrement operators
+ ($3.3.3.1), the sizeof operator ($3.3.3.4), structure and union
+ members ($3.3.2.3).
+
+
+ 3.2.2.2 void
+
+ The (nonexistent) value of a void expression (an expression that
+ has type void) shall not be used in any way, and implicit or explicit
+ conversions (except to void ) shall not be applied to such an
+ expression. If an expression of any other type occurs in a context
+ where a void expression is required, its value or designator is
+ discarded. (A void expression is evaluated for its side effects.)
+
+
+ 3.2.2.3 Pointers
+
+ A pointer to void may be converted to or from a pointer to any
+ incomplete or object type. A pointer to any incomplete or object type
+ may be converted to a pointer to void and back again; the result shall
+ compare equal to the original pointer.
+
+ A pointer to a non-q-qualified type may be converted to a pointer
+ to the q-qualified version of the type; the values stored in the
+ original and converted pointers shall compare equal.
+
+ An integral constant expression with the value 0, or such an
+ expression cast to type void * , is called a null pointer constant. If
+ a null pointer constant is assigned to or compared for equality to a
+ pointer, the constant is converted to a pointer of that type. Such a
+ pointer, called a null pointer, is guaranteed to compare unequal to a
+ pointer to any object or function.
+
+ Two null pointers, converted through possibly different sequences
+ of casts to pointer types, shall compare equal.
+
+ Forward references: cast operators ($3.3.4), equality operators
+ ($3.3.9), simple assignment ($3.3.16.1).
+
+
+ 3.3 EXPRESSIONS
+
+ An expression is a sequence of operators and operands that
+ specifies computation of a value, or that designates an object or a
+ function, or that generates side effects, or that performs a
+ combination thereof.
+
+ Between the previous and next sequence point an object shall have
+ its stored value modified at most once by the evaluation of an
+ expression. Furthermore, the prior value shall be accessed only to
+ determine the value to be stored. /26/
+
+ Except as indicated by the syntax /27/ or otherwise specified later
+ (for the function-call operator () , &amp;&amp; , || , ?: , and comma
+ operators), the order of evaluation of subexpressions and the order in
+ which side effects take place are both unspecified.
+
+ Some operators (the unary operator ~ , and the binary operators &lt;&lt;=
+ ,
+ &gt;&gt; , &amp; , ^ , and | , collectively described as bitwise operators
+ )shall have operands that have integral type. These operators return
+ values that depend on the internal representations of integers, and
+ thus have implementation-defined aspects for signed types.
+
+ If an exception occurs during the evaluation of an expression (that
+ is, if the result is not mathematically defined or not representable),
+ the behavior is undefined.
+
+ An object shall have its stored value accessed only by an lvalue
+ that has one of the following types: /28/
+
+ * the declared type of the object,=20
+
+ * a qualified version of the declared type of the object,=20
+
+ * a type that is the signed or unsigned type corresponding to the
+ declared type of the object,
+
+ * a type that is the signed or unsigned type corresponding to a
+ qualified version of the declared type of the object,
+
+ * an aggregate or union type that includes one of the aforementioned
+ types among its members (including, recursively, a member of a
+ subaggregate or contained union), or
+
+ * a character type. =20
+
+
+ 3.3.1 Primary expressions
+
+ Syntax
+
+ primary-expression:
+ identifier
+ constant
+ string-literal
+ ( expression )
+
+ Semantics
+
+ An identifier is a primary expression, provided it has been
+ declared as designating an object (in which case it is an lvalue) or a
+ function (in which case it is a function designator).
+
+ A constant is a primary expression. Its type depends on its form,
+ as detailed in $3.1.3.
+
+ A string literal is a primary expression. It is an lvalue with
+ type as detailed in $3.1.4.
+
+ A parenthesized expression is a primary expression. Its type and
+ value are identical to those of the unparenthesized expression. It is
+ an lvalue, a function designator, or a void expression if the
+ unparenthesized expression is, respectively, an lvalue, a function
+ designator, or a void expression.
+
+ Forward references: declarations ($3.5). =20
+
+
+ 3.3.2 Postfix operators
+
+ Syntax
+
+ postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]=20
+ postfix-expression ( argument-expression-list&lt;opt&gt;=
+ )=20
+ postfix-expression . identifier
+ postfix-expression -&gt; identifier
+ postfix-expression ++=20
+ postfix-expression --
+
+ argument-expression-list:
+ assignment-expression
+ argument-expression-list , assignment-expression
+
+
+ 3.3.2.1 Array subscripting
+
+ Constraints
+
+ One of the expressions shall have type ``pointer to object type ,''
+ the other expression shall have integral type, and the result has type
+ `` type .''
+
+ Semantics
+
+ A postfix expression followed by an expression in square brackets
+ [] is a subscripted designation of a member of an array object. The
+ definition of the subscript operator [] is that E1[E2] is identical to
+ (*(E1+(E2))) . Because of the conversion rules that apply to the
+ binary + operator, if E1 is an array object (equivalently, a pointer
+ to the initial member of an array object) and E2 is an integer, E1[E2]
+ designates the E2 -th member of E1 (counting from zero).
+
+ Successive subscript operators designate a member of a
+ multi-dimensional array object. If E is an n -dimensional array ( n
+ &gt;=3D2) with dimensions i x j "x ... x" k , then E (used as other than an
+ lvalue) is converted to a pointer to an ( n -1)-dimensional array with
+ dimensions j "x ... x" k . If the unary * operator is applied to this
+ pointer explicitly, or implicitly as a result of subscripting, the
+ result is the pointed-to ( n -1)-dimensional array, which itself is
+ converted into a pointer if used as other than an lvalue. It follows
+ from this that arrays are stored in row-major order (last subscript
+ varies fastest).
+
+ Example
+
+ Consider the array object defined by the declaration=20
+
+ int x[3][5];
+
+ Here x is a 3x5 array of int s; more precisely, x is an array of three
+ member objects, each of which is an array of five int s. In the
+ expression x[i] , which is equivalent to (*(x+(i))) , x is first
+ converted to a pointer to the initial array of five int s. Then i is
+ adjusted according to the type of x , which conceptually entails
+ multiplying i by the size of the object to which the pointer points,
+ namely an array of five int objects. The results are added and
+ indirection is applied to yield an array of five int s. When used in
+ the expression x[i][j] , that in turn is converted to a pointer to the
+ first of the int s, so x[i][j] yields an int.
+
+ Forward references: additive operators ($3.3.6), address and
+ indirection operators ($3.3.3.2), array declarators ($3.5.4.2).
+
+
+ 3.3.2.2 Function calls
+
+ Constraints
+
+ The expression that denotes the called function/29/ shall have type
+ pointer to function returning void or returning an object type other
+ than array.
+
+ If the expression that denotes the called function has a type that
+ includes a prototype, the number of arguments shall agree with the
+ number of parameters. Each argument shall have a type such that its
+ value may be assigned to an object with the unqualified version of the
+ type of its corresponding parameter.
+
+ Semantics
+
+ A postfix expression followed by parentheses () containing a
+ possibly empty, comma-separated list of expressions is a function
+ call. The postfix expression denotes the called function. The list
+ of expressions specifies the arguments to the function.
+
+ If the expression that precedes the parenthesized argument list in
+ a function call consists solely of an identifier, and if no
+ declaration is visible for this identifier, the identifier is
+ implicitly declared exactly as if, in the innermost block containing
+ the function call, the declaration
+
+ extern int identifier();
+
+ appeared. /30/
+
+ An argument may be an expression of any object type. In preparing
+ for the call to a function, the arguments are evaluated, and each
+ parameter is assigned the value of the corresponding argument./31/ The
+ value of the function call expression is specified in $3.6.6.4.
+
+ If the expression that denotes the called function has a type that
+ does not include a prototype, the integral promotions are performed on
+ each argument and arguments that have type float are promoted to
+ double. These are called the default argument promotions. If the
+ number of arguments does not agree with the number of parameters, the
+ behavior is undefined. If the function is defined with a type that
+ does not include a prototype, and the types of the arguments after
+ promotion are not compatible with those of the parameters after
+ promotion, the behavior is undefined. If the function is defined with
+ a type that includes a prototype, and the types of the arguments after
+ promotion are not compatible with the types of the parameters, or if
+ the prototype ends with an ellipsis ( ", ..." ), the behavior is
+ undefined.
+
+ If the expression that denotes the called function has a type that
+ includes a prototype, the arguments are implicitly converted, as if by
+ assignment, to the types of the corresponding parameters. The
+ ellipsis notation in a function prototype declarator causes argument
+ type conversion to stop after the last declared parameter. The
+ default argument promotions are performed on trailing arguments. If
+ the function is defined with a type that is not compatible with the
+ type (of the expression) pointed to by the expression that denotes the
+ called function, the behavior is undefined.
+
+ No other conversions are performed implicitly; in particular, the
+ number and types of arguments are not compared with those of the
+ parameters in a function definition that does not include a function
+ prototype declarator.
+
+ The order of evaluation of the function designator, the arguments,
+ and subexpressions within the arguments is unspecified, but there is a
+ sequence point before the actual call.
+
+ Recursive function calls shall be permitted, both directly and
+ indirectly through any chain of other functions.
+
+ Example
+
+ In the function call=20
+
+ (*pf[f1()]) (f2(), f3() + f4())
+
+ the functions f1 , f2 , f3 , and f4 may be called in any order. All
+ side effects shall be completed before the function pointed to by
+ pf[f1()] is entered.
+
+ Forward references: function declarators (including prototypes)
+ ($3.5.4.3), function definitions ($3.7.1), the return statement
+ ($3.6.6.4), simple assignment ($3.3.16.1).
+
+
+ 3.3.2.3 Structure and union members
+
+ Constraints
+
+ The first operand of the . operator shall have a qualified or
+ unqualified structure or union type, and the second operand shall name
+ a member of that type.
+
+ The first operand of the -&gt; operator shall have type ``pointer to
+ qualified or unqualified structure'' or ``pointer to qualified or
+ unqualified union,'' and the second operand shall name a member of the
+ type pointed to.
+
+ Semantics
+
+ A postfix expression followed by a dot . and an identifier
+ designates a member of a structure or union object. The value is that
+ of the named member, and is an lvalue if the first expression is an
+ lvalue. If the first expression has qualified type, the result has
+ the so-qualified version of the type of the designated member.
+
+ A postfix expression followed by an arrow -&gt; and an identifier
+ designates a member of a structure or union object. The value is that
+ of the named member of the object to which the first expression
+ points, and is an lvalue./32/ If the first expression is a pointer to
+ a qualified type, the result has the so-qualified version of the type
+ of the designated member.
+
+ With one exception, if a member of a union object is accessed after
+ a value has been stored in a different member of the object, the
+ behavior is implementation-defined./33/ One special guarantee is made
+ in order to simplify the use of unions: If a union contains several
+ structures that share a common initial sequence, and if the union
+ object currently contains one of these structures, it is permitted to
+ inspect the common initial part of any of them. Two structures share
+ a common initial sequence if corresponding members have compatible
+ types for a sequence of one or more initial members.
+
+ Example
+
+ If f is a function returning a structure or union, and x is a
+ member of that structure or union, f().x is a valid postfix expression
+ but is not an lvalue.
+
+ The following is a valid fragment:=20
+
+ union {
+ struct {
+ int alltypes;
+ } n;
+ struct {
+ int type;
+ int intnode;
+ } ni;
+ struct {
+ int type;
+ double doublenode;
+ } nf;
+ } u;
+ /*...*/
+ u.nf.type =3D 1;
+ u.nf.doublenode =3D 3.14;
+ /*...*/
+ if (u.n.alltypes =3D=3D 1)
+ /*...*/ sin(u.nf.doublenode) /*...*/
+
+
+
+ Forward references: address and indirection operators ($3.3.3.2),
+ structure and union specifiers ($3.5.2.1).
+
+
+ 3.3.2.4 Postfix increment and decrement operators
+
+ Constraints
+
+ The operand of the postfix increment or decrement operator shall
+ have qualified or unqualified scalar type and shall be a modifiable
+ lvalue.
+
+ Semantics
+
+ The result of the postfix ++ operator is the value of the operand.
+ After the result is obtained, the value of the operand is incremented.
+ (That is, the value 1 of the appropriate type is added to it.) See the
+ discussions of additive operators and compound assignment for
+ information on constraints, types and conversions and the effects of
+ operations on pointers. The side effect of updating the stored value
+ of the operand shall occur between the previous and the next sequence
+ point.
+
+ The postfix -- operator is analogous to the postfix ++ operator,
+ except that the value of the operand is decremented (that is, the
+ value 1 of the appropriate type is subtracted from it).
+
+ Forward references: additive operators ($3.3.6), compound assignment
+ ($3.3.16.2).
+
+
+ 3.3.3 Unary operators
+
+ Syntax
+
+ unary-expression:
+ postfix-expression
+ ++ unary-expression
+ -- unary-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-name )
+
+ unary-operator: one of
+ &amp; * + - ~ !
+
+
+ 3.3.3.1 Prefix increment and decrement operators
+
+ Constraints
+
+ The operand of the prefix increment or decrement operator shall
+ have qualified or unqualified scalar type and shall be a modifiable
+ lvalue.
+
+ Semantics
+
+ The value of the operand of the prefix ++ operator is incremented.
+ The result is the new value of the operand after incrementation. The
+ expression ++E is equivalent to (E+=3D1) . See the discussions of
+ additive operators and compound assignment for information on
+ constraints, types, side effects, and conversions and the effects of
+ operations on pointers.
+
+ The prefix -- operator is analogous to the prefix ++ operator,
+ except that the value of the operand is decremented.
+
+ Forward references: additive operators ($3.3.6), compound assignment
+ ($3.3.16.2).
+
+
+ 3.3.3.2 Address and indirection operators
+
+ Constraints
+
+ The operand of the unary &amp; operator shall be either a function
+ designator or an lvalue that designates an object that is not a
+ bit-field and is not declared with the register storage-class
+ specifier.
+
+ The operand of the unary * operator shall have pointer type. =20
+
+ Semantics
+
+ The result of the unary &amp; (address-of) operator is a pointer to the
+ object or function designated by its operand. If the operand has type
+ `` type ,'' the result has type ``pointer to type .''
+
+ The unary * operator denotes indirection. If the operand points to
+ a function, the result is a function designator; if it points to an
+ object, the result is an lvalue designating the object. If the
+ operand has type ``pointer to type ,'' the result has type `` type .''
+ If an invalid value has been assigned to the pointer, the behavior of
+ the unary * operator is undefined./34/
+
+ Forward references: storage-class specifiers ($3.5.1), structure and
+ union specifiers ($3.5.2.1).
+
+
+ 3.3.3.3 Unary arithmetic operators
+
+ Constraints
+
+ The operand of the unary + or - operator shall have arithmetic
+ type; of the ~ operator, integral type; of the ! operator, scalar
+ type.
+
+ Semantics
+
+ The result of the unary + operator is the value of its operand.
+ The integral promotion is performed on the operand, and the result has
+ the promoted type.
+
+ The result of the unary - operator is the negative of its operand.
+ The integral promotion is performed on the operand, and the result has
+ the promoted type.
+
+ The result of the ~ operator is the bitwise complement of its
+ operand (that is, each bit in the result is set if and only if the
+ corresponding bit in the converted operand is not set). The integral
+ promotion is performed on the operand, and the result has the promoted
+ type. The expression ~E is equivalent to (ULONG_MAX-E) if E is
+ promoted to type unsigned long , to (UINT_MAX-E) if E is promoted to
+ type unsigned int . (The constants ULONG_MAX and UINT_MAX are defined
+ in the header &lt;limits.h&gt; .)
+
+ The result of the logical negation operator ! is 0 if the value of
+ its operand compares unequal to 0, 1 if the value of its operand
+ compares equal to 0. The result has type int . The expression !E is
+ equivalent to (0=3D=3DE) .
+
+ Forward references: limits &lt;float.h&gt; and &lt;limits.h&gt; ($4.1.4). =
+ =20
+
+
+ 3.3.3.4 The sizeof operator
+
+ Constraints
+
+ The sizeof operator shall not be applied to an expression that has
+ function type or an incomplete type, to the parenthesized name of such
+ a type, or to an lvalue that designates a bit-field object.
+
+ Semantics
+
+ The sizeof operator yields the size (in bytes) of its operand,
+ which may be an expression or the parenthesized name of a type. The
+ size is determined from the type of the operand, which is not itself
+ evaluated. The result is an integer constant.
+
+ When applied to an operand that has type char , unsigned char , or
+ signed char , (or a qualified version thereof) the result is 1. When
+ applied to an operand that has array type, the result is the total
+ number of bytes in the array./35/ When applied to an operand that has
+ structure or union type, the result is the total number of bytes in
+ such an object, including internal and trailing padding.
+
+ The value of the result is implementation-defined, and its type (an
+ unsigned integral type) is size_t defined in the &lt;stddef.h&gt; header.
+
+ Examples
+
+ A principal use of the sizeof operator is in communication with
+ routines such as storage allocators and I/O systems. A
+ storage-allocation function might accept a size (in bytes) of an
+ object to allocate and return a pointer to void. For example:
+
+ extern void *alloc();
+ double *dp =3D alloc(sizeof *dp);
+
+ The implementation of the alloc function should ensure that its return
+ value is aligned suitably for conversion to a pointer to double.
+
+ Another use of the sizeof operator is to compute the number of
+ members in an array:
+
+ sizeof array / sizeof array[0]
+
+ Forward references: common definitions &lt;stddef.h&gt; ($4.1.5),
+ declarations ($3.5), structure and union specifiers ($3.5.2.1), type
+ names ($3.5.5).
+
+
+ 3.3.4 Cast operators
+
+ Syntax
+
+ cast-expression:
+ unary-expression
+ ( type-name ) cast-expression
+
+ Constraints
+
+ Unless the type name specifies void type, the type name shall
+ specify qualified or unqualified scalar type and the operand shall
+ have scalar type.
+
+ Semantics
+
+ Preceding an expression by a parenthesized type name converts the
+ value of the expression to the named type. This construction is
+ called a cast. /36/ A cast that specifies an implicit conversion or no
+ conversion has no effect on the type or value of an expression.
+
+ Conversions that involve pointers (other than as permitted by the
+ constraints of $3.3.16.1) shall be specified by means of an explicit
+ cast; they have implementation-defined aspects: A pointer may be
+ converted to an integral type. The size of integer required and the
+ result are implementation-defined. If the space provided is not long
+ enough, the behavior is undefined. An arbitrary integer may be
+ converted to a pointer. The result is implementation-defined./37/ A
+ pointer to an object or incomplete type may be converted to a pointer
+ to a different object type or a different incomplete type. The
+ resulting pointer might not be valid if it is improperly aligned for
+ the type pointed to. It is guaranteed, however, that a pointer to an
+ object of a given alignment may be converted to a pointer to an object
+ of the same alignment or a less strict alignment and back again; the
+ result shall compare equal to the original pointer. (An object that
+ has character type has the least strict alignment.) A pointer to a
+ function of one type may be converted to a pointer to a function of
+ another type and back again; the result shall compare equal to the
+ original pointer. If a converted pointer is used to call a function
+ that has a type that is not compatible with the type of the called
+ function, the behavior is undefined.
+
+ Forward references: equality operators ($3.3.9), function declarators
+ (including prototypes) ($3.5.4.3), simple assignment ($3.3.16.1), type
+ names ($3.5.5).
+
+
+ 3.3.5 Multiplicative operators
+
+ Syntax
+
+ multiplicative-expression:
+ cast-expression
+ multiplicative-expression * cast-expression
+ multiplicative-expression / cast-expression
+ multiplicative-expression % cast-expression
+
+ Constraints
+
+ Each of the operands shall have arithmetic type. The operands of
+ the % operator shall have integral type.
+
+ Semantics
+
+ The usual arithmetic conversions are performed on the operands.
+
+ The result of the binary * operator is the product of the operands.
+
+ The result of the / operator is the quotient from the division of
+ the first operand by the second; the result of the % operator is the
+ remainder. In both operations, if the value of the second operand is
+ zero, the behavior is undefined.
+
+ When integers are divided and the division is inexact, if both
+ operands are positive the result of the / operator is the largest
+ integer less than the algebraic quotient and the result of the %
+ operator is positive. If either operand is negative, whether the
+ result of the / operator is the largest integer less than the
+ algebraic quotient or the smallest integer greater than the algebraic
+ quotient is implementation-defined, as is the sign of the result of
+ the % operator. If the quotient a/b is representable, the expression
+ (a/b)*b + a%b shall equal a .
+
+
+ 3.3.6 Additive operators
+
+ Syntax
+
+ additive-expression:
+ multiplicative-expression
+ additive-expression + multiplicative-expression
+ additive-expression - multiplicative-expression
+
+ Constraints
+
+ For addition, either both operands shall have arithmetic type, or
+ one operand shall be a pointer to an object type and the other shall
+ have integral type. (Incrementing is equivalent to adding 1.)
+
+ For subtraction, one of the following shall hold:=20
+
+ * both operands have arithmetic type;=20
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible object types; or
+
+ * the left operand is a pointer to an object type and the right
+ operand has integral type. (Decrementing is equivalent to subtracting 1=
+ .)
+
+ Semantics
+
+ If both operands have arithmetic type, the usual arithmetic
+ conversions are performed on them.
+
+ The result of the binary + operator is the sum of the operands.
+
+ The result of the binary - operator is the difference resulting
+ from the subtraction of the second operand from the first.
+
+ When an expression that has integral type is added to or subtracted
+ from a pointer, the integral value is first multiplied by the size of
+ the object pointed to. The result has the type of the pointer
+ operand. If the pointer operand points to a member of an array
+ object, and the array object is large enough, the result points to a
+ member of the same array object, appropriately offset from the
+ original member. Thus if P points to a member of an array object, the
+ expression P+1 points to the next member of the array object. Unless
+ both the pointer operand and the result point to a member of the same
+ array object, or one past the last member of the array object, the
+ behavior is undefined. Unless both the pointer operand and the result
+ point to a member of the same array object, or the pointer operand
+ points one past the last member of an array object and the result
+ points to a member of the same array object, the behavior is undefined
+ if the result is used as the operand of a unary * operator.
+
+ When two pointers to members of the same array object are
+ subtracted, the difference is divided by the size of a member. The
+ result represents the difference of the subscripts of the two array
+ members. The size of the result is implementation-defined, and its
+ type (a signed integral type) is ptrdiff_t defined in the &lt;stddef.h&gt;
+ header. As with any other arithmetic overflow, if the result does not
+ fit in the space provided, the behavior is undefined. If two pointers
+ that do not point to members of the same array object are subtracted,
+ the behavior is undefined. However, if P points either to a member of
+ an array object or one past the last member of an array object, and Q
+ points to the last member of the same array object, the expression
+ (Q+1) - P has the same value as (Q-P) + 1 , even though Q+1 does not
+ point to a member of the array object.
+
+ Forward references: common definitions &lt;stddef.h&gt; ($4.1.5). =20
+
+
+ 3.3.7 Bitwise shift operators
+
+ Syntax
+
+ shift-expression:
+ additive-expression
+ shift-expression &lt;&lt; additive-expression
+ shift-expression &gt;&gt; additive-expression
+
+ Constraints
+
+ Each of the operands shall have integral type. =20
+
+ Semantics
+
+ The integral promotions are performed on each of the operands. The
+ type of the result is that of the promoted left operand. If the value
+ of the right operand is negative or is greater than or equal to the
+ width in bits of the promoted left operand, the behavior is undefined.
+
+ The result of E1 &lt;&lt; E2 is E1 left-shifted E2 bit positions; vacate=
+ d
+ bits are filled with zeros. If E1 has an unsigned type, the value of
+ the result is E1 multiplied by the quantity, 2 raised to the power E2,
+ reduced modulo ULONG_MAX+1 if E1 has type unsigned long, UINT_MAX+1
+ otherwise. (The constants ULONG_MAX and UINT_MAX are defined in the
+ header &lt;limits.h&gt; .)
+
+ The result of E1 &gt;&gt; E2 is E1 right-shifted E2 bit positions. If E=
+ 1
+ has an unsigned type or if E1 has a signed type and a nonnegative
+ value, the value of the result is the integral part of the quotient of
+ E1 divided by the quantity, 2 raised to the power E2 . If E1 has a
+ signed type and a negative value, the resulting value is
+ implementation-defined.
+
+
+ 3.3.8 Relational operators
+
+ Syntax
+
+ relational-expression:
+ shift-expression
+ relational-expression &lt; shift-expression
+ relational-expression &gt; shift-expression
+ relational-expression &lt;=3D shift-expression
+ relational-expression &gt;=3D shift-expression
+
+ Constraints
+
+ One of the following shall hold:=20
+
+ * both operands have arithmetic type;=20
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible object types; or
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible incomplete types.
+
+ Semantics
+
+ If both of the operands have arithmetic type, the usual arithmetic
+ conversions are performed.
+
+ When two pointers are compared, the result depends on the relative
+ locations in the address space of the objects pointed to. If the
+ objects pointed to are members of the same aggregate object, pointers
+ to structure members declared later compare higher than pointers to
+ members declared earlier in the structure, and pointers to array
+ elements with larger subscript values compare higher than pointers to
+ elements of the same array with lower subscript values. All pointers
+ to members of the same union object compare equal. If the objects
+ pointed to are not members of the same aggregate or union object, the
+ result is undefined, with the following exception. If P points to the
+ last member of an array object and Q points to a member of the same
+ array object, the pointer expression P+1 compares higher than Q , even
+ though P+1 does not point to a member of the array object.
+
+ Each of the operators &lt; (less than), &gt; (greater than), &lt;=3D (le=
+ ss
+ than or equal to), and &gt;=3D (greater than or equal to) shall yield 1 if
+ the specified relation is true and 0 if it is false./38/ The result
+ has type int.
+
+
+ 3.3.9 Equality operators
+
+ Syntax
+
+ equality-expression:
+ relational-expression
+ equality-expression =3D=3D relational-expression
+ equality-expression !=3D relational-expression
+
+ Constraints
+
+ One of the following shall hold:=20
+
+ * both operands have arithmetic type;=20
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible types;
+
+ * one operand is a pointer to an object or incomplete type and the
+ other is a qualified or unqualified version of void ; or
+
+ * one operand is a pointer and the other is a null pointer constant. =20
+
+ Semantics
+
+ The =3D=3D (equal to) and the !=3D (not equal to) operators are analogou=
+ s
+ to the relational operators except for their lower precedence./39/
+
+ If two pointers to object or incomplete types compare equal, they
+ point to the same object. If two pointers to functions compare equal,
+ they point to the same function. If two pointers point to the same
+ object or function, they compare equal./40/ If one of the operands is
+ a pointer to an object or incomplete type and the other has type
+ pointer to a qualified or unqualified version of void , the pointer to
+ an object or incomplete type is converted to the type of the other
+ operand.
+
+
+ 3.3.10 Bitwise AND operator
+
+ Syntax
+
+ AND-expression:
+ equality-expression
+ AND-expression &amp; equality-expression
+
+ Constraints
+
+ Each of the operands shall have integral type. =20
+
+ Semantics
+
+ The usual arithmetic conversions are performed on the operands.
+
+ The result of the binary &amp; operator is the bitwise AND of the
+ operands (that is, each bit in the result is set if and only if each
+ of the corresponding bits in the converted operands is set).
+
+
+ 3.3.11 Bitwise exclusive OR operator
+
+ Syntax
+
+ exclusive-OR-expression:
+ AND-expression
+ exclusive-OR-expression ^ AND-expression
+
+ Constraints
+
+ Each of the operands shall have integral type. =20
+
+ Semantics
+
+ The usual arithmetic conversions are performed on the operands.
+
+ The result of the ^ operator is the bitwise exclusive OR of the
+ operands (that is, each bit in the result is set if and only if
+ exactly one of the corresponding bits in the converted operands is
+ set).
+
+
+ 3.3.12 Bitwise inclusive OR operator
+
+ Syntax
+
+ inclusive-OR-expression:
+ exclusive-OR-expression
+ inclusive-OR-expression | exclusive-OR-expression
+
+ Constraints
+
+ Each of the operands shall have integral type. =20
+
+ Semantics
+
+ The usual arithmetic conversions are performed on the operands.
+
+ The result of the | operator is the bitwise inclusive OR of the
+ operands (that is, each bit in the result is set if and only if at
+ least one of the corresponding bits in the converted operands is set).
+
+
+ 3.3.13 Logical AND operator
+
+ Syntax
+
+ logical-AND-expression:
+ inclusive-OR-expression
+ logical-AND-expression &amp;&amp; inclusive-OR-expressio=
+ n
+
+ Constraints
+
+ Each of the operands shall have scalar type. =20
+
+ Semantics
+
+ The &amp;&amp; operator shall yield 1 if both of its operands compare
+ unequal to 0, otherwise it yields 0. The result has type int.
+
+ Unlike the bitwise binary &amp; operator, the &amp;&amp; operator guaran=
+ tees
+ left-to-right evaluation; there is a sequence point after the
+ evaluation of the first operand. If the first operand compares equal
+ to 0, the second operand is not evaluated.
+
+
+ 3.3.14 Logical OR operator
+
+ Syntax
+
+ logical-OR-expression:
+ logical-AND-expression
+ logical-OR-expression || logical-AND-expression
+
+ Constraints
+
+ Each of the operands shall have scalar type. =20
+
+ Semantics
+
+ The || operator shall yield 1 if either of its operands compare
+ unequal to 0, otherwise it yields 0. The result has type int.
+
+ Unlike the bitwise | operator, the || operator guarantees
+ left-to-right evaluation; there is a sequence point after the
+ evaluation of the first operand. If the first operand compares
+ unequal to 0, the second operand is not evaluated.
+
+
+ 3.3.15 Conditional operator
+
+ Syntax
+
+ conditional-expression:
+ logical-OR-expression
+ logical-OR-expression ? expression : conditional-expres=
+ sion
+
+ Constraints
+
+ The first operand shall have scalar type.
+
+ One of the following shall hold for the second and third operands:=20
+
+ * both operands have arithmetic type;=20
+
+ * both operands have compatible structure or union types;=20
+
+ * both operands have void type;=20
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible types;
+
+ * one operand is a pointer and the other is a null pointer constant; or=20
+
+ * one operand is a pointer to an object or incomplete type and the
+ other is a pointer to a qualified or unqualified version of void .
+
+ Semantics
+
+ The first operand is evaluated; there is a sequence point after its
+ evaluation. The second operand is evaluated only if the first
+ compares unequal to 0; the third operand is evaluated only if the
+ first compares equal to 0; the value of the second or third operand
+ (whichever is evaluated) is the result./41/
+
+ If both the second and third operands have arithmetic type, the
+ usual arithmetic conversions are performed to bring them to a common
+ type and the result has that type. If both the operands have
+ structure or union type, the result has that type. If both operands
+ have void type, the result has void type.
+
+ If both the second and third operands are pointers or one is a null
+ pointer constant and the other is a pointer, the result type is a
+ pointer to a type qualified with all the type qualifiers of the types
+ pointed-to by both operands. Furthermore, if both operands are
+ pointers to compatible types or differently qualified versions of a
+ compatible type, the result has the composite type; if one operand is
+ a null pointer constant, the result has the type of the other operand;
+ otherwise, one operand is a pointer to void or a qualified version of
+ void, in which case the other operand is converted to type pointer to
+ void, and the result has that type.
+
+
+ 3.3.16 Assignment operators
+
+ Syntax
+
+ assignment-expression:
+ conditional-expression
+ unary-expression assignment-operator assignment-expressio=
+ n
+
+ assignment-operator: one of
+ =3D *=3D /=3D %=3D +=3D -=3D &lt;&lt;=3D &gt;&gt;=
+ =3D &amp;=3D ^=3D |=3D
+
+ Constraints
+
+ An assignment operator shall have a modifiable lvalue as its left operan=
+ d. =20
+
+ Semantics
+
+ An assignment operator stores a value in the object designated by
+ the left operand. An assignment expression has the value of the left
+ operand after the assignment, but is not an lvalue. The type of an
+ assignment expression is the type of the left operand unless the left
+ operand has qualified type, in which case it is the unqualified
+ version of the type of the left operand. The side effect of updating
+ the stored value of the left operand shall occur between the previous
+ and the next sequence point.
+
+ The order of evaluation of the operands is unspecified. =20
+
+
+ 3.3.16.1 Simple assignment
+
+ Constraints
+
+ One of the following shall hold:/42/=20
+
+ * the left operand has qualified or unqualified arithmetic type and
+ the right has arithmetic type;
+
+ * the left operand has a qualified or unqualified version of a
+ structure or union type compatible with the type of the right;
+
+ * both operands are pointers to qualified or unqualified versions of
+ compatible types, and the type pointed to by the left has all the
+ qualifiers of the type pointed to by the right;
+
+ * one operand is a pointer to an object or incomplete type and the
+ other is a pointer to a qualified or unqualified version of void, and
+ the type pointed to by the left has all the qualifiers of the type
+ pointed to by the right; or
+
+ * the left operand is a pointer and the right is a null pointer constant. =
+ =20
+
+ Semantics
+
+ In simple assignment ( =3D ), the value of the right operand is
+ converted to the type of the assignment expression and replaces the
+ value stored in the object designated by the left operand.
+
+ If the value being stored in an object is accessed from another
+ object that overlaps in any way the storage of the first object, then
+ the overlap shall be exact and the two objects shall have qualified or
+ unqualified versions of a compatible type; otherwise the behavior is
+ undefined.
+
+ Example
+
+ In the program fragment=20
+
+ int f(void);
+ char c;
+ /*...*/
+ /*...*/ ((c =3D f()) =3D=3D -1) /*...*/
+
+ the int value returned by the function may be truncated when stored in
+ the char, and then converted back to int width prior to the
+ comparison. In an implementation in which ``plain'' char has the same
+ range of values as unsigned char (and char is narrower than int ), the
+ result of the conversion cannot be negative, so the operands of the
+ comparison can never compare equal. Therefore, for full portability
+ the variable c should be declared as int.
+
+
+ 3.3.16.2 Compound assignment
+
+ Constraints
+
+ For the operators +=3D and -=3D only, either the left operand shall be
+ a pointer to an object type and the right shall have integral type, or
+ the left operand shall have qualified or unqualified arithmetic type
+ and the right shall have arithmetic type.
+
+ For the other operators, each operand shall have arithmetic type
+ consistent with those allowed by the corresponding binary operator.
+
+ Semantics
+
+ A compound assignment of the form E1 op =3D E2 differs from the
+ simple assignment expression E1 =3D E1 op (E2) only in that the lvalue
+ E1 is evaluated only once.
+
+
+ 3.3.17 Comma operator
+
+ Syntax
+
+ expression:
+ assignment-expression
+ expression , assignment-expression
+
+ Semantics
+
+ The left operand of a comma operator is evaluated as a void
+ expression; there is a sequence point after its evaluation. Then the
+ right operand is evaluated; the result has its type and value./43/
+
+ Example
+
+ As indicated by the syntax, in contexts where a comma is a
+ punctuator (in lists of arguments to functions and lists of
+ initializers) the comma operator as described in this section cannot
+ appear. On the other hand, it can be used within a parenthesized
+ expression or within the second expression of a conditional operator
+ in such contexts. In the function call
+
+ f(a, (t=3D3, t+2), c)
+
+ the function has three arguments, the second of which has the value 5. =20
+
+ Forward references: initialization ($3.5.7). =20
+
+
+ 3.4 CONSTANT EXPRESSIONS
+
+ Syntax
+
+ constant-expression:
+ conditional-expression
+
+ Description
+
+ A constant expression can be evaluated during translation rather
+ than runtime, and accordingly may be used in any place that a constant
+ may be.
+
+ Constraints
+
+ Constant expressions shall not contain assignment, increment,
+ decrement, function-call, or comma operators, except when they are
+ contained within the operand of a sizeof operator./44/
+
+ Each constant expression shall evaluate to a constant that is in
+ the range of representable values for its type.
+
+ Semantics
+
+ An expression that evaluates to a constant is required in several
+ contexts./45/ If the expression is evaluated in the translation
+ environment, the arithmetic precision and range shall be at least as
+ great as if the expression were being evaluated in the execution
+ environment.
+
+ An integral constant expression shall have integral type and shall
+ only have operands that are integer constants, enumeration constants,
+ character constants, sizeof expressions, and floating constants that
+ are the immediate operands of casts. Cast operators in an integral
+ constant expression shall only convert arithmetic types to integral
+ types, except as part of an operand to the sizeof operator.
+
+ More latitude is permitted for constant expressions in
+ initializers. Such a constant expression shall evaluate to one of the
+ following:
+
+ * an arithmetic constant expression,=20
+
+ * an address constant, or=20
+
+ * an address constant for an object type plus or minus an integral
+ constant expression.
+
+ An arithmetic constant expression shall have arithmetic type and
+ shall only have operands that are integer constants, floating
+ constants, enumeration constants, character constants, and sizeof
+ expressions. Cast operators in an arithmetic constant expression
+ shall only convert arithmetic types to arithmetic types, except as
+ part of an operand to the sizeof operator.
+
+ An address constant is a pointer to an lvalue designating an object
+ of static storage duration, or to a function designator; it shall be
+ created explicitly, using the unary &amp; operator, or implicitly, by the
+ use of an expression of array or function type. The array-subscript
+ [] and member-access . and -&gt; operators, the address &amp; and
+ indirection * unary operators, and pointer casts may be used in the
+ creation an address constant, but the value of an object shall not be
+ accessed by use of these operators.
+
+ The semantic rules for the evaluation of a constant expression are
+ the same as for non-constant expressions./46/
+
+ Forward references: initialization ($3.5.7). =20
+
+
+ 3.5 DECLARATIONS
+
+ Syntax
+
+ declaration:
+ declaration-specifiers init-declarator-list&lt;opt&gt; ;
+
+ declaration-specifiers:
+ storage-class-specifier declaration-specifiers&lt;opt&gt;
+ type-specifier declaration-specifiers&lt;opt&gt;
+ type-qualifier declaration-specifiers&lt;opt&gt;
+
+ init-declarator-list:
+ init-declarator
+ init-declarator-list , init-declarator=20
+
+ init-declarator:
+ declarator
+ declarator =3D initializer
+
+ Constraints
+
+ A declaration shall declare at least a declarator, a tag, or the
+ members of an enumeration.
+
+ If an identifier has no linkage, there shall be no more than one
+ declaration of the identifier (in a declarator or type specifier) with
+ the same scope and in the same name space, except for tags as
+ specified in $3.5.2.3.
+
+ All declarations in the same scope that refer to the same object or
+ function shall specify compatible types.
+
+ Semantics
+
+ A declaration specifies the interpretation and attributes of a set
+ of identifiers. A declaration that also causes storage to be reserved
+ for an object or function named by an identifier is a definition ./47/
+
+ The declaration specifiers consist of a sequence of specifiers that
+ indicate the linkage, storage duration, and part of the type of the
+ entities that the declarators denote. The init-declarator-list is a
+ comma-separated sequence of declarators, each of which may have
+ additional type information, or an initializer, or both. The
+ declarators contain the identifiers (if any) being declared.
+
+ If an identifier for an object is declared with no linkage, the
+ type for the object shall be complete by the end of its declarator, or
+ by the end of its init-declarator if it has an initializer.
+
+ Forward references: declarators ($3.5.4), enumeration specifiers
+ ($3.5.2.2), initialization ($3.5.7), tags ($3.5.2.3).
+
+
+ 3.5.1 Storage-class specifiers
+
+ Syntax
+
+ storage-class-specifier:
+ typedef
+ extern
+ static
+ auto
+ register
+
+ Constraints
+
+ At most one storage-class specifier may be given in the declaration
+ specifiers in a declaration./48/
+
+ Semantics
+
+ The typedef specifier is called a ``storage-class specifier'' for
+ syntactic convenience only; it is discussed in $3.5.6. The meanings
+ of the various linkages and storage durations were discussed in
+ $3.1.2.2 and $3.1.2.4.
+
+ A declaration of an identifier for an object with storage-class
+ specifier register suggests that access to the object be as fast as
+ possible. The extent to which such suggestions are effective is
+ implementation-defined./49/
+
+ The declaration of an identifier for a function that has block
+ scope shall have no explicit storage-class specifier other than extern.
+
+ Forward references: type definitions ($3.5.6). =20
+
+
+ 3.5.2 Type specifiers
+
+ Syntax
+
+ type-specifier:
+ void
+ char
+ short
+ int
+ long
+ float
+ double
+ signed
+ unsigned
+ struct-or-union-specifier
+ enum-specifier
+ typedef-name
+
+ Constraints
+
+ Each list of type specifiers shall be one of the following sets; the
+ type specifiers may occur in any order, possibly intermixed with the
+ other declaration specifiers.
+
+ * void=20
+
+ * char=20
+
+ * signed char=20
+
+ * unsigned char=20
+
+ * short , signed short , short int , or signed short int=20
+
+ * unsigned short , or unsigned short int=20
+
+ * int , signed , signed int , or no type specifiers=20
+
+ * unsigned , or unsigned int=20
+
+ * long , signed long , long int , or signed long int=20
+
+ * unsigned long , or unsigned long int=20
+
+ * float=20
+
+ * double=20
+
+ * long double=20
+
+ * struct-or-union specifier=20
+
+ * enum-specifier=20
+
+ * typedef-name=20
+
+ Semantics
+
+ Specifiers for structures, unions, and enumerations are discussed
+ in $3.5.2.1 through $3.5.2.3. Declarations of typedef names are
+ discussed in $3.5.6. The characteristics of the other types are
+ discussed in $3.1.2.5.
+
+ Each of the above comma-separated lists designates the same type,
+ except that for bit-field declarations, signed int (or signed ) may
+ differ from int (or no type specifiers).
+
+ Forward references: enumeration specifiers ($3.5.2.2), structure and
+ union specifiers ($3.5.2.1), tags ($3.5.2.3), type definitions ($3.5.6).
+
+
+ 3.5.2.1 Structure and union specifiers
+
+ Syntax
+
+ struct-or-union-specifier:
+ struct-or-union identifier&lt;opt&gt; { struct-declarati=
+ on-list }=20
+ struct-or-union identifier
+
+ struct-or-union:
+ struct
+ union
+
+ struct-declaration-list:
+ struct-declaration
+ struct-declaration-list struct-declaration
+
+ struct-declaration:
+ specifier-qualifier-list struct-declarator-list ;
+
+ specifier-qualifier-list:
+ type-specifier specifier-qualifier-list&lt;opt&gt;
+ type-qualifier specifier-qualifier-list&lt;opt&gt;
+
+ struct-declarator-list:
+ struct-declarator
+ struct-declarator-list , struct-declarator
+
+ struct-declarator:
+ declarator
+ declarator&lt;opt&gt; : constant-expression
+
+ Constraints
+
+ A structure or union shall not contain a member with incomplete or
+ function type. Hence it shall not contain an instance of itself (but
+ may contain a pointer to an instance of itself).
+
+ The expression that specifies the width of a bit-field shall be an
+ integral constant expression that has nonnegative value that shall not
+ exceed the number of bits in an ordinary object of compatible type.
+ If the value is zero, the declaration shall have no declarator.
+
+ Semantics
+
+ As discussed in $3.1.2.5, a structure is a type consisting of a
+ sequence of named members, whose storage is allocated in an ordered
+ sequence, and a union is a type consisting of a sequence of named
+ members, whose storage overlap.
+
+ Structure and union specifiers have the same form.
+
+ The presence of a struct-declaration-list in a
+ struct-or-union-specifier declares a new type, within a translation
+ unit. The struct-declaration-list is a sequence of declarations for
+ the members of the structure or union. The type is incomplete until
+ after the } that terminates the list.
+
+ A member of a structure or union may have any object type. In
+ addition, a member may be declared to consist of a specified number of
+ bits (including a sign bit, if any). Such a member is called a
+ bit-field ;/50/ its width is preceded by a colon.
+
+ A bit-field may have type int , unsigned int , or signed int .
+ Whether the high-order bit position of a ``plain'' int bit-field is
+ treated as a sign bit is implementation-defined. A bit-field is
+ interpreted as an integral type consisting of the specified number of
+ bits.
+
+ An implementation may allocate any addressable storage unit large
+ enough to hold a bit-field. If enough space remains, a bit-field that
+ immediately follows another bit-field in a structure shall be packed
+ into adjacent bits of the same unit. If insufficient space remains,
+ whether a bit-field that does not fit is put into the next unit or
+ overlaps adjacent units is implementation-defined. The order of
+ allocation of bit-fields within a unit (high-order to low-order or
+ low-order to high-order) is implementation-defined. The alignment of
+ the addressable storage unit is unspecified.
+
+ A bit-field declaration with no declarator, but only a colon and a
+ width, indicates an unnamed bit-field./51/ As a special case of this,
+ a bit-field with a width of 0 indicates that no further bit-field is
+ to be packed into the unit in which the previous bit-field, if any,
+ was placed.
+
+ Each non-bit-field member of a structure or union object is aligned
+ in an implementation-defined manner appropriate to its type.
+
+ Within a structure object, the non-bit-field members and the units
+ in which bit-fields reside have addresses that increase in the order
+ in which they are declared. A pointer to a structure object, suitably
+ cast, points to its initial member (or if that member is a bit-field,
+ then to the unit in which it resides), and vice versa. There may
+ therefore be unnamed holes within a structure object, but not at its
+ beginning, as necessary to achieve the appropriate alignment.
+
+ The size of a union is sufficient to contain the largest of its
+ members. The value of at most one of the members can be stored in a
+ union object at any time. A pointer to a union object, suitably cast,
+ points to each of its members (or if a member is a bit-field, then to
+ the unit in which it resides), and vice versa.
+
+ There may also be unnamed padding at the end of a structure or
+ union, as necessary to achieve the appropriate alignment were the
+ structure or union to be a member of an array.
+
+
+ 3.5.2.2 Enumeration specifiers
+
+ Syntax
+
+ enum-specifier:
+ enum identifier&lt;opt&gt; { enumerator-list }
+ enum identifier
+
+ enumerator-list:
+ enumerator
+ enumerator-list , enumerator
+
+ enumerator:
+ enumeration-constant
+ enumeration-constant =3D constant-expression
+
+ Constraints
+
+ The expression that defines the value of an enumeration constant
+ shall be an integral constant expression that has a value
+ representable as an int.
+
+ Semantics
+
+ The identifiers in an enumerator list are declared as constants
+ that have type int and may appear wherever such are permitted./52/ An
+ enumerator with =3D defines its enumeration constant as the value of the
+ constant expression. If the first enumerator has no =3D , the value of
+ its enumeration constant is 0. Each subsequent enumerator with no =3D
+ defines its enumeration constant as the value of the constant
+ expression obtained by adding 1 to the value of the previous
+ enumeration constant. (A combination of both forms of enumerators may
+ produce enumeration constants with values that duplicate other values
+ in the same enumeration.) The enumerators of an enumeration are also
+ known as its members.
+
+ Each enumerated type shall be compatible with an integer type; the
+ choice of type is implementation-defined.
+
+ Example
+
+ enum hue { chartreuse, burgundy, claret=3D20, winedark };
+ /*...*/
+ enum hue col, *cp;
+ /*...*/
+ col =3D claret;
+ cp =3D &amp;col;
+ /*...*/
+ /*...*/ (*cp !=3D burgundy) /*...*/
+
+ makes hue the tag of an enumeration, and then declares col as an
+ object that has that type and cp as a pointer to an object that has
+ that type. The enumerated values are in the set {0, 1, 20, 21}.
+
+
+ 3.5.2.3 Tags
+
+ A type specifier of the form=20
+
+ struct-or-union identifier { struct-declaration-list }
+ enum identifier { enumerator-list }
+
+ declares the identifier to be the tag of the structure, union, or
+ enumeration specified by the list. The list defines the structure
+ content ,union content ,or enumeration content .If this declaration of
+ the tag is visible, a subsequent declaration that uses the tag and
+ that omits the bracketed list specifies the declared structure, union,
+ or enumerated type. Subsequent declarations in the same scope shall
+ omit the bracketed list.
+
+ If a type specifier of the form=20
+
+ struct-or-union identifier
+
+ occurs prior to the declaration that defines the content, the
+ structure or union is an incomplete type./53/ It declares a tag that
+ specifies a type that may be used only when the size of an object of
+ the specified type is not needed./54/ If the type is to be completed,
+ another declaration of the tag in the same scope (but not in an
+ enclosed block, which declares a new type known only within that
+ block) shall define the content. A declaration of the form
+
+ struct-or-union identifier ;
+
+ specifies a structure or union type and declares a tag, both visible
+ only within the scope in which the declaration occurs. It specifies a
+ new type distinct from any type with the same tag in an enclosing
+ scope (if any).
+
+ A type specifier of the form=20
+
+ struct-or-union { struct-declaration-list }
+ enum { enumerator-list }
+
+ specifies a new structure, union, or enumerated type, within the
+ translation unit, that can only be referred to by the declaration of
+ which it is a part./55/
+
+ Examples
+
+ This mechanism allows declaration of a self-referential structure. =20
+
+ struct tnode {
+ int count;
+ struct tnode *left, *right;
+ };
+
+ specifies a structure that contains an integer and two pointers to
+ objects of the same type. Once this declaration has been given, the
+ declaration
+
+ struct tnode s, *sp;
+
+ declares s to be an object of the given type and sp to be a pointer to
+ an object of the given type. With these declarations, the expression
+ sp-&gt;left refers to the left struct tnode pointer of the object to
+ which sp points; the expression s.right-&gt;count designates the count
+ member of the right struct tnode pointed to from s .
+
+ The following alternative formulation uses the typedef mechanism:=20
+
+ typedef struct tnode TNODE;
+ struct tnode {
+ int count;
+ TNODE *left, *right;
+ };
+ TNODE s, *sp;
+
+ To illustrate the use of prior declaration of a tag to specify a
+ pair of mutually-referential structures, the declarations
+
+ struct s1 { struct s2 *s2p; /*...*/ }; /* D1 */
+ struct s2 { struct s1 *s1p; /*...*/ }; /* D2 */
+
+ specify a pair of structures that contain pointers to each other.
+ Note, however, that if s2 were already declared as a tag in an
+ enclosing scope, the declaration D1 would refer to it, not to the tag
+ s2 declared in D2 . To eliminate this context sensitivity, the
+ otherwise vacuous declaration
+
+ struct s2;
+
+ may be inserted ahead of D1. This declares a new tag s2 in the inner
+ scope; the declaration D2 then completes the specification of the new type.
+
+ Forward references: type definitions ($3.5.6). =20
+
+
+ 3.5.3 Type qualifiers
+
+ Syntax
+
+ type-qualifier:
+ const
+ volatile
+
+ Constraints
+
+ The same type qualifier shall not appear more than once in the same
+ specifier list or qualifier list, either directly or via one or more
+ typedef s.
+
+ Semantics
+
+ The properties associated with qualified types are meaningful only
+ for expressions that are lvalues./56/
+
+ If an attempt is made to modify an object defined with a
+ const-qualified type through use of an lvalue with non-const-qualified
+ type, the behavior is undefined. If an attempt is made to refer to an
+ object defined with a volatile-qualified type through use of an lvalue
+ with non-volatile-qualified type, the behavior is undefined./57/
+
+ An object that has volatile-qualified type may be modified in ways
+ unknown to the implementation or have other unknown side effects.
+ Therefore any expression referring to such an object shall be
+ evaluated strictly according to the rules of the abstract machine, as
+ described in $2.1.2.3. Furthermore, at every sequence point the value
+ last stored in the object shall agree with that prescribed by the
+ abstract machine, except as modified by the unknown factors mentioned
+ previously./58/ What constitutes an access to an object that has
+ volatile-qualified type is implementation-defined.
+
+ If the specification of an array type includes any type qualifiers,
+ the element type is so-qualified, not the array type. If the
+ specification of a function type includes any type qualifiers, the
+ behavior is undefined./59/
+
+ For two qualified types to be compatible, both shall have the
+ identically qualified version of a compatible type; the order of type
+ qualifiers within a list of specifiers or qualifiers does not affect
+ the specified type.
+
+ Examples
+
+ An object declared=20
+
+ extern const volatile int real_time_clock;
+
+ may be modifiable by hardware, but cannot be assigned to, incremented,
+ or decremented.
+
+ The following declarations and expressions illustrate the behavior
+ when type qualifiers modify an aggregate type:
+
+ const struct s { int mem; } cs =3D { 1 };
+ struct s ncs; /* the object ncs is modifiable */
+ typedef int A[2][3];
+ const A a =3D {{4, 5, 6}, {7, 8, 9}}; /* array of array of const =
+ int */
+ int *pi;
+ const int *pci;
+
+ ncs =3D cs; /* valid */
+ cs =3D ncs; /* violates modifiable lvalue constraint for =3D=
+ */
+ pi =3D &amp;ncs.mem; /* valid */
+ pi =3D &amp;cs.mem; /* violates type constraints for =3D */
+ pci =3D &amp;cs.mem; /* valid */
+ pi =3D a[0]; /* invalid: a[0] has type ``const int * '' */
+
+
+ 3.5.4 Declarators
+
+ Syntax
+
+ declarator:
+ pointer&lt;opt&gt; direct-declarator
+
+ direct-declarator:
+ identifier
+ ( declarator )=20
+ direct-declarator [ constant-expression&lt;opt&gt; ]=20
+
+ direct-declarator ( parameter-type-list )=20
+ direct-declarator ( identifier-list&lt;opt&gt; )
+
+ pointer:
+ * type-qualifier-list&lt;opt&gt;
+ * type-qualifier-list&lt;opt&gt; pointer
+
+ type-qualifier-list:
+ type-qualifier
+ type-qualifier-list type-qualifier
+
+ parameter-type-list:
+ parameter-list
+ parameter-list , ...
+
+ parameter-list:
+ parameter-declaration
+ parameter-list , parameter-declaration
+
+ parameter-declaration:
+ declaration-specifiers declarator
+ declaration-specifiers abstract-declarator&lt;opt&gt;
+
+ identifier-list:
+ identifier
+ identifier-list , identifier
+
+ Semantics
+
+ Each declarator declares one identifier, and asserts that when an
+ operand of the same form as the declarator appears in an expression,
+ it designates a function or object with the scope, storage duration,
+ and type indicated by the declaration specifiers.
+
+ In the following subsections, consider a declaration=20
+
+ T D1
+
+ where T contains the declaration specifiers that specify a type T
+ (such as int) and D1 is a declarator that contains an identifier
+ ident . The type specified for the identifier ident in the various
+ forms of declarator is described inductively using this notation.
+
+ If, in the declaration `` T D1 ,'' D1 has the form=20
+
+ identifier
+
+ then the type specified for ident is T .
+
+ If, in the declaration `` T D1 ,'' D1 has the form=20
+
+ ( D )
+
+ then ident has the type specified by the declaration `` T D .'' Thus,
+ a declarator in parentheses is identical to the unparenthesized
+ declarator, but the binding of complex declarators may be altered by
+ parentheses.
+
+ "Implementation limits"
+
+ The implementation shall allow the specification of types that have
+ at least 12 pointer, array, and function declarators (in any valid
+ combinations) modifying an arithmetic, a structure, a union, or an
+ incomplete type, either directly or via one or more typedef s.
+
+ Forward references: type definitions ($3.5.6). =20
+
+
+ 3.5.4.1 Pointer declarators
+
+ Semantics
+
+ If, in the declaration `` T D1 ,'' D1 has the form=20
+
+ * type-qualifier-list&lt;opt&gt; D
+
+ and the type specified for ident in the declaration `` T D '' is ``
+ "derived-declarator-type-list T" ,'' then the type specified for ident
+ is `` "derived-declarator-type-list type-qualifier-list" pointer to T.''
+ For each type qualifier in the list, ident is a so-qualified pointer.
+
+ For two pointer types to be compatible, both shall be identically
+ qualified and both shall be pointers to compatible types.
+
+ Examples
+
+ The following pair of declarations demonstrates the difference
+ between a ``variable pointer to a constant value'' and a ``constant
+ pointer to a variable value.''
+
+ const int *ptr_to_constant;
+ int *const constant_ptr;
+
+ The contents of the const int pointed to by ptr_to_constant shall not
+ be modified, but ptr_to_constant itself may be changed to point to
+ another const int . Similarly, the contents of the int pointed to by
+ constant_ptr may be modified, but constant_ptr itself shall always
+ point to the same location.
+
+ The declaration of the constant pointer constant_ptr may be
+ clarified by including a definition for the type ``pointer to int .''
+
+ typedef int *int_ptr;
+ const int_ptr constant_ptr;
+
+ declares constant_ptr as an object that has type ``const-qualified
+ pointer to int .''
+
+
+ 3.5.4.2 Array declarators
+
+ Constraints
+
+ The expression that specifies the size of an array shall be an
+ integral constant expression that has a value greater than zero.
+
+ Semantics
+
+ If, in the declaration `` T D1 ,'' D1 has the form=20
+
+ D[ constant-expression&lt;opt&gt;]
+
+ and the type specified for ident in the declaration `` T D '' is ``
+ "derived-declarator-type-list T" ,'' then the type specified for ident
+ is `` derived-declarator-type-list array of T .''/60/ If the size is
+ not present, the array type is an incomplete type.
+
+ For two array types to be compatible, both shall have compatible
+ element types, and if both size specifiers are present, they shall
+ have the same value.
+
+ Examples
+
+ float fa[11], *afp[17];
+
+ declares an array of float numbers and an array of pointers to float
+ numbers.
+
+ Note the distinction between the declarations=20
+
+ extern int *x;
+ extern int y[];
+
+ The first declares x to be a pointer to int ; the second declares y to
+ be an array of int of unspecified size (an incomplete type), the
+ storage for which is defined elsewhere.
+
+ Forward references: function definitions ($3.7.1), initialization ($3.5.7).=
+ =20
+
+
+ 3.5.4.3 Function declarators (including prototypes)
+
+ Constraints
+
+ A function declarator shall not specify a return type that is a
+ function type or an array type.
+
+ The only storage-class specifier that shall occur in a parameter
+ declaration is register.
+
+ An identifier list in a function declarator that is not part of a
+ function definition shall be empty.
+
+ Semantics
+
+ If, in the declaration `` T D1 ,'' D1 has the form=20
+
+ D( parameter-type-list)
+ D( identifier-list&lt;opt&gt;)
+
+ and the type specified for ident in the declaration `` T D '' is ``
+ "derived-declarator-type-list T" ,'' then the type specified for ident
+ is `` derived-declarator-type-list function returning T .''
+
+ A parameter type list specifies the types of, and may declare
+ identifiers for, the parameters of the function. If the list
+ terminates with an ellipsis ( , ... ), no information about the number
+ or types of the parameters after the comma is supplied./61/ The
+ special case of void as the only item in the list specifies that the
+ function has no parameters.
+
+ In a parameter declaration, a single typedef name in parentheses is
+ taken to be an abstract declarator that specifies a function with a
+ single parameter, not as redundant parentheses around the identifier
+ for a declarator.
+
+ The storage-class specifier in the declaration specifiers for a
+ parameter declaration, if present, is ignored unless the declared
+ parameter is one of the members of the parameter type list for a
+ function definition.
+
+ An identifier list declares only the identifiers of the parameters
+ of the function. An empty list in a function declarator that is part
+ of a function definition specifies that the function has no
+ parameters. The empty list in a function declarator that is not part
+ of a function definition specifies that no information about the
+ number or types of the parameters is supplied./62/
+
+ For two function types to be compatible, both shall specify
+ compatible return types./63/ Moreover, the parameter type lists, if
+ both are present, shall agree in the number of parameters and in use
+ of the ellipsis terminator; corresponding parameters shall have
+ compatible types. If one type has a parameter type list and the other
+ type is specified by a function declarator that is not part of a
+ function definition and that contains an empty identifier list, the
+ parameter list shall not have an ellipsis terminator and the type of
+ each parameter shall be compatible with the type that results from the
+ application of the default argument promotions. If one type has a
+ parameter type list and the other type is specified by a function
+ definition that contains a (possibly empty) identifier list, both
+ shall agree in the number of parameters, and the type of each
+ prototype parameter shall be compatible with the type that results
+ from the application of the default argument promotions to the type of
+ the corresponding identifier. (For each parameter declared with
+ function or array type, its type for these comparisons is the one that
+ results from conversion to a pointer type, as in $3.7.1. For each
+ parameter declared with qualified type, its type for these comparisons
+ is the unqualified version of its declared type.)
+
+ Examples
+
+ The declaration=20
+
+ int f(void), *fip(), (*pfi)();
+
+ declares a function f with no parameters returning an int , a function
+ fip with no parameter specification returning a pointer to an int ,
+ and a pointer pfi to a function with no parameter specification
+ returning an int . It is especially useful to compare the last two.
+ The binding of *fip() is *(fip()) , so that the declaration suggests,
+ and the same construction in an expression requires, the calling of a
+ function fip , and then using indirection through the pointer result
+ to yield an int . In the declarator (*pfi)() , the extra parentheses
+ are necessary to indicate that indirection through a pointer to a
+ function yields a function designator, which is then used to call the
+ function; it returns an int.
+
+ If the declaration occurs outside of any function, the identifiers
+ have file scope and external linkage. If the declaration occurs
+ inside a function, the identifiers of the functions f and fip have
+ block scope and external linkage, and the identifier of the pointer
+ pfi has block scope and no linkage.
+
+ Here are two more intricate examples. =20
+
+ int (*apfi[3])(int *x, int *y);
+
+ declares an array apfi of three pointers to functions returning int .
+ Each of these functions has two parameters that are pointers to int .
+ The identifiers x and y are declared for descriptive purposes only and
+ go out of scope at the end of the declaration of apfi . The
+ declaration
+
+ int (*fpfi(int (*)(long), int))(int, ...);
+
+ declares a function fpfi that returns a pointer to a function
+ returning an int. The function fpfi has two parameters: a pointer to
+ a function returning an int (with one parameter of type long ), and an
+ int . The pointer returned by fpfi points to a function that has at
+ least one parameter, which has type int .
+
+ Forward references: function definitions ($3.7.1), type names ($3.5.5). =20
+
+
+ 3.5.5 Type names
+
+ Syntax
+
+ type-name:
+ specifier-qualifier-list abstract-declarator&lt;opt&gt;
+
+ abstract-declarator:
+ pointer
+ pointer&lt;opt&gt; direct-abstract-declarator
+
+ direct-abstract-declarator:
+ ( abstract-declarator )=20
+ direct-abstract-declarator&lt;opt&gt; [ constant-express=
+ ion&lt;opt&gt; ]=20
+ direct-abstract-declarator&lt;opt&gt; ( parameter-type-l=
+ ist&lt;opt&gt; )
+
+ Semantics
+
+ In several contexts it is desired to specify a type. This is
+ accomplished using a type name, which is syntactically a declaration
+ for a function or an object of that type that omits the
+ identifier./64/
+
+ Examples
+
+ The constructions=20
+
+ (a) int
+ (b) int *
+ (c) int *[3]
+ (d) int (*)[3]
+ (e) int *()
+ (f) int (*)(void)
+ (g) int (*const [])(unsigned int, ...)
+
+ name respectively the types (a) int , (b) pointer to int , (c) array
+ of three pointers to int , (d) pointer to an array of three int's, (e)
+ function with no parameter specification returning a pointer to int ,
+ (f) pointer to function with no parameters returning an int , and (g)
+ array of an unspecified number of constant pointers to functions, each
+ with one parameter that has type unsigned int and an unspecified
+ number of other parameters, returning an int .
+
+
+ 3.5.6 Type definitions
+
+ Syntax
+
+ typedef-name:
+ identifier
+
+ Semantics
+
+ In a declaration whose storage-class specifier is typedef , each
+ declarator defines an identifier to be a typedef name that specifies
+ the type specified for the identifier in the way described in $3.5.4.
+ A typedef declaration does not introduce a new type, only a synonym
+ for the type so specified. That is, in the following declarations:
+
+ typedef T type_ident;
+ type_ident D;
+
+ type_ident is defined as a typedef name with the type specified by the
+ declaration specifiers in T (known as T ), and the identifier in D has
+ the type `` "derived-declarator-type-list T" '' where the
+ derived-declarator-type-list is specified by the declarators of D . A
+ typedef name shares the same name space as other identifiers declared
+ in ordinary declarators. If the identifier is redeclared in an inner
+ scope or is declared as a member of a structure or union in the same
+ or an inner scope, the type specifiers shall not be omitted in the
+ inner declaration.
+
+ Examples
+
+ After=20
+
+ typedef int MILES, KLICKSP();
+ typedef struct { double re, im; } complex;
+
+ the constructions=20
+
+ MILES distance;
+ extern KLICKSP *metricp;
+ complex x;
+ complex z, *zp;
+
+ are all valid declarations. The type of distance is int , that of
+ metricp is ``pointer to function with no parameter specification
+ returning int ,'' and that of x and z is the specified structure; zp
+ is a pointer to such a structure. The object distance has a type
+ compatible with any other int object.
+
+ After the declarations=20
+
+ typedef struct s1 { int x; } t1, *tp1;
+ typedef struct s2 { int x; } t2, *tp2;
+
+ type t1 and the type pointed to by tp1 are compatible. Type t1 is
+ also compatible with type struct s1 , but not compatible with the
+ types struct s2 , t2 , the type pointed to by tp2 , and int .
+
+ The following constructions=20
+
+ typedef signed int t;
+ typedef int plain;
+ struct tag {
+ unsigned t:4;
+ const t:5;
+ plain r:5;
+ };
+
+ declare a typedef name t with type signed int , a typedef name plain
+ with type int , and a structure with three bit-field members, one
+ named t that contains values in the range [0,15], an unnamed
+ const-qualified bit-field which (if it could be accessed) would
+ contain values in at least the range [-15,+15], and one named r that
+ contains values in the range [0,31] or values in at least the range
+ [-15,+15]. (The choice of range is implementation-defined.) If these
+ declarations are followed in an inner scope by
+
+ t f(t (t));
+ long t;
+
+ then a function f is declared with type ``function returning signed
+ int with one unnamed parameter with type pointer to function returning
+ signed int with one unnamed parameter with type signed int ,'' and an
+ identifier t with type long .
+
+
+ 3.5.7 Initialization
+
+ Syntax
+
+ initializer:
+ assignment-expression
+ { initializer-list }=20
+ { initializer-list , }
+
+ initializer-list:
+ initializer
+ initializer-list , initializer
+
+ Constraints
+
+ There shall be no more initializers in an initializer list than
+ there are objects to be initialized.
+
+ The type of the entity to be initialized shall be an object type or
+ an array of unknown size.
+
+ All the expressions in an initializer for an object that has static
+ storage duration or in an initializer list for an object that has
+ aggregate or union type shall be constant expressions.
+
+ If the declaration of an identifier has block scope, and the
+ identifier has external or internal linkage, there shall be no
+ initializer for the identifier.
+
+ Semantics
+
+ An initializer specifies the initial value stored in an object.
+
+ All unnamed structure or union members are ignored during initialization=
+ .
+
+ If an object that has static storage duration is not initialized
+ explicitly, it is initialized implicitly as if every member that has
+ arithmetic type were assigned 0 and every member that has pointer type
+ were assigned a null pointer constant. If an object that has
+ automatic storage duration is not initialized explicitly, its value is
+ indeterminate./65/
+
+ The initializer for a scalar shall be a single expression,
+ optionally enclosed in braces. The initial value of the object is
+ that of the expression; the same type constraints and conversions as
+ for simple assignment apply.
+
+ A brace-enclosed initializer for a union object initializes the
+ member that appears first in the declaration list of the union type.
+
+ The initializer for a structure or union object that has automatic
+ storage duration either shall be an initializer list as described
+ below, or shall be a single expression that has compatible structure
+ or union type. In the latter case, the initial value of the object is
+ that of the expression.
+
+ The rest of this section deals with initializers for objects that
+ have aggregate or union type.
+
+ An array of character type may be initialized by a character string
+ literal, optionally enclosed in braces. Successive characters of the
+ character string literal (including the terminating null character if
+ there is room or if the array is of unknown size) initialize the
+ members of the array.
+
+ An array with element type compatible with wchar_t may be
+ initialized by a wide string literal, optionally enclosed in braces.
+ Successive codes of the wide string literal (including the terminating
+ zero-valued code if there is room or if the array is of unknown size)
+ initialize the members of the array.
+
+ Otherwise, the initializer for an object that has aggregate type
+ shall be a brace-enclosed list of initializers for the members of the
+ aggregate, written in increasing subscript or member order; and the
+ initializer for an object that has union type shall be a
+ brace-enclosed initializer for the first member of the union.
+
+ If the aggregate contains members that are aggregates or unions, or
+ if the first member of a union is an aggregate or union, the rules
+ apply recursively to the subaggregates or contained unions. If the
+ initializer of a subaggregate or contained union begins with a left
+ brace, the initializers enclosed by that brace and its matching right
+ brace initialize the members of the subaggregate or the first member
+ of the contained union. Otherwise, only enough initializers from the
+ list are taken to account for the members of the first subaggregate or
+ the first member of the contained union; any remaining initializers
+ are left to initialize the next member of the aggregate of which the
+ current subaggregate or contained union is a part.
+
+ If there are fewer initializers in a list than there are members of
+ an aggregate, the remainder of the aggregate shall be initialized
+ implicitly the same as objects that have static storage duration.
+
+ If an array of unknown size is initialized, its size is determined
+ by the number of initializers provided for its members. At the end of
+ its initializer list, the array no longer has incomplete type.
+
+ Examples
+
+ The declaration=20
+
+ int x[] =3D { 1, 3, 5 };
+
+ defines and initializes x as a one-dimensional array object that has
+ three members, as no size was specified and there are three
+ initializers.
+
+ float y[4][3] =3D {
+ { 1, 3, 5 },
+ { 2, 4, 6 },
+ { 3, 5, 7 },
+ };
+
+ is a definition with a fully bracketed initialization: 1, 3, and 5
+ initialize the first row of the array object y[0] , namely y[0][0] ,
+ y[0][1] , and y[0][2] . Likewise the next two lines initialize y[1]
+ and y[2] . The initializer ends early, so y[3] is initialized with
+ zeros. Precisely the same effect could have been achieved by
+
+ float y[4][3] =3D {
+ 1, 3, 5, 2, 4, 6, 3, 5, 7
+ };
+
+ The initializer for y[0] does not begin with a left brace, so three
+ items from the list are used. Likewise the next three are taken
+ successively for y[1] and y[2] . Also,
+
+ float z[4][3] =3D {
+ { 1 }, { 2 }, { 3 }, { 4 }
+ };
+
+ initializes the first column of z as specified and initializes the
+ rest with zeros.
+ =20
+ struct { int a[3], b; } w[] =3D { { 1 }, 2 };
+
+ is a definition with an inconsistently bracketed initialization. It
+ defines an array with two member structures: w[0].a[0] is 1 and
+ w[1].a[0] is 2; all the other elements are zero.
+
+ The declaration=20
+
+ short q[4][3][2] =3D {
+ { 1 },
+ { 2, 3 },
+ { 4, 5, 6 }
+ };
+
+ contains an incompletely but consistently bracketed initialization.
+ It defines a three-dimensional array object: q[0][0][0] is 1,
+ q[1][0][0] is 2, q[1][0][1] is 3, and 4, 5, and 6 initialize
+ q[2][0][0] , q[2][0][1] , and q[2][1][0] , respectively; all the rest
+ are zero. The initializer for q[0][0][0] does not begin with a left
+ brace, so up to six items from the current list may be used. There is
+ only one, so the values for the remaining five members are initialized
+ with zero. Likewise, the initializers for q[1][0][0] and q[2][0][0]
+ do not begin with a left brace, so each uses up to six items,
+ initializing their respective two-dimensional subaggregates. If there
+ had been more than six items in any of the lists, a diagnostic message
+ would occur. The same initialization result could have been achieved
+ by:
+
+ short q[4][3][2] =3D {
+ 1, 0, 0, 0, 0, 0,
+ 2, 3, 0, 0, 0, 0,
+ 4, 5, 6
+ };
+
+ or by:=20
+
+ short q[4][3][2] =3D {
+ {
+ { 1 },
+ },
+ {
+ { 2, 3 },
+ },
+ {
+ { 4, 5 },
+ { 6 },
+ }
+ };
+
+ in a fully-bracketed form.
+
+ Note that the fully-bracketed and minimally-bracketed forms of
+ initialization are, in general, less likely to cause confusion.
+
+ Finally, the declaration=20
+
+ char s[] =3D "abc", t[3] =3D "abc";
+
+ defines ``plain'' char array objects s and t whose members are
+ initialized with character string literals. This declaration is
+ identical to
+
+ char s[] =3D { 'a', 'b', 'c', '\0' },
+ t[] =3D { 'a', 'b', 'c' };
+
+ The contents of the arrays are modifiable. On the other hand, the
+ declaration
+
+ char *p =3D "abc";
+
+ defines p with type ``pointer to char '' that is initialized to point
+ to an object with type ``array of char '' whose members are
+ initialized with a character string literal. If an attempt is made to
+ use p to modify the contents of the array, the behavior is undefined.
+
+ Forward references: common definitions &lt;stddef.h&gt; ($4.1.5). =20
+
+
+ 3.6 STATEMENTS
+
+ Syntax
+
+ statement:
+ labeled-statement
+ compound-statement
+ expression-statement
+ selection-statement
+ iteration-statement
+ jump-statement
+
+ Semantics
+
+ A statement specifies an action to be performed. Except as
+ indicated, statements are executed in sequence.
+
+ A full expression is an expression that is not part of another
+ expression. Each of the following is a full expression: an
+ initializer; the expression in an expression statement; the
+ controlling expression of a selection statement ( if or switch ); the
+ controlling expression of a while or do statement; each of the three
+ expressions of a for statement; the expression in a return statement.
+ The end of a full expression is a sequence point.
+
+ Forward references: expression and null statements ($3.6.3), selection
+ statements ($3.6.4), iteration statements ($3.6.5), the return
+ statement ($3.6.6.4).
+
+
+ 3.6.1 Labeled statements
+
+ Syntax
+
+ labeled-statement:
+ identifier : statement
+ case constant-expression : statement
+ default : statement
+
+ Constraints
+
+ A case or default label shall appear only in a switch statement.
+ Further constraints on such labels are discussed under the switch
+ statement.
+
+ Semantics
+
+ Any statement may be preceded by a prefix that declares an
+ identifier as a label name. Labels in themselves do not alter the
+ flow of control, which continues unimpeded across them.
+
+ Forward references: the goto statement ($3.6.6.1), the switch
+ statement ($3.6.4.2).
+
+
+ 3.6.2 Compound statement, or block
+
+ Syntax
+
+ compound-statement:
+ { declaration-list&lt;opt&gt; statement-list&lt;opt&gt; =
+ }
+
+ declaration-list:
+ declaration
+ declaration-list declaration
+
+ statement-list:
+ statement
+ statement-list statement
+
+ Semantics
+
+ A compound statement (also called a block )allows a set of
+ statements to be grouped into one syntactic unit, which may have its
+ own set of declarations and initializations (as discussed in
+ $3.1.2.4). The initializers of objects that have automatic storage
+ duration are evaluated and the values are stored in the objects in the
+ order their declarators appear in the translation unit.
+
+
+ 3.6.3 Expression and null statements
+
+ Syntax
+
+ expression-statement:
+ expression&lt;opt&gt; ;
+
+ Semantics
+
+ The expression in an expression statement is evaluated as a void
+ expression for its side effects./66/
+
+ A null statement (consisting of just a semicolon) performs no
+ operations.
+
+ Examples
+
+ If a function call is evaluated as an expression statement for its
+ side effects only, the discarding of its value may be made explicit by
+ converting the expression to a void expression by means of a cast:
+
+ int p(int);
+ /*...*/
+ (void)p(0);
+
+
+ In the program fragment=20
+
+ char *s;
+ /*...*/
+ while (*s++ !=3D '\0')
+ ;
+
+ a null statement is used to supply an empty loop body to the iteration
+ statement.
+
+ A null statement may also be used to carry a label just before the
+ closing } of a compound statement.
+
+ while (loop1) {
+ /*...*/
+ while (loop2) {
+ /*...*/
+ if (want_out)
+ goto end_loop1;
+ /*...*/
+ }
+ /*...*/
+ end_loop1: ;
+ }
+
+
+
+ Forward references: iteration statements ($3.6.5). =20
+
+
+ 3.6.4 Selection statements
+
+ Syntax
+
+ selection-statement:
+ if ( expression ) statement
+ if ( expression ) statement else statement
+ switch ( expression ) statement
+
+ Semantics
+
+ A selection statement selects among a set of statements depending
+ on the value of a controlling expression.
+
+
+ 3.6.4.1 The if statement
+
+ Constraints
+
+ The controlling expression of an if statement shall have scalar type. =
+ =20
+
+ Semantics
+
+ In both forms, the first substatement is executed if the expression
+ compares unequal to 0. In the else form, the second substatement is
+ executed if the expression compares equal to 0. If the first
+ substatement is reached via a label, the second substatement is not
+ executed.
+
+ An else is associated with the lexically immediately preceding else
+ -less if that is in the same block (but not in an enclosed block).
+
+
+ 3.6.4.2 The switch statement
+
+ Constraints
+
+ The controlling expression of a switch statement shall have
+ integral type. The expression of each case label shall be an integral
+ constant expression. No two of the case constant expressions in the
+ same switch statement shall have the same value after conversion.
+ There may be at most one default label in a switch statement. (Any
+ enclosed switch statement may have a default label or case constant
+ expressions with values that duplicate case constant expressions in
+ the enclosing switch statement.)
+
+ Semantics
+
+ A switch statement causes control to jump to, into, or past the
+ statement that is the switch body, depending on the value of a
+ controlling expression, and on the presence of a default label and the
+ values of any case labels on or in the switch body. A case or default
+ label is accessible only within the closest enclosing switch
+ statement.
+
+ The integral promotions are performed on the controlling
+ expression. The constant expression in each case label is converted
+ to the promoted type of the controlling expression. If a converted
+ value matches that of the promoted controlling expression, control
+ jumps to the statement following the matched case label. Otherwise,
+ if there is a default label, control jumps to the labeled statement.
+ If no converted case constant expression matches and there is no
+ default label, no part of the switch body is executed.
+
+ "Implementation limits"
+
+ As discussed previously ($2.2.4.1), the implementation may limit
+ the number of case values in a switch statement.
+
+
+ 3.6.5 Iteration statements
+
+ Syntax
+
+ iteration-statement:
+ while ( expression ) statement
+ do statement while ( expression ) ;
+ for ( expression&lt;opt&gt; ; expression&lt;opt&gt; ;
+ expression&lt;opt&gt; ) statement
+
+ Constraints
+
+ The controlling expression of an iteration statement shall have scalar t=
+ ype. =20
+ Semantics
+
+ An iteration statement causes a statement called the loop body to
+ be executed repeatedly until the controlling expression compares equal
+ to 0.
+
+
+ 3.6.5.1 The while statement
+
+ The evaluation of the controlling expression takes place before
+ each execution of the loop body.
+
+
+ 3.6.5.2 The do statement
+
+ The evaluation of the controlling expression takes place after each
+ execution of the loop body.
+
+
+ 3.6.5.3 The for statement
+
+ Except for the behavior of a continue statement in the loop body,
+ the statement
+
+ for ( expression-1 ; expression-2 ; expression-3 ) statement
+
+ and the sequence of statements=20
+
+ expression-1 ;
+ while ( expression-2) {
+ statement
+ expression-3 ;
+ }
+
+ are equivalent./67/ expression-1 expression-2 , expression-3
+
+ Both expression-1 and expression-3 may be omitted. Each is
+ evaluated as a void expression. An omitted expression-2 is replaced
+ by a nonzero constant.
+
+ Forward references: the continue statement ($3.6.6.2). =20
+
+
+ 3.6.6 Jump statements
+
+ Syntax
+
+ jump-statement:
+ goto identifier ;
+ continue ;
+ break ;
+ return expression&lt;opt&gt; ;
+
+ Semantics
+
+ A jump statement causes an unconditional jump to another place. =20
+
+
+ 3.6.6.1 The goto statement
+
+ Constraints
+
+ The identifier in a goto statement shall name a label located
+ somewhere in the current function.
+
+ Semantics
+
+ A goto statement causes an unconditional jump to the statement
+ prefixed by the named label in the current function.
+
+
+ 3.6.6.2 The continue statement
+
+ Constraints
+
+ A continue statement shall appear only in or as a loop body. =20
+
+ Semantics
+
+ A continue statement causes a jump to the loop-continuation portion
+ of the smallest enclosing iteration statement; that is, to the end of
+ the loop body. More precisely, in each of the statements
+
+ while (/*...*/) { do { for (/*...*/) {
+ /*...*/ /*...*/ /*...*/
+ continue; continue; continue;
+ /*...*/ /*...*/ /*...*/
+ contin: ; contin: ; contin: ;
+ } } while (/*...*/); }
+
+ unless the continue statement shown is in an enclosed iteration
+ statement (in which case it is interpreted within that statement), it
+ is equivalent to goto contin; ./68/
+
+
+ 3.6.6.3 The break statement
+
+ Constraints
+
+ A break statement shall appear only in or as a switch body or loop body.=
+ =20
+
+ Semantics
+
+ A break statement terminates execution of the smallest enclosing
+ switch or iteration statement.
+
+
+ 3.6.6.4 The return statement
+
+ Constraints
+
+ A return statement with an expression shall not appear in a
+ function whose return type is void .
+
+ Semantics
+
+ A return statement terminates execution of the current function and
+ returns control to its caller. A function may have any number of
+ return statements, with and without expressions.
+
+ If a return statement with an expression is executed, the value of
+ the expression is returned to the caller as the value of the function
+ call expression. If the expression has a type different from that of
+ the function in which it appears, it is converted as if it were
+ assigned to an object of that type.
+
+ If a return statement without an expression is executed, and the
+ value of the function call is used by the caller, the behavior is
+ undefined. Reaching the } that terminates a function is equivalent to
+ executing a return statement without an expression.
+
+
+ 3.7 EXTERNAL DEFINITIONS
+
+ Syntax
+
+ translation-unit:
+ external-declaration
+ translation-unit external-declaration
+
+ external-declaration:
+ function-definition
+ declaration
+
+ Constraints
+
+ The storage-class specifiers auto and register shall not appear in
+ the declaration specifiers in an external declaration.
+
+ There shall be no more than one external definition for each
+ identifier declared with internal linkage in a translation unit.
+ Moreover, if an identifier declared with internal linkage is used in
+ an expression (other than as a part of the operand of a sizeof
+ operator), there shall be exactly one external definition for the
+ identifier in the translation unit.
+
+ Semantics
+
+ As discussed in $2.1.1.1, the unit of program text after
+ preprocessing is a translation unit, which consists of a sequence of
+ external declarations. These are described as ``external'' because
+ they appear outside any function (and hence have file scope). As
+ discussed in $3.5, a declaration that also causes storage to be
+ reserved for an object or a function named by the identifier is a
+ definition.
+
+ An external definition is an external declaration that is also a
+ definition of a function or an object. If an identifier declared with
+ external linkage is used in an expression (other than as part of the
+ operand of a sizeof operator), somewhere in the entire program there
+ shall be exactly one external definition for the identifier./69/
+
+
+ 3.7.1 Function definitions
+
+ Syntax
+
+ function-definition:
+ declaration-specifiers&lt;opt&gt; declarator
+ declaration-list&lt;opt&gt; compound-statement
+
+ Constraints
+
+ The identifier declared in a function definition (which is the name
+ of the function) shall have a function type, as specified by the
+ declarator portion of the function definition./70/
+
+ The return type of a function shall be void or an object type other
+ than array.
+
+ The storage-class specifier, if any, in the declaration specifiers
+ shall be either extern or static .
+
+ If the declarator includes a parameter type list, the declaration
+ of each parameter shall include an identifier (except for the special
+ case of a parameter list consisting of a single parameter of type void,
+ in which there shall not be an identifier). No declaration list
+ shall follow.
+
+ If the declarator includes an identifier list, only the identifiers
+ it names shall be declared in the declaration list. An identifier
+ declared as a typedef name shall not be redeclared as a parameter.
+ The declarations in the declaration list shall contain no
+ storage-class specifier other than register and no initializations.
+
+ Semantics
+
+ The declarator in a function definition specifies the name of the
+ function being defined and the identifiers of its parameters. If the
+ declarator includes a parameter type list, the list also specifies the
+ types of all the parameters; such a declarator also serves as a
+ function prototype for later calls to the same function in the same
+ translation unit. If the declarator includes an identifier list,/71/
+ the types of the parameters may be declared in a following declaration
+ list. Any parameter that is not declared has type int .
+
+ If a function that accepts a variable number of arguments is
+ defined without a parameter type list that ends with the ellipsis
+ notation, the behavior is undefined.
+
+ On entry to the function the value of each argument expression
+ shall be converted to the type of its corresponding parameter, as if
+ by assignment to the parameter. Array expressions and function
+ designators as arguments are converted to pointers before the call. A
+ declaration of a parameter as ``array of type '' shall be adjusted to
+ ``pointer to type ,'' and a declaration of a parameter as ``function
+ returning type '' shall be adjusted to ``pointer to function returning
+ type ,'' as in $3.2.2.1. The resulting parameter type shall be an
+ object type.
+
+ Each parameter has automatic storage duration. Its identifier is
+ an lvalue./72/ The layout of the storage for parameters is
+ unspecified.
+
+ Examples
+
+ extern int max(int a, int b)
+ {
+ return a &gt; b ? a : b;
+ }
+
+ Here extern is the storage-class specifier and int is the type
+ specifier (each of which may be omitted as those are the defaults);
+ max(int a, int b) is the function declarator; and
+
+ { return a &gt; b ? a : b; }
+
+ is the function body. The following similar definition uses the
+ identifier-list form for the parameter declarations:
+
+ extern int max(a, b)
+ int a, b;
+ {
+ return a &gt; b ? a : b;
+ }
+
+ Here int a, b; is the declaration list for the parameters, which may
+ be omitted because those are the defaults. The difference between
+ these two definitions is that the first form acts as a prototype
+ declaration that forces conversion of the arguments of subsequent
+ calls to the function, whereas the second form may not.
+
+ To pass one function to another, one might say=20
+
+ int f(void);
+ /*...*/
+ g(f);
+
+ Note that f must be declared explicitly in the calling function, as
+ its appearance in the expression g(f) was not followed by ( . Then
+ the definition of g might read
+
+ g(int (*funcp)(void))
+ {
+ /*...*/ (*funcp)() /* or funcp() ... */
+ }
+
+ or, equivalently,=20
+
+ g(int func(void))
+ {
+ /*...*/ func() /* or (*func)() ... */
+ }
+
+
+ 3.7.2 External object definitions
+
+ Semantics
+
+ If the declaration of an identifier for an object has file scope
+ and an initializer, the declaration is an external definition for the
+ identifier.
+
+ A declaration of an identifier for an object that has file scope
+ without an initializer, and without a storage-class specifier or with
+ the storage-class specifier static , constitutes a tentative
+ definition. If a translation unit contains one or more tentative
+ definitions for an identifier, and the translation unit contains no
+ external definition for that identifier, then the behavior is exactly
+ as if the translation unit contains a file scope declaration of that
+ identifier, with the composite type as of the end of the translation
+ unit, with an initializer equal to 0.
+
+ If the declaration of an identifier for an object is a tentative
+ definition and has internal linkage, the declared type shall not be an
+ incomplete type.
+
+ Examples
+
+ int i1 =3D 1; /* definition, external linkage */
+ static int i2 =3D 2; /* definition, internal linkage */
+ extern int i3 =3D 3; /* definition, external linkage */
+ int i4; /* tentative definition, external linkage */
+ static int i5; /* tentative definition, internal linkage */
+
+ int i1; /* valid tentative definition, refers to previous */
+ int i2; /* $3.1.2.2 renders undefined, linkage disagreement */
+ int i3; /* valid tentative definition, refers to previous */
+ int i4; /* valid tentative definition, refers to previous */
+ int i5; /* $3.1.2.2 renders undefined, linkage disagreement */
+
+
+
+ extern int i1; /* refers to previous, whose linkage is external */
+ extern int i2; /* refers to previous, whose linkage is internal */
+ extern int i3; /* refers to previous, whose linkage is external */
+ extern int i4; /* refers to previous, whose linkage is external */
+ extern int i5; /* refers to previous, whose linkage is internal */
+
+
+ 3.8 PREPROCESSING DIRECTIVES
+
+ Syntax
+
+ preprocessing-file:
+ group&lt;opt&gt;
+
+ group:
+ group-part
+ group group-part
+
+ group-part:
+ pp-tokens&lt;opt&gt; new-line
+ if-section
+ control-line
+
+ if-section:
+ if-group elif-groups&lt;opt&gt; else-group&lt;opt&gt; end=
+ if-line
+
+ if-group:
+ # if constant-expression new-line group&lt;opt&gt;
+ # ifdef identifier new-line group&lt;opt&gt;
+ # ifndef identifier new-line group&lt;opt&gt;
+
+ elif-groups:
+ elif-group
+ elif-groups elif-group
+
+ elif-group:
+ # elif constant-expression new-line group&lt;opt&gt;
+
+ else-group:
+ # else new-line group&lt;opt&gt;
+
+ endif-line:
+ # endif new-line
+
+ control-line:
+ # include pp-tokens new-line
+ # define identifier replacement-list new-line
+ # define identifier lparen identifier-list&lt;opt&gt; )
+ replacement-list new-line
+ # undef identifier new-line
+ # line pp-tokens new-line
+ # error pp-tokens&lt;opt&gt; new-line
+ # pragma pp-tokens&lt;opt&gt; new-line
+ # new-line
+
+ lparen:
+ the left-parenthesis character without preceding white-sp=
+ ace
+
+ replacement-list:
+ pp-tokens&lt;opt&gt;
+
+ pp-tokens:
+ preprocessing-token
+ pp-tokens preprocessing-token
+
+ new-line:
+ the new-line character
+
+ Description
+
+ A preprocessing directive consists of a sequence of preprocessing
+ tokens that begins with a # preprocessing token that is either the
+ first character in the source file (optionally after white space
+ containing no new-line characters) or that follows white space
+ containing at least one new-line character, and is ended by the next
+ new-line character./73/
+
+ Constraints
+
+ The only white-space characters that shall appear between
+ preprocessing tokens within a preprocessing directive (from just after
+ the introducing # preprocessing token through just before the
+ terminating new-line character) are space and horizontal-tab
+ (including spaces that have replaced comments in translation phase 3).
+
+ Semantics
+
+ The implementation can process and skip sections of source files
+ conditionally, include other source files, and replace macros. These
+ capabilities are called preprocessing , because conceptually they
+ occur before translation of the resulting translation unit.
+
+ The preprocessing tokens within a preprocessing directive are not
+ subject to macro expansion unless otherwise stated.
+
+
+ 3.8.1 Conditional inclusion
+
+ Constraints
+
+ The expression that controls conditional inclusion shall be an
+ integral constant expression except that: it shall not contain a cast;
+ identifiers (including those lexically identical to keywords) are
+ interpreted as described below;/74/ and it may contain unary operator
+ expressions of the form
+
+ defined identifier
+ defined ( identifier )
+
+ which evaluate to 1 if the identifier is currently defined as a macro
+ name (that is, if it is predefined or if it has been the subject of a
+ #define preprocessing directive without an intervening #undef
+ directive with the same subject identifier), 0 if it is not.
+
+ Each preprocessing token that remains after all macro replacements
+ have occurred shall be in the lexical form of a token.
+
+ Semantics
+
+ Preprocessing directives of the forms=20
+
+ # if constant-expression new-line group&lt;opt&gt;
+ # elif constant-expression new-line group&lt;opt&gt;
+
+ check whether the controlling constant expression evaluates to
+ nonzero.
+
+ Prior to evaluation, macro invocations in the list of preprocessing
+ tokens that will become the controlling constant expression are
+ replaced (except for those macro names modified by the defined unary
+ operator), just as in normal text. If the token defined is generated
+ as a result of this replacement process, the behavior is undefined.
+ After all replacements are finished, the resulting preprocessing
+ tokens are converted into tokens, and then all remaining identifiers
+ are replaced with 0 . The resulting tokens comprise the controlling
+ constant expression which is evaluated according to the rules of $3.4
+ using arithmetic that has at least the ranges specified in $2.2.4.2,
+ except that int and unsigned int act as if they have the same
+ representation as, respectively, long and unsigned long . This
+ includes interpreting character constants, which may involve
+ converting escape sequences into execution character set members.
+ Whether the numeric value for these character constants matches the
+ value obtained when an identical character constant occurs in an
+ expression (other than within a #if or #elif directive) is
+ implementation-defined./75/ Also, whether a single-character character
+ constant may have a negative value is implementation-defined.
+
+ Preprocessing directives of the forms=20
+
+ # ifdef identifier new-line group&lt;opt&gt;
+ # ifndef identifier new-line group&lt;opt&gt;
+
+ check whether the identifier is or is not currently defined as a macro
+ name. Their conditions are equivalent to #if defined identifier and
+ #if !defined identifier respectively.
+
+ Each directive's condition is checked in order. If it evaluates to
+ false (zero), the group that it controls is skipped: directives are
+ processed only through the name that determines the directive in order
+ to keep track of the level of nested conditionals; the rest of the
+ directives' preprocessing tokens are ignored, as are the other
+ preprocessing tokens in the group. Only the first group whose control
+ condition evaluates to true (nonzero) is processed. If none of the
+ conditions evaluates to true, and there is a #else directive, the
+ group controlled by the #else is processed; lacking a #else directive,
+ all the groups until the #endif are skipped./76/
+
+ Forward references: macro replacement ($3.8.3), source file inclusion
+ ($3.8.2).
+
+
+ 3.8.2 Source file inclusion
+
+ Constraints
+
+ A #include directive shall identify a header or source file that
+ can be processed by the implementation.
+
+ Semantics
+
+ A preprocessing directive of the form=20
+
+ # include &lt;h-char-sequence&gt; new-line
+
+ searches a sequence of implementation-defined places for a header
+ identified uniquely by the specified sequence between the &lt; and &gt;
+ delimiters, and causes the replacement of that directive by the entire
+ contents of the header. How the places are specified or the header
+ identified is implementation-defined.
+
+ A preprocessing directive of the form=20
+
+ # include "q-char-sequence" new-line
+
+ causes the replacement of that directive by the entire contents of the
+ source file identified by the specified sequence between the
+ delimiters. The named source file is searched for in an
+ implementation-defined manner. If this search is not supported, or if
+ the search fails, the directive is reprocessed as if it read
+
+ # include &lt;h-char-sequence&gt; new-line
+
+ with the identical contained sequence (including &gt; characters, if any)
+ from the original directive.
+
+ A preprocessing directive of the form=20
+
+ # include pp-tokens new-line
+
+ (that does not match one of the two previous forms) is permitted. The
+ preprocessing tokens after include in the directive are processed just
+ as in normal text. (Each identifier currently defined as a macro name
+ is replaced by its replacement list of preprocessing tokens.) The
+ directive resulting after all replacements shall match one of the two
+ previous forms./77/ The method by which a sequence of preprocessing
+ tokens between a &lt; and a &gt; preprocessing token pair or a pair of
+ characters is combined into a single header name preprocessing token
+ is implementation-defined.
+
+ There shall be an implementation-defined mapping between the
+ delimited sequence and the external source file name. The
+ implementation shall provide unique mappings for sequences consisting
+ of one or more letters (as defined in $2.2.1) followed by a period (.)=20
+ and a single letter. The implementation may ignore the distinctions=20
+ of alphabetical case and restrict the mapping to six significant
+ characters before the period.
+
+ A #include preprocessing directive may appear in a source file that
+ has been read because of a #include directive in another file, up to
+ an implementation-defined nesting limit (see $2.2.4.1).
+
+ Examples
+
+ The most common uses of #include preprocessing directives are as in
+ the following:
+
+ #include &lt;stdio.h&gt;
+ #include "myprog.h"
+
+
+ This example illustrates a macro-replaced #include directive:=20
+
+ #if VERSION =3D=3D 1
+ #define INCFILE "vers1.h"
+ #elif VERSION =3D=3D 2
+ #define INCFILE "vers2.h"
+ /* and so on */
+ #else
+ #define INCFILE "versN.h"
+ #endif
+ /*...*/
+ #include INCFILE
+
+ Forward references: macro replacement ($3.8.3). =20
+
+
+ 3.8.3 Macro replacement
+
+ Constraints
+
+ Two replacement lists are identical if and only if the
+ preprocessing tokens in both have the same number, ordering, spelling,
+ and white-space separation, where all white-space separations are
+ considered identical.
+
+ An identifier currently defined as a macro without use of lparen
+ (an object-like macro) may be redefined by another #define
+ preprocessing directive provided that the second definition is an
+ object-like macro definition and the two replacement lists are
+ identical.
+
+ An identifier currently defined as a macro using lparen (a
+ function-like macro) may be redefined by another #define preprocessing
+ directive provided that the second definition is a function-like macro
+ definition that has the same number and spelling of parameters, and
+ the two replacement lists are identical.
+
+ The number of arguments in an invocation of a function-like macro
+ shall agree with the number of parameters in the macro definition, and
+ there shall exist a ) preprocessing token that terminates the
+ invocation.
+
+ A parameter identifier in a function-like macro shall be uniquely
+ declared within its scope.
+
+ Semantics
+
+ The identifier immediately following the define is called the macro
+ name. Any white-space characters preceding or following the
+ replacement list of preprocessing tokens are not considered part of
+ the replacement list for either form of macro.
+
+ If a # preprocessing token, followed by an identifier, occurs
+ lexically at the point at which a preprocessing directive could begin,
+ the identifier is not subject to macro replacement.
+
+ A preprocessing directive of the form=20
+
+ # define identifier replacement-list new-line
+
+ defines an object-like macro that causes each subsequent instance of
+ the macro name/78/ to be replaced by the replacement list of
+ preprocessing tokens that constitute the remainder of the directive.
+ The replacement list is then rescanned for more macro names as
+ specified below.
+
+ A preprocessing directive of the form=20
+
+ # define identifier lparen identifier-list&lt;opt&gt; )
+ replacement-list new-line
+
+ defines a function-like macro with arguments, similar syntactically to
+ a function call. The parameters are specified by the optional list of
+ identifiers, whose scope extends from their declaration in the
+ identifier list until the new-line character that terminates the
+ #define preprocessing directive. Each subsequent instance of the
+ function-like macro name followed by a ( as the next preprocessing
+ token introduces the sequence of preprocessing tokens that is replaced
+ by the replacement list in the definition (an invocation of the
+ macro). The replaced sequence of preprocessing tokens is terminated
+ by the matching ) preprocessing token, skipping intervening matched
+ pairs of left and right parenthesis preprocessing tokens. Within the
+ sequence of preprocessing tokens making up an invocation of a
+ function-like macro, new-line is considered a normal white-space
+ character.
+
+ The sequence of preprocessing tokens bounded by the outside-most
+ matching parentheses forms the list of arguments for the function-like
+ macro. The individual arguments within the list are separated by
+ comma preprocessing tokens, but comma preprocessing tokens bounded by
+ nested parentheses do not separate arguments. If (before argument
+ substitution) any argument consists of no preprocessing tokens, the
+ behavior is undefined. If there are sequences of preprocessing tokens
+ within the list of arguments that would otherwise act as preprocessing
+ directives, the behavior is undefined.
+
+
+ 3.8.3.1 Argument substitution
+
+ After the arguments for the invocation of a function-like macro
+ have been identified, argument substitution takes place. A parameter
+ in the replacement list, unless preceded by a # or ## preprocessing
+ token or followed by a ## preprocessing token (see below), is replaced
+ by the corresponding argument after all macros contained therein have
+ been expanded. Before being substituted, each argument's
+ preprocessing tokens are completely macro replaced as if they formed
+ the rest of the source file; no other preprocessing tokens are
+ available.
+
+
+ 3.8.3.2 The # operator
+
+ Constraints
+
+ Each # preprocessing token in the replacement list for a
+ function-like macro shall be followed by a parameter as the next
+ preprocessing token in the replacement list.
+
+ Semantics
+
+ If, in the replacement list, a parameter is immediately preceded by
+ a # preprocessing token, both are replaced by a single character
+ string literal preprocessing token that contains the spelling of the
+ preprocessing token sequence for the corresponding argument. Each
+ occurrence of white space between the argument's preprocessing tokens
+ becomes a single space character in the character string literal.
+ White space before the first preprocessing token and after the last
+ preprocessing token comprising the argument is deleted. Otherwise,
+ the original spelling of each preprocessing token in the argument is
+ retained in the character string literal, except for special handling
+ for producing the spelling of string literals and character constants:
+ a \ character is inserted before each and \ character of a character
+ constant or string literal (including the delimiting characters). If
+ the replacement that results is not a valid character string literal,
+ the behavior is undefined. The order of evaluation of # and ##
+ operators is unspecified.
+
+
+ 3.8.3.3 The ## operator
+
+ Constraints
+
+ A ## preprocessing token shall not occur at the beginning or at the
+ end of a replacement list for either form of macro definition.
+
+ Semantics
+
+ If, in the replacement list, a parameter is immediately preceded or
+ followed by a ## preprocessing token, the parameter is replaced by the
+ corresponding argument's preprocessing token sequence.
+
+ For both object-like and function-like macro invocations, before
+ the replacement list is reexamined for more macro names to replace,
+ each instance of a ## preprocessing token in the replacement list (not
+ from an argument) is deleted and the preceding preprocessing token is
+ concatenated with the following preprocessing token. If the result is
+ not a valid preprocessing token, the behavior is undefined. The
+ resulting token is available for further macro replacement. The order
+ of evaluation of ## operators is unspecified.
+
+
+ 3.8.3.4 Rescanning and further replacement
+
+ After all parameters in the replacement list have been substituted,
+ the resulting preprocessing token sequence is rescanned with the rest
+ of the source file's preprocessing tokens for more macro names to
+ replace.
+
+ If the name of the macro being replaced is found during this scan
+ of the replacement list (not including the rest of the source file's
+ preprocessing tokens), it is not replaced. Further, if any nested
+ replacements encounter the name of the macro being replaced, it is not
+ replaced. These nonreplaced macro name preprocessing tokens are no
+ longer available for further replacement even if they are later
+ (re)examined in contexts in which that macro name preprocessing token
+ would otherwise have been replaced.
+
+ The resulting completely macro-replaced preprocessing token
+ sequence is not processed as a preprocessing directive even if it
+ resembles one.
+
+
+ 3.8.3.5 Scope of macro definitions
+
+ A macro definition lasts (independent of block structure) until a
+ corresponding #undef directive is encountered or (if none is
+ encountered) until the end of the translation unit.
+
+ A preprocessing directive of the form=20
+
+ # undef identifier new-line
+
+ causes the specified identifier no longer to be defined as a macro
+ name. It is ignored if the specified identifier is not currently
+ defined as a macro name.
+
+ Examples
+
+ The simplest use of this facility is to define a ``manifest
+ constant,'' as in
+
+ #define TABSIZE 100
+
+ int table[TABSIZE];
+
+ The following defines a function-like macro whose value is the
+ maximum of its arguments. It has the advantages of working for any
+ compatible types of the arguments and of generating in-line code
+ without the overhead of function calling. It has the disadvantages of
+ evaluating one or the other of its arguments a second time (including
+ side effects) and of generating more code than a function if invoked
+ several times.
+
+ #define max(a, b) ((a) &gt; (b) ? (a) : (b))
+
+ The parentheses ensure that the arguments and the resulting expression
+ are bound properly.
+
+ To illustrate the rules for redefinition and reexamination, the
+ sequence
+
+ #define x 3
+ #define f(a) f(x * (a))
+ #undef x
+ #define x 2
+ #define g f
+ #define z z[0]
+ #define h g(~
+ #define m(a) a(w)
+ #define w 0,1
+ #define t(a) a
+
+ f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
+ g(x+(3,4)-w) | h 5) &amp; m
+ (f)^m(m);
+
+ results in=20
+
+ f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
+ f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) &amp; f(2 * (0,1))^m(0,1);
+
+
+ To illustrate the rules for creating character string literals and
+ concatenating tokens, the sequence
+
+ #define str(s) # s
+ #define xstr(s) str(s)
+ #define debug(s, t) printf("x" # s "=3D %d, x" # t "=3D %s", \
+ x ## s, x ## t)
+ #define INCFILE(n) vers ## n /* from previous #include example */
+ #define glue(a, b) a ## b
+ #define xglue(a, b) glue(a, b)
+ #define HIGHLOW "hello"
+ #define LOW LOW ", world"
+
+ debug(1, 2);
+ fputs(str(strncmp("abc\0d", "abc", '\4') /* this goes away */
+ =3D=3D 0) str(: @\n), s);
+ #include xstr(INCFILE(2).h)
+ glue(HIGH, LOW);
+ xglue(HIGH, LOW)
+
+ results in=20
+
+ printf("x" "1" "=3D %d, x" "2" "=3D %s", x1, x2);
+ fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') =3D=3D 0" ": @\n", s);
+ #include "vers2.h" (after macro replacement, before file access)
+ "hello";
+ "hello" ", world"
+
+ or, after concatenation of the character string literals,=20
+
+ printf("x1=3D %d, x2=3D %s", x1, x2);
+ fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') =3D=3D 0: @\n", s);
+ #include "vers2.h" (after macro replacement, before file access)
+ "hello";
+ "hello, world"
+
+ Space around the # and ## tokens in the macro definition is optional.
+
+ And finally, to demonstrate the redefinition rules, the following
+ sequence is valid.
+
+ #define OBJ_LIKE (1-1)
+ #define OBJ_LIKE /* white space */ (1-1) /* other */
+ #define FTN_LIKE(a) ( a )
+ #define FTN_LIKE( a )( /* note the white space */ \
+ a /* other stuff on this line
+ */ )
+
+ But the following redefinitions are invalid:=20
+
+ #define OBJ_LIKE (0) /* different token sequence */
+ #define OBJ_LIKE (1 - 1) /* different white space */
+ #define FTN_LIKE(b) ( a ) /* different parameter usage */
+ #define FTN_LIKE(b) ( b ) /* different parameter spelling */
+
+
+ 3.8.4 Line control
+
+ Constraints
+
+ The string literal of a #line directive, if present, shall be a
+ character string literal.
+
+ Semantics
+
+ The line number of the current source line is one greater than the
+ number of new-line characters read or introduced in translation phase
+ 1 ($2.1.1.2) while processing the source file to the current token.
+
+ A preprocessing directive of the form=20
+
+ # line digit-sequence new-line
+
+ causes the implementation to behave as if the following sequence of
+ source lines begins with a source line that has a line number as
+ specified by the digit sequence (interpreted as a decimal integer).
+
+ A preprocessing directive of the form=20
+
+ # line digit-sequence " s-char-sequence&lt;opt&gt;" new-line
+
+ sets the line number similarly and changes the presumed name of the
+ source file to be the contents of the character string literal.
+
+ A preprocessing directive of the form=20
+
+ # line pp-tokens new-line
+
+ (that does not match one of the two previous forms) is permitted. The
+ preprocessing tokens after line on the directive are processed just as
+ in normal text (each identifier currently defined as a macro name is
+ replaced by its replacement list of preprocessing tokens). The
+ directive resulting after all replacements shall match one of the two
+ previous forms and is then processed as appropriate.
+
+
+ 3.8.5 Error directive
+
+ Semantics
+
+ A preprocessing directive of the form=20
+
+ # error pp-tokens&lt;opt&gt; new-line
+
+ causes the implementation to produce a diagnostic message that
+ includes the specified sequence of preprocessing tokens.
+
+
+ 3.8.6 Pragma directive
+
+ Semantics
+
+ A preprocessing directive of the form=20
+
+ # pragma pp-tokens&lt;opt&gt; new-line
+
+ causes the implementation to behave in an implementation-defined
+ manner. Any pragma that is not recognized by the implementation is
+ ignored.
+
+
+ 3.8.7 Null directive
+
+ Semantics
+
+ A preprocessing directive of the form=20
+
+ # new-line
+
+ has no effect. =20
+
+
+ 3.8.8 Predefined macro names
+
+ The following macro names shall be defined by the implementation:
+ The line number of the current source line (a decimal constant). The
+ presumed name of the source file (a character string literal). The
+ date of translation of the source file (a character string literal of
+ the form Mmm dd yyyy , where the names of the months are the same as
+ those generated by the asctime function, and the first character of dd
+ is a space character if the value is less than 10). If the date of
+ translation is not available, an implementation-defined valid date
+ shall be supplied. The time of translation of the source file (a
+ character string literal of the form hh:mm:ss as in the time generated
+ by the asctime function). If the time of translation is not
+ available, an implementation-defined valid time shall be supplied.
+ the decimal constant 1./79/
+
+ The values of the predefined macros (except for __LINE__ and
+ __FILE__ ) remain constant throughout the translation unit.
+
+ None of these macro names, nor the identifier defined , shall be
+ the subject of a #define or a #undef preprocessing directive. All
+ predefined macro names shall begin with a leading underscore followed
+ by an upper-case letter or a second underscore.
+
+ Forward references: the asctime function ($4.12.3.1). =20
+
+
+ 3.9 FUTURE LANGUAGE DIRECTIONS
+
+
+ 3.9.1 External names
+
+ Restriction of the significance of an external name to fewer than
+ 31 characters or to only one case is an obsolescent feature that is a
+ concession to existing implementations.
+
+
+ 3.9.2 Character escape sequences
+
+ Lower-case letters as escape sequences are reserved for future
+ standardization. Other characters may be used in extensions.
+
+
+ 3.9.3 Storage-class specifiers
+
+ The placement of a storage-class specifier other than at the
+ beginning of the declaration specifiers in a declaration is an
+ obsolescent feature.
+
+
+ 3.9.4 Function declarators
+
+ The use of function declarators with empty parentheses (not
+ prototype-format parameter type declarators) is an obsolescent
+ feature.
+
+
+ 3.9.5 Function definitions
+
+ The use of function definitions with separate parameter identifier
+ and declaration lists (not prototype-format parameter type and
+ identifier declarators) is an obsolescent feature.
+
+
+ 4. LIBRARY
+
+ 4.1 INTRODUCTION
+
+ 4.1.1 Definitions of terms
+
+ A string is a contiguous sequence of characters terminated by and
+ including the first null character. It is represented by a pointer to
+ its initial (lowest addressed) character and its length is the number
+ of characters preceding the null character.
+
+ A letter is a printing character in the execution character set
+ corresponding to any of the 52 required lower-case and upper-case
+ letters in the source character set, listed in $2.2.1.
+
+ The decimal-point character is the character used by functions that
+ convert floating-point numbers to or from character sequences to
+ denote the beginning of the fractional part of such character
+ sequences./80/ It is represented in the text and examples by a period,
+ but may be changed by the setlocale function.
+
+ Forward references: character handling ($4.3), the setlocale function
+ ($4.4.1.1).
+
+
+ 4.1.2 Standard headers
+
+ Each library function is declared in a header, /81/ whose contents
+ are made available by the #include preprocessing directive. The
+ header declares a set of related functions, plus any necessary types
+ and additional macros needed to facilitate their use. Each header
+ declares and defines only those identifiers listed in its associated
+ section. All external identifiers declared in any of the headers are
+ reserved, whether or not the associated header is included. All
+ external identifiers that begin with an underscore are reserved. All
+ other identifiers that begin with an underscore and either an
+ upper-case letter or another underscore are reserved. If the program
+ defines an external identifier with the same name as a reserved
+ external identifier, even in a semantically equivalent form, the
+ behavior is undefined./82/
+
+ The standard headers are=20
+
+ &lt;assert.h&gt; &lt;locale.h&gt; =
+ &lt;stddef.h&gt;
+ &lt;ctype.h&gt; &lt;math.h&gt; =
+ &lt;stdio.h&gt;
+ &lt;errno.h&gt; &lt;setjmp.h&gt; =
+ &lt;stdlib.h&gt;
+ &lt;float.h&gt; &lt;signal.h&gt; =
+ &lt;string.h&gt;
+ &lt;limits.h&gt; &lt;stdarg.h&gt; =
+ &lt;time.h&gt;
+
+
+ If a file with the same name as one of the above &lt; and &gt; delimited
+ sequences, not provided as part of the implementation, is placed in
+ any of the standard places for a source file to be included, the
+ behavior is undefined.
+
+ Headers may be included in any order; each may be included more
+ than once in a given scope, with no effect different from being
+ included only once, except that the effect of including &lt;assert.h&gt;
+ depends on the definition of NDEBUG . If used, a header shall be
+ included outside of any external declaration or definition, and it
+ shall first be included before the first reference to any of the
+ functions or objects it declares, or to any of the types or macros it
+ defines. Furthermore, the program shall not have any macros with
+ names lexically identical to keywords currently defined prior to the
+ inclusion.
+
+ Forward references: diagnostics ($4.2). =20
+
+
+ 4.1.3 Errors &lt;errno.h&gt;
+
+ The header &lt;errno.h&gt; defines several macros, all relating to the
+ reporting of error conditions.
+
+ The macros are=20
+
+ EDOM
+ ERANGE
+
+ which expand to distinct nonzero integral constant expressions; and=20
+
+ errno
+
+ which expands to a modifiable lvalue/83/ that has type int , the value
+ of which is set to a positive error number by several library
+ functions. It is unspecified whether errno is a macro or an
+ identifier declared with external linkage. If a macro definition is
+ suppressed in order to access an actual object, or a program defines
+ an external identifier with the name errno , the behavior is
+ undefined.
+
+ The value of errno is zero at program startup, but is never set to
+ zero by any library function./84/ The value of errno may be set to
+ nonzero by a library function call whether or not there is an error,
+ provided the use of errno is not documented in the description of the
+ function in the Standard.
+
+ Additional macro definitions, beginning with E and a digit or E and
+ an upper-case letter,/85/ may also be specified by the implementation.
+
+
+ 4.1.4 Limits &lt;float.h&gt; and &lt;limits.h&gt;
+
+ The headers &lt;float.h&gt; and &lt;limits.h&gt; define several macros t=
+ hat
+ expand to various limits and parameters.
+
+ The macros, their meanings, and their minimum magnitudes are listed
+ in $2.2.4.2.
+
+
+ 4.1.5 Common definitions &lt;stddef.h&gt;
+
+ The following types and macros are defined in the standard header
+ &lt;stddef.h&gt; . Some are also defined in other headers, as noted in
+ their respective sections.
+
+ The types are=20
+
+ ptrdiff_t
+
+ which is the signed integral type of the result of subtracting two
+ pointers;
+
+ size_t
+
+ which is the unsigned integral type of the result of the sizeof
+ operator; and
+
+ wchar_t
+
+ which is an integral type whose range of values can represent distinct
+ codes for all members of the largest extended character set specified
+ among the supported locales; the null character shall have the code
+ value zero and each member of the basic character set defined in
+ $2.2.1 shall have a code value equal to its value when used as the
+ lone character in an integer character constant.
+
+ The macros are=20
+
+ NULL
+
+ which expands to an implementation-defined null pointer constant; and=20
+
+ offsetof( type, member-designator)
+
+ which expands to an integral constant expression that has type size_t,=20
+ the value of which is the offset in bytes, to the structure member
+ (designated by member-designator ), from the beginning of its
+ structure (designated by type ). The member-designator shall be such
+ that given
+
+ static type t;
+
+ then the expression &amp;(t. member-designator ) evaluates to an address
+ constant. (If the specified member is a bit-field, the behavior is
+ undefined.)
+
+ Forward references: localization ($4.4). =20
+
+
+ 4.1.6 Use of library functions
+
+ Each of the following statements applies unless explicitly stated
+ otherwise in the detailed descriptions that follow. If an argument to
+ a function has an invalid value (such as a value outside the domain of
+ the function, or a pointer outside the address space of the program,
+ or a null pointer), the behavior is undefined. Any function declared
+ in a header may be implemented as a macro defined in the header, so a
+ library function should not be declared explicitly if its header is
+ included. Any macro definition of a function can be suppressed
+ locally by enclosing the name of the function in parentheses, because
+ the name is then not followed by the left parenthesis that indicates
+ expansion of a macro function name. For the same syntactic reason, it
+ is permitted to take the address of a library function even if it is
+ also defined as a macro./86/ The use of #undef to remove any macro
+ definition will also ensure that an actual function is referred to.
+ Any invocation of a library function that is implemented as a macro
+ will expand to code that evaluates each of its arguments exactly once,
+ fully protected by parentheses where necessary, so it is generally
+ safe to use arbitrary expressions as arguments. Likewise, those
+ function-like macros described in the following sections may be
+ invoked in an expression anywhere a function with a compatible return
+ type could be called./87/
+
+ Provided that a library function can be declared without reference
+ to any type defined in a header, it is also permissible to declare the
+ function, either explicitly or implicitly, and use it without
+ including its associated header. If a function that accepts a
+ variable number of arguments is not declared (explicitly or by
+ including its associated header), the behavior is undefined.
+
+ Examples
+
+ The function atoi may be used in any of several ways:=20
+
+ * by use of its associated header (possibly generating a macro expansion)=
+ =20
+
+ #include &lt;stdlib.h&gt;
+ const char *str;
+ /*...*/
+ i =3D atoi(str);
+
+
+
+ * by use of its associated header (assuredly generating a true
+ function reference)
+
+ #include &lt;stdlib.h&gt;
+ #undef atoi
+ const char *str;
+ /*...*/
+ i =3D atoi(str);
+
+ or=20
+
+ #include &lt;stdlib.h&gt;
+ const char *str;
+ /*...*/
+ i =3D (atoi)(str);
+
+ * by explicit declaration=20
+
+ extern int atoi(const char *);
+ const char *str;
+ /*...*/
+ i =3D atoi(str);
+
+ * by implicit declaration=20
+
+ const char *str;
+ /*...*/
+ i =3D atoi(str);
+
+
+ 4.2 DIAGNOSTICS &lt;assert.h&gt;
+
+ The header &lt;assert.h&gt; defines the assert macro and refers to
+ another macro,
+
+ NDEBUG
+
+ which is not defined by &lt;assert.h&gt; . If NDEBUG is defined as a macro
+ name at the point in the source file where &lt;assert.h&gt; is included, th=
+ e
+ assert macro is defined simply as
+
+ #define assert(ignore) ((void)0)
+
+ The assert macro shall be implemented as a macro, not as an actual
+ function. If the macro definition is suppressed in order to access an
+ actual function, the behavior is undefined.
+
+
+ 4.2.1 Program diagnostics
+
+ 4.2.1.1 The assert macro
+
+ Synopsis
+
+ #include &lt;assert.h&gt;
+ void assert(int expression);
+
+ Description
+
+ The assert macro puts diagnostics into programs. When it is
+ executed, if expression is false (that is, compares equal to 0), the
+ assert macro writes information about the particular call that failed
+ (including the text of the argument, the name of the source file, and
+ the source line number EM the latter are respectively the values of
+ the preprocessing macros __FILE__ and __LINE__ ) on the standard error
+ file in an implementation-defined format./88/
+ expression , xyz , nnn It then calls the abort function. =20
+
+ Returns
+
+ The assert macro returns no value. =20
+
+ Forward references: the abort function ($4.10.4.1). =20
+
+
+ 4.3 CHARACTER HANDLING &lt;ctype.h&gt;
+
+ The header &lt;ctype.h&gt; declares several functions useful for testing
+ and mapping characters./89/ In all cases the argument is an int , the
+ value of which shall be representable as an unsigned char or shall
+ equal the value of the macro EOF . If the argument has any other
+ value, the behavior is undefined.
+
+ The behavior of these functions is affected by the current locale.
+ Those functions that have no implementation-defined aspects in the C
+ locale are noted below.
+
+ The term printing character refers to a member of an
+ implementation-defined set of characters, each of which occupies one
+ printing position on a display device; the term control character
+ refers to a member of an implementation-defined set of characters that
+ are not printing characters./90/
+
+ Forward references: EOF ($4.9.1), localization ($4.4). =20
+
+
+ 4.3.1 Character testing functions
+
+ The functions in this section return nonzero (true) if and only if
+ the value of the argument c conforms to that in the description of the
+ function.
+
+
+ 4.3.1.1 The isalnum function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isalnum(int c);
+
+ Description
+
+ The isalnum function tests for any character for which isalpha or
+ isdigit is true.
+
+
+ 4.3.1.2 The isalpha function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isalpha(int c);
+
+ Description
+
+ The isalpha function tests for any character for which isupper or
+ islower is true, or any of an implementation-defined set of characters
+ for which none of iscntrl , isdigit , ispunct , or isspace is true.
+ In the C locale, isalpha returns true only for the characters for
+ which isupper or islower is true.
+
+
+ 4.3.1.3 The iscntrl function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int iscntrl(int c);
+
+ Description
+
+ The iscntrl function tests for any control character. =20
+
+
+ 4.3.1.4 The isdigit function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isdigit(int c);
+
+ Description
+
+ The isdigit function tests for any decimal-digit character (as
+ defined in $2.2.1).
+
+
+ 4.3.1.5 The isgraph function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isgraph(int c);
+
+ Description
+
+ The isgraph function tests for any printing character except space (' ')=
+ . =20
+
+
+ 4.3.1.6 The islower function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int islower(int c);
+
+ Description
+
+ The islower function tests for any lower-case letter or any of an
+ implementation-defined set of characters for which none of iscntrl ,
+ isdigit , ispunct , or isspace is true. In the C locale, islower
+ returns true only for the characters defined as lower-case letters (as
+ defined in $2.2.1).
+
+
+ 4.3.1.7 The isprint function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isprint(int c);
+
+ Description
+
+ The isprint function tests for any printing character including
+ space (' ').
+
+
+ 4.3.1.8 The ispunct function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int ispunct(int c);
+
+ Description
+
+ The ispunct function tests for any printing character except space
+ (' ') or a character for which isalnum is true.
+
+
+ 4.3.1.9 The isspace function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isspace(int c);
+
+ Description
+
+ The isspace function tests for the standard white-space characters
+ or for any of an implementation-defined set of characters for which
+ isalnum is false. The standard white-space characters are the
+ following: space (' '), form feed ('\f'), new-line ('\n'), carriage
+ return ('\r'), horizontal tab ('\t'), and vertical tab ('\v'). In the
+ C locale, isspace returns true only for the standard white-space
+ characters.
+
+
+ 4.3.1.10 The isupper function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isupper(int c);
+
+ Description
+
+ The isupper function tests for any upper-case letter or any of an
+ implementation-defined set of characters for which none of iscntrl ,
+ isdigit , ispunct , or isspace is true. In the C locale, isupper
+ returns true only for the characters defined as upper-case letters (as
+ defined in $2.2.1).
+
+ 4.3.1.11 The isxdigit function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int isxdigit(int c);
+
+ Description
+
+ The isxdigit function tests for any hexadecimal-digit character (as
+ defined in $3.1.3.2).
+
+
+ 4.3.2 Character case mapping functions
+
+ 4.3.2.1 The tolower function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int tolower(int c);
+
+ Description
+
+ The tolower function converts an upper-case letter to the
+ corresponding lower-case letter.
+
+ Returns
+
+ If the argument is an upper-case letter, the tolower function
+ returns the corresponding lower-case letter if there is one; otherwise
+ the argument is returned unchanged. In the C locale, tolower maps
+ only the characters for which isupper is true to the corresponding
+ characters for which islower is true.
+
+
+ 4.3.2.2 The toupper function
+
+ Synopsis
+
+ #include &lt;ctype.h&gt;
+ int toupper(int c);
+
+ Description
+
+ The toupper function converts a lower-case letter to the corresponding u=
+ pper-case letter. =20
+
+ Returns
+
+ If the argument is a lower-case letter, the toupper function
+ returns the corresponding upper-case letter if there is one; otherwise
+ the argument is returned unchanged. In the C locale, toupper maps
+ only the characters for which islower is true to the corresponding
+ characters for which isupper is true.
+
+
+ 4.4 LOCALIZATION &lt;locale.h&gt;
+
+ The header &lt;locale.h&gt; declares two functions, one type, and define=
+ s
+ several macros.
+
+ The type is=20
+
+ struct lconv
+
+ which contains members related to the formatting of numeric values.
+ The structure shall contain at least the following members, in any
+ order. The semantics of the members and their normal ranges is
+ explained in $4.4.2.1. In the C locale, the members shall have the
+ values specified in the comments.
+
+ char *decimal_point; /* "." */
+ char *thousands_sep; /* "" */
+ char *grouping; /* "" */
+ char *int_curr_symbol; /* "" */
+ char *currency_symbol; /* "" */
+ char *mon_decimal_point; /* "" */
+ char *mon_thousands_sep; /* "" */
+ char *mon_grouping; /* "" */
+ char *positive_sign; /* "" */
+ char *negative_sign; /* "" */
+ char int_frac_digits; /* CHAR_MAX */
+ char frac_digits; /* CHAR_MAX */
+ char p_cs_precedes; /* CHAR_MAX */
+ char p_sep_by_space; /* CHAR_MAX */
+ char n_cs_precedes; /* CHAR_MAX */
+ char n_sep_by_space; /* CHAR_MAX */
+ char p_sign_posn; /* CHAR_MAX */
+ char n_sign_posn; /* CHAR_MAX */
+
+ The macros defined are NULL (described in $4.1.5); and=20
+
+ LC_ALL
+ LC_COLLATE
+ LC_CTYPE
+ LC_MONETARY
+ LC_NUMERIC
+ LC_TIME
+
+ which expand to distinct integral constant expressions, suitable for
+ use as the first argument to the setlocale function. Additional macro
+ definitions, beginning with the characters LC_ and an upper-case
+ letter,/91/ may also be specified by the implementation.
+
+
+ 4.4.1 Locale control
+
+ 4.4.1.1 The setlocale function
+
+ Synopsis
+
+ #include &lt;locale.h&gt;
+ char *setlocale(int category, const char *locale);
+
+ Description
+
+ The setlocale function selects the appropriate portion of the
+ program's locale as specified by the category and locale arguments.
+ The setlocale function may be used to change or query the program's
+ entire current locale or portions thereof. The value LC_ALL for
+ category names the program's entire locale; the other values for
+ category name only a portion of the program's locale. LC_COLLATE
+ affects the behavior of the strcoll and strxfrm functions. LC_CTYPE
+ affects the behavior of the character handling functions/92/ and the
+ multibyte functions. LC_MONETARY affects the monetary formatting
+ information returned by the localeconv function. LC_NUMERIC affects
+ the decimal-point character for the formatted input/output functions
+ and the string conversion functions, as well as the non-monetary
+ formatting information returned by the localeconv function. LC_TIME
+ affects the behavior of the strftime function.
+
+ A value of "C" for locale specifies the minimal environment for C
+ translation; a value of "" for locale specifies the implementation-defined
+ native environment. Other implementation-defined strings may be passed
+ as the second argument to setlocale .
+
+ At program startup, the equivalent of=20
+
+ setlocale(LC_ALL, "C");
+
+ is executed.
+
+ The implementation shall behave as if no library function calls the
+ setlocale function.
+
+ Returns
+
+ If a pointer to a string is given for locale and the selection can
+ be honored, the setlocale function returns the string associated with
+ the specified category for the new locale. If the selection cannot be
+ honored, the setlocale function returns a null pointer and the
+ program's locale is not changed.
+
+ A null pointer for locale causes the setlocale function to return
+ the string associated with the category for the program's current
+ locale; the program's locale is not changed.
+
+ The string returned by the setlocale function is such that a
+ subsequent call with that string and its associated category will
+ restore that part of the program's locale. The string returned shall
+ not be modified by the program, but may be overwritten by a subsequent
+ call to the setlocale function.
+
+ Forward references: formatted input/output functions ($4.9.6), the
+ multibyte character functions ($4.10.7), the multibyte string
+ functions ($4.10.8), string conversion functions ($4.10.1), the
+ strcoll function ($4.11.4.3), the strftime function ($4.12.3.5), the
+ strxfrm function ($4.11.4.5).
+
+
+ 4.4.2 Numeric formatting convention inquiry
+
+ 4.4.2.1 The localeconv function
+
+ Synopsis
+
+ #include &lt;locale.h&gt;
+ struct lconv *localeconv(void);
+
+ Description
+
+ The localeconv function sets the components of an object with type
+ struct lconv with values appropriate for the formatting of numeric
+ quantities (monetary and otherwise) according to the rules of the
+ current locale.
+
+ The members of the structure with type char * are strings, any of
+ which (except decimal_point ) can point to , to indicate that the
+ value is not available in the current locale or is of zero length.
+ The members with type char are nonnegative numbers, any of which can
+ be CHAR_MAX to indicate that the value is not available in the current
+ locale. The members include the following: The decimal-point
+ character used to format non-monetary quantities. The character used
+ to separate groups of digits to the left of the decimal-point
+ character in formatted non-monetary quantities. A string whose
+ elements indicate the size of each group of digits in formatted
+ non-monetary quantities. The international currency symbol applicable
+ to the current locale. The first three characters contain the
+ alphabetic international currency symbol in accordance with those
+ specified in ISO 4217 Codes for the Representation of Currency and
+ Funds .The fourth character (immediately preceding the null character)
+ is the character used to separate the international currency symbol
+ from the monetary quantity. The local currency symbol applicable to
+ the current locale. The decimal-point used to format monetary
+ quantities. The separator for groups of digits to the left of the
+ decimal-point in formatted monetary quantities. A string whose
+ elements indicate the size of each group of digits in formatted
+ monetary quantities. The string used to indicate a nonnegative-valued
+ formatted monetary quantity. The string used to indicate a
+ negative-valued formatted monetary quantity. The number of fractional
+ digits (those to the right of the decimal-point) to be displayed in a
+ internationally formatted monetary quantity. The number of fractional
+ digits (those to the right of the decimal-point) to be displayed in a
+ formatted monetary quantity. Set to 1 or 0 if the currency_symbol
+ respectively precedes or succeeds the value for a nonnegative
+ formatted monetary quantity. Set to 1 or 0 if the currency_symbol
+ respectively is or is not separated by a space from the value for a
+ nonnegative formatted monetary quantity. Set to 1 or 0 if the
+ currency_symbol respectively precedes or succeeds the value for a
+ negative formatted monetary quantity. Set to 1 or 0 if the
+ currency_symbol respectively is or is not separated by a space from
+ the value for a negative formatted monetary quantity. Set to a value
+ indicating the positioning of the positive_sign for a nonnegative
+ formatted monetary quantity. Set to a value indicating the
+ positioning of the negative_sign for a negative formatted monetary
+ quantity.
+
+ The elements of grouping and mon_grouping are interpreted according
+ to the following: No further grouping is to be performed. The
+ previous element is to be repeatedly used for the remainder of the
+ digits. The value is the number of digits that comprise the current
+ group. The next element is examined to determine the size of the next
+ group of digits to the left of the current group.
+
+ The value of p_sign_posn and n_sign_posn is interpreted according
+ to the following: Parentheses surround the quantity and
+ currency_symbol. The sign string precedes the quantity and
+ currency_symbol. The sign string succeeds the quantity and
+ currency_symbol. The sign string immediately precedes the
+ currency_symbol. The sign string immediately succeeds the
+ currency_symbol.
+
+ The implementation shall behave as if no library function calls the
+ localeconv function.
+
+ Returns
+
+ The localeconv function returns a pointer to the filled-in object.
+ The structure pointed to by the return value shall not be modified by
+ the program, but may be overwritten by a subsequent call to the
+ localeconv function. In addition, calls to the setlocale function
+ with categories LC_ALL , LC_MONETARY , or LC_NUMERIC may overwrite the
+ contents of the structure.
+
+ Examples
+
+ The following table illustrates the rules used by four countries to
+ format monetary quantities.
+
+ Country Positive format Negative format International format
+
+ Italy L.1.234 -L.1.234 ITL.1.234
+ Netherlands F 1.234,56 F -1.234,56 NLG 1.234,56
+ Norway kr1.234,56 kr1.234,56- NOK 1.234,56
+ Switzerland SFrs.1,234.56 SFrs.1,234.56C CHF 1,234.56
+
+
+ For these four countries, the respective values for the monetary
+ members of the structure returned by localeconv are:
+
+ Italy Netherlands Norway Switzerland
+
+ int_curr_symbol "ITL." "NLG " "NOK " "CHF "
+ currency_symbol "L." "F" "kr" "SFrs."
+ mon_decimal_point "" "," "," "."
+ mon_thousands_sep "." "." "." ","
+ mon_grouping "\3" "\3" "\3" "\3"
+ positive_sign "" "" "" ""
+ negative_sign "-" "-" "-" "C"
+ int_frac_digits 0 2 2 2
+ frac_digits 0 2 2 2
+ p_cs_precedes 1 1 1 1
+ p_sep_by_space 0 1 0 0
+ n_cs_precedes 1 1 1 1
+ n_sep_by_space 0 1 0 0
+ p_sign_posn 1 1 1 1
+ n_sign_posn 1 4 2 2
+
+
+
+ 4.5 MATHEMATICS &lt;math.h&gt;
+
+ The header &lt;math.h&gt; declares several mathematical functions and
+ defines one macro. The functions take double-precision arguments and
+ return double-precision values./93/ Integer arithmetic functions and
+ conversion functions are discussed later.
+
+ The macro defined is=20
+
+ HUGE_VAL
+
+ which expands to a positive double expression, not necessarily
+ representable as a float .
+
+ Forward references: integer arithmetic functions ($4.10.6), the atof
+ function ($4.10.1.1), the strtod function ($4.10.1.4).
+
+
+ 4.5.1 Treatment of error conditions
+
+ The behavior of each of these functions is defined for all
+ representable values of its input arguments. Each function shall
+ execute as if it were a single operation, without generating any
+ externally visible exceptions.
+
+ For all functions, a domain error occurs if an input argument is
+ outside the domain over which the mathematical function is defined.
+ The description of each function lists any required domain errors; an
+ implementation may define additional domain errors, provided that such
+ errors are consistent with the mathematical definition of the
+ function./94/ On a domain error, the function returns an
+ implementation-defined value; the value of the macro EDOM is stored in
+ errno .
+
+ Similarly, a range error occurs if the result of the function
+ cannot be represented as a double value. If the result overflows (the
+ magnitude of the result is so large that it cannot be represented in
+ an object of the specified type), the function returns the value of
+ the macro HUGE_VAL , with the same sign as the correct value of the
+ function; the value of the macro ERANGE is stored in errno . If the
+ result underflows (the magnitude of the result is so small that it
+ cannot be represented in an object of the specified type), the
+ function returns zero; whether the integer expression errno acquires
+ the value of the macro ERANGE is implementation-defined.
+
+
+ 4.5.2 Trigonometric functions
+
+ 4.5.2.1 The acos function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double acos(double x);
+
+ Description
+
+ The acos function computes the principal value of the arc cosine of x.
+ A domain error occurs for arguments not in the range [-1, +1].
+
+ Returns
+
+ The acos function returns the arc cosine in the range [0, PI] radians. =
+ =20
+
+
+ 4.5.2.2 The asin function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double asin(double x);
+
+ Description
+
+ The asin function computes the principal value of the arc sine of x.
+ A domain error occurs for arguments not in the range [-1, +1].
+
+ Returns
+
+ The asin function returns the arc sine in the range [-PI/2, +PI/2]
+ radians.
+
+
+ 4.5.2.3 The atan function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double atan(double x);
+
+ Description
+
+ The atan function computes the principal value of the arc tangent of x. =
+ =20
+
+ Returns
+
+ The atan function returns the arc tangent in the range [-PI/2, +PI/2]
+ radians.
+
+
+ 4.5.2.4 The atan2 function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double atan2(double y, double x);
+
+ Description
+
+ The atan2 function computes the principal value of the arc tangent
+ of y/x , using the signs of both arguments to determine the quadrant
+ of the return value. A domain error may occur if both arguments are
+ zero.
+
+ Returns
+
+ The atan2 function returns the arc tangent of y/x , in the range
+ [-PI, +PI] radians.
+
+
+ 4.5.2.5 The cos function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double cos(double x);
+
+ Description
+
+ The cos function computes the cosine of x (measured in radians). A
+ large magnitude argument may yield a result with little or no
+ significance.
+
+ Returns
+
+ The cos function returns the cosine value. =20
+
+
+ 4.5.2.6 The sin function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double sin(double x);
+
+ Description
+
+ The sin function computes the sine of x (measured in radians). A
+ large magnitude argument may yield a result with little or no
+ significance.
+
+ Returns
+
+ The sin function returns the sine value. =20
+
+
+ 4.5.2.7 The tan function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double tan(double x);
+
+ Description
+
+ The tan function returns the tangent of x (measured in radians). A larg=
+ e magnitude argument may yield a result with little or no significance. =20
+
+ Returns
+
+ The tan function returns the tangent value. =20
+
+
+ 4.5.3 Hyperbolic functions
+
+ 4.5.3.1 The cosh function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double cosh(double x);
+
+ Description
+
+ The cosh function computes the hyperbolic cosine of x. A range
+ error occurs if the magnitude of x is too large.
+
+ Returns
+
+ The cosh function returns the hyperbolic cosine value. =20
+
+
+ 4.5.3.2 The sinh function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double sinh(double x);
+
+ Description
+
+ The sinh function computes the hyperbolic sine of x . A range error occ=
+ urs if the magnitude of x is too large. =20
+
+ Returns
+
+ The sinh function returns the hyperbolic sine value. =20
+
+
+ 4.5.3.3 The tanh function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double tanh(double x);
+
+ Description
+
+ The tanh function computes the hyperbolic tangent of x . =20
+
+ Returns
+
+ The tanh function returns the hyperbolic tangent value. =20
+
+
+ 4.5.4 Exponential and logarithmic functions
+
+ 4.5.4.1 The exp function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double exp(double x);
+
+ Description
+
+ The exp function computes the exponential function of x . A range
+ error occurs if the magnitude of x is too large.
+
+ Returns
+
+ The exp function returns the exponential value. =20
+
+
+ 4.5.4.2 The frexp function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double frexp(double value, int *exp);
+
+ Description
+
+ The frexp function breaks a floating-point number into a normalized
+ fraction and an integral power of 2. It stores the integer in the int
+ object pointed to by exp .
+
+ Returns
+
+ The frexp function returns the value x , such that x is a double
+ with magnitude in the interval [1/2, 1) or zero, and value equals x
+ times 2 raised to the power *exp . If value is zero, both parts of
+ the result are zero.
+
+
+ 4.5.4.3 The ldexp function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double ldexp(double x, int exp);
+
+ Description
+
+ The ldexp function multiplies a floating-point number by an
+ integral power of 2. A range error may occur.
+
+ Returns
+
+ The ldexp function returns the value of x times 2 raised to the
+ power exp .
+
+
+ 4.5.4.4 The log function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double log(double x);
+
+ Description
+
+ The log function computes the natural logarithm of x. A domain
+ error occurs if the argument is negative. A range error occurs if the
+ argument is zero and the logarithm of zero cannot be represented.
+
+ Returns
+
+ The log function returns the natural logarithm. =20
+
+
+ 4.5.4.5 The log10 function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double log10(double x);
+
+ Description
+
+ The log10 function computes the base-ten logarithm of x . A domain
+ error occurs if the argument is negative. A range error occurs if the
+ argument is zero and the logarithm of zero cannot be represented.
+
+ Returns
+
+ The log10 function returns the base-ten logarithm. =20
+
+
+ 4.5.4.6 The modf function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double modf(double value, double *iptr);
+
+ Description
+
+ The modf function breaks the argument value into integral and
+ fractional parts, each of which has the same sign as the argument. It
+ stores the integral part as a double in the object pointed to by iptr.
+
+ Returns
+
+ The modf function returns the signed fractional part of value . =20
+
+
+ 4.5.5 Power functions
+
+ 4.5.5.1 The pow function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double pow(double x, double y);
+
+ Description
+
+ The pow function computes x raised to the power y . A domain error
+ occurs if x is negative and y is not an integer. A domain error
+ occurs if the result cannot be represented when x is zero and y is
+ less than or equal to zero. A range error may occur.
+
+ Returns
+
+ The pow function returns the value of x raised to the power y . =20
+
+
+ 4.5.5.2 The sqrt function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double sqrt(double x);
+
+ Description
+
+ The sqrt function computes the nonnegative square root of x . A
+ domain error occurs if the argument is negative.
+
+ Returns
+
+ The sqrt function returns the value of the square root. =20
+
+
+ 4.5.6 Nearest integer, absolute value, and remainder functions
+
+ 4.5.6.1 The ceil function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double ceil(double x);
+
+ Description
+
+ The ceil function computes the smallest integral value not less than x .=
+ =20
+
+ Returns
+
+ The ceil function returns the smallest integral value not less than
+ x , expressed as a double.
+
+
+ 4.5.6.2 The fabs function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double fabs(double x);
+
+ Description
+
+ The fabs function computes the absolute value of a floating-point
+ number x .
+
+ Returns
+
+ The fabs function returns the absolute value of x. =20
+
+
+ 4.5.6.3 The floor function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double floor(double x);
+
+ Description
+
+ The floor function computes the largest integral value not greater
+ than x .
+
+ Returns
+
+ The floor function returns the largest integral value not greater
+ than x , expressed as a double.
+
+
+ 4.5.6.4 The fmod function
+
+ Synopsis
+
+ #include &lt;math.h&gt;
+ double fmod(double x, double y);
+
+ Description
+
+ The fmod function computes the floating-point remainder of x/y . =20
+
+ Returns
+
+ The fmod function returns the value x i y , for some integer i such
+ that, if y is nonzero, the result has the same sign as x and magnitude
+ less than the magnitude of y . If y is zero, whether a domain error
+ occurs or the fmod function returns zero is implementation-defined.
+
+
+ 4.6 NON-LOCAL JUMPS &lt;setjmp.h&gt;
+
+ The header &lt;setjmp.h&gt; defines the macro setjmp , and declares one
+ function and one type, for bypassing the normal function call and
+ return discipline./95/
+
+ The type declared is=20
+
+ jmp_buf
+
+ which is an array type suitable for holding the information needed to
+ restore a calling environment.
+
+ It is unspecified whether setjmp is a macro or an identifier
+ declared with external linkage. If a macro definition is suppressed
+ in order to access an actual function, or a program defines an
+ external identifier with the name setjmp , the behavior is undefined.
+
+
+ 4.6.1 Save calling environment
+
+ 4.6.1.1 The setjmp macro
+
+ Synopsis
+
+ #include &lt;setjmp.h&gt;
+ int setjmp(jmp_buf env);
+
+ Description
+
+ The setjmp macro saves its calling environment in its jmp_buf
+ argument for later use by the longjmp function.
+
+ Returns
+
+ If the return is from a direct invocation, the setjmp macro returns
+ the value zero. If the return is from a call to the longjmp function,
+ the setjmp macro returns a nonzero value.
+
+ "Environmental constraint"
+
+ An invocation of the setjmp macro shall appear only in one of the
+ following contexts:
+
+ * the entire controlling expression of a selection or iteration statement;=
+ =20
+
+ * one operand of a relational or equality operator with the other
+ operand an integral constant expression, with the resulting expression
+ being the entire controlling expression of a selection or iteration
+ statement;
+
+ * the operand of a unary ! operator with the resulting expression
+ being the entire controlling expression of a selection or iteration
+ statement; or
+
+ * the entire expression of an expression statement (possibly cast to void)=
+ . =20
+
+
+ 4.6.2 Restore calling environment
+
+ 4.6.2.1 The longjmp function
+
+ Synopsis
+
+ #include &lt;setjmp.h&gt;
+ void longjmp(jmp_buf env, int val);
+
+ Description
+
+ The longjmp function restores the environment saved by the most
+ recent invocation of the setjmp macro in the same invocation of the
+ program, with the corresponding jmp_buf argument. If there has been
+ no such invocation, or if the function containing the invocation of
+ the setjmp macro has terminated execution/96/ in the interim, the
+ behavior is undefined.
+
+ All accessible objects have values as of the time longjmp was
+ called, except that the values of objects of automatic storage
+ duration that do not have volatile type and have been changed between
+ the setjmp invocation and longjmp call are indeterminate.
+
+ As it bypasses the usual function call and return mechanisms, the
+ longjmp function shall execute correctly in contexts of interrupts,
+ signals and any of their associated functions. However, if the
+ longjmp function is invoked from a nested signal handler (that is,
+ from a function invoked as a result of a signal raised during the
+ handling of another signal), the behavior is undefined.
+
+ Returns
+
+ After longjmp is completed, program execution continues as if the
+ corresponding invocation of the setjmp macro had just returned the
+ value specified by val . The longjmp function cannot cause the setjmp
+ macro to return the value 0; if val is 0, the setjmp macro returns the
+ value 1.
+
+
+ 4.7 SIGNAL HANDLING &lt;signal.h&gt;
+
+ The header &lt;signal.h&gt; declares a type and two functions and define=
+ s
+ several macros, for handling various signals (conditions that may be
+ reported during program execution).
+
+ The type defined is=20
+
+ sig_atomic_t
+
+ which is the integral type of an object that can be accessed as an
+ atomic entity, even in the presence of asynchronous interrupts.
+
+ The macros defined are=20
+
+ SIG_DFL
+ SIG_ERR
+ SIG_IGN
+
+ which expand to distinct constant expressions that have type
+ compatible with the second argument to and the return value of the
+ signal function, and whose value compares unequal to the address of
+ any declarable function; and the following, each of which expands to a
+ positive integral constant expression that is the signal number
+ corresponding to the specified condition:
+
+ SIGABRT abnormal termination, such as is initiated by the abort function
+
+ SIGFPE an erroneous arithmetic operation, such as zero divide or an
+ operation resulting in overflow
+
+ SIGILL detection of an invalid function image, such as an illegal=20
+ instruction
+
+ SIGINT receipt of an interactive attention signal=20
+
+ SIGSEGV an invalid access to storage=20
+
+ SIGTERM a termination request sent to the program
+
+ An implementation need not generate any of these signals, except as
+ a result of explicit calls to the raise function. Additional signals
+ and pointers to undeclarable functions, with macro definitions
+ beginning, respectively, with the letters SIG and an upper-case letter
+ or with SIG_ and an upper-case letter,/97/ may also be specified by
+ the implementation. The complete set of signals, their semantics, and
+ their default handling is implementation-defined; all signal values
+ shall be positive.
+
+
+ 4.7.1 Specify signal handling
+
+ 4.7.1.1 The signal function
+
+ Synopsis
+
+ #include &lt;signal.h&gt;
+ void (*signal(int sig, void (*func)(int)))(int);
+
+ Description
+
+ The signal function chooses one of three ways in which receipt of
+ the signal number sig is to be subsequently handled. If the value of
+ func is SIG_DFL , default handling for that signal will occur. If the
+ value of func is SIG_IGN , the signal will be ignored. Otherwise,
+ func shall point to a function to be called when that signal occurs.
+ Such a function is called a signal handler .
+
+ When a signal occurs, if func points to a function, first the
+ equivalent of signal(sig, SIG_DFL); is executed or an
+ implementation-defined blocking of the signal is performed. (If the
+ value of sig is SIGILL, whether the reset to SIG_DFL occurs is
+ implementation-defined.) Next the equivalent of (*func)(sig); is
+ executed. The function func may terminate by executing a return
+ statement or by calling the abort , exit , or longjmp function. If
+ func executes a return statement and the value of sig was SIGFPE or
+ any other implementation-defined value corresponding to a
+ computational exception, the behavior is undefined. Otherwise, the
+ program will resume execution at the point it was interrupted.
+
+ If the signal occurs other than as the result of calling the abort
+ or raise function, the behavior is undefined if the signal handler
+ calls any function in the standard library other than the signal
+ function itself or refers to any object with static storage duration
+ other than by assigning a value to a static storage duration variable
+ of type volatile sig_atomic_t . Furthermore, if such a call to the
+ signal function results in a SIG_ERR return, the value of errno is
+ indeterminate.
+
+ At program startup, the equivalent of=20
+
+ signal(sig, SIG_IGN);
+
+ may be executed for some signals selected in an implementation-defined
+ manner; the equivalent of
+
+ signal(sig, SIG_DFL);
+
+ is executed for all other signals defined by the implementation.
+
+ The implementation shall behave as if no library function calls the
+ signal function.
+
+ Returns
+
+ If the request can be honored, the signal function returns the
+ value of func for the most recent call to signal for the specified
+ signal sig . Otherwise, a value of SIG_ERR is returned and a positive
+ value is stored in errno .
+
+ Forward references: the abort function ($4.10.4.1). =20
+
+
+ 4.7.2 Send signal
+
+ 4.7.2.1 The raise function
+
+ Synopsis
+
+ #include &lt;signal.h&gt;
+ int raise(int sig);
+
+ Description
+
+ The raise function sends the signal sig to the executing program. =20
+
+ Returns
+
+ The raise function returns zero if successful, nonzero if unsuccessful. =
+ =20
+
+
+ 4.8 VARIABLE ARGUMENTS &lt;stdarg.h&gt;
+
+ The header &lt;stdarg.h&gt; declares a type and defines three macros, fo=
+ r
+ advancing through a list of arguments whose number and types are not
+ known to the called function when it is translated.
+
+ A function may be called with a variable number of arguments of
+ varying types. As described in $3.7.1, its parameter list contains
+ one or more parameters. The rightmost parameter plays a special role
+ in the access mechanism, and will be designated parmN in this
+ description.
+
+ The type declared is=20
+
+ va_list
+
+ which is a type suitable for holding information needed by the macros
+ va_start , va_arg , and va_end . If access to the varying arguments
+ is desired, the called function shall declare an object (referred to
+ as ap in this section) having type va_list . The object ap may be
+ passed as an argument to another function; if that function invokes
+ the va_arg macro with parameter ap , the value of ap in the calling
+ function is indeterminate and shall be passed to the va_end macro
+ prior to any further reference to ap .
+
+
+ 4.8.1 Variable argument list access macros
+
+ The va_start and va_arg macros described in this section shall be
+ implemented as macros, not as actual functions. It is unspecified
+ whether va_end is a macro or an identifier declared with external
+ linkage. If a macro definition is suppressed in order to access an
+ actual function, or a program defines an external identifier with the
+ name va_end , the behavior is undefined. The va_start and va_end
+ macros shall be invoked in the function accepting a varying number of
+ arguments, if access to the varying arguments is desired.
+
+
+ 4.8.1.1 The va_start macro
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ void va_start(va_list ap, parmN);
+
+ Description
+
+ The va_start macro shall be invoked before any access to the
+ unnamed arguments.
+
+ The va_start macro initializes ap for subsequent use by va_arg and
+ va_end .
+
+ The parameter parmN is the identifier of the rightmost parameter in
+ the variable parameter list in the function definition (the one just
+ before the , ... ). If the parameter parmN is declared with the
+ register storage class, with a function or array type, or with a type
+ that is not compatible with the type that results after application of
+ the default argument promotions, the behavior is undefined.
+
+ Returns
+
+ The va_start macro returns no value. =20
+
+
+ 4.8.1.2 The va_arg macro
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ type va_arg(va_list ap, type);
+
+ Description
+
+ The va_arg macro expands to an expression that has the type and
+ value of the next argument in the call. The parameter ap shall be the
+ same as the va_list ap initialized by va_start . Each invocation of
+ va_arg modifies ap so that the values of successive arguments are
+ returned in turn. The parameter type is a type name specified such
+ that the type of a pointer to an object that has the specified type
+ can be obtained simply by postfixing a * to type . If there is no
+ actual next argument, or if type is not compatible with the type of
+ the actual next argument (as promoted according to the default
+ argument promotions), the behavior is undefined.
+
+ Returns
+
+ The first invocation of the va_arg macro after that of the va_start
+ macro returns the value of the argument after that specified by parmN.
+ Successive invocations return the values of the remaining arguments
+ in succession.
+
+
+ 4.8.1.3 The va_end macro
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ void va_end(va_list ap);
+
+ Description
+
+ The va_end macro facilitates a normal return from the function
+ whose variable argument list was referred to by the expansion of
+ va_start that initialized the va_list ap . The va_end macro may
+ modify ap so that it is no longer usable (without an intervening
+ invocation of va_start ). If there is no corresponding invocation of
+ the va_start macro, or if the va_end macro is not invoked before the
+ return, the behavior is undefined.
+
+ Returns
+
+ The va_end macro returns no value. =20
+
+ Example
+
+ The function f1 gathers into an array a list of arguments that are
+ pointers to strings (but not more than MAXARGS arguments), then passes
+ the array as a single argument to function f2 . The number of
+ pointers is specified by the first argument to f1 .
+
+ #include &lt;stdarg.h&gt;
+ #define MAXARGS 31
+
+ void f1(int n_ptrs, ...)
+ {
+ va_list ap;
+ char *array[MAXARGS];
+ int ptr_no =3D 0;
+
+ if (n_ptrs &gt; MAXARGS)
+ n_ptrs =3D MAXARGS;
+ va_start(ap, n_ptrs);
+ while (ptr_no &lt; n_ptrs)
+ array[ptr_no++] =3D va_arg(ap, char *);
+ va_end(ap);
+ f2(n_ptrs, array);
+ }
+
+ Each call to f1 shall have visible the definition of the function or a
+ declaration such as
+
+ void f1(int, ...);
+
+
+ 4.9 INPUT/OUTPUT &lt;stdio.h&gt;
+
+ 4.9.1 Introduction
+
+ The header &lt;stdio.h&gt; declares three types, several macros, and man=
+ y
+ functions for performing input and output.
+
+ The types declared are size_t (described in $4.1.5);=20
+
+ FILE
+
+ which is an object type capable of recording all the information
+ needed to control a stream, including its file position indicator, a
+ pointer to its associated buffer, an error indicator that records
+ whether a read/write error has occurred, and an end-of-file indicator
+ that records whether the end of the file has been reached; and
+
+ fpos_t
+
+ which is an object type capable of recording all the information
+ needed to specify uniquely every position within a file.
+
+ The macros are NULL (described in $4.1.5);=20
+
+ _IOFBF
+ _IOLBF
+ _IONBF
+
+ which expand to distinct integral constant expressions, suitable for
+ use as the third argument to the setvbuf function;
+
+ BUFSIZ
+
+ which expands to an integral constant expression, which is the size of
+ the buffer used by the setbuf function;
+
+ EOF
+
+ which expands to a negative integral constant expression that is
+ returned by several functions to indicate end-of-file ,that is, no
+ more input from a stream;
+
+ FOPEN_MAX
+
+ which expands to an integral constant expression that is the minimum
+ number of files that the implementation guarantees can be open
+ simultaneously;
+
+ FILENAME_MAX
+
+ which expands to an integral constant expression that is the maximum
+ length for a file name string that the implementation guarantees can
+ be opened;/98/
+
+ L_tmpnam
+
+ which expands to an integral constant expression that is the size of
+ an array of char large enough to hold a temporary file name string
+ generated by the tmpnam function;
+
+ SEEK_CUR
+ SEEK_END
+ SEEK_SET
+
+ which expand to distinct integral constant expressions, suitable for
+ use as the third argument to the fseek function;
+
+ TMP_MAX
+
+ which expands to an integral constant expression that is the minimum
+ number of unique file names that shall be generated by the tmpnam
+ function;
+
+ stderr
+ stdin=20
+ stdout
+
+ which are expressions of type ``pointer to FILE '' that point to the
+ FILE objects associated, respectively, with the standard error, input,
+ and output streams.
+
+ Forward references: files ($4.9.3), the fseek function ($4.9.9.2),
+ streams ($4.9.2), the tmpnam function ($4.9.4.4).
+
+
+ 4.9.2 Streams
+
+ Input and output, whether to or from physical devices such as
+ terminals and tape drives, or whether to or from files supported on
+ structured storage devices, are mapped into logical data streams
+ ,whose properties are more uniform than their various inputs and
+ outputs. Two forms of mapping are supported, for text streams and for
+ binary streams ./99/
+
+ A text stream is an ordered sequence of characters composed into
+ lines , each line consisting of zero or more characters plus a
+ terminating new-line character. Whether the last line requires a
+ terminating new-line character is implementation-defined. Characters
+ may have to be added, altered, or deleted on input and output to
+ conform to differing conventions for representing text in the host
+ environment. Thus, there need not be a one-to-one correspondence
+ between the characters in a stream and those in the external
+ representation. Data read in from a text stream will necessarily
+ compare equal to the data that were earlier written out to that stream
+ only if: the data consist only of printable characters and the control
+ characters horizontal tab and new-line; no new-line character is
+ immediately preceded by space characters; and the last character is a
+ new-line character. Whether space characters that are written out
+ immediately before a new-line character appear when read in is
+ implementation-defined.
+
+ A binary stream is an ordered sequence of characters that can
+ transparently record internal data. Data read in from a binary stream
+ shall compare equal to the data that were earlier written out to that
+ stream, under the same implementation. Such a stream may, however,
+ have an implementation-defined number of null characters appended.
+
+ "Environmental limits"
+
+ An implementation shall support text files with lines containing at
+ least 254 characters, including the terminating new-line character.
+ The value of the macro BUFSIZ shall be at least 256.
+
+
+ 4.9.3 Files
+
+ A stream is associated with an external file (which may be a
+ physical device) by opening a file, which may involve creating a new
+ file. Creating an existing file causes its former contents to be
+ discarded, if necessary, so that it appears as if newly created. If a
+ file can support positioning requests (such as a disk file, as opposed
+ to a terminal), then a file position indicator /100/ associated with
+ the stream is positioned at the start (character number zero) of the
+ file, unless the file is opened with append mode in which case it is
+ implementation-defined whether the file position indicator is
+ positioned at the beginning or the end of the file. The file position
+ indicator is maintained by subsequent reads, writes, and positioning
+ requests, to facilitate an orderly progression through the file. All
+ input takes place as if characters were read by successive calls to the
+ fgetc function; all output takes place as if characters were written by
+ successive calls to the fputc function.
+
+ Binary files are not truncated, except as defined in $4.9.5.3.
+ Whether a write on a text stream causes the associated file to be
+ truncated beyond that point is implementation-defined.
+
+ When a stream is unbuffered, characters are intended to appear
+ from the source or at the destination as soon as possible. Otherwise
+ characters may be accumulated and transmitted to or from the host
+ environment as a block. When a stream is fully buffered, characters
+ are intended to be transmitted to or from the host environment as a
+ block when a buffer is filled. When a stream is line buffered,
+ characters are intended to be transmitted to or from the host
+ environment as a block when a new-line character is encountered.
+ Furthermore, characters are intended to be transmitted as a block to
+ the host environment when a buffer is filled, when input is requested
+ on an unbuffered stream, or when input is requested on a line buffered
+ stream that requires the transmission of characters from the host
+ environment. Support for these characteristics is
+ implementation-defined, and may be affected via the setbuf and setvbuf
+ functions.
+
+ A file may be disassociated from its controlling stream by closing
+ the file. Output streams are flushed (any unwritten buffer contents
+ are transmitted to the host environment) before the stream is
+ disassociated from the file. The value of a pointer to a FILE object
+ is indeterminate after the associated file is closed (including the
+ standard text streams). Whether a file of zero length (on which no
+ characters have been written by an output stream) actually exists is
+ implementation-defined.
+
+ The file may be subsequently reopened, by the same or another
+ program execution, and its contents reclaimed or modified (if it can
+ be repositioned at its start). If the main function returns to its
+ original caller, or if the exit function is called, all open files are
+ closed (hence all output streams are flushed) before program
+ termination. Other paths to program termination, such as calling the
+ abort function, need not close all files properly.
+
+ The address of the FILE object used to control a stream may be
+ significant; a copy of a FILE object may not necessarily serve in
+ place of the original.
+
+ At program startup, three text streams are predefined and need not
+ be opened explicitly --- standard input (for reading conventional
+ input), standard output (for writing conventional output), and
+ standard error (for writing diagnostic output). When opened, the
+ standard error stream is not fully buffered; the standard input and
+ standard output streams are fully buffered if and only if the stream
+ can be determined not to refer to an interactive device.
+
+ Functions that open additional (nontemporary) files require a file
+ name, which is a string. The rules for composing valid file names are
+ implementation-defined. Whether the same file can be simultaneously
+ open multiple times is also implementation-defined.
+
+ "Environmental limits"
+
+ The value of the macro FOPEN_MAX shall be at least eight, including
+ the three standard text streams.
+
+ Forward references: the exit function ($4.10.4.3), the fgetc function
+ ($4.9.7.1), the fopen function ($4.9.5.3), the fputc function
+ ($4.9.7.3), the setbuf function ($4.9.5.5), the setvbuf function
+ ($4.9.5.6).
+
+
+ 4.9.4 Operations on files
+
+ 4.9.4.1 The remove function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int remove(const char *filename);
+
+ Description
+
+ The remove function causes the file whose name is the string
+ pointed to by filename to be no longer accessible by that name. A
+ subsequent attempt to open that file using that name will fail, unless
+ it is created anew. If the file is open, the behavior of the remove
+ function is implementation-defined.
+
+ Returns
+
+ The remove function returns zero if the operation succeeds, nonzero
+ if it fails.
+
+
+ 4.9.4.2 The rename function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int rename(const char *old, const char *new);
+
+ Description
+
+ The rename function causes the file whose name is the string
+ pointed to by old to be henceforth known by the name given by the
+ string pointed to by new . The file named old is effectively removed.
+ If a file named by the string pointed to by new exists prior to the
+ call to the rename function, the behavior is implementation-defined.
+
+ Returns
+
+ The rename function returns zero if the operation succeeds, nonzero
+ if it fails,/101/ in which case if the file existed previously it is
+ still known by its original name.
+
+
+ 4.9.4.3 The tmpfile function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ FILE *tmpfile(void);
+
+ Description
+
+ The tmpfile function creates a temporary binary file that will
+ automatically be removed when it is closed or at program termination.
+ If the program terminates abnormally, whether an open temporary file
+ is removed is implementation-defined. The file is opened for update
+ with wb+ mode.
+
+ Returns
+
+ The tmpfile function returns a pointer to the stream of the file
+ that it created. If the file cannot be created, the tmpfile function
+ returns a null pointer.
+
+ Forward references: the fopen function ($4.9.5.3). =20
+
+
+ 4.9.4.4 The tmpnam function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ char *tmpnam(char *s);
+
+ Description
+
+ The tmpnam function generates a string that is a valid file name
+ and that is not the same as the name of an existing file./102/
+
+ The tmpnam function generates a different string each time it is
+ called, up to TMP_MAX times. If it is called more than TMP_MAX times,
+ the behavior is implementation-defined.
+
+ The implementation shall behave as if no library function calls the
+ tmpnam function.
+
+ Returns
+
+ If the argument is a null pointer, the tmpnam function leaves its
+ result in an internal static object and returns a pointer to that
+ object. Subsequent calls to the tmpnam function may modify the same
+ object. If the argument is not a null pointer, it is assumed to point
+ to an array of at least L_tmpnam char s; the tmpnam function writes
+ its result in that array and returns the argument as its value.
+
+ "Environmental limits"
+
+ The value of the macro TMP_MAX shall be at least 25. =20
+
+
+ 4.9.5 File access functions
+
+ 4.9.5.1 The fclose function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fclose(FILE *stream);
+
+ Description
+
+ The fclose function causes the stream pointed to by stream to be
+ flushed and the associated file to be closed. Any unwritten buffered
+ data for the stream are delivered to the host environment to be
+ written to the file; any unread buffered data are discarded. The
+ stream is disassociated from the file. If the associated buffer was
+ automatically allocated, it is deallocated.
+
+ Returns
+
+ The fclose function returns zero if the stream was successfully
+ closed, or EOF if any errors were detected.
+
+
+ 4.9.5.2 The fflush function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fflush(FILE *stream);
+
+ Description
+
+ If stream points to an output stream or an update stream in which
+ the most recent operation was output, the fflush function causes any
+ unwritten data for that stream to be delivered to the host environment
+ to be written to the file; otherwise, the behavior is undefined.
+
+ If stream is a null pointer, the fflush function performs this
+ flushing action on all streams for which the behavior is defined
+ above.
+
+ Returns
+
+ The fflush function returns EOF if a write error occurs, otherwise zero.=
+ =20
+
+ Forward references: the ungetc function ($4.9.7.11). =20
+
+
+ 4.9.5.3 The fopen function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ FILE *fopen(const char *filename, const char *mode);
+
+ Description
+
+ The fopen function opens the file whose name is the string pointed
+ to by filename , and associates a stream with it.
+
+ The argument mode points to a string beginning with one of the
+ following sequences:/103/
+
+ "r" open text file for reading
+ "w" truncate to zero length or create text file for writing
+ "a" append; open or create text file for writing at end-of-fi=
+ le
+ "rb" open binary file for reading
+ "wb" truncate to zero length or create binary file for writing
+ "ab" append; open or create binary file for writing at end-of-=
+ file
+ "r+" open text file for update (reading and writing)
+ "w+" truncate to zero length or create text file for update
+ "a+" append; open or create text file for update, writing at
+ end-of-file
+ "r+b" or "rb+" open binary file for update (reading and writing)
+ "w+b" or "wb+" truncate to zero length or create binary file for update
+ "a+b" or "ab+" append; open or create binary file for update, writing at
+ end-of-file
+
+
+ Opening a file with read mode ('r' as the first character in the
+ mode argument) fails if the file does not exist or cannot be read.
+
+ Opening a file with append mode ('a' as the first character in the
+ mode argument) causes all subsequent writes to the file to be forced
+ to the then current end-of-file, regardless of intervening calls to
+ the fseek function. In some implementations, opening a binary file
+ with append mode ('b' as the second or third character in the mode
+ argument) may initially position the file position indicator for the
+ stream beyond the last data written, because of null character
+ padding.
+
+ When a file is opened with update mode ('+' as the second or third
+ character in the mode argument), both input and output may be
+ performed on the associated stream. However, output may not be
+ directly followed by input without an intervening call to the fflush
+ function or to a file positioning function ( fseek , fsetpos , or
+ rewind ), and input may not be directly followed by output without an
+ intervening call to a file positioning function, unless the input
+ operation encounters end-of-file. Opening a file with update mode may
+ open or create a binary stream in some implementations.
+
+ When opened, a stream is fully buffered if and only if it can be
+ determined not to refer to an interactive device. The error and
+ end-of-file indicators for the stream are cleared.
+
+ Returns
+
+ The fopen function returns a pointer to the object controlling the
+ stream. If the open operation fails, fopen returns a null pointer.
+
+ Forward references: file positioning functions ($4.9.9). =20
+
+
+ 4.9.5.4 The freopen function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ FILE *freopen(const char *filename, const char *mode,
+ FILE *stream);
+
+ Description
+
+ The freopen function opens the file whose name is the string
+ pointed to by filename and associates the stream pointed to by stream
+ with it. The mode argument is used just as in the fopen
+ function./104/
+
+ The freopen function first attempts to close any file that is
+ associated with the specified stream. Failure to close the file
+ successfully is ignored. The error and end-of-file indicators for the
+ stream are cleared.
+
+ Returns
+
+ The freopen function returns a null pointer if the open operation
+ fails. Otherwise, freopen returns the value of stream .
+
+
+ 4.9.5.5 The setbuf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ void setbuf(FILE *stream, char *buf);
+
+ Description
+
+ Except that it returns no value, the setbuf function is equivalent
+ to the setvbuf function invoked with the values _IOFBF for mode and
+ BUFSIZ for size , or (if buf is a null pointer), with the value _IONBF
+ for mode .
+
+ Returns
+
+ The setbuf function returns no value. =20
+
+ Forward references: the setvbuf function ($4.9.5.6). =20
+
+
+ 4.9.5.6 The setvbuf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int setvbuf(FILE *stream, char *buf, int mode, size_t size);
+
+ Description
+
+ The setvbuf function may be used after the stream pointed to by
+ stream has been associated with an open file but before any other
+ operation is performed on the stream. The argument mode determines
+ how stream will be buffered, as follows: _IOFBF causes input/output to
+ be fully buffered; _IOLBF causes output to be line buffered; _IONBF
+ causes input/output to be unbuffered. If buf is not a null pointer,
+ the array it points to may be used instead of a buffer allocated by
+ the setvbuf function./105/ The argument size specifies the size of the
+ array. The contents of the array at any time are indeterminate.
+
+ Returns
+
+ The setvbuf function returns zero on success, or nonzero if an
+ invalid value is given for mode or if the request cannot be honored.
+
+
+ 4.9.6 Formatted input/output functions
+
+ 4.9.6.1 The fprintf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fprintf(FILE *stream, const char *format, ...);
+
+ Description
+
+ The fprintf function writes output to the stream pointed to by
+ stream , under control of the string pointed to by format that
+ specifies how subsequent arguments are converted for output. If there
+ are insufficient arguments for the format, the behavior is undefined.
+ If the format is exhausted while arguments remain, the excess
+ arguments are evaluated (as always) but are otherwise ignored. The
+ fprintf function returns when the end of the format string is
+ encountered.
+
+ The format shall be a multibyte character sequence, beginning and
+ ending in its initial shift state. The format is composed of zero or
+ more directives: ordinary multibyte characters (not % ), which are
+ copied unchanged to the output stream; and conversion specifications,
+ each of which results in fetching zero or more subsequent arguments.
+ Each conversion specification is introduced by the character % .
+ After the % , the following appear in sequence:
+
+ * Zero or more flags that modify the meaning of the conversion
+ specification.
+
+ * An optional decimal integer specifying a minimum field width ./106/
+ If the converted value has fewer characters than the field width, it
+ will be padded with spaces on the left (or right, if the left
+ adjustment flag, described later, has been given) to the field width.
+
+ * An optional precision that gives the minimum number of digits to
+ appear for the d , i , o , u , x , and X conversions, the number of
+ digits to appear after the decimal-point character for e , E , and f
+ conversions, the maximum number of significant digits for the g and G
+ conversions, or the maximum number of characters to be written from a
+ string in s conversion. The precision takes the form of a period (.)
+ followed by an optional decimal integer; if the integer is
+ omitted, it is treated as zero.
+
+ * An optional h specifying that a following d , i , o , u , x , or X
+ conversion specifier applies to a short int or unsigned short int
+ argument (the argument will have been promoted according to the
+ integral promotions, and its value shall be converted to short int or
+ unsigned short int before printing); an optional h specifying that a
+ following n conversion specifier applies to a pointer to a short int
+ argument; an optional l (ell) specifying that a following d , i , o ,
+ u , x , or X conversion specifier applies to a long int or unsigned
+ long int argument; an optional l specifying that a following n
+ conversion specifier applies to a pointer to a long int argument; or
+ an optional L specifying that a following e , E , f , g , or G
+ conversion specifier applies to a long double argument. If an h , l ,
+ or L appears with any other conversion specifier, the behavior is
+ undefined.
+
+ * A character that specifies the type of conversion to be applied.
+
+ A field width or precision, or both, may be indicated by an
+ asterisk * instead of a digit string. In this case, an int argument
+ supplies the field width or precision. The arguments specifying field
+ width or precision, or both, shall appear (in that order) before the
+ argument (if any) to be converted. A negative field width argument is
+ taken as a - flag followed by a positive field width. A negative
+ precision argument is taken as if it were missing.
+
+ The flag characters and their meanings are=20
+
+ - The result of the conversion will be left-justified within the field. =
+ =20
+
+ + The result of a signed conversion will always begin with a plus or=20
+ minus sign. =20
+
+ space If the first character of a signed conversion is not a sign,=20
+ or if a signed conversion results in no characters, a space will be
+ prepended to the result. If the space and + flags both appear, the
+ space flag will be ignored.
+
+ # The result is to be converted to an ``alternate form.'' For
+ o conversion, it increases the precision to force the first digit of
+ the result to be a zero. For x (or X ) conversion, a nonzero result
+ will have 0x (or 0X ) prepended to it. For e , E , f , g , and G
+ conversions, the result will always contain a decimal-point character,
+ even if no digits follow it (normally, a decimal-point character
+ appears in the result of these conversions only if a digit follows
+ it). For g and G conversions, trailing zeros will not be removed from
+ the result. For other conversions, the behavior is undefined. =20
+
+ 0 For d, i, o, u, x, X, e, E, f, g and G conversions, leading zeros=20
+ (following any indication of sign or base) are used to pad to the
+ field width; no space padding is performed. If the 0 and - flags
+ both appear, the 0 flag will be ignored. For d, i, o, u, x and X
+ conversions, if a precision is specified, the 0 flag will be
+ ignored. For other conversions, the behavior is undefined.
+
+ The conversion specifiers and their meanings are
+
+ d, i, o, u, x, X The int argument is converted to signed decimal ( d
+ or i ), unsigned octal ( o ), unsigned decimal ( u ), or unsigned
+ hexadecimal notation ( x or X ); the letters abcdef are used for x
+ conversion and the letters ABCDEF for X conversion. The precision
+ specifies the minimum number of digits to appear; if the value being
+ converted can be represented in fewer digits, it will be expanded with
+ leading zeros. The default precision is 1. The result of converting
+ a zero value with an explicit precision of zero is no characters.
+
+ f The double argument is converted to decimal notation in the style
+ [-]ddd.ddd , where the number of digits after the decimal-point
+ character is equal to the precision specification. If the precision
+ is missing, it is taken as 6; if the precision is explicitly zero, no
+ decimal-point character appears. If a decimal-point character
+ appears, at least one digit appears before it. The value is rounded
+ to the appropriate number of digits.
+
+ e, E The double argument is converted in the style [-]d.ddde+- dd ,
+ where there is one digit before the decimal-point character (which is
+ nonzero if the argument is nonzero) and the number of digits after it
+ is equal to the precision; if the precision is missing, it is taken as
+ 6; if the precision is zero, no decimal-point character appears. The
+ value is rounded to the appropriate number of digits. The E
+ conversion specifier will produce a number with E instead of e
+ introducing the exponent. The exponent always contains at least two
+ digits. If the value is zero, the exponent is zero.
+
+ g, G The double argument is converted in style f or e (or in style E
+ in the case of a G conversion specifier), with the precision
+ specifying the number of significant digits. If an explicit precision
+ is zero, it is taken as 1. The style used depends on the value
+ converted; style e will be used only if the exponent resulting from
+ such a conversion is less than -4 or greater than or equal to the
+ precision. Trailing zeros are removed from the fractional portion of
+ the result; a decimal-point character appears only if it is followed
+ by a digit.
+
+ c The int argument is converted to an unsigned char , and the resulting
+ character is written.
+
+ s The argument shall be a pointer to an array of character type./107/
+ Characters from the array are written up to (but not including) a
+ terminating null character; if the precision is specified, no more
+ than that many characters are written. If the precision is not
+ specified or is greater than the size of the array, the array shall
+ contain a null character.
+
+ p The argument shall be a pointer to void . The value of the pointer
+ is converted to a sequence of printable characters, in an
+ implementation-defined manner.
+
+ n The argument shall be a pointer to an integer into which is written
+ the number of characters written to the output stream so far by this
+ call to fprintf . No argument is converted.
+
+ % A % is written. No argument is converted. The complete conversion
+ specification shall be %% .
+
+ If a conversion specification is invalid, the behavior is
+ undefined./108/
+
+ If any argument is, or points to, a union or an aggregate (except
+ for an array of character type using %s conversion, or a pointer cast
+ to be a pointer to void using %p conversion), the behavior is
+ undefined.
+
+ In no case does a nonexistent or small field width cause truncation
+ of a field; if the result of a conversion is wider than the field
+ width, the field is expanded to contain the conversion result.
+
+ Returns
+
+ The fprintf function returns the number of characters transmitted,
+ or a negative value if an output error occurred.
+
+ "Environmental limit"
+
+ The minimum value for the maximum number of characters produced by
+ any single conversion shall be 509.
+
+ Examples
+
+ To print a date and time in the form ``Sunday, July 3, 10:02,''
+ where weekday and month are pointers to strings:
+
+ #include &lt;stdio.h&gt;
+ fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
+ weekday, month, day, hour, min);
+
+ To print PI to five decimal places:=20
+
+ #include &lt;math.h&gt;
+ #include &lt;stdio.h&gt;
+ fprintf(stdout, "pi =3D %.5f\n", 4 * atan(1.0));
+
+
+ 4.9.6.2 The fscanf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fscanf(FILE *stream, const char *format, ...);
+
+ Description
+
+ The fscanf function reads input from the stream pointed to by
+ stream , under control of the string pointed to by format that
+ specifies the admissible input sequences and how they are to be
+ converted for assignment, using subsequent arguments as pointers to
+ the objects to receive the converted input. If there are insufficient
+ arguments for the format, the behavior is undefined. If the format is
+ exhausted while arguments remain, the excess arguments are evaluated
+ (as always) but are otherwise ignored.
+
+ The format shall be a multibyte character sequence, beginning and
+ ending in its initial shift state. The format is composed of zero or
+ more directives: one or more white-space characters; an ordinary
+ multibyte character (not % ); or a conversion specification. Each
+ conversion specification is introduced by the character % . After the %,
+ the following appear in sequence:
+
+ * An optional assignment-suppressing character * . =20
+
+ * An optional decimal integer that specifies the maximum field width. =20
+
+ * An optional h , l (ell) or L indicating the size of the receiving
+ object. The conversion specifiers d , i , and n shall be preceded by
+ h if the corresponding argument is a pointer to short int rather than
+ a pointer to int , or by l if it is a pointer to long int .
+ Similarly, the conversion specifiers o , u , and x shall be preceded
+ by h if the corresponding argument is a pointer to unsigned short int
+ rather than a pointer to unsigned int , or by l if it is a pointer to
+ unsigned long int . Finally, the conversion specifiers e , f , and g
+ shall be preceded by l if the corresponding argument is a pointer to
+ double rather than a pointer to float , or by L if it is a pointer to
+ long double . If an h , l , or L appears with any other conversion
+ specifier, the behavior is undefined.
+
+ * A character that specifies the type of conversion to be applied.
+ The valid conversion specifiers are described below.
+
+ The fscanf function executes each directive of the format in turn.
+ If a directive fails, as detailed below, the fscanf function returns.
+ Failures are described as input failures (due to the unavailability of
+ input characters), or matching failures (due to inappropriate input).
+
+ A directive composed of white space is executed by reading input up
+ to the first non-white-space character (which remains unread), or
+ until no more characters can be read.
+
+ A directive that is an ordinary multibyte character is executed by
+ reading the next characters of the stream. If one of the characters
+ differs from one comprising the directive, the directive fails, and
+ the differing and subsequent characters remain unread.
+
+ A directive that is a conversion specification defines a set of
+ matching input sequences, as described below for each specifier. A
+ conversion specification is executed in the following steps:
+
+ Input white-space characters (as specified by the isspace function)
+ are skipped, unless the specification includes a [ , c , or n
+ specifier.
+
+ An input item is read from the stream, unless the specification
+ includes an n specifier. An input item is defined as the longest
+ sequence of input characters (up to any specified maximum field width)
+ which is an initial subsequence of a matching sequence. The first
+ character, if any, after the input item remains unread. If the length
+ of the input item is zero, the execution of the directive fails: this
+ condition is a matching failure, unless an error prevented input from
+ the stream, in which case it is an input failure.
+
+ Except in the case of a % specifier, the input item (or, in the
+ case of a %n directive, the count of input characters) is converted to
+ a type appropriate to the conversion specifier. If the input item is
+ not a matching sequence, the execution of the directive fails: this
+ condition is a matching failure. Unless assignment suppression was
+ indicated by a * , the result of the conversion is placed in the
+ object pointed to by the first argument following the format argument
+ that has not already received a conversion result. If this object
+ does not have an appropriate type, or if the result of the conversion
+ cannot be represented in the space provided, the behavior is
+ undefined.
+
+ The following conversion specifiers are valid:
+
+ d Matches an optionally signed decimal integer, whose format is the
+ same as expected for the subject sequence of the strtol function with
+ the value 10 for the base argument. The corresponding argument shall
+ be a pointer to integer.
+
+ i Matches an optionally signed integer, whose format is the same as
+ expected for the subject sequence of the strtol function with the
+ value 0 for the base argument. The corresponding argument shall be a
+ pointer to integer.
+
+ o Matches an optionally signed octal integer, whose format is the same
+ as expected for the subject sequence of the strtoul function with the
+ value 8 for the base argument. The corresponding argument shall be a
+ pointer to unsigned integer.
+
+ u Matches an optionally signed decimal integer, whose format is the same
+ as expected for the subject sequence of the strtoul function with the
+ value 10 for the base argument. The corresponding argument shall be a
+ pointer to unsigned integer.
+
+ x Matches an optionally signed hexadecimal integer, whose format is the
+ same as expected for the subject sequence of the strtoul function with
+ the value 16 for the base argument. The corresponding argument shall
+ be a pointer to unsigned integer.
+
+ e,f,g Matches an optionally signed floating-point number, whose format is
+ the same as expected for the subject string of the strtod function.
+ The corresponding argument shall be a pointer to floating.
+
+ s Matches a sequence of non-white-space characters. The corresponding
+ argument shall be a pointer to the initial character of an array large
+ enough to accept the sequence and a terminating null character, which
+ will be added automatically.
+
+ [ Matches a nonempty sequence of characters from a set of expected
+ characters (the scanset ). The corresponding argument shall be a
+ pointer to the initial character of an array large enough to accept
+ the sequence and a terminating null character, which will be added
+ automatically. The conversion specifier includes all subsequent
+ characters in the format string, up to and including the matching
+ right bracket ( ] ). The characters between the brackets (the
+ scanlist ) comprise the scanset, unless the character after the left
+ bracket is a circumflex ( ^ ), in which case the scanset contains all
+ characters that do not appear in the scanlist between the circumflex
+ and the right bracket. As a special case, if the conversion specifier
+ begins with [] or [^] , the right bracket character is in the scanlist
+ and the next right bracket character is the matching right bracket
+ that ends the specification. If a - character is in the scanlist and
+ is not the first, nor the second where the first character is a ^ ,
+ nor the last character, the behavior is implementation-defined.
+
+ c Matches a sequence of characters of the number specified by the
+ field width (1 if no field width is present in the directive). The
+ corresponding argument shall be a pointer to the initial character of
+ an array large enough to accept the sequence. No null character is
+ added.
+
+ p Matches an implementation-defined set of sequences, which should be
+ the same as the set of sequences that may be produced by the %p
+ conversion of the fprintf function. The corresponding argument shall
+ be a pointer to a pointer to void . The interpretation of the input
+ item is implementation-defined; however, for any input item other than
+ a value converted earlier during the same program execution, the
+ behavior of the %p conversion is undefined.
+
+ n No input is consumed. The corresponding argument shall be a pointer
+ to integer into which is to be written the number of characters read
+ from the input stream so far by this call to the fscanf function.
+ Execution of a %n directive does not increment the assignment count
+ returned at the completion of execution of the fscanf function.
+
+ % Matches a single % ; no conversion or assignment occurs. The complete
+ conversion specification shall be %% .
+
+ If a conversion specification is invalid, the behavior is
+ undefined./110/
+
+ The conversion specifiers E , G , and X are also valid and behave
+ the same as, respectively, e , g , and x .
+
+ If end-of-file is encountered during input, conversion is
+ terminated. If end-of-file occurs before any characters matching the
+ current directive have been read (other than leading white space,
+ where permitted), execution of the current directive terminates with
+ an input failure; otherwise, unless execution of the current directive
+ is terminated with a matching failure, execution of the following
+ directive (if any) is terminated with an input failure.
+
+ If conversion terminates on a conflicting input character, the
+ offending input character is left unread in the input stream.
+ Trailing white space (including new-line characters) is left unread
+ unless matched by a directive. The success of literal matches and
+ suppressed assignments is not directly determinable other than via the
+ %n directive.
+
+ Returns
+
+ The fscanf function returns the value of the macro EOF if an input
+ failure occurs before any conversion. Otherwise, the fscanf function
+ returns the number of input items assigned, which can be fewer than
+ provided for, or even zero, in the event of an early matching failure.
+
+ Examples
+
+ The call:=20
+
+ #include &lt;stdio.h&gt;
+ int n, i; float x; char name[50];
+ n =3D fscanf(stdin, "%d%f%s", &amp;i, &amp;x, name);
+
+ with the input line:=20
+
+ 25 54.32E-1 thompson
+
+ will assign to n the value 3, to i the value 25, to x the value 5.432,
+ and name will contain thompson\0 . Or:
+
+ #include &lt;stdio.h&gt;
+ int i; float x; char name[50];
+ fscanf(stdin, "%2d%f%*d %[0123456789]", &amp;i, &amp;x, name);
+
+ with input:=20
+
+ 56789 0123 56a72
+
+ will assign to i the value 56 and to x the value 789.0, will skip
+ 0123, and name will contain 56\0 . The next character read from the
+ input stream will be a .
+
+ To accept repeatedly from stdin a quantity, a unit of measure and
+ an item name:
+
+ #include &lt;stdio.h&gt;
+ int count; float quant; char units[21], item[21];
+ while (!feof(stdin) &amp;&amp; !ferror(stdin)) {
+ count =3D fscanf(stdin, "%f%20s of %20s",
+ &amp;quant, units, item);
+ fscanf(stdin,"%*[^\n]");
+ }
+
+
+ If the stdin stream contains the following lines:=20
+
+ 2 quarts of oil
+ -12.8degrees Celsius
+ lots of luck
+ 10.0LBS of fertilizer
+ 100ergs of energy
+
+ the execution of the above example will be equivalent to the following
+ assignments:
+
+ quant =3D 2; strcpy(units, "quarts"); strcpy(item, "oil");
+ count =3D 3;
+ quant =3D -12.8; strcpy(units, "degrees");
+ count =3D 2; /* "C" fails to match "o" */
+ count =3D 0; /* "l" fails to match "%f" */
+ quant =3D 10.0; strcpy(units, "LBS"); strcpy(item, "fertilizer");
+ count =3D 3;
+ count =3D 0; /* "100e" fails to match "%f" */
+ count =3D EOF;
+
+ Forward references: the strtod function ($4.10.1.4), the strtol
+ function ($4.10.1.5), the strtoul function ($4.10.1.6).
+
+
+ 4.9.6.3 The printf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int printf(const char *format, ...);
+
+ Description
+
+ The printf function is equivalent to fprintf with the argument
+ stdout interposed before the arguments to printf .
+
+ Returns
+
+ The printf function returns the number of characters transmitted,
+ or a negative value if an output error occurred.
+
+
+ 4.9.6.4 The scanf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int scanf(const char *format, ...);
+
+ Description
+
+ The scanf function is equivalent to fscanf with the argument stdin
+ interposed before the arguments to scanf .
+
+ Returns
+
+ The scanf function returns the value of the macro EOF if an input
+ failure occurs before any conversion. Otherwise, the scanf function
+ returns the number of input items assigned, which can be fewer than
+ provided for, or even zero, in the event of an early matching failure.
+
+
+ 4.9.6.5 The sprintf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int sprintf(char *s, const char *format, ...);
+
+ Description
+
+ The sprintf function is equivalent to fprintf , except that the
+ argument s specifies an array into which the generated output is to be
+ written, rather than to a stream. A null character is written at the
+ end of the characters written; it is not counted as part of the
+ returned sum. If copying takes place between objects that overlap,
+ the behavior is undefined.
+
+ Returns
+
+ The sprintf function returns the number of characters written in
+ the array, not counting the terminating null character.
+
+
+ 4.9.6.6 The sscanf function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int sscanf(const char *s, const char *format, ...);
+
+ Description
+
+ The sscanf function is equivalent to fscanf , except that the
+ argument s specifies a string from which the input is to be obtained,
+ rather than from a stream. Reaching the end of the string is
+ equivalent to encountering end-of-file for the fscanf function. If
+ copying takes place between objects that overlap, the behavior is
+ undefined.
+
+ Returns
+
+ The sscanf function returns the value of the macro EOF if an input
+ failure occurs before any conversion. Otherwise, the sscanf function
+ returns the number of input items assigned, which can be fewer than
+ provided for, or even zero, in the event of an early matching failure.
+
+
+ 4.9.6.7 The vfprintf function
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ #include &lt;stdio.h&gt;
+ int vfprintf(FILE *stream, const char *format, va_list arg);
+
+ Description
+
+ The vfprintf function is equivalent to fprintf , with the variable
+ argument list replaced by arg , which has been initialized by the
+ va_start macro (and possibly subsequent va_arg calls). The vfprintf
+ function does not invoke the va_end macro.
+
+ Returns
+
+ The vfprintf function returns the number of characters transmitted,
+ or a negative value if an output error occurred.
+
+ Example
+
+ The following shows the use of the vfprintf function in a general
+ error-reporting routine.
+
+ #include &lt;stdarg.h&gt;
+ #include &lt;stdio.h&gt;
+
+ void error(char *function_name, char *format, ...)
+ {
+ va_list args;
+
+ va_start(args, format);
+ /* print out name of function causing error */
+ fprintf(stderr, "ERROR in %s: ", function_name);
+ /* print out remainder of message */
+ vfprintf(stderr, format, args);
+ va_end(args);
+ }
+
+
+ 4.9.6.8 The vprintf function
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ #include &lt;stdio.h&gt;
+ int vprintf(const char *format, va_list arg);
+
+ Description
+
+ The vprintf function is equivalent to printf , with the variable
+ argument list replaced by arg , which has been initialized by the
+ va_start macro (and possibly subsequent va_arg calls). The vprintf
+ function does not invoke the va_end macro.rN
+
+ Returns
+
+ The vprintf function returns the number of characters transmitted,
+ or a negative value if an output error occurred.
+
+
+ 4.9.6.9 The vsprintf function
+
+ Synopsis
+
+ #include &lt;stdarg.h&gt;
+ #include &lt;stdio.h&gt;
+ int vsprintf(char *s, const char *format, va_list arg);
+
+ Description
+
+ The vsprintf function is equivalent to sprintf , with the variable
+ argument list replaced by arg , which has been initialized by the
+ va_start macro (and possibly subsequent va_arg calls). The vsprintf
+ function does not invoke the va_end macro.rN If copying takes place
+ between objects that overlap, the behavior is undefined.
+
+ Returns
+
+ The vsprintf function returns the number of characters written in
+ the array, not counting the terminating null character.
+
+
+ 4.9.7 Character input/output functions
+
+ 4.9.7.1 The fgetc function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fgetc(FILE *stream);
+
+ Description
+
+ The fgetc function obtains the next character (if present) as an
+ unsigned char converted to an int , from the input stream pointed to
+ by stream , and advances the associated file position indicator for
+ the stream (if defined).
+
+ Returns
+
+ The fgetc function returns the next character from the input stream
+ pointed to by stream . If the stream is at end-of-file, the
+ end-of-file indicator for the stream is set and fgetc returns EOF .
+ If a read error occurs, the error indicator for the stream is set and
+ fgetc returns EOF ./112/
+
+
+ 4.9.7.2 The fgets function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ char *fgets(char *s, int n, FILE *stream);
+
+ Description
+
+ The fgets function reads at most one less than the number of
+ characters specified by n from the stream pointed to by stream into
+ the array pointed to by s . No additional characters are read after a
+ new-line character (which is retained) or after end-of-file. A null
+ character is written immediately after the last character read into
+ the array.
+
+ Returns
+
+ The fgets function returns s if successful. If end-of-file is
+ encountered and no characters have been read into the array, the
+ contents of the array remain unchanged and a null pointer is returned.
+ If a read error occurs during the operation, the array contents are
+ indeterminate and a null pointer is returned.
+
+
+ 4.9.7.3 The fputc function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fputc(int c, FILE *stream);
+
+ Description
+
+ The fputc function writes the character specified by c (converted
+ to an unsigned char ) to the output stream pointed to by stream , at
+ the position indicated by the associated file position indicator for
+ the stream (if defined), and advances the indicator appropriately. If
+ the file cannot support positioning requests, or if the stream was
+ opened with append mode, the character is appended to the output
+ stream.
+
+ Returns
+
+ The fputc function returns the character written. If a write error
+ occurs, the error indicator for the stream is set and fputc returns EOF.
+
+
+ 4.9.7.4 The fputs function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fputs(const char *s, FILE *stream);
+
+ Description
+
+ The fputs function writes the string pointed to by s to the stream
+ pointed to by stream . The terminating null character is not written.
+
+ Returns
+
+ The fputs function returns EOF if a write error occurs; otherwise
+ it returns a nonnegative value.
+
+
+ 4.9.7.5 The getc function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int getc(FILE *stream);
+
+ Description
+
+ The getc function is equivalent to fgetc , except that if it is
+ implemented as a macro, it may evaluate stream more than once, so the
+ argument should never be an expression with side effects.
+
+ Returns
+
+ The getc function returns the next character from the input stream
+ pointed to by stream . If the stream is at end-of-file, the
+ end-of-file indicator for the stream is set and getc returns EOF . If
+ a read error occurs, the error indicator for the stream is set and
+ getc returns EOF .
+
+
+ 4.9.7.6 The getchar function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int getchar(void);
+
+ Description
+
+ The getchar function is equivalent to getc with the argument stdin . =20
+
+ Returns
+
+ The getchar function returns the next character from the input
+ stream pointed to by stdin . If the stream is at end-of-file, the
+ end-of-file indicator for the stream is set and getchar returns EOF .
+ If a read error occurs, the error indicator for the stream is set and
+ getchar returns EOF .
+
+
+ 4.9.7.7 The gets function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ char *gets(char *s);
+
+ Description
+
+ The gets function reads characters from the input stream pointed to
+ by stdin , into the array pointed to by s , until end-of-file is
+ encountered or a new-line character is read. Any new-line character
+ is discarded, and a null character is written immediately after the
+ last character read into the array.
+
+ Returns
+
+ The gets function returns s if successful. If end-of-file is
+ encountered and no characters have been read into the array, the
+ contents of the array remain unchanged and a null pointer is returned.
+ If a read error occurs during the operation, the array contents are
+ indeterminate and a null pointer is returned.
+
+
+ 4.9.7.8 The putc function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int putc(int c, FILE *stream);
+
+ Description
+
+ The putc function is equivalent to fputc , except that if it is
+ implemented as a macro, it may evaluate stream more than once, so the
+ argument should never be an expression with side effects.
+
+ Returns
+
+ The putc function returns the character written. If a write error
+ occurs, the error indicator for the stream is set and putc returns EOF.
+
+
+ 4.9.7.9 The putchar function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int putchar(int c);
+
+ Description
+
+ The putchar function is equivalent to putc with the second argument
+ stdout.
+
+ Returns
+
+ The putchar function returns the character written. If a write
+ error occurs, the error indicator for the stream is set and putchar
+ returns EOF.
+
+
+ 4.9.7.10 The puts function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int puts(const char *s);
+
+ Description
+
+ The puts function writes the string pointed to by s to the stream
+ pointed to by stdout , and appends a new-line character to the output.
+ The terminating null character is not written.
+
+ Returns
+
+ The puts function returns EOF if a write error occurs; otherwise it
+ returns a nonnegative value.
+
+
+ 4.9.7.11 The ungetc function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int ungetc(int c, FILE *stream);
+
+ Description
+
+ The ungetc function pushes the character specified by c (converted
+ to an unsigned char ) back onto the input stream pointed to by stream.
+ The pushed-back characters will be returned by subsequent reads on
+ that stream in the reverse order of their pushing. A successful
+ intervening call (with the stream pointed to by stream ) to a file
+ positioning function ( fseek , fsetpos , or rewind ) discards any
+ pushed-back characters for the stream. The external storage
+ corresponding to the stream is unchanged.
+
+ One character of pushback is guaranteed. If the ungetc function is
+ called too many times on the same stream without an intervening read
+ or file positioning operation on that stream, the operation may fail.
+
+ If the value of c equals that of the macro EOF , the operation
+ fails and the input stream is unchanged.
+
+ A successful call to the ungetc function clears the end-of-file
+ indicator for the stream. The value of the file position indicator
+ for the stream after reading or discarding all pushed-back characters
+ shall be the same as it was before the characters were pushed back.
+ For a text stream, the value of its file position indicator after a
+ successful call to the ungetc function is unspecified until all
+ pushed-back characters are read or discarded. For a binary stream,
+ its file position indicator is decremented by each successful call to
+ the ungetc function; if its value was zero before a call, it is
+ indeterminate after the call.
+
+ Returns
+
+ The ungetc function returns the character pushed back after
+ conversion, or EOF if the operation fails.
+
+ Forward references: file positioning functions ($4.9.9). =20
+
+
+ 4.9.8 Direct input/output functions
+
+ 4.9.8.1 The fread function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ size_t fread(void *ptr, size_t size, size_t nmemb,
+ FILE *stream);
+
+ Description
+
+ The fread function reads, into the array pointed to by ptr , up to
+ nmemb members whose size is specified by size , from the stream
+ pointed to by stream . The file position indicator for the stream (if
+ defined) is advanced by the number of characters successfully read.
+ If an error occurs, the resulting value of the file position indicator
+ for the stream is indeterminate. If a partial member is read, its
+ value is indeterminate.
+
+ Returns
+
+ The fread function returns the number of members successfully read,
+ which may be less than nmemb if a read error or end-of-file is
+ encountered. If size or nmemb is zero, fread returns zero and the
+ contents of the array and the state of the stream remain unchanged.
+
+
+ 4.9.8.2 The fwrite function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ size_t fwrite(const void *ptr, size_t size, size_t nmemb,
+ FILE *stream);
+
+ Description
+
+ The fwrite function writes, from the array pointed to by ptr , up
+ to nmemb members whose size is specified by size , to the stream
+ pointed to by stream . The file position indicator for the stream (if
+ defined) is advanced by the number of characters successfully written.
+ If an error occurs, the resulting value of the file position indicator
+ for the stream is indeterminate.
+
+ Returns
+
+ The fwrite function returns the number of members successfully
+ written, which will be less than nmemb only if a write error is
+ encountered.
+
+
+ 4.9.9 File positioning functions
+
+ 4.9.9.1 The fgetpos function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fgetpos(FILE *stream, fpos_t *pos);
+
+ Description
+
+ The fgetpos function stores the current value of the file position
+ indicator for the stream pointed to by stream in the object pointed to
+ by pos . The value stored contains unspecified information usable by
+ the fsetpos function for repositioning the stream to its position at
+ the time of the call to the fgetpos function.
+
+ Returns
+
+ If successful, the fgetpos function returns zero; on failure, the
+ fgetpos function returns nonzero and stores an implementation-defined
+ positive value in errno .
+
+ Forward references: the fsetpos function ($4.9.9.3). =20
+
+
+ 4.9.9.2 The fseek function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fseek(FILE *stream, long int offset, int whence);
+
+ Description
+
+ The fseek function sets the file position indicator for the stream
+ pointed to by stream .
+
+ For a binary stream, the new position, measured in characters from
+ the beginning of the file, is obtained by adding offset to the
+ position specified by whence. The specified point is the beginning
+ of the file for SEEK_SET, the current value of the file position
+ indicator for SEEK_CUR, or end-of-file for SEEK_END. A binary
+ stream need not meaningfully support fseek calls with a whence value
+ of SEEK_END.
+
+ For a text stream, either offset shall be zero, or offset shall be
+ a value returned by an earlier call to the ftell function on the same
+ stream and whence shall be SEEK_SET .
+
+ A successful call to the fseek function clears the end-of-file
+ indicator for the stream and undoes any effects of the ungetc function
+ on the same stream. After an fseek call, the next operation on an
+ update stream may be either input or output.
+
+ Returns
+
+ The fseek function returns nonzero only for a request that cannot
+ be satisfied.
+
+ Forward references: the ftell function ($4.9.9.4). =20
+
+
+ 4.9.9.3 The fsetpos function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int fsetpos(FILE *stream, const fpos_t *pos);
+
+ Description
+
+ The fsetpos function sets the file position indicator for the
+ stream pointed to by stream according to the value of the object
+ pointed to by pos , which shall be a value returned by an earlier call
+ to the fgetpos function on the same stream.
+
+ A successful call to the fsetpos function clears the end-of-file
+ indicator for the stream and undoes any effects of the ungetc function
+ on the same stream. After an fsetpos call, the next operation on an
+ update stream may be either input or output.
+
+ Returns
+
+ If successful, the fsetpos function returns zero; on failure, the
+ fsetpos function returns nonzero and stores an implementation-defined
+ positive value in errno .
+
+
+ 4.9.9.4 The ftell function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ long int ftell(FILE *stream);
+
+ Description
+
+ The ftell function obtains the current value of the file position
+ indicator for the stream pointed to by stream . For a binary stream,
+ the value is the number of characters from the beginning of the file.
+ For a text stream, its file position indicator contains unspecified
+ information, usable by the fseek function for returning the file
+ position indicator for the stream to its position at the time of the
+ ftell call; the difference between two such return values is not
+ necessarily a meaningful measure of the number of characters written
+ or read.
+
+ Returns
+
+ If successful, the ftell function returns the current value of the
+ file position indicator for the stream. On failure, the ftell
+ function returns -1L and stores an implementation-defined positive
+ value in errno .
+
+
+ 4.9.9.5 The rewind function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ void rewind(FILE *stream);
+
+ Description
+
+ The rewind function sets the file position indicator for the stream
+ pointed to by stream to the beginning of the file. It is equivalent to
+
+ (void)fseek(stream, 0L, SEEK_SET)
+
+ except that the error indicator for the stream is also cleared. =20
+
+ Returns
+
+ The rewind function returns no value. =20
+
+
+ 4.9.10 Error-handling functions
+
+ 4.9.10.1 The clearerr function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ void clearerr(FILE *stream);
+
+ Description
+
+ The clearerr function clears the end-of-file and error indicators
+ for the stream pointed to by stream .
+
+ Returns
+
+ The clearerr function returns no value. =20
+
+
+ 4.9.10.2 The feof function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int feof(FILE *stream);
+
+ Description
+
+ The feof function tests the end-of-file indicator for the stream
+ pointed to by stream .
+
+ Returns
+
+ The feof function returns nonzero if and only if the end-of-file
+ indicator is set for stream .
+
+
+ 4.9.10.3 The ferror function
+
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ int ferror(FILE *stream);
+
+ Description
+
+ The ferror function tests the error indicator for the stream
+ pointed to by stream .
+
+ Returns
+
+ The ferror function returns nonzero if and only if the error
+ indicator is set for stream .
+
+
+ 4.9.10.4 The perror function
+
+ Synopsis
+
+ #include &lt;stdio.h&gt;
+ void perror(const char *s);
+
+ Description
+
+ The perror function maps the error number in the integer expression
+ errno to an error message. It writes a sequence of characters to the
+ standard error stream thus: first (if s is not a null pointer and the
+ character pointed to by s is not the null character), the string
+ pointed to by s followed by a colon and a space; then an appropriate
+ error message string followed by a new-line character. The contents
+ of the error message strings are the same as those returned by the
+ strerror function with argument errno , which are
+ implementation-defined.
+
+ Returns
+
+ The perror function returns no value. =20
+
+ Forward references: the strerror function ($4.11.6.2). =20
+
+
+ 4.10 GENERAL UTILITIES &lt;stdlib.h&gt;
+
+ The header &lt;stdlib.h&gt; declares four types and several functions of
+ general utility, and defines several macros./113/
+
+ The types declared are size_t and wchar_t (both described in $4.1.5),=20
+
+ div_t
+
+ which is a structure type that is the type of the value returned by
+ the div function, and
+
+ ldiv_t
+
+ which is a structure type that is the type of the value returned by
+ the ldiv function.
+
+ The macros defined are NULL (described in $4.1.5);=20
+
+ EXIT_FAILURE
+
+ and=20
+
+ EXIT_SUCCESS
+
+ which expand to integral expressions that may be used as the argument
+ to the exit function to return unsuccessful or successful termination
+ status, respectively, to the host environment;
+
+ RAND_MAX
+
+ which expands to an integral constant expression, the value of which
+ is the maximum value returned by the rand function; and
+
+ MB_CUR_MAX
+
+ which expands to a positive integer expression whose value is the
+ maximum number of bytes in a multibyte character for the extended
+ character set specified by the current locale (category LC_CTYPE ),
+ and whose value is never greater than MB_LEN_MAX .
+
+
+ 4.10.1 String conversion functions
+
+ The functions atof , atoi , and atol need not affect the value of
+ the integer expression errno on an error. If the value of the result
+ cannot be represented, the behavior is undefined.
+
+
+ 4.10.1.1 The atof function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ double atof(const char *nptr);
+
+ Description
+
+ The atof function converts the initial portion of the string
+ pointed to by nptr to double representation. Except for the behavior
+ on error, it is equivalent to
+
+ strtod(nptr, (char **)NULL)
+
+ Returns
+
+ The atof function returns the converted value. =20
+
+ Forward references: the strtod function ($4.10.1.4). =20
+
+
+ 4.10.1.2 The atoi function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int atoi(const char *nptr);
+
+ Description
+
+ The atoi function converts the initial portion of the string
+ pointed to by nptr to int representation. Except for the behavior on
+ error, it is equivalent to
+
+ (int)strtol(nptr, (char **)NULL, 10)
+
+ Returns
+
+ The atoi function returns the converted value. =20
+
+ Forward references: the strtol function ($4.10.1.5). =20
+
+
+ 4.10.1.3 The atol function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ long int atol(const char *nptr);
+
+ Description
+
+ The atol function converts the initial portion of the string
+ pointed to by nptr to long int representation. Except for the
+ behavior on error, it is equivalent to
+
+ strtol(nptr, (char **)NULL, 10)
+
+ Returns
+
+ The atol function returns the converted value. =20
+
+ Forward references: the strtol function ($4.10.1.5). =20
+
+
+ 4.10.1.4 The strtod function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ double strtod(const char *nptr, char **endptr);
+
+ Description
+
+ The strtod function converts the initial portion of the string
+ pointed to by nptr to double representation. First it decomposes the
+ input string into three parts: an initial, possibly empty, sequence of
+ white-space characters (as specified by the isspace function), a
+ subject sequence resembling a floating-point constant; and a final
+ string of one or more unrecognized characters, including the
+ terminating null character of the input string. Then it attempts to
+ convert the subject sequence to a floating-point number, and returns
+ the result.
+
+ The expected form of the subject sequence is an optional plus or
+ minus sign, then a nonempty sequence of digits optionally containing a
+ decimal-point character, then an optional exponent part as defined in
+ $3.1.3.1, but no floating suffix. The subject sequence is defined as
+ the longest subsequence of the input string, starting with the first
+ non-white-space character, that is an initial subsequence of a
+ sequence of the expected form. The subject sequence contains no
+ characters if the input string is empty or consists entirely of white
+ space, or if the first non-white-space character is other than a sign,
+ a digit, or a decimal-point character.
+
+ If the subject sequence has the expected form, the sequence of
+ characters starting with the first digit or the decimal-point
+ character (whichever occurs first) is interpreted as a floating
+ constant according to the rules of $3.1.3.1, except that the
+ decimal-point character is used in place of a period, and that if
+ neither an exponent part nor a decimal-point character appears, a
+ decimal point is assumed to follow the last digit in the string. If
+ the subject sequence begins with a minus sign, the value resulting
+ from the conversion is negated. A pointer to the final string is
+ stored in the object pointed to by endptr , provided that endptr is
+ not a null pointer.
+
+ In other than the C locale, additional implementation-defined
+ subject sequence forms may be accepted.
+
+ If the subject sequence is empty or does not have the expected
+ form, no conversion is performed; the value of nptr is stored in the
+ object pointed to by endptr , provided that endptr is not a null
+ pointer.
+
+ Returns
+
+ The strtod function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct value
+ would cause overflow, plus or minus HUGE_VAL is returned (according to
+ the sign of the value), and the value of the macro ERANGE is stored in
+ errno . If the correct value would cause underflow, zero is returned
+ and the value of the macro ERANGE is stored in errno .
+
+
+ 4.10.1.5 The strtol function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ long int strtol(const char *nptr, char **endptr, int base);
+
+ Description
+
+ The strtol function converts the initial portion of the string
+ pointed to by nptr to long int representation. First it decomposes
+ the input string into three parts: an initial, possibly empty,
+ sequence of white-space characters (as specified by the isspace
+ function), a subject sequence resembling an integer represented in
+ some radix determined by the value of base , and a final string of one
+ or more unrecognized characters, including the terminating null
+ character of the input string. Then it attempts to convert the
+ subject sequence to an integer, and returns the result.
+
+ If the value of base is zero, the expected form of the subject
+ sequence is that of an integer constant as described in $3.1.3.2,
+ optionally preceded by a plus or minus sign, but not including an
+ integer suffix. If the value of base is between 2 and 36, the
+ expected form of the subject sequence is a sequence of letters and
+ digits representing an integer with the radix specified by base ,
+ optionally preceded by a plus or minus sign, but not including an
+ integer suffix. The letters from a (or A ) through z (or Z ) are
+ ascribed the values 10 to 35; only letters whose ascribed values are
+ less than that of base are permitted. If the value of base is 16, the
+ characters 0x or 0X may optionally precede the sequence of letters and
+ digits, following the sign if present.
+
+ The subject sequence is defined as the longest subsequence of the
+ input string, starting with the first non-white-space character, that
+ is an initial subsequence of a sequence of the expected form. The
+ subject sequence contains no characters if the input string is empty
+ or consists entirely of white space, or if the first non-white-space
+ character is other than a sign or a permissible letter or digit.
+
+ If the subject sequence has the expected form and the value of base
+ is zero, the sequence of characters starting with the first digit is
+ interpreted as an integer constant according to the rules of $3.1.3.2.
+ If the subject sequence has the expected form and the value of base is
+ between 2 and 36, it is used as the base for conversion, ascribing to
+ each letter its value as given above. If the subject sequence begins
+ with a minus sign, the value resulting from the conversion is negated.
+ A pointer to the final string is stored in the object pointed to by
+ endptr , provided that endptr is not a null pointer.
+
+ In other than the C locale, additional implementation-defined
+ subject sequence forms may be accepted.
+
+ If the subject sequence is empty or does not have the expected
+ form, no conversion is performed; the value of nptr is stored in the
+ object pointed to by endptr , provided that endptr is not a null
+ pointer.
+
+ Returns
+
+ The strtol function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct value
+ would cause overflow, LONG_MAX or LONG_MIN is returned (according to
+ the sign of the value), and the value of the macro ERANGE is stored in
+ errno .
+
+
+ 4.10.1.6 The strtoul function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ unsigned long int strtoul(const char *nptr, char **endptr,
+ int base);
+
+ Description
+
+ The strtoul function converts the initial portion of the string
+ pointed to by nptr to unsigned long int representation. First it
+ decomposes the input string into three parts: an initial, possibly
+ empty, sequence of white-space characters (as specified by the isspace
+ function), a subject sequence resembling an unsigned integer
+ represented in some radix determined by the value of base , and a
+ final string of one or more unrecognized characters, including the
+ terminating null character of the input string. Then it attempts to
+ convert the subject sequence to an unsigned integer, and returns the
+ result.
+
+ If the value of base is zero, the expected form of the subject
+ sequence is that of an integer constant as described in $3.1.3.2,
+ optionally preceded by a plus or minus sign, but not including an
+ integer suffix. If the value of base is between 2 and 36, the
+ expected form of the subject sequence is a sequence of letters and
+ digits representing an integer with the radix specified by base ,
+ optionally preceded by a plus or minus sign, but not including an
+ integer suffix. The letters from a (or A ) through z (or Z ) are
+ ascribed the values 10 to 35; only letters whose ascribed values are
+ less than that of base are permitted. If the value of base is 16, the
+ characters 0x or 0X may optionally precede the sequence of letters and
+ digits, following the sign if present.
+
+ The subject sequence is defined as the longest subsequence of the
+ input string, starting with the first non-white-space character, that
+ is an initial subsequence of a sequence of the expected form. The
+ subject sequence contains no characters if the input string is empty
+ or consists entirely of white space, or if the first non-white-space
+ character is other than a sign or a permissible letter or digit.
+
+ If the subject sequence has the expected form and the value of base
+ is zero, the sequence of characters starting with the first digit is
+ interpreted as an integer constant according to the rules of $3.1.3.2.
+ If the subject sequence has the expected form and the value of base is
+ between 2 and 36, it is used as the base for conversion, ascribing to
+ each letter its value as given above. If the subject sequence begins
+ with a minus sign, the value resulting from the conversion is negated.
+ A pointer to the final string is stored in the object pointed to by
+ endptr , provided that endptr is not a null pointer.
+
+ In other than the C locale, additional implementation-defined
+ subject sequence forms may be accepted.
+
+ If the subject sequence is empty or does not have the expected
+ form, no conversion is performed; the value of nptr is stored in the
+ object pointed to by endptr , provided that endptr is not a null
+ pointer.
+
+ Returns
+
+ The strtoul function returns the converted value, if any. If no
+ conversion could be performed, zero is returned. If the correct value
+ would cause overflow, ULONG_MAX is returned, and the value of the
+ macro ERANGE is stored in errno .
+
+
+ 4.10.2 Pseudo-random sequence generation functions
+
+ 4.10.2.1 The rand function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int rand(void);
+
+ Description
+
+ The rand function computes a sequence of pseudo-random integers in
+ the range 0 to RAND_MAX .
+
+ The implementation shall behave as if no library function calls the
+ rand function.
+
+ Returns
+
+ The rand function returns a pseudo-random integer. =20
+
+ "Environmental limit"
+
+ The value of the RAND_MAX macro shall be at least 32767. =20
+
+
+ 4.10.2.2 The srand function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void srand(unsigned int seed);
+
+ Description
+
+ The srand function uses the argument as a seed for a new sequence
+ of pseudo-random numbers to be returned by subsequent calls to rand .
+ If srand is then called with the same seed value, the sequence of
+ pseudo-random numbers shall be repeated. If rand is called before any
+ calls to srand have been made, the same sequence shall be generated as
+ when srand is first called with a seed value of 1.
+
+ The implementation shall behave as if no library function calls the
+ srand function.
+
+ Returns
+
+ The srand function returns no value. =20
+
+ Example
+
+ The following functions define a portable implementation of rand
+ and srand. Specifying the semantics makes it possible to determine
+ reproducibly the behavior of programs that use pseudo-random
+ sequences. This facilitates the testing of portable applications in
+ different implementations.
+
+ static unsigned long int next =3D 1;
+
+ int rand(void) /* RAND_MAX assumed to be 32767 */
+ {
+ next =3D next * 1103515245 + 12345;
+ return (unsigned int)(next/65536) % 32768;
+ }
+
+ void srand(unsigned int seed)
+ {
+ next =3D seed;
+ }
+
+
+
+ 4.10.3 Memory management functions
+
+ The order and contiguity of storage allocated by successive calls
+ to the calloc , malloc , and realloc functions is unspecified. The
+ pointer returned if the allocation succeeds is suitably aligned so
+ that it may be assigned to a pointer to any type of object and then
+ used to access such an object in the space allocated (until the space
+ is explicitly freed or reallocated). Each such allocation shall yield
+ a pointer to an object disjoint from any other object. The pointer
+ returned points to the start (lowest byte address) of the allocated
+ space. If the space cannot be allocated, a null pointer is returned.
+ If the size of the space requested is zero, the behavior is
+ implementation-defined; the value returned shall be either a null
+ pointer or a unique pointer. The value of a pointer that refers to
+ freed space is indeterminate.
+
+
+ 4.10.3.1 The calloc function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void *calloc(size_t nmemb, size_t size);
+
+ Description
+
+ The calloc function allocates space for an array of nmemb objects,
+ each of whose size is size . The space is initialized to all bits
+ zero./114/
+
+ Returns
+
+ The calloc function returns either a null pointer or a pointer to
+ the allocated space.
+
+
+ 4.10.3.2 The free function
+
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void free(void *ptr);
+
+ Description
+
+ The free function causes the space pointed to by ptr to be
+ deallocated, that is, made available for further allocation. If ptr
+ is a null pointer, no action occurs. Otherwise, if the argument does
+ not match a pointer earlier returned by the calloc , malloc , or
+ realloc function, or if the space has been deallocated by a call to
+ free or realloc , the behavior is undefined.
+
+ Returns
+
+ The free function returns no value. =20
+
+
+ 4.10.3.3 The malloc function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void *malloc(size_t size);
+
+ Description
+
+ The malloc function allocates space for an object whose size is
+ specified by size and whose value is indeterminate.
+
+ Returns
+
+ The malloc function returns either a null pointer or a pointer to
+ the allocated space.
+
+
+ 4.10.3.4 The realloc function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void *realloc(void *ptr, size_t size);
+
+ Description
+
+ The realloc function changes the size of the object pointed to by
+ ptr to the size specified by size . The contents of the object shall
+ be unchanged up to the lesser of the new and old sizes. If the new
+ size is larger, the value of the newly allocated portion of the object
+ is indeterminate. If ptr is a null pointer, the realloc function
+ behaves like the malloc function for the specified size. Otherwise,
+ if ptr does not match a pointer earlier returned by the calloc ,
+ malloc , or realloc function, or if the space has been deallocated by
+ a call to the free or realloc function, the behavior is undefined. If
+ the space cannot be allocated, the object pointed to by ptr is
+ unchanged. If size is zero and ptr is not a null pointer, the object
+ it points to is freed.
+
+ Returns
+
+ The realloc function returns either a null pointer or a pointer to
+ the possibly moved allocated space.
+
+
+ 4.10.4 Communication with the environment
+
+ 4.10.4.1 The abort function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void abort(void);
+
+ Description
+
+ The abort function causes abnormal program termination to occur,
+ unless the signal SIGABRT is being caught and the signal handler does
+ not return. Whether open output streams are flushed or open streams
+ closed or temporary files removed is implementation-defined. An
+ implementation-defined form of the status unsuccessful termination is
+ returned to the host environment by means of the function call
+ raise(SIGABRT) .
+
+ Returns
+
+ The abort function cannot return to its caller. =20
+
+ 4.10.4.2 The atexit function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int atexit(void (*func)(void));
+
+ Description
+
+ The atexit function registers the function pointed to by func , to
+ be called without arguments at normal program termination.
+
+ "Implementation limits"
+
+ The implementation shall support the registration of at least 32
+ functions.
+
+ Returns
+
+ The atexit function returns zero if the registration succeeds,
+ nonzero if it fails.
+
+ Forward references: the exit function ($4.10.4.3). =20
+
+
+ 4.10.4.3 The exit function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void exit(int status);
+
+ Description
+
+ The exit function causes normal program termination to occur. If
+ more than one call to the exit function is executed by a program, the
+ behavior is undefined.
+
+ First, all functions registered by the atexit function are called,
+ in the reverse order of their registration./115/
+
+ Next, all open output streams are flushed, all open streams are
+ closed, and all files created by the tmpfile function are removed.
+
+ Finally, control is returned to the host environment. If the value
+ of status is zero or EXIT_SUCCESS , an implementation-defined form of
+ the status successful termination is returned. If the value of status
+ is EXIT_FAILURE , an implementation-defined form of the status
+ unsuccessful termination is returned. Otherwise the status returned
+ is implementation-defined.
+
+ Returns
+
+ The exit function cannot return to its caller. =20
+
+
+ 4.10.4.4 The getenv function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ char *getenv(const char *name);
+
+ Description
+
+ The getenv function searches an environment list, provided by the
+ host environment, for a string that matches the string pointed to by
+ name . The set of environment names and the method for altering the
+ environment list are implementation-defined.
+
+ The implementation shall behave as if no library function calls the
+ getenv function.
+
+ Returns
+
+ The getenv function returns a pointer to a string associated with
+ the matched list member. The array pointed to shall not be modified
+ by the program, but may be overwritten by a subsequent call to the
+ getenv function. If the specified name cannot be found, a null
+ pointer is returned.
+
+
+ 4.10.4.5 The system function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int system(const char *string);
+
+ Description
+
+ The system function passes the string pointed to by string to the
+ host environment to be executed by a command processor in an
+ implementation-defined manner. A null pointer may be used for string
+ to inquire whether a command processor exists.
+
+ Returns
+
+ If the argument is a null pointer, the system function returns
+ nonzero only if a command processor is available. If the argument is
+ not a null pointer, the system function returns an
+ implementation-defined value.
+
+
+ 4.10.5 Searching and sorting utilities
+
+ 4.10.5.1 The bsearch function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void *bsearch(const void *key, const void *base,
+ size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+
+ Description
+
+ The bsearch function searches an array of nmemb objects, the
+ initial member of which is pointed to by base , for a member that
+ matches the object pointed to by key . The size of each member of the
+ array is specified by size .
+
+ The contents of the array shall be in ascending sorted order
+ according to a comparison function pointed to by compar ,/116/ induces
+ which is called with two arguments that point to the key object and to
+ an array member, in that order. The function shall return an integer
+ less than, equal to, or greater than zero if the key object is
+ considered, respectively, to be less than, to match, or to be greater
+ than the array member.
+
+ Returns
+
+ The bsearch function returns a pointer to a matching member of the
+ array, or a null pointer if no match is found. If two members compare
+ as equal, which member is matched is unspecified.
+
+
+ 4.10.5.2 The qsort function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ void qsort(void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+
+ Description
+
+ The qsort function sorts an array of nmemb objects, the initial
+ member of which is pointed to by base . The size of each object is
+ specified by size .
+
+ The contents of the array are sorted in ascending order according
+ to a comparison function pointed to by compar , which is called with
+ two arguments that point to the objects being compared. The function
+ shall return an integer less than, equal to, or greater than zero if
+ the first argument is considered to be respectively less than, equal
+ to, or greater than the second.
+
+ If two members compare as equal, their order in the sorted array is
+ unspecified.
+
+ Returns
+
+ The qsort function returns no value. =20
+
+
+ 4.10.6 Integer arithmetic functions
+
+ 4.10.6.1 The abs function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int abs(int j);
+
+ Description
+
+ The abs function computes the absolute value of an integer j . If
+ the result cannot be represented, the behavior is undefined./117/
+
+ Returns
+
+ The abs function returns the absolute value. =20
+
+
+ 4.10.6.2 The div function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ div_t div(int numer, int denom);
+
+ Description
+
+ The div function computes the quotient and remainder of the
+ division of the numerator numer by the denominator denom . If the
+ division is inexact, the sign of the resulting quotient is that of the
+ algebraic quotient, and the magnitude of the resulting quotient is the
+ largest integer less than the magnitude of the algebraic quotient. If
+ the result cannot be represented, the behavior is undefined;
+ otherwise, quot * denom + rem shall equal numer .
+
+ Returns
+
+ The div function returns a structure of type div_t , comprising
+ both the quotient and the remainder. The structure shall contain the
+ following members, in either order.
+
+ int quot; /* quotient */
+ int rem; /* remainder */
+
+
+ 4.10.6.3 The labs function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ long int labs(long int j);
+
+ Description
+
+ The labs function is similar to the abs function, except that the
+ argument and the returned value each have type long int .
+
+
+ 4.10.6.4 The ldiv function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ ldiv_t ldiv(long int numer, long int denom);
+
+ Description
+
+ The ldiv function is similar to the div function, except that the
+ arguments and the members of the returned structure (which has type
+ ldiv_t ) all have type long int .
+
+
+ 4.10.7 Multibyte character functions
+
+ The behavior of the multibyte character functions is affected by
+ the LC_CTYPE category of the current locale. For a state-dependent
+ encoding, each function is placed into its initial state by a call for
+ which its character pointer argument, s , is a null pointer.
+ Subsequent calls with s as other than a null pointer cause the
+ internal state of the function to be altered as necessary. A call
+ with s as a null pointer causes these functions to return a nonzero
+ value if encodings have state dependency, and zero otherwise. After
+ the LC_CTYPE category is changed, the shift state of these functions
+ is indeterminate.
+
+
+ 4.10.7.1 The mblen function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int mblen(const char *s, size_t n);
+
+ Description
+
+ If s is not a null pointer, the mblen function determines the
+ number of bytes comprising the multibyte character pointed to by s .
+ Except that the shift state of the mbtowc function is not affected, it
+ is equivalent to
+
+ mbtowc((wchar_t *)0, s, n);
+
+
+ The implementation shall behave as if no library function calls the
+ mblen function.
+
+ Returns
+
+ If s is a null pointer, the mblen function returns a nonzero or
+ zero value, if multibyte character encodings, respectively, do or do
+ not have state-dependent encodings. If s is not a null pointer, the
+ mblen function either returns 0 (if s points to the null character),
+ or returns the number of bytes that comprise the multibyte character
+ (if the next n or fewer bytes form a valid multibyte character), or
+ returns -1 (if they do not form a valid multibyte character).
+
+ Forward references: the mbtowc function ($4.10.7.2). =20
+
+
+ 4.10.7.2 The mbtowc function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int mbtowc(wchar_t *pwc, const char *s, size_t n);
+
+ Description
+
+ If s is not a null pointer, the mbtowc function determines the
+ number of bytes that comprise the multibyte character pointed to by s.
+ It then determines the code for value of type wchar_t that
+ corresponds to that multibyte character. (The value of the code
+ corresponding to the null character is zero.) If the multibyte
+ character is valid and pwc is not a null pointer, the mbtowc function
+ stores the code in the object pointed to by pwc . At most n bytes of
+ the array pointed to by s will be examined.
+
+ The implementation shall behave as if no library function calls the
+ mbtowc function.
+
+ Returns
+
+ If s is a null pointer, the mbtowc function returns a nonzero or zero
+ value, if multibyte character encodings, respectively, do or do not
+ have state-dependent encodings. If s is not a null pointer, the
+ mbtowc function either returns 0 (if s points to the null character),
+ or returns the number of bytes that comprise the converted multibyte
+ character (if the next n or fewer bytes form a valid multibyte
+ character), or returns -1 (if they do not form a valid multibyte
+ character).
+
+ In no case will the value returned be greater than n or the value
+ of the MB_CUR_MAX macro.
+
+
+ 4.10.7.3 The wctomb function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ int wctomb(char *s, wchar_t wchar);
+
+ Description
+
+ The wctomb function determines the number of bytes needed to
+ represent the multibyte character corresponding to the code whose
+ value is wchar (including any change in shift state). It stores the
+ multibyte character representation in the array object pointed to by s
+ (if s is not a null pointer). At most MB_CUR_MAX characters are
+ stored. If the value of wchar is zero, the wctomb function is left in
+ the initial shift state.
+
+ The implementation shall behave as if no library function calls the
+ wctomb function.
+
+ Returns
+
+ If s is a null pointer, the wctomb function returns a nonzero or
+ zero value, if multibyte character encodings, respectively, do or do
+ not have state-dependent encodings. If s is not a null pointer, the
+ wctomb function returns -1 if the value of wchar does not correspond
+ to a valid multibyte character, or returns the number of bytes that
+ comprise the multibyte character corresponding to the value of wchar .
+
+ In no case will the value returned be greater than the value of the
+ MB_CUR_MAX macro.
+
+
+ 4.10.8 Multibyte string functions
+
+ The behavior of the multibyte string functions is affected by the
+ LC_CTYPE category of the current locale.
+
+
+ 4.10.8.1 The mbstowcs function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
+
+ Description
+
+ The mbstowcs function converts a sequence of multibyte characters
+ that begins in the initial shift state from the array pointed to by s
+ into a sequence of corresponding codes and stores not more than n
+ codes into the array pointed to by pwcs . No multibyte characters
+ that follow a null character (which is converted into a code with
+ value zero) will be examined or converted. Each multibyte character
+ is converted as if by a call to the mbtowc function, except that the
+ shift state of the mbtowc function is not affected.
+
+ No more than n elements will be modified in the array pointed to by
+ pwcs . If copying takes place between objects that overlap, the
+ behavior is undefined.
+
+ Returns
+
+ If an invalid multibyte character is encountered, the mbstowcs
+ function returns (size_t)-1 . Otherwise, the mbstowcs function
+ returns the number of array elements modified, not including a
+ terminating zero code, if any.rN
+
+
+ 4.10.8.2 The wcstombs function
+
+ Synopsis
+
+ #include &lt;stdlib.h&gt;
+ size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
+
+ Description
+
+ The wcstombs function converts a sequence of codes that correspond
+ to multibyte characters from the array pointed to by pwcs into a
+ sequence of multibyte characters that begins in the initial shift
+ state and stores these multibyte characters into the array pointed to
+ by s , stopping if a multibyte character would exceed the limit of n
+ total bytes or if a null character is stored. Each code is converted
+ as if by a call to the wctomb function, except that the shift state of
+ the wctomb function is not affected.
+
+ No more than n bytes will be modified in the array pointed to by s
+ . If copying takes place between objects that overlap, the behavior
+ is undefined.
+
+ Returns
+
+ If a code is encountered that does not correspond to a valid
+ multibyte character, the wcstombs function returns (size_t)-1 .
+ Otherwise, the wcstombs function returns the number of bytes modified,
+ not including a terminating null character, if any.rN
+
+
+ 4.11 STRING HANDLING &lt;string.h&gt;
+
+ 4.11.1 String function conventions
+
+ The header &lt;string.h&gt; declares one type and several functions, and
+ defines one macro useful for manipulating arrays of character type and
+ other objects treated as arrays of character type./119/ The type is
+ size_t and the macro is NULL (both described in $4.1.5). Various
+ methods are used for determining the lengths of the arrays, but in all
+ cases a char * or void * argument points to the initial (lowest
+ addressed) character of the array. If an array is accessed beyond the
+ end of an object, the behavior is undefined.
+
+
+ 4.11.2 Copying functions
+
+ 4.11.2.1 The memcpy function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ void *memcpy(void *s1, const void *s2, size_t n);
+
+ Description
+
+ The memcpy function copies n characters from the object pointed to
+ by s2 into the object pointed to by s1 . If copying takes place
+ between objects that overlap, the behavior is undefined.
+
+ Returns
+
+ The memcpy function returns the value of s1 . =20
+
+
+ 4.11.2.2 The memmove function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ void *memmove(void *s1, const void *s2, size_t n);
+
+ Description
+
+ The memmove function copies n characters from the object pointed to
+ by s2 into the object pointed to by s1 . Copying takes place as if
+ the n characters from the object pointed to by s2 are first copied
+ into a temporary array of n characters that does not overlap the
+ objects pointed to by s1 and s2 , and then the n characters from the
+ temporary array are copied into the object pointed to by s1 .
+
+ Returns
+
+ The memmove function returns the value of s1 . =20
+
+
+ 4.11.2.3 The strcpy function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strcpy(char *s1, const char *s2);
+
+ Description
+
+ The strcpy function copies the string pointed to by s2 (including
+ the terminating null character) into the array pointed to by s1 . If
+ copying takes place between objects that overlap, the behavior is
+ undefined.
+
+ Returns
+
+ The strcpy function returns the value of s1 . =20
+
+
+ 4.11.2.4 The strncpy function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strncpy(char *s1, const char *s2, size_t n);
+
+ Description
+
+ The strncpy function copies not more than n characters (characters
+ that follow a null character are not copied) from the array pointed to
+ by s2 to the array pointed to by s1 ./120/ If copying takes place
+ between objects that overlap, the behavior is undefined.
+
+ If the array pointed to by s2 is a string that is shorter than n
+ characters, null characters are appended to the copy in the array
+ pointed to by s1 , until n characters in all have been written.
+
+ Returns
+
+ The strncpy function returns the value of s1 . =20
+
+
+ 4.11.3 Concatenation functions
+
+ 4.11.3.1 The strcat function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strcat(char *s1, const char *s2);
+
+ Description
+
+ The strcat function appends a copy of the string pointed to by s2
+ (including the terminating null character) to the end of the string
+ pointed to by s1 . The initial character of s2 overwrites the null
+ character at the end of s1 . If copying takes place between objects
+ that overlap, the behavior is undefined.
+
+ Returns
+
+ The strcat function returns the value of s1 . =20
+
+
+ 4.11.3.2 The strncat function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strncat(char *s1, const char *s2, size_t n);
+
+ Description
+
+ The strncat function appends not more than n characters (a null
+ character and characters that follow it are not appended) from the
+ array pointed to by s2 to the end of the string pointed to by s1 .
+ The initial character of s2 overwrites the null character at the end
+ of s1 . A terminating null character is always appended to the
+ result./121/ If copying takes place between objects that overlap, the
+ behavior is undefined.
+
+ Returns
+
+ The strncat function returns the value of s1 . =20
+
+ Forward references: the strlen function ($4.11.6.3). =20
+
+
+ 4.11.4 Comparison functions
+
+ The sign of a nonzero value returned by the comparison functions is
+ determined by the sign of the difference between the values of the
+ first pair of characters (both interpreted as unsigned char ) that
+ differ in the objects being compared.
+
+
+ 4.11.4.1 The memcmp function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ int memcmp(const void *s1, const void *s2, size_t n);
+
+ Description
+
+ The memcmp function compares the first n characters of the object
+ pointed to by s1 to the first n characters of the object pointed to by
+ s2 ./122/
+
+ Returns
+
+ The memcmp function returns an integer greater than, equal to, or
+ less than zero, according as the object pointed to by s1 is greater
+ than, equal to, or less than the object pointed to by s2 .
+
+
+ 4.11.4.2 The strcmp function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ int strcmp(const char *s1, const char *s2);
+
+ Description
+
+ The strcmp function compares the string pointed to by s1 to the
+ string pointed to by s2 .
+
+ Returns
+
+ The strcmp function returns an integer greater than, equal to, or
+ less than zero, according as the string pointed to by s1 is greater
+ than, equal to, or less than the string pointed to by s2 .
+
+
+ 4.11.4.3 The strcoll function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ int strcoll(const char *s1, const char *s2);
+
+ Description
+
+ The strcoll function compares the string pointed to by s1 to the
+ string pointed to by s2 , both interpreted as appropriate to the
+ LC_COLLATE category of the current locale.
+
+ Returns
+
+ The strcoll function returns an integer greater than, equal to, or
+ less than zero, according as the string pointed to by s1 is greater
+ than, equal to, or less than the string pointed to by s2 when both are
+ interpreted as appropriate to the current locale.
+
+
+ 4.11.4.4 The strncmp function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ int strncmp(const char *s1, const char *s2, size_t n);
+
+ Description
+
+ The strncmp function compares not more than n characters
+ (characters that follow a null character are not compared) from the
+ array pointed to by s1 to the array pointed to by s2 .
+
+ Returns
+
+ The strncmp function returns an integer greater than, equal to, or
+ less than zero, according as the possibly null-terminated array
+ pointed to by s1 is greater than, equal to, or less than the possibly
+ null-terminated array pointed to by s2 .
+
+
+ 4.11.4.5 The strxfrm function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ size_t strxfrm(char *s1, const char *s2, size_t n);
+
+ Description
+
+ The strxfrm function transforms the string pointed to by s2 and
+ places the resulting string into the array pointed to by s1 . The
+ transformation is such that if the strcmp function is applied to two
+ transformed strings, it returns a value greater than, equal to, or
+ less than zero, corresponding to the result of the strcoll function
+ applied to the same two original strings. No more than n characters
+ are placed into the resulting array pointed to by s1 , including the
+ terminating null character. If n is zero, s1 is permitted to be a
+ null pointer. If copying takes place between objects that overlap,
+ the behavior is undefined.
+
+ Returns
+
+ The strxfrm function returns the length of the transformed string
+ (not including the terminating null character). If the value returned
+ is n or more, the contents of the array pointed to by s1 are
+ indeterminate.
+
+ Example
+
+ The value of the following expression is the size of the array
+ needed to hold the transformation of the string pointed to by s .
+
+ 1 + strxfrm(NULL, s, 0)
+
+
+ 4.11.5 Search functions
+
+ 4.11.5.1 The memchr function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ void *memchr(const void *s, int c, size_t n);
+
+ Description
+
+ The memchr function locates the first occurrence of c (converted to
+ an unsigned char ) in the initial n characters (each interpreted as
+ unsigned char ) of the object pointed to by s .
+
+ Returns
+
+ The memchr function returns a pointer to the located character, or
+ a null pointer if the character does not occur in the object.
+
+
+ 4.11.5.2 The strchr function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strchr(const char *s, int c);
+
+ Description
+
+ The strchr function locates the first occurrence of c (converted to
+ a char ) in the string pointed to by s . The terminating null
+ character is considered to be part of the string.
+
+ Returns
+
+ The strchr function returns a pointer to the located character, or
+ a null pointer if the character does not occur in the string.
+
+
+ 4.11.5.3 The strcspn function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ size_t strcspn(const char *s1, const char *s2);
+
+ Description
+
+ The strcspn function computes the length of the maximum initial
+ segment of the string pointed to by s1 which consists entirely of
+ characters not from the string pointed to by s2 .
+
+ Returns
+
+ The strcspn function returns the length of the segment. =20
+
+
+ 4.11.5.4 The strpbrk function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strpbrk(const char *s1, const char *s2);
+
+ Description
+
+ The strpbrk function locates the first occurrence in the string
+ pointed to by s1 of any character from the string pointed to by s2 .
+
+ Returns
+
+ The strpbrk function returns a pointer to the character, or a null
+ pointer if no character from s2 occurs in s1 .
+
+
+ 4.11.5.5 The strrchr function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strrchr(const char *s, int c);
+
+ Description
+
+ The strrchr function locates the last occurrence of c (converted to
+ a char ) in the string pointed to by s . The terminating null
+ character is considered to be part of the string.
+
+ Returns
+
+ The strrchr function returns a pointer to the character, or a null
+ pointer if c does not occur in the string.
+
+
+ 4.11.5.6 The strspn function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ size_t strspn(const char *s1, const char *s2);
+
+ Description
+
+ The strspn function computes the length of the maximum initial
+ segment of the string pointed to by s1 which consists entirely of
+ characters from the string pointed to by s2 .
+
+ Returns
+
+ The strspn function returns the length of the segment. =20
+
+
+ 4.11.5.7 The strstr function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strstr(const char *s1, const char *s2);
+
+ Description
+
+ The strstr function locates the first occurrence in the string
+ pointed to by s1 of the sequence of characters (excluding the
+ terminating null character) in the string pointed to by s2
+
+ Returns
+
+ The strstr function returns a pointer to the located string, or a
+ null pointer if the string is not found. If s2 points to a string
+ with zero length, the function returns s1 .
+
+
+ 4.11.5.8 The strtok function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strtok(char *s1, const char *s2);
+
+ Description
+
+ A sequence of calls to the strtok function breaks the string
+ pointed to by s1 into a sequence of tokens, each of which is delimited
+ by a character from the string pointed to by s2 . The first call in
+ the sequence has s1 as its first argument, and is followed by calls
+ with a null pointer as their first argument. The separator string
+ pointed to by s2 may be different from call to call.
+
+ The first call in the sequence searches the string pointed to by s1
+ for the first character that is not contained in the current separator
+ string pointed to by s2 . If no such character is found, then there
+ are no tokens in the string pointed to by s1 and the strtok function
+ returns a null pointer. If such a character is found, it is the start
+ of the first token.
+
+ The strtok function then searches from there for a character that
+ is contained in the current separator string. If no such character is
+ found, the current token extends to the end of the string pointed to
+ by s1 , and subsequent searches for a token will return a null
+ pointer. If such a character is found, it is overwritten by a null
+ character, which terminates the current token. The strtok function
+ saves a pointer to the following character, from which the next search
+ for a token will start.
+
+ Each subsequent call, with a null pointer as the value of the first
+ argument, starts searching from the saved pointer and behaves as
+ described above.
+
+ The implementation shall behave as if no library function calls the
+ strtok function.
+
+ Returns
+
+ The strtok function returns a pointer to the first character of a
+ token, or a null pointer if there is no token.
+
+ Example
+
+ #include &lt;string.h&gt;
+ static char str[] =3D "?a???b,,,#c";
+ char *t;
+
+ t =3D strtok(str, "?"); /* t points to the token "a" */
+ t =3D strtok(NULL, ","); /* t points to the token "??b" */
+ t =3D strtok(NULL, "#,"); /* t points to the token "c" */
+ t =3D strtok(NULL, "?"); /* t is a null pointer */
+
+
+ 4.11.6 Miscellaneous functions
+
+ 4.11.6.1 The memset function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ void *memset(void *s, int c, size_t n);
+
+ Description
+
+ The memset function copies the value of c (converted to an unsigned
+ char ) into each of the first n characters of the object pointed to by
+ s .
+
+ Returns
+
+ The memset function returns the value of s . =20
+
+
+ 4.11.6.2 The strerror function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ char *strerror(int errnum);
+
+ Description
+
+ The strerror function maps the error number in errnum to an error
+ message string.
+
+ The implementation shall behave as if no library function calls the
+ strerror function.
+
+ Returns
+
+ The strerror function returns a pointer to the string, the contents
+ of which are implementation-defined. The array pointed to shall not
+ be modified by the program, but may be overwritten by a subsequent
+ call to the strerror function.
+
+
+ 4.11.6.3 The strlen function
+
+ Synopsis
+
+ #include &lt;string.h&gt;
+ size_t strlen(const char *s);
+
+ Description
+
+ The strlen function computes the length of the string pointed to by s . =
+ =20
+
+ Returns
+
+ The strlen function returns the number of characters that precede
+ the terminating null character.
+
+
+ 4.12 DATE AND TIME &lt;time.h&gt;
+
+ 4.12.1 Components of time
+
+ The header &lt;time.h&gt; defines two macros, and declares four types an=
+ d
+ several functions for manipulating time. Many functions deal with a
+ calendar time that represents the current date (according to the
+ Gregorian calendar) and time. Some functions deal with local time,=20
+ which is the calendar time expressed for some specific time zone, and=20
+ with Daylight Saving Time, which is a temporary change in the
+ algorithm for determining local time. The local time zone and
+ Daylight Saving Time are implementation-defined.
+
+ The macros defined are NULL (described in $4.1.5); and=20
+
+ CLK_TCK
+
+ which is the number per second of the value returned by the clock function.
+
+ The types declared are size_t (described in $4.1.5);=20
+
+ clock_t
+
+ and=20
+
+ time_t
+
+ which are arithmetic types capable of representing times; and=20
+
+ struct tm
+
+ which holds the components of a calendar time, called the broken-down
+ time. The structure shall contain at least the following members, in
+ any order. The semantics of the members and their normal ranges are
+ expressed in the comments./123/
+
+ int tm_sec; /* seconds after the minute --- [0, 60] */
+ int tm_min; /* minutes after the hour --- [0, 59] */
+ int tm_hour; /* hours since midnight --- [0, 23] */
+ int tm_mday; /* day of the month --- [1, 31] */
+ int tm_mon; /* months since January --- [0, 11] */
+ int tm_year; /* years since 1900 */
+ int tm_wday; /* days since Sunday --- [0, 6] */
+ int tm_yday; /* days since January 1 --- [0, 365] */
+ int tm_isdst; /* Daylight Saving Time flag */
+
+ The value of tm_isdst is positive if Daylight Saving Time is in
+ effect, zero if Daylight Saving Time is not in effect, and negative if
+ the information is not available.
+
+
+ 4.12.2 Time manipulation functions
+
+ 4.12.2.1 The clock function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ clock_t clock(void);
+
+ Description
+
+ The clock function determines the processor time used. =20
+
+ Returns
+
+ The clock function returns the implementation's best approximation
+ to the processor time used by the program since the beginning of an
+ implementation-defined era related only to the program invocation. To
+ determine the time in seconds, the value returned by the clock
+ function should be divided by the value of the macro CLK_TCK . If the
+ processor time used is not available or its value cannot be
+ represented, the function returns the value (clock_t)-1 .
+
+
+ 4.12.2.2 The difftime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ double difftime(time_t time1, time_t time0);
+
+ Description
+
+ The difftime function computes the difference between two calendar
+ times: time1 - time0 .
+
+ Returns
+
+ The difftime function returns the difference expressed in seconds
+ as a double .
+
+
+ 4.12.2.3 The mktime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ time_t mktime(struct tm *timeptr);
+
+ Description
+
+ The mktime function converts the broken-down time, expressed as
+ local time, in the structure pointed to by timeptr into a calendar
+ time value with the same encoding as that of the values returned by
+ the time function. The original values of the tm_wday and tm_yday
+ components of the structure are ignored, and the original values of
+ the other components are not restricted to the ranges indicated
+ above./124/ On successful completion, the values of the tm_wday and
+ tm_yday components of the structure are set appropriately, and the
+ other components are set to represent the specified calendar time, but
+ with their values forced to the ranges indicated above; the final
+ value of tm_mday is not set until tm_mon and tm_year are determined.
+
+ Returns
+
+ The mktime function returns the specified calendar time encoded as
+ a value of type time_t . If the calendar time cannot be represented,
+ the function returns the value (time_t)-1 .
+
+ Example
+
+ What day of the week is July 4, 2001?=20
+ =20
+
+ #include &lt;stdio.h&gt;
+ #include &lt;time.h&gt;
+ static const char *const wday[] =3D {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday", "-unknown-"
+ };
+ struct tm time_str;
+
+
+
+ time_str.tm_year =3D 2001 - 1900;
+ time_str.tm_mon =3D 7 - 1;
+ time_str.tm_mday =3D 4;
+ time_str.tm_hour =3D 0;
+ time_str.tm_min =3D 0;
+ time_str.tm_sec =3D 1;
+ time_str.tm_isdst =3D -1;
+ if (mktime(&amp;time_str) =3D=3D -1)
+ time_str.tm_wday =3D 7;
+ printf("%s\n", wday[time_str.tm_wday]);
+
+
+ 4.12.2.4 The time function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ time_t time(time_t *timer);
+
+ Description
+
+ The time function determines the current calendar time. The
+ encoding of the value is unspecified.
+
+ Returns
+
+ The time function returns the implementation's best approximation
+ to the current calendar time. The value (time_t)-1 is returned if the
+ calendar time is not available. If timer is not a null pointer, the
+ return value is also assigned to the object it points to.
+
+
+ 4.12.3 Time conversion functions
+
+ Except for the strftime function, these functions return values in
+ one of two static objects: a broken-down time structure and an array
+ of char . Execution of any of the functions may overwrite the
+ information returned in either of these objects by any of the other
+ functions. The implementation shall behave as if no other library
+ functions call these functions.
+
+
+ 4.12.3.1 The asctime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ char *asctime(const struct tm *timeptr);
+
+ Description
+
+ The asctime function converts the broken-down time in the structure
+ pointed to by timeptr into a string in the form
+
+ Sun Sep 16 01:03:52 1973\n\0
+
+ using the equivalent of the following algorithm. =20
+
+ char *asctime(const struct tm *timeptr)
+ {
+ static const char wday_name[7][3] =3D {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+ };
+ static const char mon_name[12][3] =3D {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ static char result[26];
+
+ sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
+ wday_name[timeptr-&gt;tm_wday],
+ mon_name[timeptr-&gt;tm_mon],
+ timeptr-&gt;tm_mday, timeptr-&gt;tm_hour,
+ timeptr-&gt;tm_min, timeptr-&gt;tm_sec,
+ 1900 + timeptr-&gt;tm_year);
+ return result;
+ }
+
+ Returns
+
+ The asctime function returns a pointer to the string. =20
+
+
+ 4.12.3.2 The ctime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ char *ctime(const time_t *timer);
+
+ Description
+
+ The ctime function converts the calendar time pointed to by timer to loc=
+ al time in the form of a string. It is equivalent to=20
+
+ asctime(localtime(timer))
+
+ Returns
+
+ The ctime function returns the pointer returned by the asctime
+ function with that broken-down time as argument.
+
+ Forward references: the localtime function ($4.12.3.4). =20
+
+
+ 4.12.3.3 The gmtime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ struct tm *gmtime(const time_t *timer);
+
+ Description
+
+ The gmtime function converts the calendar time pointed to by timer
+ into a broken-down time, expressed as Coordinated Universal Time
+ (UTC).
+
+ Returns
+
+ The gmtime function returns a pointer to that object, or a null
+ pointer if UTC is not available.
+
+
+ 4.12.3.4 The localtime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ struct tm *localtime(const time_t *timer);
+
+ Description
+
+ The localtime function converts the calendar time pointed to by
+ timer into a broken-down time, expressed as local time.
+
+ Returns
+
+ The localtime function returns a pointer to that object. =20
+
+
+ 4.12.3.5 The strftime function
+
+ Synopsis
+
+ #include &lt;time.h&gt;
+ size_t strftime(char *s, size_t maxsize,
+ const char *format, const struct tm *timeptr);
+
+ Description
+
+ The strftime function places characters into the array pointed to
+ by s as controlled by the string pointed to by format . The format
+ shall be a multibyte character sequence, beginning and ending in its
+ initial shift state. The format string consists of zero or more
+ conversion specifications and ordinary multibyte characters. A
+ conversion specification consists of a % character followed by a
+ character that determines the conversion specification's behavior.
+ All ordinary multibyte characters (including the terminating null
+ character) are copied unchanged into the array. If copying takes
+ place between objects that overlap, the behavior is undefined. No
+ more than maxsize characters are placed into the array. Each
+ conversion specification is replaced by appropriate characters as
+ described in the following list. The appropriate characters are
+ determined by the program's locale and by the values contained in the
+ structure pointed to by timeptr .
+
+ "%a" is replaced by the locale's abbreviated weekday name. =20
+ "%A" is replaced by the locale's full weekday name. =20
+ "%b" is replaced by the locale's abbreviated month name. =20
+ "%B" is replaced by the locale's full month name.
+ "%c" is replaced by the locale's appropriate date and time representation.
+ "%d" is replaced by the day of the month as a decimal number (01-31).
+ "%H" is replaced by the hour (24-hour clock) as a decimal number (00-23).
+ "%I" is replaced by the hour (12-hour clock) as a decimal number (01-12).=
+ =20
+ "%j" is replaced by the day of the year as a decimal number (001-366 ). =20
+ "%m" is replaced by the month as a decimal number (01-12). =20
+ "%M" is replaced by the minute as a decimal number (00-59). =20
+ "%p" is replaced by the locale's equivalent of either AM or PM . =20
+ "%S" is replaced by the second as a decimal number (00-60). =20
+ "%U" is replaced by the week number of the year (ithe first Sunday as the=
+ =20
+ first day of week 1) as a decimal number (00-53). =20
+ "%w" is replaced by the weekday as a decimal number (0-6), where Sunday is
+ 0.
+ "%W" is replaced by the week number of the year (the first Monday as the=20
+ first day of week 1) as a decimal number (00-53).=20
+ "%x" is replaced by the locale's appropriate date representation. =20
+ "%X" is replaced by the locale's appropriate time representation. =20
+ "%y" is replaced by the year without century as a decimal number (00-99).=
+ =20
+ "%Y" is replaced by the year with century as a decimal number. =20
+ "%Z" is replaced by the time zone name, or by no characters if no time=20
+ zone is determinable. =20
+ "%%" is replaced by %.
+
+ If a conversion specification is not one of the above, the behavior
+ is undefined.
+
+ Returns
+
+ If the total number of resulting characters including the
+ terminating null character is not more than maxsize , the strftime
+ function returns the number of characters placed into the array
+ pointed to by s not including the terminating null character.
+ Otherwise, zero is returned and the contents of the array are
+ indeterminate.
+
+
+ 4.13 FUTURE LIBRARY DIRECTIONS
+
+ The following names are grouped under individual headers for
+ convenience. All external names described below are reserved no
+ matter what headers are included by the program.
+
+
+ 4.13.1 Errors &lt;errno.h&gt;
+
+ Macros that begin with E and a digit or E and an upper-case letter
+ (followed by any combination of digits, letters and underscore) may be
+ added to the declarations in the &lt;errno.h&gt; header.
+
+
+ 4.13.2 Character handling &lt;ctype.h&gt;
+
+ Function names that begin with either is or to , and a lower-case
+ letter (followed by any combination of digits, letters and underscore)
+ may be added to the declarations in the &lt;ctype.h&gt; header.
+
+
+ 4.13.3 Localization &lt;locale.h&gt;
+
+ Macros that begin with LC_ and an upper-case letter (followed by
+ any combination of digits, letters and underscore) may be added to the
+ definitions in the &lt;locale.h&gt; header.
+
+
+ 4.13.4 Mathematics &lt;math.h&gt;
+
+ The names of all existing functions declared in the &lt;math.h&gt;
+ header, suffixed with f or l , are reserved respectively for
+ corresponding functions with float and long double arguments and
+ return values.
+
+
+ 4.13.5 Signal handling &lt;signal.h&gt;
+
+ Macros that begin with either SIG and an upper-case letter or SIG_
+ and an upper-case letter (followed by any combination of digits,
+ letters and underscore) may be added to the definitions in the
+ &lt;signal.h&gt; header.
+
+
+ 4.13.6 Input/output &lt;stdio.h&gt;
+
+ Lower-case letters may be added to the conversion specifiers in
+ fprintf and fscanf . Other characters may be used in extensions.
+
+
+ 4.13.7 General utilities &lt;stdlib.h&gt;
+
+ Function names that begin with str and a lower-case letter
+ (followed by any combination of digits, letters and underscore) may be
+ added to the declarations in the &lt;stdlib.h&gt; header.
+
+
+ 4.13.8 String handling &lt;string.h&gt;
+
+ Function names that begin with str , mem , or wcs and a lower-case
+ letter (followed by any combination of digits, letters and underscore)
+ may be added to the declarations in the &lt;string.h&gt; header.=20
+
+
+ A. APPENDICES
+
+ (These appendices are not a part of American National Standard for
+ Information Systems --- Programming Language C, X3.???-1988.)
+
+ These appendices collect information that appears in the Standard,
+ and are not necessarily complete.
+
+
+ A.1 LANGUAGE SYNTAX SUMMARY
+
+ The notation is described in the introduction to $3 (Language). =20
+
+
+ A.1.1 Lexical grammar
+
+ A.1.1.1 Tokens
+
+ keyword
+ identifier
+ constant
+ string-literal
+ operator
+ punctuator
+ header-name
+ identifier
+ pp-number
+ character-constant
+ string-literal
+ operator
+ punctuator
+ each non-white-space character that cannot be one of
+ the above
+
+
+ A.1.1.2 Keywords
+
+ auto double int struct
+ break else long switch
+ case enum register typedef
+ char extern return union
+ const float short unsigned
+ continue for signed void
+ default goto sizeof volatile
+ do if static while
+
+
+ A.1.1.3 Identifiers
+
+ nondigit
+ identifier nondigit
+ identifier digit
+
+ _ a b c d e f g h i j k l m
+ n o p q r s t u v w x y z
+ A B C D E F G H I J K L M
+ N O P Q R S T U V W X Y Z
+
+ 0 1 2 3 4 5 6 7 8 9
+
+
+ A.1.1.4 Constants
+
+ floating-constant
+ integer-constant
+ enumeration-constant
+ character-constant
+
+ fractional-constant exponent-part&lt;opt&gt; floating-suf=
+ fix&lt;opt&gt;
+ digit-sequence exponent-part floating-suffix&lt;opt&gt;
+
+ digit-sequence&lt;opt&gt; . digit-sequence
+ digit-sequence .
+
+ e sign&lt;opt&gt; digit-sequence
+ E sign&lt;opt&gt; digit-sequence
+
+ + -
+
+ digit
+ digit-sequence digit
+
+ f l F L
+
+ decimal-constant integer-suffix&lt;opt&gt;
+ octal-constant integer-suffix&lt;opt&gt;
+ hexadecimal-constant integer-suffix&lt;opt&gt;
+
+ nonzero-digit
+ decimal-constant digit
+
+ 0=20
+ octal-constant octal-digit
+
+ 0x hexadecimal-digit
+ 0X hexadecimal-digit
+ hexadecimal-constant hexadecimal-digit
+
+ 1 2 3 4 5 6 7 8 9
+
+ 0 1 2 3 4 5 6 7
+
+ 0 1 2 3 4 5 6 7 8 9
+ a b c d e f
+ A B C D E F
+
+ unsigned-suffix long-suffix&lt;opt&gt;
+ long-suffix unsigned-suffix&lt;opt&gt;
+
+ u U
+
+ l L
+
+ identifier
+
+ ' c-char-sequence'=20
+ L' c-char-sequence'=20
+
+ c-char
+ c-char-sequence c-char
+
+ any member of the source character set except
+ the single-quote ', backslash \, or new-line character
+ escape-sequence
+
+ simple-escape-sequence
+ octal-escape-sequence
+ hexadecimal-escape-sequence
+
+ \' \" \? \\
+ \a \b \f \n \r \t \v
+
+ \ octal-digit
+ \ octal-digit octal-digit
+ \ octal-digit octal-digit octal-digit
+
+ \x hexadecimal-digit
+ hexadecimal-escape-sequence hexadecimal-digit
+
+
+ A.1.1.5 String literals
+
+ " s-char-sequence&lt;opt&gt;"
+ L" s-char-sequence&lt;opt&gt;"
+
+ s-char
+ s-char-sequence s-char
+
+ any member of the source character set except
+ the double-quote ", backslash \, or new-line character
+ escape-sequence
+
+
+ A.1.1.6 Operators
+
+ [ ] ( ) . -&gt;
+ ++ -- &amp; * + - ~ ! sizeof
+ / % &lt;&lt; &gt;&gt; &lt; &gt; &lt;=3D &gt;=3D =
+ =3D=3D !=3D ^ | &amp;&amp; ||
+ ? :
+ =3D *=3D /=3D %=3D +=3D -=3D &lt;&lt;=3D &gt;&gt;=
+ =3D &amp;=3D ^=3D |=3D
+ , # ##
+
+
+ A.1.1.7 Punctuators
+
+ [ ] ( ) { } * , : =3D ; ... #
+
+
+ A.1.1.8 Header names
+
+ &lt; h-char-sequence&gt;
+ " q-char-sequence"
+
+ h-char
+ h-char-sequence h-char
+
+ any member of the source character set except
+ the new-line character and &gt;
+
+ q-char
+ q-char-sequence q-char
+
+ any member of the source character set except
+ the new-line character and "
+
+
+ A.1.1.9 Preprocessing numbers
+
+ digit
+ . digit
+ pp-number digit
+ pp-number nondigit
+ pp-number e sign
+ pp-number E sign
+ pp-number .
+
+
+ A.1.2 Phrase structure grammar
+
+ A.1.2.1 Expressions
+
+ identifier
+ constant
+ string-literal
+ ( expression )
+
+ primary-expression
+ postfix-expression [ expression ]=20
+ postfix-expression ( argument-expression-list&lt;opt&gt;=
+ )=20
+ postfix-expression . identifier
+ postfix-expression -&gt; identifier
+ postfix-expression ++=20
+ postfix-expression --
+
+ assignment-expression
+ argument-expression-list , assignment-expression
+
+ postfix-expression
+ ++ unary-expression
+ -- unary-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-name )
+
+ &amp; * + - ~ !
+
+ unary-expression
+ ( type-name ) cast-expression
+
+ cast-expression
+ multiplicative-expression * cast-expression
+ multiplicative-expression / cast-expression
+ multiplicative-expression % cast-expression
+
+ multiplicative-expression
+ additive-expression + multiplicative-expression
+ additive-expression - multiplicative-expression
+
+ additive-expression
+ shift-expression &lt;&lt; additive-expression
+ shift-expression &gt;&gt; additive-expression
+
+ shift-expression
+ relational-expression &lt; shift-expression
+ relational-expression &gt; shift-expression
+ relational-expression &lt;=3D shift-expression
+ relational-expression &gt;=3D shift-expression
+
+ relational-expression
+ equality-expression =3D=3D relational-expression
+ equality-expression !=3D relational-expression
+
+ equality-expression
+ AND-expression &amp; equality-expression
+
+ AND-expression
+ exclusive-OR-expression ^ AND-expression
+
+ exclusive-OR-expression
+ inclusive-OR-expression | exclusive-OR-expression
+
+ inclusive-OR-expression
+ logical-AND-expression &amp;&amp; inclusive-OR-expressio=
+ n
+
+ logical-AND-expression
+ logical-OR-expression || logical-AND-expression
+
+ logical-OR-expression
+ logical-OR-expression ? expression : conditional-expres=
+ sion
+
+ conditional-expression
+ unary-expression assignment-operator assignment-expressio=
+ n
+
+ =3D *=3D /=3D %=3D +=3D -=3D &lt;&lt;=3D &gt;&gt;=
+ =3D &amp;=3D ^=3D |=3D
+
+ assignment-expression
+ expression , assignment-expression
+
+ conditional-expression
+
+
+ A.1.2.2 Declarations
+
+ declaration-specifiers init-declarator-list&lt;opt&gt; ;
+
+ storage-class-specifier declaration-specifiers&lt;opt&gt;
+ type-specifier declaration-specifiers&lt;opt&gt;
+ type-qualifier declaration-specifiers&lt;opt&gt;
+
+ init-declarator
+ init-declarator-list , init-declarator=20
+
+ declarator
+ declarator =3D initializer
+
+ typedef
+ extern
+ static
+ auto
+ register
+
+ void
+ char
+ short
+ int
+ long
+ float
+ double
+ signed
+ unsigned
+ struct-or-union-specifier
+ enum-specifier
+ typedef-name
+
+ struct-or-union identifier&lt;opt&gt; { struct-declarati=
+ on-list }=20
+ struct-or-union identifier
+
+ struct
+ union
+
+ struct-declaration
+ struct-declaration-list struct-declaration
+
+ specifier-qualifier-list struct-declarator-list ;
+
+ type-specifier specifier-qualifier-list&lt;opt&gt;
+ type-qualifier specifier-qualifier-list&lt;opt&gt;
+
+ struct-declarator
+ struct-declarator-list , struct-declarator
+
+ declarator
+ declarator&lt;opt&gt; : constant-expression
+
+ enum identifier&lt;opt&gt; { enumerator-list }
+ enum identifier
+
+ enumerator
+ enumerator-list , enumerator
+
+ enumeration-constant
+ enumeration-constant =3D constant-expression
+
+ const
+ volatile
+
+ pointer&lt;opt&gt; direct-declarator
+
+ identifier
+ ( declarator )=20
+ direct-declarator [ constant-expression&lt;opt&gt; ]=20
+
+ direct-declarator ( parameter-type-list )=20
+ direct-declarator ( identifier-list&lt;opt&gt; )
+
+ * type-qualifier-list&lt;opt&gt;
+ * type-qualifier-list&lt;opt&gt; pointer
+
+ type-qualifier
+ type-qualifier-list type-qualifier
+
+ parameter-list
+ parameter-list , ...
+
+ parameter-declaration
+ parameter-list , parameter-declaration
+
+ declaration-specifiers declarator
+ declaration-specifiers abstract-declarator&lt;opt&gt;
+
+ identifier
+ identifier-list , identifier
+
+ specifier-qualifier-list abstract-declarator&lt;opt&gt;
+
+ pointer
+ pointer&lt;opt&gt; direct-abstract-declarator
+
+ ( abstract-declarator )=20
+ direct-abstract-declarator&lt;opt&gt; [ constant-express=
+ ion&lt;opt&gt; ]=20
+ direct-abstract-declarator&lt;opt&gt; ( parameter-type-l=
+ ist&lt;opt&gt; )
+
+ identifier
+
+ assignment-expression
+ { initializer-list }=20
+ { initializer-list , }
+
+ initializer
+ initializer-list , initializer
+
+
+ A.1.2.3 Statements
+
+ labeled-statement
+ compound-statement
+ expression-statement
+ selection-statement
+ iteration-statement
+ jump-statement
+
+ identifier : statement
+ case constant-expression : statement
+ default : statement
+
+ { declaration-list&lt;opt&gt; statement-list&lt;opt&gt; =
+ }
+
+ declaration
+ declaration-list declaration
+
+ statement
+ statement-list statement
+
+ expression&lt;opt&gt; ;
+
+ if ( expression ) statement
+ if ( expression ) statement else statement
+ switch ( expression ) statement
+
+ while ( expression ) statement
+ do statement while ( expression ) ;
+ for ( expression&lt;opt&gt; ; expression&lt;opt&gt; ;
+ expression&lt;opt&gt; ) statement
+
+ goto identifier ;
+ continue ;
+ break ;
+ return expression&lt;opt&gt; ;
+
+
+ A.1.2.4 External definitions
+
+ external-declaration
+ translation-unit external-declaration
+
+ function-definition
+ declaration
+
+ declaration-specifiers&lt;opt&gt; declarator
+ declaration-list&lt;opt&gt; compound-statement
+
+
+ A.1.3 Preprocessing directives
+
+ group&lt;opt&gt;
+
+ group-part
+ group group-part
+
+ pp-tokens&lt;opt&gt; new-line
+ if-section
+ control-line
+
+ if-group elif-groups&lt;opt&gt; else-group&lt;opt&gt; end=
+ if-line
+
+ # if constant-expression new-line group&lt;opt&gt;
+ # ifdef identifier new-line group&lt;opt&gt;
+ # ifndef identifier new-line group&lt;opt&gt;
+
+ elif-group
+ elif-groups elif-group
+
+ # elif constant-expression new-line group&lt;opt&gt;
+
+ # else new-line group&lt;opt&gt;
+
+ # endif new-line
+
+ control-line:
+
+ the left-parenthesis character without preceding white sp=
+ ace
+
+ pp-tokens&lt;opt&gt;
+
+ preprocessing-token
+ pp-tokens preprocessing-token
+
+ the new-line character
+
+
+ A.2 SEQUENCE POINTS
+
+ The following are the sequence points described in $2.1.2.3. =20
+ =20
+
+ * The call to a function, after the arguments have been evaluated
+ ($3.3.2.2).
+
+ * The end of the first operand of the following operators: logical
+ AND &amp;&amp; ($3.3.13); logical OR || ($3.3.14); conditional ? ($3.3.1=
+ 5);
+ comma , ($3.3.17).
+
+ * The end of a full expression: an initializer ($3.5.7); the
+ expression in an expression statement ($3.6.3); the controlling
+ expression of a selection statement ( if or switch ) ($3.6.4); the
+ controlling expression of a while or do statement ($3.6.5); the three
+ expressions of a for statement ($3.6.5.3); the expression in a return
+ statement ($3.6.6.4).
+
+
+ A.3 LIBRARY SUMMARY
+
+ A.3.1 ERRORS &lt;errno.h&gt;
+
+ EDOM
+ ERANGE
+ errno
+
+
+ A.3.2 COMMON DEFINITIONS &lt;stddef.h&gt;
+
+ NULL
+ offsetof( type, member-designator)
+ ptrdiff_t
+ size_t
+ wchar_t
+
+
+ A.3.3 DIAGNOSTICS &lt;assert.h&gt;
+
+ NDEBUG
+ void assert(int expression);
+
+
+ A.3.4 CHARACTER HANDLING &lt;ctype.h&gt;
+
+ int isalnum(int c);
+ int isalpha(int c);
+ int iscntrl(int c);
+ int isdigit(int c);
+ int isgraph(int c);
+ int islower(int c);
+ int isprint(int c);
+ int ispunct(int c);
+ int isspace(int c);
+ int isupper(int c);
+ int isxdigit(int c);
+ int tolower(int c);
+ int toupper(int c);
+
+
+ A.3.5 LOCALIZATION &lt;locale.h&gt;
+
+ LC_ALL
+ LC_COLLATE
+ LC_CTYPE
+ LC_MONETARY
+ LC_NUMERIC
+ LC_TIME
+ NULL
+ struct lconv
+ char *setlocale(int category, const char *locale);
+ struct lconv *localeconv(void);
+
+
+ A.3.6 MATHEMATICS &lt;math.h&gt;
+
+ HUGE_VAL
+ double acos(double x);
+ double asin(double x);
+ double atan(double x);
+ double atan2(double y, double x);
+ double cos(double x);
+ double sin(double x);
+ double tan(double x);
+ double cosh(double x);
+ double sinh(double x);
+ double tanh(double x);
+ double exp(double x);
+ double frexp(double value, int *exp);
+ double ldexp(double x, int exp);
+ double log(double x);
+ double log10(double x);
+ double modf(double value, double *iptr);
+ double pow(double x, double y);
+ double sqrt(double x);
+ double ceil(double x);
+ double fabs(double x);
+ double floor(double x);
+ double fmod(double x, double y);
+
+
+ A.3.7 NON-LOCAL JUMPS &lt;setjmp.h&gt;
+
+ jmp_buf
+ int setjmp(jmp_buf env);
+ void longjmp(jmp_buf env, int val);
+
+
+ A.3.8 SIGNAL HANDLING &lt;signal.h&gt;
+
+ sig_atomic_t
+ SIG_DFL
+ SIG_ERR
+ SIG_IGN
+ SIGABRT
+ SIGFPE
+ SIGILL
+ SIGINT
+ SIGSEGV
+ SIGTERM
+ void (*signal(int sig, void (*func)(int)))(int);
+ int raise(int sig);
+
+
+ A.3.9 VARIABLE ARGUMENTS &lt;stdarg.h&gt;
+
+ va_list
+ void va_start(va_list ap, parmN);
+ type va_arg(va_list ap, type);
+ void va_end(va_list ap);
+
+
+ A.3.10 INPUT/OUTPUT &lt;stdio.h&gt;
+
+ _IOFBF
+ _IOLBF
+ _IONBF
+ BUFSIZ
+ EOF
+ FILE
+ FILENAME_MAX
+ FOPEN_MAX
+ fpos_t
+ L_tmpnam
+ NULL
+ SEEK_CUR
+ SEEK_END
+ SEEK_SET
+ size_t
+ stderr
+ stdin
+ stdout
+ TMP_MAX
+ int remove(const char *filename);
+ int rename(const char *old, const char *new);
+ FILE *tmpfile(void);
+ char *tmpnam(char *s);
+ int fclose(FILE *stream);
+ int fflush(FILE *stream);
+ FILE *fopen(const char *filename, const char *mode);
+ FILE *freopen(const char *filename, const char *mode,
+ FILE *stream);
+ void setbuf(FILE *stream, char *buf);
+ int setvbuf(FILE *stream, char *buf, int mode, size_t size);
+ int fprintf(FILE *stream, const char *format, ...);
+ int fscanf(FILE *stream, const char *format, ...);
+ int printf(const char *format, ...);
+ int scanf(const char *format, ...);
+ int sprintf(char *s, const char *format, ...);
+ int sscanf(const char *s, const char *format, ...);
+ int vfprintf(FILE *stream, const char *format, va_list arg);
+ int vprintf(const char *format, va_list arg);
+ int vsprintf(char *s, const char *format, va_list arg);
+ int fgetc(FILE *stream);
+ char *fgets(char *s, int n, FILE *stream);
+ int fputc(int c, FILE *stream);
+ int fputs(const char *s, FILE *stream);
+ int getc(FILE *stream);
+ int getchar(void);
+ char *gets(char *s);
+ int putc(int c, FILE *stream);
+ int putchar(int c);
+ int puts(const char *s);
+ int ungetc(int c, FILE *stream);
+ size_t fread(void *ptr, size_t size, size_t nmemb,
+ FILE *stream);
+ size_t fwrite(const void *ptr, size_t size, size_t nmemb,
+ FILE *stream);
+ int fgetpos(FILE *stream, fpos_t *pos);
+ int fseek(FILE *stream, long int offset, int whence);
+ int fsetpos(FILE *stream, const fpos_t *pos);
+ long int ftell(FILE *stream);
+ void rewind(FILE *stream);
+ void clearerr(FILE *stream);
+ int feof(FILE *stream);
+ int ferror(FILE *stream);
+ void perror(const char *s);
+
+
+ A.3.11 GENERAL UTILITIES &lt;stdlib.h&gt;
+
+ EXIT_FAILURE
+ EXIT_SUCCESS
+ MB_CUR_MAX
+ NULL
+ RAND_MAX
+ div_t
+ ldiv_t
+ size_t
+ wchar_t
+ double atof(const char *nptr);
+ int atoi(const char *nptr);
+ long int atol(const char *nptr);
+ double strtod(const char *nptr, char **endptr);
+ long int strtol(const char *nptr, char **endptr, int base);
+ unsigned long int strtoul(const char *nptr, char **endptr,
+ int base);
+ int rand(void);
+ void srand(unsigned int seed);
+ void *calloc(size_t nmemb, size_t size);
+ void free(void *ptr);
+ void *malloc(size_t size);
+ void *realloc(void *ptr, size_t size);
+ void abort(void);
+ int atexit(void (*func)(void));
+ void exit(int status);
+ char *getenv(const char *name);
+ int system(const char *string);
+ void *bsearch(const void *key, const void *base,
+ size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+ void qsort(void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+ int abs(int j);
+ div_t div(int numer, int denom);
+ long int labs(long int j);
+ ldiv_t ldiv(long int numer, long int denom);
+ int mblen(const char *s, size_t n);
+ int mbtowc(wchar_t *pwc, const char *s, size_t n);
+ int wctomb(char *s, wchar_t wchar);
+ size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
+ size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
+
+
+
+ A.3.12 STRING HANDLING &lt;string.h&gt;
+
+ NULL
+ size_t
+ void *memcpy(void *s1, const void *s2, size_t n);
+ void *memmove(void *s1, const void *s2, size_t n);
+ char *strcpy(char *s1, const char *s2);
+ char *strncpy(char *s1, const char *s2, size_t n);
+ char *strcat(char *s1, const char *s2);
+ char *strncat(char *s1, const char *s2, size_t n);
+ int memcmp(const void *s1, const void *s2, size_t n);
+ int strcmp(const char *s1, const char *s2);
+ int strcoll(const char *s1, const char *s2);
+ int strncmp(const char *s1, const char *s2, size_t n);
+ size_t strxfrm(char *s1, const char *s2, size_t n);
+ void *memchr(const void *s, int c, size_t n);
+ char *strchr(const char *s, int c);
+ size_t strcspn(const char *s1, const char *s2);
+ char *strpbrk(const char *s1, const char *s2);
+ char *strrchr(const char *s, int c);
+ size_t strspn(const char *s1, const char *s2);
+ char *strstr(const char *s1, const char *s2);
+ char *strtok(char *s1, const char *s2);
+ void *memset(void *s, int c, size_t n);
+ char *strerror(int errnum);
+ size_t strlen(const char *s);
+
+
+ A.3.13 DATE AND TIME &lt;time.h&gt;
+
+ CLK_TCK
+ NULL
+ clock_t
+ time_t
+ size_t
+ struct tm
+ clock_t clock(void);
+ double difftime(time_t time1, time_t time0);
+ time_t mktime(struct tm *timeptr);
+ time_t time(time_t *timer);
+ char *asctime(const struct tm *timeptr);
+ char *ctime(const time_t *timer);
+ struct tm *gmtime(const time_t *timer);
+ struct tm *localtime(const time_t *timer);
+ size_t strftime(char *s, size_t maxsize,
+ const char *format, const struct tm *timeptr);
+
+
+ A.4 IMPLEMENTATION LIMITS
+
+ The contents of a header &lt;limits.h&gt; are given below, in alphabetic
+ order. The minimum magnitudes shown shall be replaced by
+ implementation-defined magnitudes with the same sign. The values
+ shall all be constant expressions suitable for use in #if
+ preprocessing directives. The components are described further in
+ $2.2.4.2.
+
+ #define CHAR_BIT 8
+ #define CHAR_MAX UCHAR_MAX or SCHAR_MAX
+ #define CHAR_MIN 0 or SCHAR_MIN
+ #define MB_LEN_MAX 1
+ #define INT_MAX +32767
+ #define INT_MIN -32767
+ #define LONG_MAX +2147483647
+ #define LONG_MIN -2147483647
+ #define SCHAR_MAX +127
+ #define SCHAR_MIN -127
+ #define SHRT_MAX +32767
+ #define SHRT_MIN -32767
+ #define UCHAR_MAX 255
+ #define UINT_MAX 65535
+ #define ULONG_MAX 4294967295
+ #define USHRT_MAX 65535
+
+
+ The contents of a header &lt;float.h&gt; are given below, in alphabetic
+ order. The value of FLT_RADIX shall be a constant expression suitable
+ for use in #if preprocessing directives. Values that need not be
+ constant expressions shall be supplied for all other components. The
+ minimum magnitudes shown for integers and exponents shall be replaced
+ by implementation-defined magnitudes with the same sign. The
+ components are described further in $2.2.4.2.
+
+ #define DBL_DIG 10
+ #define DBL_EPSILON 1E-9
+ #define DBL_MANT_DIG
+ #define DBL_MAX 1E+37
+ #define DBL_MAX_10_EXP +37
+ #define DBL_MAX_EXP
+ #define DBL_MIN 1E-37
+ #define DBL_MIN_10_EXP -37
+ #define DBL_MIN_EXP
+ #define FLT_DIG 6
+ #define FLT_EPSILON 1E-5
+ #define FLT_MANT_DIG
+ #define FLT_MAX 1E+37
+ #define FLT_MAX_10_EXP +37
+ #define FLT_MAX_EXP
+ #define FLT_MIN 1E-37
+ #define FLT_MIN_10_EXP -37
+ #define FLT_MIN_EXP
+ #define FLT_RADIX 2
+ #define FLT_ROUNDS
+ #define LDBL_DIG 10
+ #define LDBL_EPSILON 1E-9
+ #define LDBL_MANT_DIG
+ #define LDBL_MAX 1E+37
+ #define LDBL_MAX_10_EXP +37
+ #define LDBL_MAX_EXP
+ #define LDBL_MIN 1E-37
+ #define LDBL_MIN_10_EXP -37
+ #define LDBL_MIN_EXP
+
+
+ A.5 COMMON WARNINGS
+
+ An implementation may generate warnings in many situations, none of
+ which is specified as part of the Standard. The following are a few
+ of the more common situations.
+
+ * A block with initialization of an object that has automatic storage
+ duration is jumped into ($3.1.2.4).
+
+ * An integer character constant includes more than one character or a
+ wide character constant includes more than one multibyte character
+ ($3.1.3.4).
+
+ * The characters /* are found in a comment ($3.1.7). =20
+
+ * An implicit narrowing conversion is encountered, such as the
+ assignment of a long int or a double to an int , or a pointer to void
+ to a pointer to any type of object other than char ($3.2).
+
+ * An ``unordered'' binary operator (not comma, &amp;&amp; or || ) contains=
+ a
+ side-effect to an lvalue in one operand, and a side-effect to, or an
+ access to the value of, the identical lvalue in the other operand
+ ($3.3).
+
+ * A function is called but no prototype has been supplied ($3.3.2.2). =20
+
+ * The arguments in a function call do not agree in number and type
+ with those of the parameters in a function definition that is not a
+ prototype ($3.3.2.2).
+
+ * An object is defined but not used ($3.5). =20
+
+ * A value is given to an object of an enumeration type other than by
+ assignment of an enumeration constant that is a member of that type,
+ or an enumeration variable that has the same type, or the value of a
+ function that returns the same enumeration type ($3.5.2.2).
+
+ * An aggregate has a partly bracketed initialization ($3.5.7). =20
+
+ * A statement cannot be reached ($3.6). =20
+
+ * A statement with no apparent effect is encountered ($3.6). =20
+
+ * A constant expression is used as the controlling expression of a=20
+ selection statement ($3.6.4).
+
+ * A function has return statements with and without expressions ($3.6.6.4)=
+ . =20
+
+ * An incorrectly formed preprocessing group is encountered while
+ skipping a preprocessing group ($3.8.1).
+
+ * An unrecognized #pragma directive is encountered ($3.8.6). =20
+
+
+ A.6 PORTABILITY ISSUES
+
+ This appendix collects some information about portability that
+ appears in the Standard.
+
+
+ A.6.1 Unspecified behavior
+
+ The following are unspecified:=20
+
+ * The manner and timing of static initialization ($2.1.2). =20
+
+ * The behavior if a printable character is written when the active
+ position is at the final position of a line ($2.2.2).
+
+ * The behavior if a backspace character is written when the active
+ position is at the initial position of a line ($2.2.2).
+
+ * The behavior if a horizontal tab character is written when the
+ active position is at or past the last defined horizontal tabulation
+ position ($2.2.2).
+
+ * The behavior if a vertical tab character is written when the active
+ position is at or past the last defined vertical tabulation position
+ ($2.2.2).
+
+ * The representations of floating types ($3.1.2.5). =20
+
+ * The order in which expressions are evaluated --- in any order
+ conforming to the precedence rules, even in the presence of
+ parentheses ($3.3).
+
+ * The order in which side effects take place ($3.3). =20
+
+ * The order in which the function designator and the arguments in a
+ function call are evaluated ($3.3.2.2).
+
+ * The alignment of the addressable storage unit allocated to hold a
+ bit-field ($3.5.2.1).
+
+ * The layout of storage for parameters ($3.7.1). =20
+
+ * The order in which # and ## operations are evaluated during macro
+ substitution ($3.8.3.3).
+
+ * Whether errno is a macro or an external identifier ($4.1.3). =20
+
+ * Whether setjmp is a macro or an external identifier ($4.6.1.1). =20
+
+ * Whether va_end is a macro or an external identifier ($4.8.1.3). =20
+
+ * The value of the file position indicator after a successful call to
+ the ungetc function for a text stream, until all pushed-back
+ characters are read or discarded ($4.9.7.11).
+
+ * The details of the value stored by the fgetpos function on success
+ ($4.9.9.1).
+
+ * The details of the value returned by the ftell function for a text
+ stream on success ($4.9.9.4).
+
+ * The order and contiguity of storage allocated by the calloc ,
+ malloc , and realloc functions ($4.10.3).
+
+ * Which of two members that compare as equal is returned by the
+ bsearch function ($4.10.5.1).
+
+ * The order in an array sorted by the qsort function of two members
+ that compare as equal ($4.10.5.2).
+
+ * The encoding of the calendar time returned by the time function
+ ($4.12.2.3).
+
+
+ A.6.2 Undefined behavior
+
+ The behavior in the following circumstances is undefined:=20
+
+ * A nonempty source file does not end in a new-line character, ends
+ in new-line character immediately preceded by a backslash character,
+ or ends in a partial preprocessing token or comment ($2.1.1.2).
+
+ * A character not in the required character set is encountered in a
+ source file, except in a preprocessing token that is never converted
+ to a token, a character constant, a string literal, or a comment
+ ($2.2.1).
+
+ * A comment, string literal, character constant, or header name
+ contains an invalid multibyte character or does not begin and end in
+ the initial shift state ($2.2.1.2).
+
+ * An unmatched ' or character is encountered on a logical source line
+ during tokenization ($3.1).
+
+ * The same identifier is used more than once as a label in the same
+ function ($3.1.2.1).
+
+ * An identifier is used that is not visible in the current scope ($3.1.2.1=
+ ). =20
+
+ * Identifiers that are intended to denote the same entity differ in a
+ character beyond the minimal significant characters ($3.1.2).
+
+ * The same identifier has both internal and external linkage in the
+ same translation unit ($3.1.2.2).
+
+ * An identifier with external linkage is used but there does not
+ exist exactly one external definition in the program for the
+ identifier ($3.1.2.2).
+
+ * The value stored in a pointer that referred to an object with
+ automatic storage duration is used ($3.1.2.4).
+
+ * Two declarations of the same object or function specify types that
+ are not compatible ($3.1.2.6).
+
+ * An unspecified escape sequence is encountered in a character
+ constant or a string literal ($3.1.3.4).
+
+ * An attempt is made to modify a string literal of either form ($3.1.4). =
+ =20
+
+ * A character string literal token is adjacent to a wide string
+ literal token ($3.1.4).
+
+ * The characters ', \ , , or /* are encountered between the &lt; and &gt;
+ delimiters or the characters ', \ , or /* are encountered between the
+ delimiters in the two forms of a header name preprocessing token
+ ($3.1.7).
+
+ * An arithmetic conversion produces a result that cannot be
+ represented in the space provided ($3.2.1).
+
+ * An lvalue with an incomplete type is used in a context that
+ requires the value of the designated object ($3.2.2.1).
+
+ * The value of a void expression is used or an implicit conversion
+ (except to void ) is applied to a void expression ($3.2.2.2).
+
+ * An object is modified more than once, or is modified and accessed
+ other than to determine the new value, between two sequence points
+ ($3.3).
+
+ * An arithmetic operation is invalid (such as division or modulus by 0)
+ or produces a result that cannot be represented in the space
+ provided (such as overflow or underflow) ($3.3).
+
+ * An object has its stored value accessed by an lvalue that does not
+ have one of the following types: the declared type of the object, a=20
+ qualified version of the declared type of the object, the signed or
+ unsigned type corresponding to the declared type of the object, the
+ signed or unsigned type corresponding to a qualified version of the
+ declared type of the object, an aggregate or union type that
+ (recursively) includes one of the aforementioned types among its
+ members, or a character type ($3.3).
+
+ * An argument to a function is a void expression ($3.3.2.2). =20
+
+ * For a function call without a function prototype, the number of
+ arguments does not agree with the number of parameters ($3.3.2.2).
+
+ * For a function call without a function prototype, if the function
+ is defined without a function prototype, and the types of the
+ arguments after promotion do not agree with those of the parameters
+ after promotion ($3.3.2.2).
+
+ * If a function is called with a function prototype and the function
+ is not defined with a compatible type ($3.3.2.2).
+
+ * A function that accepts a variable number of arguments is called
+ without a function prototype that ends with an ellipsis ($3.3.2.2).
+
+ * An invalid array reference, null pointer reference, or reference to
+ an object declared with automatic storage duration in a terminated
+ block occurs ($3.3.3.2).
+
+ * A pointer to a function is converted to point to a function of a
+ different type and used to call a function of a type not compatible
+ with the original type ($3.3.4).
+
+ * A pointer to a function is converted to a pointer to an object or a
+ pointer to an object is converted to a pointer to a function ($3.3.4).
+
+ * A pointer is converted to other than an integral or pointer type ($3.3.4=
+ ). =20
+
+ * A pointer that is not to a member of an array object is added to or
+ subtracted from ($3.3.6).
+
+ * Pointers that are not to the same array object are subtracted ($3.3.6). =
+ =20
+
+ * An expression is shifted by a negative number or by an amount
+ greater than or equal to the width in bits of the expression being
+ shifted ($3.3.7).
+
+ * Pointers are compared using a relational operator that do not point
+ to the same aggregate or union ($3.3.8).
+
+ * An object is assigned to an overlapping object ($3.3.16.1). =20
+
+ * An identifier for an object is declared with no linkage and the
+ type of the object is incomplete after its declarator, or after its
+ init-declarator if it has an initializer ($3.5).
+
+ * A function is declared at block scope with a storage-class
+ specifier other than extern ($3.5.1).
+
+ * A bit-field is declared with a type other than int , signed int ,
+ or unsigned int ($3.5.2.1).
+
+ * An attempt is made to modify an object with const-qualified type by
+ means of an lvalue with non-const-qualified type ($3.5.3).
+
+ * An attempt is made to refer to an object with volatile-qualified
+ type by means of an lvalue with non-volatile-qualified type ($3.5.3).
+
+ * The value of an uninitialized object that has automatic storage
+ duration is used before a value is assigned ($3.5.7).
+
+ * An object with aggregate or union type with static storage duration
+ has a non-brace-enclosed initializer, or an object with aggregate or
+ union type with automatic storage duration has either a single
+ expression initializer with a type other than that of the object or a
+ non-brace-enclosed initializer ($3.5.7).
+
+ * The value of a function is used, but no value was returned ($3.6.6.4). =
+ =20
+
+ * A function that accepts a variable number of arguments is defined
+ without a parameter type list that ends with the ellipsis notation
+ ($3.7.1).
+
+ * An identifier for an object with internal linkage and an incomplete
+ type is declared with a tentative definition ($3.7.2).
+
+ * The token defined is generated during the expansion of a #if or
+ #elif preprocessing directive ($3.8.1).
+
+ * The #include preprocessing directive that results after expansion
+ does not match one of the two header name forms ($3.8.2).
+
+ * A macro argument consists of no preprocessing tokens ($3.8.3). =20
+
+ * There are sequences of preprocessing tokens within the list of
+ macro arguments that would otherwise act as preprocessing directive
+ lines ($3.8.3).
+
+ * The result of the preprocessing concatenation operator ## is not a
+ valid preprocessing token ($3.8.3).
+
+ * The #line preprocessing directive that results after expansion does
+ not match one of the two well-defined forms ($3.8.4).
+
+ * One of the following identifiers is the subject of a #define or
+ #undef preprocessing directive: defined , __LINE__ , __FILE__ ,
+ __DATE__ , __TIME__ , or __STDC__ ($3.8.8).
+
+ * An attempt is made to copy an object to an overlapping object by
+ use of a library function other than memmove ($4.).
+
+ * The effect if the program redefines a reserved external identifier
+ ($4.1.2).
+
+ * The effect if a standard header is included within an external
+ definition; is included for the first time after the first reference
+ to any of the functions or objects it declares, or to any of the types
+ or macros it defines; or is included while a macro is defined with a
+ name the same as a keyword ($4.1.2).
+
+ * A macro definition of errno is suppressed to obtain access to an
+ actual object ($4.1.3).
+
+ * The parameter member-designator of an offsetof macro is an invalid
+ right operand of the . operator for the type parameter or designates
+ bit-field member of a structure ($4.1.5).
+
+ * A library function argument has an invalid value, unless the
+ behavior is specified explicitly ($4.1.6).
+
+ * A library function that accepts a variable number of arguments is
+ not declared ($4.1.6).
+
+ * The macro definition of assert is suppressed to obtain access to an
+ actual function ($4.2).
+
+ * The argument to a character handling function is out of the domain ($4.3=
+ ). =20
+
+ * A macro definition of setjmp is suppressed to obtain access to an
+ actual function ($4.6).
+
+ * An invocation of the setjmp macro occurs in a context other than as
+ the controlling expression in a selection or iteration statement, or
+ in a comparison with an integral constant expression (possibly as
+ implied by the unary ! operator) as the controlling expression of a
+ selection or iteration statement, or as an expression statement
+ (possibly cast to void ) ($4.6.1.1).
+
+ * An object of automatic storage class that does not have
+ volatile-qualified type has been changed between a setjmp invocation
+ and a longjmp call and then has its value accessed ($4.6.2.1).
+
+ * The longjmp function is invoked from a nested signal routine ($4.6.2.1).=
+ =20
+
+ * A signal occurs other than as the result of calling the abort or
+ raise function, and the signal handler calls any function in the
+ standard library other than the signal function itself or refers to
+ any object with static storage duration other than by assigning a=20
+ value to a static storage duration variable of type volatile
+ sig_atomic_t ($4.7.1.1).
+
+ * The value of errno is referred to after a signal occurs other than
+ as the result of calling the abort or raise function and the
+ corresponding signal handler calls the signal function such that it
+ returns the value SIG_ERR ($4.7.1.1).
+
+ * The macro va_arg is invoked with the parameter ap that was passed
+ to a function that invoked the macro va_arg with the same parameter
+ ($4.8).
+
+ * A macro definition of va_start , va_arg , or va_end or a
+ combination thereof is suppressed to obtain access to an actual
+ function ($4.8.1).
+
+ * The parameter parmN of a va_start macro is declared with the
+ register storage class, or with a function or array type, or with a
+ type that is not compatible with the type that results after
+ application of the default argument promotions ($4.8.1.1).
+
+ * There is no actual next argument for a va_arg macro invocation
+ ($4.8.1.2).
+
+ * The type of the actual next argument in a variable argument list
+ disagrees with the type specified by the va_arg macro ($4.8.1.2).
+
+ * The va_end macro is invoked without a corresponding invocation of
+ the va_start macro ($4.8.1.3).
+
+ * A return occurs from a function with a variable argument list
+ initialized by the va_start macro before the va_end macro is invoked
+ ($4.8.1.3).
+
+ * The stream for the fflush function points to an input stream or to
+ an update stream in which the most recent operation was input
+ ($4.9.5.2).
+
+ * An output operation on an update stream is followed by an input
+ operation without an intervening call to the fflush function or a file
+ positioning function, or an input operation on an update stream is
+ followed by an output operation without an intervening call to a file
+ positioning function ($4.9.5.3).
+
+ * The format for the fprintf or fscanf function does not match the
+ argument list ($4.9.6).
+
+ * An invalid conversion specification is found in the format for the
+ fprintf or fscanf function ($4.9.6).
+
+ * A %% conversion specification for the fprintf or fscanf function
+ contains characters between the pair of % characters ($4.9.6).
+
+ * A conversion specification for the fprintf function contains an h
+ or l with a conversion specifier other than d , i , n , o , u , x , or
+ X , or an L with a conversion specifier other than e , E , f , g , or
+ G ($4.9.6.1).
+
+ * A conversion specification for the fprintf function contains a #
+ flag with a conversion specifier other than o , x , X , e , E , f , g,
+ or G ($4.9.6.1).
+
+ * A conversion specification for the fprintf function contains a 0
+ flag with a conversion specifier other than d , i , o , u , x , X , e,
+ E , f , g , or G ($4.9.6.1).
+
+ * An aggregate or union, or a pointer to an aggregate or union is an
+ argument to the fprintf function, except for the conversion specifiers
+ %s (for an array of character type) or %p (for a pointer to void )
+ ($4.9.6.1).
+
+ * A single conversion by the fprintf function produces more than 509
+ characters of output ($4.9.6.1).
+
+ * A conversion specification for the fscanf function contains an h or
+ l with a conversion specifier other than d , i , n , o , u , or x , or
+ an L with a conversion specifier other than e , f , or g ($4.9.6.2).
+
+ * A pointer value printed by %p conversion by the fprintf function
+ during a previous program execution is the argument for %p conversion
+ by the fscanf function ($4.9.6.2).
+
+ * The result of a conversion by the fscanf function cannot be
+ represented in the space provided, or the receiving object does not
+ have an appropriate type ($4.9.6.2).
+
+ * The result of converting a string to a number by the atof , atoi ,
+ or atol function cannot be represented ($4.10.1).
+
+ * The value of a pointer that refers to space deallocated by a call
+ to the free or realloc function is referred to ($4.10.3).
+
+ * The pointer argument to the free or realloc function does not match
+ a pointer earlier returned by calloc , malloc , or realloc , or the
+ object pointed to has been deallocated by a call to free or realloc
+ ($4.10.3).
+
+ * A program executes more than one call to the exit function ($4.10.4.3). =
+ =20
+
+ * The result of an integer arithmetic function ( abs , div , labs ,
+ or ldiv ) cannot be represented ($4.10.6).
+
+ * The shift states for the mblen , mbtowc , and wctomb functions are
+ not explicitly reset to the initial state when the LC_CTYPE category
+ of the current locale is changed ($4.10.7).
+
+ * An array written to by a copying or concatenation function is too
+ small ($4.11.2, $4.11.3).
+
+ * An invalid conversion specification is found in the format for the
+ strftime function ($4.12.3.5).
+
+
+ A.6.3 Implementation-defined behavior
+
+ Each implementation shall document its behavior in each of the
+ areas listed in this section. The following are
+ implementation-defined:
+
+
+ A.6.3.1 Environment
+
+ * The semantics of the arguments to main ($2.1.2.2). =20
+
+ * What constitutes an interactive device ($2.1.2.3). =20
+
+
+ A.6.3.2 Identifiers
+
+ * The number of significant initial characters (beyond 31) in an
+ identifier without external linkage ($3.1.2).
+
+ * The number of significant initial characters (beyond 6) in an
+ identifier with external linkage ($3.1.2).
+
+ * Whether case distinctions are significant in an identifier with
+ external linkage ($3.1.2).
+
+
+ A.6.3.3 Characters
+
+ * The members of the source and execution character sets, except as
+ explicitly specified in the Standard ($2.2.1).
+
+ * The shift states used for the encoding of multibyte characters $2.2.1.2)=
+ . =20
+
+ * The number of bits in a character in the execution character set
+ ($2.2.4.2).
+
+ * The mapping of members of the source character set (in character
+ constants and string literals) to members of the execution character
+ set ($3.1.3.4).
+
+ * The value of an integer character constant that contains a
+ character or escape sequence not represented in the basic execution
+ character set or the extended character set for a wide character
+ constant ($3.1.3.4).
+
+ * The value of an integer character constant that contains more than
+ one character or a wide character constant that contains more than one=
+ =20
+ multibyte character ($3.1.3.4).
+
+ * The current locale used to convert multibyte characters into
+ corresponding wide characters (codes) for a wide character constant
+ ($3.1.3.4).
+
+ * Whether a ``plain'' char has the same range of values as signed
+ char or unsigned char ($3.2.1.1).
+
+
+ A.6.3.4 Integers
+
+ * The representations and sets of values of the various types of
+ integers ($3.1.2.5).
+
+ * The result of converting an integer to a shorter signed integer, or
+ the result of converting an unsigned integer to a signed integer of
+ equal length, if the value cannot be represented ($3.2.1.2).
+
+ * The results of bitwise operations on signed integers ($3.3).
+
+ * The sign of the remainder on integer division ($3.3.5). =20
+
+ * The result of a right shift of a negative-valued signed integral
+ type ($3.3.7).
+
+
+ A.6.3.5 Floating point
+
+ * The representations and sets of values of the various types of
+ floating-point numbers ($3.1.2.5).
+
+ * The direction of truncation when an integral number is converted to
+ a floating-point number that cannot exactly represent the original
+ value ($3.2.1.3).
+
+ * The direction of truncation or rounding when a floating-point
+ number is converted to a narrower floating-point number ($3.2.1.4).
+
+
+ A.6.3.6 Arrays and pointers
+
+ * The type of integer required to hold the maximum size of an array
+ --- that is, the type of the sizeof operator, size_t ($3.3.3.4,
+ $4.1.1).
+
+ * The result of casting a pointer to an integer or vice versa ($3.3.4). =
+ =20
+
+ * The type of integer required to hold the difference between two
+ pointers to members of the same array, ptrdiff_t ($3.3.6, $4.1.1).
+
+
+ A.6.3.7 Registers
+
+ * The extent to which objects can actually be placed in registers by
+ use of the register storage-class specifier ($3.5.1).
+
+
+ A.6.3.8 Structures, unions, enumerations, and bit-fields
+
+ * A member of a union object is accessed using a member of a
+ different type ($3.3.2.3).
+
+ * The padding and alignment of members of structures ($3.5.2.1).
+ This should present no problem unless binary data written by one
+ implementation are read by another.
+
+ * Whether a ``plain'' int bit-field is treated as a signed int
+ bit-field or as an unsigned int bit-field ($3.5.2.1).
+
+ * The order of allocation of bit-fields within an int ($3.5.2.1).
+
+ * Whether a bit-field can straddle a storage-unit boundary ($3.5.2.1). =20
+
+ * The integer type chosen to represent the values of an enumeration
+ type ($3.5.2.2).
+
+
+ A.6.3.9 Qualifiers
+
+ * What constitutes an access to an object that has volatile-qualified
+ type ($3.5.5.3).
+
+
+ A.6.3.10 Declarators
+
+ * The maximum number of declarators that may modify an arithmetic,
+ structure, or union type ($3.5.4).
+
+
+ A.6.3.11 Statements
+
+ * The maximum number of case values in a switch statement ($3.6.4.2). =20
+
+
+ A.6.3.12 Preprocessing directives
+
+ * Whether the value of a single-character character constant in a
+ constant expression that controls conditional inclusion matches the
+ value of the same character constant in the execution character set.
+ Whether such a character constant may have a negative value ($3.8.1).
+
+ * The method for locating includable source files ($3.8.2). =20
+
+ * The support of quoted names for includable source files ($3.8.2). =20
+
+ * The mapping of source file character sequences ($3.8.2). =20
+
+ * The behavior on each recognized #pragma directive ($3.8.6). =20
+
+ * The definitions for __DATE__ and __TIME__ when respectively, the
+ date and time of translation are not available ($3.8.8).
+
+
+ A.6.3.13 Library functions
+
+ * The null pointer constant to which the macro NULL expands ($4.1.5). =20
+
+ * The diagnostic printed by and the termination behavior of the
+ assert function ($4.2).
+
+ * The sets of characters tested for by the isalnum , isalpha ,
+ iscntrl , islower , isprint , and isupper functions ($4.3.1).
+
+ * The values returned by the mathematics functions on domain errors
+ ($4.5.1).
+
+ * Whether the mathematics functions set the integer expression errno
+ to the value of the macro ERANGE on underflow range errors ($4.5.1).
+
+ * Whether a domain error occurs or zero is returned when the fmod
+ function has a second argument of zero ($4.5.6.4).
+
+ * The set of signals for the signal function ($4.7.1.1). =20
+
+ * The semantics for each signal recognized by the signal function
+ ($4.7.1.1).
+
+ * The default handling and the handling at program startup for each
+ signal recognized by the signal function ($4.7.1.1).
+
+ * If the equivalent of signal(sig, SIG_DFL); is not executed prior to
+ the call of a signal handler, the blocking of the signal that is
+ performed ($4.7.1.1).
+
+ * Whether the default handling is reset if the SIGILL signal is
+ received by a handler specified to the signal function ($4.7.1.1).
+
+ * Whether the last line of a text stream requires a terminating
+ new-line character ($4.9.2).
+
+ * Whether space characters that are written out to a text stream
+ immediately before a new-line character appear when read in ($4.9.2).
+
+ * The number of null characters that may be appended to data written
+ to a binary stream ($4.9.2).
+
+ * Whether the file position indicator of an append mode stream is
+ initially positioned at the beginning or end of the file ($4.9.3).
+
+ * Whether a write on a text stream causes the associated file to be
+ truncated beyond that point ($4.9.3).
+
+ * The characteristics of file buffering ($4.9.3). =20
+
+ * Whether a zero-length file actually exists ($4.9.3). =20
+
+ * The rules for composing valid file names ($4.9.3). =20
+
+ * Whether the same file can be open multiple times ($4.9.3). =20
+
+ * The effect of the remove function on an open file ($4.9.4.1). =20
+
+ * The effect if a file with the new name exists prior to a call to
+ the rename function ($4.9.4.2).
+
+ * The output for %p conversion in the fprintf function ($4.9.6.1). =20
+
+ * The input for %p conversion in the fscanf function ($4.9.6.2). =20
+
+ * The interpretation of a - character that is neither the first nor
+ the last character in the scanlist for %[ conversion in the fscanf
+ function ($4.9.6.2).
+
+ * The value to which the macro errno is set by the fgetpos or ftell
+ function on failure ($4.9.9.1, $4.9.9.4).
+
+ * The messages generated by the perror function ($4.9.10.4). =20
+
+ * The behavior of the calloc , malloc , or realloc function if the
+ size requested is zero ($4.10.3).
+
+ * The behavior of the abort function with regard to open and
+ temporary files ($4.10.4.1).
+
+ * The status returned by the exit function if the value of the
+ argument is other than zero, EXIT_SUCCESS , or EXIT_FAILURE
+ ($4.10.4.3).
+
+ * The set of environment names and the method for altering the
+ environment list used by the getenv function ($4.10.4.4).
+
+ * The contents and mode of execution of the string by the system
+ function ($4.10.4.5).
+
+ * The contents of the error message strings returned by the strerror
+ function ($4.11.6.2).
+
+ * The local time zone and Daylight Saving Time ($4.12.1). =20
+
+ * The era for the clock function ($4.12.2.1). =20
+
+
+ A.6.4 Locale-specific Behavior
+
+ The following characteristics of a hosted environment are locale-specifi=
+ c:=20
+
+ * The content of the execution character set, in addition to the
+ required members ($2.2.1).
+
+ * The direction of printing ($2.2.2). =20
+
+ * The decimal-point character ($4.1.1). =20
+
+ * The implementation-defined aspects of character testing and case
+ mapping functions ($4.3).
+
+ * The collation sequence of the execution character set ($4.11.4.4). =20
+
+ * The formats for time and date ($4.12.3.5). =20
+
+
+ A.6.5 Common extensions
+
+ The following extensions are widely used in many systems, but are
+ not portable to all implementations. The inclusion of any extension
+ that may cause a strictly conforming program to become invalid renders
+ an implementation nonconforming. Examples of such extensions are new
+ keywords, or library functions declared in standard headers or
+ predefined macros with names that do not begin with an underscore.
+
+
+ A.6.5.1 Environment arguments
+
+ In a hosted environment, the main function receives a third
+ argument, char *envp[] , that points to a null-terminated array of
+ pointers to char , each of which points to a string that provides
+ information about the environment for this execution of the process
+ ($2.1.2.2).
+
+
+ A.6.5.2 Specialized identifiers
+
+ Characters other than the underscore _ , letters, and digits, that
+ are not defined in the required source character set (such as the
+ dollar sign $ , or characters in national character sets) may appear
+ in an identifier ($3.1.2).
+
+
+ A.6.5.3 Lengths and cases of identifiers
+
+ All characters in identifiers (with or without external linkage)
+ are significant and case distinctions are observed ($3.1.2).
+
+
+ A.6.5.4 Scopes of identifiers
+
+ A function identifier, or the identifier of an object the
+ declaration of which contains the keyword extern , has file scope
+ ($3.1.2.1).
+
+
+ A.6.5.5 Writable string literals
+
+ String literals are modifiable. Identical string literals shall be
+ distinct ($3.1.4).
+
+
+ A.6.5.6 Other arithmetic types
+
+ Other arithmetic types, such as long long int , and their
+ appropriate conversions are defined ($3.2.2.1).
+
+
+ A.6.5.7 Function pointer casts
+
+ A pointer to an object or to void may be cast to a pointer to a
+ function, allowing data to be invoked as a function ($3.3.4). A
+ pointer to a function may be cast to a pointer to an object or to void
+ , allowing a function to be inspected or modified (for example, by a
+ debugger) ($3.3.4).
+
+
+ A.6.5.8 Non-int bit-field types
+
+ Types other than int , unsigned int , or signed int can be declared
+ as bit-fields, with appropriate maximum widths ($3.5.2.1).
+
+
+ A.6.5.9 The fortran keyword
+
+ The fortran type specifier may be used in a function declaration to
+ indicate that function linkage suitable for FORTRAN is to be
+ generated, or that different representations for external names are to
+ be generated ($3.5.4.3).
+
+
+ A.6.5.10 The asm keyword
+
+ The asm keyword may be used to insert assembly-language code
+ directly into the translator output. The most common implementation
+ is via a statement of the form
+
+ asm ( character-string-literal );
+
+ ($3.6). =20
+
+
+ A.6.5.11 Multiple external definitions
+
+ There may be more than one external definition for the identifier
+ of an object, with or without the explicit use of the keyword extern ,
+ If the definitions disagree, or more than one is initialized, the
+ behavior is undefined ($3.7.2).
+
+
+ A.6.5.12 Empty macro arguments
+
+ A macro argument may consist of no preprocessing tokens ($3.8.3). =20
+
+
+ A.6.5.13 Predefined macro names
+
+ Macro names that do not begin with an underscore, describing the
+ translation and execution environments, may be defined by the
+ implementation before translation begins ($3.8.8).
+
+
+ A.6.5.14 Extra arguments for signal handlers
+
+ Handlers for specific signals may be called with extra arguments in
+ addition to the signal number ($4.7.1.1).
+
+
+ A.6.5.15 Additional stream types and file-opening modes
+
+ Additional mappings from files to streams may be supported
+ ($4.9.2), and additional file-opening modes may be specified by
+ characters appended to the mode argument of the fopen function
+ ($4.9.5.3).
+
+
+ A.6.5.16 Defined file position indicator
+
+ The file position indicator is decremented by each successful call
+ to the ungetc function for a text stream, except if its value was zero
+ before a call ($4.9.7.11).
+
+ A.7 INDEX
+
+ Only major references are listed.
+
+ absolute-value functions, 4.5.6.2, 4.10.6.1
+ abstract declarator, type name, 3.5.5
+ abstract machine, 2.1.2.3
+ abstract semantics, 2.1.2.3
+ active position, 2.2.2
+ addition assignment operator, +=3D, 3.3.16.2
+ addition operator, +, 3.3.6
+ additive expressions, 3.3.6
+ address operator, &amp;, 3.3.3.2
+ aggregate type, 3.1.2.5
+ alert escape sequence, \a, 2.2.2, 3.1.3.4
+ alignment, definition of, 1.6
+ alignment of structure members, 3.5.2.1
+ AND operator, bitwise, &amp;, 3.3.10
+ AND operator, logical, &amp;&amp;, 3.3.13
+ argument, function, 3.3.2.2
+ argument, 1.6
+ argument promotion, default, 3.3.2.2
+ arithmetic conversions, usual, 3.2.1.5
+ arithmetic operators, unary, 3.3.3.3
+ arithmetic type, 3.1.2.5
+ array declarator, 3.5.4.2
+ array parameter, 3.7.1
+ array subscript operator, [ ], 3.3.2.1
+ array type, 3.1.2.5
+ array type conversion, 3.2.2.1
+ arrow operator, -&gt;, 3.3.2.3
+ ASCII character set, 2.2.1.1
+ assignment operators, 3.3.16
+ asterisk punctuator, *, 3.1.6, 3.5.4.1
+ automatic storage, reentrancy, 2.1.2.3, 2.2.3
+ automatic storage duration, 3.1.2.4
+
+ backslash character, \, 2.1.1.2, 2.2.1
+ backspace escape sequence, \b, 2.2.2, 3.1.3.4
+ base documents, 1.5
+ basic character set, 1.6, 2.2.1
+ basic type, 3.1.2.5
+ binary stream, 4.9.2
+ bit, definition of, 1.6
+ bit, high-order, 1.6
+ bit, low-order, 1.6
+ bit-field structure member, 3.5.2.1
+ bitwise operators, 3.3, 3.3.7, 3.3.10, 3.3.11, 3.3.12
+ block, 3.6.2
+ block identifier scope, 3.1.2.1
+ braces punctuator, { }, 3.1.6, 3.5.7, 3.6.2
+ brackets punctuator, [ ], 3.1.6, 3.3.2.1, 3.5.4.2
+ broken-down-time type, 4.12.1
+ byte, definition of, 1.6
+
+ C program, 2.1.1.1
+ C Standard, definition of terms, 1.6
+ C Standard, organization of document, 1.4
+ C Standard, purpose of, 1.1
+ C Standard, references, 1.3
+ C Standard, scope, restrictions and limits, 1.2
+ carriage-return escape sequence, \r, 2.2.2, 3.1.3.4
+ case mapping functions, 4.3.2
+ cast expressions, 3.3.4
+ cast operator, ( ), 3.3.4
+ character, 1.6
+ character case mapping functions, 4.3.2
+ character constant, 2.1.1.2, 2.2.1, 3.1.3.4
+ character display semantics, 2.2.2
+ character handling header, 4.3
+ character input/output functions, 4.9.7
+ character sets, 2.2.1
+ character string literal, 2.1.1.2, 3.1.4
+ character testing functions, 4.3.1
+ character type, 3.1.2.5, 3.2.2.1, 3.5.7
+ character type conversion, 3.2.1.1
+ collating sequence, character set, 2.2.1
+ colon punctuator, :, 3.1.6, 3.5.2.1
+ comma operator, ,, 3.3.17
+ command processor, 4.10.4.5
+ comment delimiters, /* */, 3.1.9
+ comments, 2.1.1.2, 3.1, 3.1.9
+ common initial sequence, 3.3.2.3
+ comparison functions, 4.11.4
+ compatible type, 3.1.2.6, 3.5.2, 3.5.3, 3.5.4
+ complement operator, ~, 3.3.3.3
+ compliance, 1.7
+ composite type, 3.1.2.6
+ compound assignment operators, 3.3.16.2
+ compound statement, 3.6.2
+ concatenation functions, 4.11.3
+ conceptual models, 2.1
+ conditional inclusion, 3.8.1
+ conditional operator, ? :, 3.3.15
+ conforming freestanding implementation, 1.7
+ conforming hosted implementation, 1.7
+ conforming implementation, 1.7
+ conforming program, 1.7
+ const-qualified type, 3.1.2.5, 3.2.2.1, 3.5.3
+ constant, character, 3.1.3.4
+ constant, enumeration, 3.1.2, 3.1.3.3
+ constant, floating, 3.1.3.1
+ constant, integer, 3.1.3.2
+ constant, primary expression, 3.3.1
+ constant expressions, 3.4
+ constants, 3.1.3
+ constraints, definition of, 1.6
+ content, structure/union/enumeration, 3.5.2.3
+ contiguity, memory allocation, 4.10.3
+ control characters, 2.2.1, 4.3.1, 4.3.1.3
+ conversion, arithmetic operands, 3.2.1
+ conversion, array, 3.2.2.1
+ conversion, characters and integers, 3.2.1.1
+ conversion, explicit, 3.2
+ conversion, floating and integral, 3.2.1.3
+ conversion, floating types, 3.2.1.4, 3.2.1.5
+ conversion, function, 3.2.2.1
+ conversion, function arguments, 3.3.2.2, 3.7.1
+ conversion, implicit, 3.2
+ conversion, pointer, 3.2.2.1, 3.2.2.3
+ conversion, signed and unsigned integers, 3.2.1.2
+ conversion, void type, 3.2.2.2
+ conversions, 3.2
+ conversions, usual arithmetic, 3.2.1.5
+ copying functions, 4.11.2
+
+ data streams, 4.9.2
+ date and time header, 4.12
+ decimal constant, 3.1.3.2
+ decimal digits, 2.2.1
+ decimal-point character, 4.1.1
+ declaration specifiers, 3.5
+ declarations, 3.5
+ declarators, 3.5.4
+ declarator type derivation, 3.1.2.5, 3.5.4
+ decrement operator, postfix, --, 3.3.2.4
+ decrement operator, prefix, --, 3.3.3.1
+ default argument promotions, 3.3.2.2
+ definition, 3.5
+ derived declarator types, 3.1.2.5
+ derived types, 3.1.2.5
+ device input/output, 2.1.2.3
+ diagnostics, 2.1.1.3
+ diagnostics, assert.h, 4.2
+ direct input/output functions, 4.9.8
+ display device, 2.2.2
+ division assignment operator, /=3D, 3.3.16.2
+ division operator, /, 3.3.5
+ documentation of implementation, 1.7
+ domain error, 4.5.1
+ dot operator, ., 3.3.2.3
+ double-precision arithmetic, 2.1.2.3
+
+ element type, 3.1.2.5
+ ellipsis, unspecified parameters, , ..., 3.5.4.3
+ end-of-file macro, EOF, 4.3, 4.9.1
+ end-of-file indicator, 4.9.1, 4.9.7.1
+ end-of-line indicator, 2.2.1
+ enumerated types, 3.1.2.5
+ enumeration constant, 3.1.2, 3.1.3.3
+ enumeration content, 3.5.2.3
+ enumeration members, 3.5.2.2
+ enumeration specifiers, 3.5.2.2
+ enumeration tag, 3.5.2.3
+ enumerator, 3.5.2.2
+ environment, 2
+ environment functions, 4.10.4
+ environment list, 4.10.4.4
+ environmental considerations, 2.2
+ environmental limits, 2.2.4
+ equal-sign punctuator, =3D, 3.1.6, 3.5, 3.5.7
+ equal-to operator, =3D=3D, 3.3.9
+ equality expressions, 3.3.9
+ error, domain, 4.5.1
+ error, range, 4.5.1
+ error conditions, 4.5.1
+ error handling functions, 4.9.10, 4.11.6.2
+ error indicator, 4.9.1, 4.9.7.1, 4.9.7.3
+ escape sequences, 2.2.1, 2.2.2, 3.1.3.4
+ evaluation, 3.1.5, 3.3
+ exception, 3.3
+ exclusive OR assignment operator, ^=3D, 3.3.16.2
+ exclusive OR operator, ^, 3.3.11
+ executable program, 2.1.1.1
+ execution environment, character sets, 2.2.1
+ execution environment limits, 2.2.4.2
+ execution environments, 2.1.2
+ execution sequence, 2.1.2.3, 3.6
+ explicit conversion, 3.2
+ exponent part, floating constant, 3.1.3.1
+ exponential functions, 4.5.4
+ expression, 3.3
+ expression, full, 3.6
+ expression, primary, 3.3.1
+ expression, unary, 3.3.3
+ expression statement, 3.6.3
+ extended character set, 1.6, 2.2.1.2
+ external definitions, 3.7
+ external identifiers, underscore, 4.1.2
+ external linkage, 3.1.2.2
+ external name, 3.1.2
+ external object definitions, 3.7.2
+
+ file, closing, 4.9.3
+ file, creating, 4.9.3
+ file, opening, 4.9.3
+ file access functions, 4.9.5
+ file identifier scope, 3.1.2.1, 3.7
+ file name, 4.9.3
+ file operations, 4.9.4
+ file position indicator, 4.9.3
+ file positioning functions, 4.9.9
+ files, 4.9.3
+ floating arithmetic functions, 4.5.6
+ floating constants, 3.1.3.1
+ floating suffix, f or F, 3.1.3.1
+ floating types, 3.1.2.5
+ floating-point numbers, 3.1.2.5
+ form-feed character, 2.2.1, 3.1
+ form-feed escape sequence, \f, 2.2.2, 3.1.3.4
+ formatted input/output functions, 4.9.6
+ forward references, definition of, 1.6
+ freestanding execution environment, 2.1.2, 2.1.2.1
+ full expression, 3.6
+ fully buffered stream, 4.9.3
+ function, definition of, 1.6, 3.5.4.3
+ function, recursive call, 3.3.2.2
+ function argument, 3.3.2.2
+ function body, 3.7, 3.7.1
+ function call, 3.3.2.2
+ function call, library, 4.1.6
+ function declarator, 3.5.4.3
+ function definition, 3.5.4.3, 3.7.1
+ function designator, 3.2.2.1
+ function identifier scope, 3.1.2.1
+ function image, 2.2.3
+ function library, 2.1.1.1, 4.1.6
+ function parameter, 2.1.2.2, 3.3.2.2
+ function prototype, 3.1.2.1, 3.3.2.2, 3.5.4.3, 3.7.1
+ function prototype identifier scope, 3.1.2.1
+ function return, 3.6.6.4
+ function type, 3.1.2.5
+ function type conversion, 3.2.2.1
+ function-call operator, ( ), 3.3.2.2
+ future directions, 1.8, 3.9, 4.13
+ future language directions, 3.9
+ future library directions, 4.13
+
+ general utility library, 4.10
+ graphic characters, 2.2.1
+ greater-than operator, &gt;, 3.3.8
+ greater-than-or-equal-to operator, &gt;=3D, 3.3.8
+
+ header names, 3.1, 3.1.7, 3.8.2
+ headers, 4.1.2
+ hexadecimal constant, 3.1.3.2
+ hexadecimal digit, 3.1.3.2, 3.1.3.4
+ hexadecimal escape sequence, 3.1.3.4
+ high-order bit, 1.6
+ horizontal-tab character, 2.2.1, 3.1
+ horizontal-tab escape sequence, \t, 2.2.2, 3.1.3.4
+ hosted execution environment, 2.1.2, 2.1.2.2
+ hyperbolic functions, 4.5.3
+
+ identifier, 3.1.2, 3.3.1
+ identifier, maximum length, 3.1.2
+ identifier, reserved, 4.1.2
+ identifier linkage, 3.1.2.2
+ identifier list, 3.5.4
+ identifier name space, 3.1.2.3
+ identifier scope, 3.1.2.1
+ identifier type, 3.1.2.5
+ IEEE floating-point arithmetic standard, 2.2.4.2
+ implementation, definition of, 1.6
+ implementation limits, 1.6, 2.2.4
+ implementation-defined behavior, 1.6
+ implicit conversion, 3.2
+ implicit function declaration, 3.3.2.2
+ inclusive OR assignment operator, |=3D, 3.3.16.2
+ inclusive OR operator, |, 3.3.12
+ incomplete type, 3.1.2.5
+ increment operator, postfix, ++, 3.3.2.4
+ increment operator, prefix, ++, 3.3.3.1
+ indirection operator, *, 3.3.3.2
+ inequality operator, !=3D, 3.3.9
+ initialization, 2.1.2, 3.1.2.4, 3.2.2.1, 3.5.7, 3.6.2
+ initializer, string literal, 3.2.2.1, 3.5.7
+ initializer braces, 3.5.7
+ initial shift state, 2.2.1.2, 4.10.7
+ input/output, device, 2.1.2.3
+ input/output header, 4.9
+ integer arithmetic functions, 4.10.6
+ integer character constant, 3.1.3.4
+ integer constants, 3.1.3.2
+ integer suffix, 3.1.3.2
+ integer type, 3.1.2.5
+ integer type conversion, 3.2.1.1, 3.2.1.2
+ integral constant expression, 3.4
+ integral promotions, 2.1.2.3, 3.2.1.1
+ integral type, 3.1.2.5
+ integral type conversion, 3.2.1.3
+ interactive device, 2.1.2.3, 4.9.3, 4.9.5.3
+ internal linkage, 3.1.2.2
+ internal name, 3.1.2
+ interrupt handler, 2.1.2.3, 2.2.3, 4.7
+ ISO 4217 Currency and Funds Representation, 1.3, 4.4.2.1
+ ISO 646 Invariant Code Set, 1.3, 2.2.1.1
+ iteration statements, 3.6.5
+
+ jump statements, 3.6.6
+
+ keywords, 3.1.1
+
+ label name, 3.1.2.1, 3.1.2.3
+ labeled statements, 3.6.1
+ language, 3 language, future directions, 3.9
+ leading underscore in identifiers, 4.1.2
+ left-shift assignment operator, &lt;&lt;=3D, 3.3.16.2
+ left-shift operator, &lt;&lt;, 3.3.7
+ length function, 4.11.6.3
+ less-than operator, &lt;, 3.3.8
+ less-than-or-equal-to operator, &lt;=3D, 3.3.8
+ letter, 4.1.1
+ lexical elements, 2.1.1.2, 3.1
+ library, 2.1.1.1, 4
+ library, future directions, 4.13
+ library functions, use of, 4.1.6
+ library terms, 4.1.1
+ limits, environmental, 2.2.4
+ limits, numerical, 2.2.4.2
+ limits, translation, 2.2.4.1
+ line buffered stream, 4.9.3
+ line number, 3.8.4
+ lines, 2.1.1.2, 3.8, 4.9.2
+ linkages of identifiers, 3.1.2.2
+ locale, definition of, 1.6
+ localization, 4.4
+ logarithmic functions, 4.5.4
+ logical AND operator, &amp;&amp;, 3.3.13
+ logical negation operator, !, 3.3.3.3
+ logical OR operator, ||, 3.3.14
+ logical source lines, 2.1.1.2
+ long double suffix, l or L, 3.1.3.1
+ long integer suffix, l or L, 3.1.3.2
+ low-order bit, 1.6 lvalue, 3.2.2.1, 3.3.1, 3.3.2.4, 3.3.3.1, 3.3.16
+
+ macro function vs. definition, 4.1.6
+ macro name definition, 2.2.4.1
+ macro names, predefined, 3.8.8
+ macro, redefinition of, 3.8.3
+ macro replacement, 3.8.3
+ member-access operators, . and -&gt;, 3.3.2.3
+ memory management functions, 4.10.3
+ minus operator, unary, -, 3.3.3.3
+ modifiable lvalue, 3.2.2.1
+ modulus function, 4.5.4.6
+ multibyte characters, 2.2.1.2, 3.1.3.4, 4.10.7, 4.10.8
+ multibyte functions, 4.10.7, 4.10.8
+ multiplication assignment operator, *=3D, 3.3.16.2
+ multiplication operator, *, 3.3.5
+ multiplicative expressions, 3.3.5
+
+ name, file, 4.9.3
+ name spaces of identifiers, 3.1.2.3
+ nearest-integer functions, 4.5.6
+ new-line character, 2.1.1.2, 2.2.1, 3.1, 3.8, 3.8.4
+ new-line escape sequence, \n, 2.2.2, 3.1.3.4
+ nongraphic characters, 2.2.2, 3.1.3.4
+ nonlocal jumps header, 4.6
+ not-equal-to operator, !=3D, 3.3.9
+ null character padding of binary streams, 4.9.2
+ null character, \0, 2.2.1, 3.1.3.4, 3.1.4
+ null pointer, 3.2.2.3
+ null pointer constant, 3.2.2.3
+ null preprocessing directive, 3.8.7
+ null statement, 3.6.3
+ number, floating-point, 3.1.2.5
+ numerical limits, 2.2.4.2
+
+ object, definition of, 1.6
+ object type, 3.1.2.5
+ obsolescence, 1.8, 3.9, 4.13
+ octal constant, 3.1.3.2
+ octal digit, 3.1.3.2, 3.1.3.4
+ octal escape sequence, 3.1.3.4
+ operand, 3.1.5, 3.3
+ operating system, 2.1.2.1, 4.10.4.5
+ operator, unary, 3.3.3
+ operators, 3.1.5, 3.3
+ OR assignment operator, exclusive, ^=3D, 3.3.16.2
+ OR assignment operator, inclusive, |=3D, 3.3.16.2
+ OR operator, exclusive, ^, 3.3.11
+ OR operator, inclusive, |, 3.3.12
+ OR operator, logical, ||, 3.3.14
+ order of memory allocation, 4.10.3
+ order of evaluation of expression, 3.3
+ ordinary identifier name space, 3.1.2.3
+
+ padding, null character, 4.9.2
+ parameter, ellipsis, , ..., 3.5.4.3
+ parameter, function, 3.3.2.2
+ parameter, main function, 2.1.2.2
+ parameter, 1.6
+ parameter type list, 3.5.4.3
+ parameters, program, 2.1.2.2
+ parentheses punctuator, ( ), 3.1.6, 3.5.4.3
+ parenthesized expression, 3.3.1
+ physical source lines, 2.1.1.2
+ plus operator, unary, +, 3.3.3.3
+ pointer, null, 3.2.2.3
+ pointer declarator, 3.5.4.1
+ pointer operator, -&gt;, 3.3.2.3
+ pointer to function returning type, 3.3.2.2
+ pointer type, 3.1.2.5
+ pointer type conversion, 3.2.2.1, 3.2.2.3
+ portability of implementations, 1.7
+ position indicator, file, 4.9.3
+ postfix decrement operator, --, 3.3.2.4
+ postfix expressions, 3.3.2
+ postfix increment operator, ++, 3.3.2.4
+ power functions, 4.5.5
+ precedence of expression operators, 3.3
+ precedence of syntax rules, 2.1.1.2
+ predefined macro names, 3.8.8
+ prefix decrement operator, --, 3.3.3.1
+ prefix increment operator, ++, 3.3.3.1
+ preprocessing concatenation, 2.1.1.2, 3.8.3
+ preprocessing directives, 2.1.1.2, 3.8
+ preprocessing numbers, 3.1, 3.1.8
+ preprocessing tokens, 2.1.1.2, 3.1, 3.8
+ primary expressions, 3.3.1
+ printing characters, 2.2.2, 4.3.1, 4.3.1.7
+ program, conforming, 1.7
+ program, strictly conforming, 1.7
+ program diagnostics, 4.2.1
+ program execution, 2.1.2.3
+ program file, 2.1.1.1
+ program image, 2.1.1.2
+ program name, argv[0], 2.1.2.2
+ program parameters, 2.1.2.2
+ program startup, 2.1.2, 2.1.2.1, 2.1.2.2
+ program structure, 2.1.1.1
+ program termination, 2.1.2, 2.1.2.1, 2.1.2.2, 2.1.2.3
+ promotions, default argument, 3.3.2.2
+ promotions, integral, 2.1.2.3, 3.2.1.1
+ prototype, function, 3.1.2.1, 3.3.2.2, 3.5.4.3, 3.7.1
+ pseudo-random sequence functions, 4.10.2
+ punctuators, 3.1.6
+
+ qualified types, 3.1.2.5
+
+ range error, 4.5.1
+ recursive function call, 3.3.2.2
+ redefinition of macro, 3.8.3
+ reentrancy, 2.1.2.3, 2.2.3
+ referenced type, 3.1.2.5
+ relational expressions, 3.3.8
+ reliability of data, interrupted, 2.1.2.3
+ remainder assignment operator, %=3D, 3.3.16.2
+ remainder operator, %, 3.3.5
+ restore calling environment function, 4.6.2.1
+ reserved identifiers, 4.1.2
+ right-shift assignment operator, &gt;&gt;=3D, 3.3.16.2
+ right-shift operator, &gt;&gt;, 3.3.7
+ rvalue, 3.2.2.1
+
+ save calling environment function, 4.6.1.1
+ scalar type, 3.1.2.5
+ scope of identifiers, 3.1.2.1
+ search functions, 4.10.5.1, 4.11.5
+ selection statements, 3.6.4
+ semicolon punctuator, ;, 3.1.6, 3.5, 3.6.3
+ sequence points, 2.1.2.3, 3.3, 3.6
+ shift expressions, 3.3.7
+ shift states, 2.2.1.2, 4.10.7
+ side effects, 2.1.2.3, 3.3
+ signal handler, 2.2.3, 4.7.1.1
+ signals, 2.1.2.3, 2.2.3, 4.7
+ signed integer types, 3.1.2.5, 3.1.3.2, 3.2.1.2
+ simple assignment operator, =3D, 3.3.16.1
+ single-precision arithmetic, 2.1.2.3
+ sort function, 4.10.5.2
+ source character set, 2.2.1
+ source file inclusion, 3.8.2
+ source files, 2.1.1.1
+ source text, 2.1.1.2
+ space character, 2.1.1.2, 2.2.1, 3.1
+ standard streams, 4.9.1, 4.9.3
+ standard header, float.h, 1.7, 2.2.4.2, 4.1.4
+ standard header, limits.h, 1.7, 2.2.4.2, 4.1.4
+ standard header, stdarg.h, 1.7, 4.8
+ standard header, stddef.h, 1.7, 4.1.5
+ standard headers, 4.1.2
+ state-dependent encoding, 2.2.1.2, 4.10.7
+ statements, 3.6
+ static storage duration, 3.1.2.4
+ storage duration, 3.1.2.4
+ storage-class specifier, 3.5.1
+ stream, fully buffered, 4.9.3
+ stream, line buffered, 4.9.3
+ stream, standard error, stderr, 4.9.1, 4.9.3
+ stream, standard input, stdin, 4.9.1, 4.9.3
+ stream, standard output, stdout, 4.9.1, 4.9.3
+ stream, unbuffered, 4.9.3
+ streams, 4.9.2
+ strictly conforming program, 1.7
+ string, 4.1.1
+ string conversion functions, 4.10.1
+ string handling header, 4.11
+ string length, 4.1.1, 4.11.6.3
+ string literal, 2.1.1.2, 2.2.1, 3.1.4, 3.3.1, 3.5.7
+ structure/union arrow operator, -&gt;, 3.3.2.3
+ structure/union content, 3.5.2.3
+ structure/union dot operator, ., 3.3.2.3
+ structure/union member name space, 3.1.2.3
+ structure/union specifiers, 3.5.2.1
+ structure/union tag, 3.5.2.3
+ structure/union type, 3.1.2.5, 3.5.2.1
+ subtraction assignment operator, -=3D, 3.3.16.2
+ subtraction operator, -, 3.3.6
+ suffix, floating constant, 3.1.3.1
+ suffix, integer constant, 3.1.3.2
+ switch body, 3.6.4.2
+ switch case label, 3.6.1, 3.6.4.2
+ switch default label, 3.6.1, 3.6.4.2
+ syntactic categories, 3
+ syntax notation, 3
+ syntax rules, precedence of, 2.1.1.2
+
+ tab characters, 2.2.1
+ tabs, white space, 3.1
+ tag, enumeration, 3.5.2.3
+ tag, structure/union, 3.5.2.3
+ tag name space, 3.1.2.3
+ tentative definitions, 3.7.2
+ text stream, 4.9.2
+ time components, 4.12.1
+ time conversion functions, 4.12.3
+ time manipulation functions, 4.12.2
+ tokens, 2.1.1.2, 3.1, 3.8
+ top type, 3.1.2.5
+ translation environment, 2.1.1
+ translation limits, 2.2.4.2
+ translation phases, 2.1.1.2
+ translation unit, 2.1.1.1, 3.7
+ trigonometric functions, 4.5.2
+ trigraph sequences, 2.1.1.2, 2.2.1.1
+ type, character, 3.1.2.5, 3.2.2.1, 3.5.7
+ type, compatible, 3.1.2.6, 3.5.2, 3.5.3, 3.5.4
+ type, composite, 3.1.2.6
+ type, const-qualified, 3.1.2.5, 3.5.3
+ type, function, 3.1.2.5
+ type, incomplete, 3.1.2.5
+ type, object, 3.1.2.5
+ type, qualified, 3.1.2.5
+ type, unqualified, 3.1.2.5
+ type, volatile-qualified, 3.1.2.5, 3.5.3
+ type conversions, 3.2
+ type definitions, 3.5.6
+ type names, 3.5.5
+ type specifiers, 3.5.2
+ type qualifiers, 3.5.3
+ types, 3.1.2.5
+
+ unary arithmetic operators, 3.3.3.3
+ unary expressions, 3.3.3
+ unary minus operator, -, 3.3.3.3
+ unary operators, 3.3.3
+ unary plus operator, +, 3.3.3.3
+ unbuffered stream, 4.9.3
+ undefined behavior, 1.6
+ underscore, leading, in identifiers, 4.1.2
+ union tag, 3.5.2.3
+ union type specifier, 3.1.2.5, 3.5.2, 3.5.2.1
+ unqualified type, 3.1.2.5
+ unsigned integer suffix, u or U, 3.1.3.2
+ unsigned integer types, 3.1.2.5, 3.1.3.2
+ unspecified behavior, 1.6
+ usual arithmetic conversions, 3.2.1.5
+
+ value part, floating constant, 3.1.3.1
+ variable arguments header, 4.8
+ vertical-tab character, 2.2.1, 3.1
+ vertical-tab escape sequence, \v, 2.2.2, 3.1.3.4
+ visibility of identifiers, 3.1.2.1
+ void expression, 3.2.2.2
+ volatile storage, 2.1.2.3
+ volatile-qualified type, 3.1.2.5, 3.5.3
+
+ white space, 2.1.1.2, 3.1, 3.8, 4.3.1.9
+ wide character, 3.1.3.4
+ wide character constant, 3.1.3.4
+ wide string literal, 2.1.1.2, 3.1.4
+
+
+
+ 1. This Standard is designed to promote the portability of C programs
+ among a variety of data-processing systems. It is intended for use by
+ implementors and knowledgeable programmers, and is not a tutorial. It
+ is accompanied by a Rationale document that explains many of the
+ decisions of the Technical Committee that produced it.
+
+ 2. Strictly conforming programs are intended to be maximally portable
+ among conforming implementations. Conforming programs may depend upon
+ nonportable features of a conforming implementation.
+
+ 3. Implementations must behave as if these separate phases occur, even
+ though many are typically folded together in practice.
+
+ 4. As described in $3.1, the process of dividing a source file's
+ characters into preprocessing tokens is context-dependent. For
+ example, see the handling of &lt; within a #include preprocessing
+ directive.
+
+ 5. The trigraph sequences enable the input of characters that are not
+ defined in the "ISO 646-1983" Invariant Code Set, which is a subset of
+ the seven-bit ASCII code set.
+
+ 6. Implementations should avoid imposing fixed translation limits
+ whenever possible.
+
+ 7. See $3.1.2.5.
+
+ 8. This model precludes floating-point representations other than
+ sign-magnitude.
+
+ 9. The floating-point model in that standard sums powers of from zero,
+ so the values of the exponent limits are one less than shown here.
+
+ 10. See ``future language directions'' ($3.9.1).
+
+ 11. There is only one name space for tags even though three are
+ possible.
+
+ 12. In the case of a volatile object, the last store may not be
+ explicit in the program.
+
+ 13. A positional representation for integers that uses the binary
+ digits 0 and 1, in which the values represented by successive bits are
+ additive, begin with 1, and are multiplied by successive integral
+ powers of 2, except perhaps the bit with the highest position.
+
+ 14. Note that aggregate type does not include union type because an
+ object with union type can only contain one member at a time.
+
+ 15. There are three distinct combinations of qualified types.
+
+ 16. Two types need not be identical to be compatible.
+
+ 17. The semantics of these characters were discussed in $2.2.2.
+
+ 18. See ``future language directions'' ($3.9.2).
+
+ 19. A character string literal need not be a string (see $4.1.1),
+ because a null character may be embedded in it by a \0 escape
+ sequence.
+
+ 20. Thus, sequences of characters that resemble escape sequences cause
+ undefined behavior.
+
+ 21. Thus comments do not nest.
+
+ 22. In a two's-complement representation, there is no actual change in
+ the bit pattern except filling the high-order bits with copies of the
+ sign bit if the unsigned integer has greater size.
+
+ 23. The remaindering operation done when a value of integral type is
+ converted to unsigned type need not be done when a value of floating
+ type is converted to unsigned type. Thus the range of portable values
+ is [0, U type _MAX +1).
+
+ 24. The name ``lvalue'' comes originally from the assignment
+ expression E1 =3D E2 , in which the left operand E1 must be a
+ (modifiable) lvalue. It is perhaps better considered as representing
+ an object ``locator value.'' What is sometimes called ``rvalue'' is in
+ this Standard described as the ``value of an expression.'' An obvious
+ example of an lvalue is an identifier of an object. As a further
+ example, if E is a unary expression that is a pointer to an object, *E
+ is an lvalue that designates the object to which E points.
+
+ 25. Because this conversion does not occur, the operand of the sizeof
+ operator remains a function designator and violates the constraint in
+ $3.3.3.4.
+
+ 26. This paragraph renders undefined statement expressions such as
+ i =3D ++i + 1; while allowing i =3D i + 1;
+
+ 27. The syntax specifies the precedence of operators in the evaluation
+ of an expression, which is the same as the order of the major
+ subsections of this section, highest precedence first. Thus, for
+ example, the expressions allowed as the operands of the binary +
+ operator ($3.3.6) shall be those expressions defined in $3.3.1 through
+ $3.3.6. The exceptions are cast expressions ($3.3.4) as operands of
+ unary operators ($3.3.3), and an operand contained between any of the
+ following pairs of operators: grouping parentheses () ($3.3.1),
+ subscripting brackets [] ($3.3.2.1), function-call parentheses ()
+ ($3.3.2.2), and the conditional operator ?: ($3.3.15). Within each
+ major subsection, the operators have the same precedence. Left- or
+ right-associativity is indicated in each subsection by the syntax for
+ the expressions discussed therein.
+
+ 28. The intent of this list is to specify those circumstances in which
+ an object may or may not be aliased.
+
+ 29. Most often, this is the result of converting an identifier that is
+ a function designator.
+
+ 30. That is, a function with external linkage and no information about
+ its parameters that returns an int . If in fact it is not defined as
+ having type ``function returning int ,'' the behavior is undefined.
+
+ 31. A function may change the values of its parameters, but these
+ changes cannot affect the values of the arguments. On the other hand,
+ it is possible to pass a pointer to an object, and the function may
+ change the value of the object pointed to. A parameter declared to
+ have array or function type is converted to a parameter with a pointer
+ type as described in
+
+ 32. If &amp;E is a valid pointer expression (where &amp; is the ``address-o=
+ f''
+ operator, which generates a pointer to its operand) the expression
+ (&amp;E)-&gt;MOS is the same as E.MOS .
+
+ 33. The ``byte orders'' for scalar types are invisible to isolated
+ programs that do not indulge in type punning (for example, by
+ assigning to one member of a union and inspecting the storage by
+ accessing another member that is an appropriately sized array of
+ character type), but must be accounted for when conforming to
+ externally-imposed storage layouts.
+
+ 34. It is always true that if E is a function designator or an lvalue
+ that is a valid operand of the unary &amp; operator, *&amp;E is a function
+ designator or an lvalue equal to E . If *P is an lvalue and T is the
+ name of an object pointer type, the cast expression *(T)P is an lvalue
+ that has a type compatible with that to which T points. Among the
+ invalid values for dereferencing a pointer by the unary * operator are
+ a null pointer, an address inappropriately aligned for the type of
+ object pointed to, or the address of an object that has automatic
+ storage duration when execution of the block in which the object is
+ declared and of all enclosed blocks has terminated.
+
+ 35. When applied to a parameter declared to have array or function
+ type, the sizeof operator yields the size of the pointer obtained by
+ converting as in $3.2.2.1; see $3.7.1.
+
+ 36. A cast does not yield an lvalue.
+
+ 37. The mapping functions for converting a pointer to an integer or an
+ integer to a pointer are intended to be consistent with the addressing
+ structure of the execution environment.
+
+ 38. The expression a&lt;b&lt;c is not interpreted as in ordinary
+ mathematics. As the syntax indicates, it means (a&lt;b)&lt;c ; in other
+ words, ``if a is less than b compare 1 to c ; otherwise compare 0 to c
+ .''
+
+ 39. Because of the precedences, a&lt;b =3D=3D c&lt;d is 1 whenever a&lt;b a=
+ nd c&lt;d
+ have the same truth-value.
+
+ 40. If invalid prior pointer operations, such as accesses outside
+ array bounds, produced undefined behavior, the effect of subsequent
+ comparisons is undefined.
+
+ 41. A conditional expression does not yield an lvalue.
+
+ 42. The asymmetric appearance of these constraints with respect to
+ type qualifiers is due to the conversion (specified in $3.2.2.1) that
+ changes lvalues to ``the value of the expression'' which removes any
+ type qualifiers from the top type of the expression.
+
+ 43. A comma operator does not yield an lvalue.
+
+ 44. The operand of a sizeof operator is not evaluated ($3.3.3.4), and
+ thus any operator in $3.3 may be used.
+
+ 45. An integral constant expression must be used to specify the size
+ of a bit-field member of a structure, the value of an enumeration
+ constant, the size of an array, or the value of a case constant.
+ Further constraints that apply to the integral constant expressions
+ used in conditional-inclusion preprocessing directives are discussed
+ in $3.8.1.
+
+ 46. Thus in the following initialization, static int i =3D 2 || 1 / 0;
+ the expression is a valid integral constant expression with value one.
+
+ 47. Function definitions have a different syntax, described in $3.7.1.
+
+ 48. See ``future language directions'' ($3.9.3).
+
+ 49. The implementation may treat any register declaration simply as an
+ auto declaration. However, whether or not addressable storage is
+ actually used, the address of any part of an object declared with
+ storage-class specifier register may not be computed, either
+ explicitly (by use of the unary &amp; operator as discussed in $3.3.3.2)
+ or implicitly (by converting an array name to a pointer as discussed
+ in $3.2.2.1). Thus the only operator that can be applied to an array
+ declared with storage-class specifier register is sizeof .
+
+ 50. The unary &amp; (address-of) operator may not be applied to a
+ bit-field object; thus there are no pointers to or arrays of bit-field
+ objects.
+
+ 51. An unnamed bit-field is useful for padding to conform to
+ externally-imposed layouts.
+
+ 52. Thus, the identifiers of enumeration constants in the same scope
+ shall all be distinct from each other and from other identifiers
+ declared in ordinary declarators.
+
+ 53. A similar construction with enum does not exist and is not
+ necessary as there can be no mutual dependencies between the
+ declaration of an enumerated type and any other type.
+
+ 54. It is not needed, for example, when a typedef name is declared to
+ be a specifier for a structure or union, or when a pointer to or a
+ function returning a structure or union is being declared. (See
+ incomplete types in $3.1.2.5.) The specification shall be complete
+ before such a function is called or defined.
+
+ 55. Of course, when the declaration is of a typedef name, subsequent
+ declarations can make use of the typedef name to declare objects
+ having the specified structure, union, or enumerated type.
+
+ 56. The implementation may place a const object that is not volatile
+ in a read-only region of storage. Moreover, the implementation need
+ not allocate storage for such an object if its address is never used.
+
+ 57. This applies to those objects that behave as if they were defined
+ with qualified types, even if they are never actually defined as
+ objects in the program (such as an object at a memory-mapped
+ input/output address).
+
+ 58. A volatile declaration may be used to describe an object
+ corresponding to a memory-mapped input/output port or an object
+ accessed by an asynchronously interrupting function. Actions on
+ objects so declared shall not be ``optimized out'' by an
+ implementation or reordered except as permitted by the rules for
+ evaluating expressions.
+
+ 59. Both of these can only occur through the use of typedef s.
+
+ 60. When several ``array of'' specifications are adjacent, a
+ multi-dimensional array is declared.
+
+ 61. The macros defined in the &lt;stdarg.h&gt; header ($4.8) may be used to
+ access arguments that follow an ellipsis.
+
+ 62. See ``future language directions'' ($3.9.4).
+
+ 63. If both function types are ``old style,'' parameter types are not
+ compared.
+
+ 64. As indicated by the syntax, empty parentheses in a type name are
+ interpreted as ``function with no parameter specification,'' rather
+ than redundant parentheses around the omitted identifier.
+
+ 65. Unlike in the base document, any automatic duration object may be
+ initialized.
+
+ 66. Such as assignments, and function calls which have side effects.
+
+ 67. Thus specifies initialization for the loop; the controlling
+ expression, specifies an evaluation made before each iteration, such
+ that execution of the loop continues until the expression compares
+ equal to 0; specifies an operation (such as incrementing) that is
+ performed after each iteration.
+
+ 68. Following the contin: label is a null statement.
+
+ 69. Thus, if an identifier declared with external linkage is not used
+ in an expression, there need be no external definition for it.
+
+ 70. The intent is that the top type in a function definition cannot be
+ inherited from a typedef: typedef int F(void); /* type F is ``function
+ of no arguments returning int '' */ F f, g; /* f and g both have type
+ compatible with F */ F f { /*...*/ } /* WRONG: syntax/constraint error
+ */ F g() { /*...*/ } /* WRONG: declares that g returns a function */
+ int f(void) { /*...*/ } /* RIGHT: f has type compatible with F */ int
+ g() { /*...*/ } /* RIGHT: g has type compatible with F */ F *e(void) {
+ /*...*/ } /* e returns a pointer to a function */ F *((e))(void) {
+ /*...*/ } /* same: parentheses irrelevant */ int (*fp)(void); /* fp
+ points to a function that has type F */ F *Fp; /* Fp points to a
+ function that has type F */
+
+ 71. See ``future language directions'' ($3.9.5).
+
+ 72. A parameter is in effect declared at the head of the compound
+ statement that constitutes the function body, and therefore may not be
+ redeclared in the function body (except in an enclosed block).
+
+ 73. Thus preprocessing directives are commonly called ``lines.'' These
+ ``lines'' have no other syntactic significance, as all white space is
+ equivalent except in certain situations during preprocessing (see the
+ # character string literal creation operator in $3.8.3.2, for
+ example).
+
+ 74. Because the controlling constant expression is evaluated during
+ translation phase 4, all identifiers either are or are not macro names
+ --- there simply are no keywords, enumeration constants, and so on.
+
+ 75. Thus the constant expression in the following #if directive and if
+ statement is not guaranteed to evaluate to the same value in these two
+ contexts. #if 'z' - 'a' =3D=3D 25 if ('z' - 'a' =3D=3D 25)
+
+ 76. As indicated by the syntax, a preprocessing token shall not follow
+ a #else or #endif directive before the terminating new-line character.
+ However, comments may appear anywhere in a source file, including
+ within a preprocessing directive.
+
+ 77. Note that adjacent string literals are not concatenated into a
+ single string literal (see the translation phases in $2.1.1.2); thus
+ an expansion that results in two string literals is an invalid
+ directive.
+
+ 78. Since, by macro-replacement time, all character constants and
+ string literals are preprocessing tokens, not sequences possibly
+ containing identifier-like subsequences (see $2.1.1.2, translation
+ phases), they are never scanned for macro names or parameters.
+
+ 79. Thus indicating a Standard-conforming implementation.
+
+ 80. The functions that make use of the decimal-point character are
+ localeconv , fprintf , fscanf , printf , scanf , sprintf , sscanf ,
+ vfprintf , vprintf , vsprintf , atof , and strtod .
+
+ 81. A header is not necessarily a source file, nor are the &lt; and &gt;
+ delimited sequences in header names necessarily valid source file
+ names.
+
+ 82. The list of reserved external identifiers includes errno , setjmp ,
+ and va_end .
+
+ 83. The macro errno need not be the identifier of an object. It might
+ be a modifiable lvalue resulting from a function call (for example,
+ *errno() ).
+
+ 84. Thus, a program that uses errno for error checking should set it
+ to zero before a library function call, then inspect it before a
+ subsequent library function call.
+
+ 85. See ``future library directions'' ($4.13.1).
+
+ 86. This means that an implementation must provide an actual function
+ for each library function, even if it also provides a macro for that
+ function.
+
+ 87. Because external identifiers and some macro names beginning with
+ an underscore are reserved, implementations may provide special
+ semantics for such names. For example, the identifier _BUILTIN_abs
+ could be used to indicate generation of in-line code for the abs
+ function. Thus, the appropriate header could specify #define abs(x)
+ _BUILTIN_abs(x) for a compiler whose code generator will accept it.
+ In this manner, a user desiring to guarantee that a given library
+ function such as abs will be a genuine function may write #undef abs
+ whether the implementation's header provides a macro implementation of
+ abs or a builtin implementation. The prototype for the function,
+ which precedes and is hidden by any macro definition, is thereby
+ revealed also.
+
+ 88. The message written might be of the form Assertion failed: file
+ line
+
+ 89. See ``future library directions'' ($4.13.2).
+
+ 90. In an implementation that uses the seven-bit ASCII character set,
+ the printing characters are those whose values lie from 0x20 (space)
+ through 0x7E (tilde); the control characters are those whose values
+ lie from 0 (NUL) through 0x1F (US), and the character 0x7F (DEL).
+
+ 91. See ``future library directions'' ($4.13.3).
+
+ 92. The only functions in $4.3 whose behavior is not affected by the
+ current locale are isdigit and isxdigit .
+
+ 93. See ``future library directions'' ($4.13.4).
+
+ 94. In an implementation that supports infinities, this allows
+ infinity as an argument to be a domain error if the mathematical
+ domain of the function does not include infinity.
+
+ 95. These functions are useful for dealing with unusual conditions
+ encountered in a low-level function of a program.
+
+ 96. For example, by executing a return statement or because another
+ longjmp call has caused a transfer to a setjmp invocation in a
+ function earlier in the set of nested calls.
+
+ 97. See ``future library directions'' ($4.13.5). The names of the
+ signal numbers reflect the following terms (respectively): abort,
+ floating-point exception, illegal instruction, interrupt, segmentation
+ violation, and termination.
+
+ 98. Of course, the contents of the file name strings are subject to
+ other system-specific constraints.
+
+ 99. An implementation need not distinguish between text streams and
+ binary streams. In such an implementation, there need be no new-line
+ characters in a text stream nor any limit to the length of a line.
+
+ 100. This is described in the Base Document as a That term is not used
+ in this Standard to avoid confusion with a pointer to an object that
+ has type FILE .
+
+ 101. Among the reasons the implementation may cause the rename
+ function to fail are that the file is open or that it is necessary to
+ copy its contents to effectuate its renaming.
+
+ 102. Files created using strings generated by the tmpnam function are
+ temporary only in the sense that their names should not collide with
+ those generated by conventional naming rules for the implementation.
+ It is still necessary to use the remove function to remove such files
+ when their use is ended, and before program termination.
+
+ 103. Additional characters may follow these sequences.
+
+ 104. The primary use of the freopen function is to change the file
+ associated with a standard text stream ( stderr , stdin , or stdout ),
+ as those identifiers need not be modifiable lvalues to which the value
+ returned by the fopen function may be assigned.
+
+ 105. The buffer must have a lifetime at least as great as the open
+ stream, so the stream should be closed before a buffer that has
+ automatic storage duration is deallocated upon block exit.
+
+ 106. Note that 0 is taken as a flag, not as the beginning of a field
+ width.
+
+ 107. No special provisions are made for multibyte characters.
+
+ 108. See ``future library directions'' ($4.13.6).
+
+ 109. No special provisions are made for multibyte characters.
+
+ 110. See ``future library directions'' ($4.13.6).
+
+ 111. As vfprintf , vsprintf , and vprintf invoke the va_arg macro, the
+ value of arg after the return is indeterminate.
+
+ 112. An end-of-file and a read error can be distinguished by use of
+ the feof and ferror functions.
+
+ 113. See ``future library directions'' ($4.13.7).
+
+ 114. Note that this need not be the same as the representation of
+ floating-point zero or a null pointer constant.
+
+ 115. Each function is called as many times as it was registered.
+
+ 116. Notice that the key-to-member comparison an ordering on the
+ array.
+
+ 117. In a two's complement representation, the absolute value of the
+ most negative number cannot be represented.
+
+ 118. The array will not be null- or zero-terminated if the value
+ returned is n .
+
+ 119. See ``future library directions'' ($4.13.8).
+
+ 120. Thus, if there is no null character in the first n characters of
+ the array pointed to by s2 , the result will not be null-terminated.
+
+ 121. Thus the maximum number of characters that end up in the array
+ pointed to by s1 is strlen(s1)+n+1 .
+
+ 122. The contents of ``holes'' used as padding for purposes of
+ alignment within structure objects are indeterminate, unless the
+ contents of the entire object have been set explicitly, as by the
+ calloc or memset function. Strings shorter than their allocated space
+ and unions may also cause problems in comparison.
+
+ 123. The range [0, 60] for tm_sec allows for the occasional leap
+ second.
+
+ 124. Thus, a positive or zero value for tm_isdst causes the mktime
+ function initially to presume that Daylight Saving Time, respectively,
+ is or is not in effect for the specified time. A negative value for
+ tm_isdst causes the mktime function to attempt to determine whether
+ Daylight Saving Time is in effect for the specified time.
F diff --git a/all.h b/all.h new file mode 100644 --- /dev/null +++ b/all.h
+ #ifndef GCC_ALL
+ #define GCC_ALL GCC_ALL
+
+
+
+ #include "lexer.h"
+ #include "program.h"
+ #include "scope.h"
+ #include "type.h"
+ #include "parse_declaration.h"
+ #include "ast.h"
+ #include "parse_expression.h"
+ #include "parse_statement.h"
+ #include "parse_translation_unit.h"
+ #include "semantics.h"
+
+
+ #include "parse_expression.c"
+ #include "parse_statement.c"
+ #include "parse_declaration.c"
+ #include "parse_translation_unit.c"
+ #include "ast.c"
+ #include "scope.c"
+ #include "lexer.c"
+ #include "print.c"
+ #include "type.c"
+ #include "semantics.c"
+ #include "program.c"
+
+
+
+
+
+
+ #endif
F diff --git a/ast.c b/ast.c new file mode 100644 --- /dev/null +++ b/ast.c
+ #ifndef GCC_AST_C
+ #define GCC_AST_C GCC_AST_C
+ #include "ast.h"
+
+ struct AST_Error* get_error_tree(struct AST *error)
+ {
+ struct AST_Error *ret;
+ ret=malloc(sizeof(struct AST_Error));
+ ret->type=ERROR;
+ ret->error=error;
+ return ret;
+ }
+ struct AST_Binary_Expression* get_binary_expression_tree(struct AST *left,struct AST *right,enum AST_Type type)
+ {
+ struct AST_Binary_Expression *ret;
+ ret=malloc(sizeof(struct AST_Binary_Expression));
+ ret->type=type;
+ ret->left=left;
+ ret->right=right;
+
+ return ret;
+ }
+ struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST *left,struct AST *center,struct AST *right)
+ {
+ struct AST_Conditional_Expression *ret;
+ ret=malloc(sizeof(struct AST_Conditional_Expression));
+ ret->type=OP_COND;
+ ret->left=left;
+ ret->center=center;
+ ret->right=right;
+ return ret;
+ }
+
+ struct AST_Function_Expression* get_function_expression_tree(struct AST* id,struct Scope *scope)
+ {
+ struct AST_Function_Expression *ret;
+ ret=malloc(sizeof(struct AST_Function_Expression));
+ ret->type=OP_FUNCTION;
+ ret->id=id;
+ Queue_Init(&ret->arguments);
+ return ret;
+ }
+ struct AST_Unary_Expression* get_unary_expression_tree(struct AST *operand,enum AST_Type type)
+ {
+
+ struct AST_Unary_Expression *ret;
+ ret=malloc(sizeof(struct AST_Unary_Expression));
+ ret->operand=operand;
+ ret->type=type;
+
+ return ret;
+ }
+ struct AST_Rvalue_Expression* get_rvalue_expression_tree(struct token *id)
+ {
+ struct AST_Rvalue_Expression *ret;
+ ret=malloc(sizeof(struct AST_Rvalue_Expression));
+ ret->type=OP_RVALUE;
+ ret->id=id;
+ return ret;
+ }
+ struct AST_Lvalue_Expression* get_lvalue_expression_tree(struct token *id,struct Scope* scope)
+ {
+ struct AST_Lvalue_Expression *ret;
+ ret=malloc(sizeof(struct AST_Lvalue_Expression));
+ ret->type=OP_LVALUE;
+ ret->id=id;
+ ret->value_type=check_ordinary(scope,id);
+ if(ret->value_type==NULL)
+ {
+ /*TODO error*/
+ }
+ return ret;
+ }
+
+
+
+
+
+ struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,struct Scope *scope,enum AST_Type type)
+ {
+ struct AST_Labeled_Statement *ret;
+ ret=malloc(sizeof(struct AST_Labeled_Statement));
+ ret->type=type;
+ ret->label=label;
+ ret->statement=statement;
+ ret->scope=scope;
+
+ return ret;
+ }
+ struct AST_Compound_Statement* get_compound_statement_tree(struct Scope *parent_scope)
+ {
+ struct AST_Compound_Statement *ret;
+ ret=malloc(sizeof(struct AST_Compound_Statement));
+ ret->type=ST_COMPOUND;
+ Queue_Init(&ret->components);
+ ret->scope=get_scope(parent_scope);
+ return ret;
+ }
+ struct AST_If_Statement* get_if_statement_tree()
+ {
+ struct AST_If_Statement *ret;
+ ret=malloc(sizeof(struct AST_If_Statement));
+ ret->type=ST_IF;
+
+ return ret;
+ }
+ struct AST_Switch_Statement* get_switch_statement_tree()
+ {
+ struct AST_Switch_Statement *ret;
+ ret=malloc(sizeof(struct AST_Switch_Statement));
+ ret->type=ST_SWITCH;
+ return ret;
+ }
+ struct AST_While_Statement* get_while_statement_tree()
+ {
+ struct AST_While_Statement *ret;
+ ret=malloc(sizeof(struct AST_While_Statement));
+ ret->type=ST_WHILE;
+ return ret;
+ }
+ struct AST_Do_While_Statement* get_do_while_statement_tree()
+ {
+ struct AST_Do_While_Statement *ret;
+ ret=malloc(sizeof(struct AST_Do_While_Statement));
+ ret->type=ST_DO_WHILE;
+ return ret;
+ }
+
+ struct AST_For_Statement* get_for_statement_tree()
+ {
+ struct AST_For_Statement *ret;
+ ret=malloc(sizeof(struct AST_For_Statement));
+ ret->type=ST_FOR;
+ return ret;
+ }
+ struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression)
+ {
+ struct AST_Return_Statement *ret;
+ ret=malloc(sizeof(struct AST_If_Statement));
+ ret->type=ST_RETURN;
+ ret->return_expression=return_expression;
+ return ret;
+ }
+
+ struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope)
+ {
+ struct AST_Goto_Statement *ret;
+ ret=malloc(sizeof(struct AST_Goto_Statement));
+ ret->type=ST_GOTO;
+ ret->label=label;
+ return ret;
+ }
+
+
+ struct AST* get_nop_tree()
+ {
+ struct AST* ret;
+ ret=malloc(sizeof(struct AST*));
+ ret->type=OP_NOP;
+ return ret;
+ }
+
+
+
+ struct AST_Declaration* get_declaration_tree(struct Scope* scope)
+ {
+ struct AST_Declaration *ret;
+ ret=malloc(sizeof(struct AST_Declaration));
+ ret->type=ST_DECLARATION;
+ ret->base_type=malloc(sizeof(struct Type_Node));
+ Queue_Init(&ret->declarators);
+ ret->scope=scope;
+
+ return ret;
+ }
+ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope)
+ {
+ struct AST_Function_Definition *ret;
+ ret=malloc(sizeof(struct AST_Function_Definition));
+ ret->type=ST_FUNCTION_DEFINITION;
+ return ret;
+ }
+
+ struct AST_Translation_Unit* get_translation_unit_tree(struct Scope* parent_scope)
+ {
+ struct AST_Translation_Unit *ret;
+ ret=malloc(sizeof(struct AST_Translation_Unit));
+ ret->type=TRANSLATION_UNIT;
+ Queue_Init(&ret->components);
+ ret->scope=get_scope(parent_scope);
+ return ret;
+ }
+
+
+
+
+
+
+
+
+ #endif
F diff --git a/ast.h b/ast.h new file mode 100644 --- /dev/null +++ b/ast.h
+ #ifndef GCC_AST_H
+ #define GCC_AST_H GCC_AST_H
+ #include "scope.h"
+ #include "parse_declaration.h"
+
+ enum AST_Type{
+ OP_COMMA
+ ,OP_ADDITION,OP_SUBTRACTION,OP_MUL,OP_DIV,OP_REMAINDER
+ ,OP_COND,OP_FUNCTION
+ ,OP_ASSIGN,OP_ADD_ASSIGN,OP_SUBTRACT_ASSIGN,OP_MULTIPLY_ASSIGN,OP_REMAINDER_ASSIGN,OP_DIV_ASSIGN
+ ,OP_SHIFT_LEFT_ASSIGN,OP_SHIFT_RIGHT_ASSIGN
+ ,OP_AND_ASSIGN,OP_XOR_ASSIGN,OP_PIPE_ASSIGN
+ ,OP_NOP
+ ,OP_LOGICAL_OR,OP_LOGICAL_AND,OP_LOGICAL_NOT
+ ,OP_BITWISE_OR,OP_BITWISE_AND,OP_BITWISE_XOR,OP_BITWISE_NOT
+ ,OP_ADDR_OF,OP_DEREFERENCE,OP_MEMBER_TROUGH_PTR,OP_MEMBER,OP_ARR_SUBSCRIPT
+ ,OP_POSTFIX_INC,OP_POSTFIX_DEC
+ ,OP_PREFIX_INC,OP_PREFIX_DEC
+ ,OP_UNARY_PLUS,OP_UNARY_MINUS
+ ,OP_CAST,OP_SIZEOF
+ ,OP_SHIFT_LEFT,OP_SHIFT_RIGHT
+ ,OP_LESS_EQ,OP_GREATER_EQ
+ ,OP_LESS,OP_GREATER
+ ,OP_EQUAL,OP_NOT_EQUAL
+ ,OP_LVALUE,OP_RVALUE
+ ,ST_COMPOUND,ST_EXPRESSION,ST_SWITCH,ST_IF,ST_WHILE,ST_DO_WHILE,ST_GOTO,ST_LABEL,ST_CASE,ST_DEFAULT
+ ,ST_CONTINUE,ST_BREAK,ST_RETURN,ST_FOR
+ ,ST_DECLARATION,ST_FUNCTION_DEFINITION
+ ,TRANSLATION_UNIT
+ ,ERROR
+ };
+
+
+
+
+ /*
+ struct AST
+ {
+ enum AST_Type type;
+
+ unsigned long value_type;
+ void *data;
+
+ struct Queue arguments;
+
+ };
+ */
+ struct AST
+ {
+ enum AST_Type type;
+ };
+ struct AST_Error
+ {
+ enum AST_Type type;
+ struct AST *error;
+ };
+ struct AST_Binary_Expression
+ {
+ enum AST_Type type;
+
+ struct Type *value_type;
+ struct AST *left;
+ struct AST *right;
+
+ };
+ struct AST_Conditional_Expression
+ {
+ enum AST_Type type;
+
+ struct Type *value_type;
+
+ struct AST *left;
+ struct AST *center;
+ struct AST *right;
+
+ };
+ struct AST_Function_Expression
+ {
+ enum AST_Type type;
+ struct Type *value_type;
+
+ struct AST *id;
+ /*queue of astrees*/
+ struct Queue arguments;
+ };
+ struct AST_Rvalue_Expression
+ {
+ enum AST_Type type;
+ struct Type *value_type;
+ struct token *id;
+ };
+ struct AST_Lvalue_Expression
+ {
+ enum AST_Type type;
+ struct Type *value_type;
+ struct token *id;
+ /*TODO*/
+ void *object;
+ };
+ struct AST_Unary_Expression
+ {
+ enum AST_Type type;
+ struct Type *value_type;
+ struct AST *operand;
+ };
+
+ struct AST_Labeled_Statement
+ {
+ enum AST_Type type;
+ struct token *label;
+ struct AST *statement;
+ struct Scope *scope;
+ };
+ struct AST_Compound_Statement
+ {
+ enum AST_Type type;
+ struct Scope *scope;
+ struct Queue components;
+ };
+
+ struct AST_For_Statement
+ {
+ enum AST_Type type;
+ struct AST *condition;
+ struct AST *initialisation;
+ struct AST *update;
+ struct AST *body_statement;
+ };
+ struct AST_While_Statement
+ {
+ enum AST_Type type;
+ struct AST *condition;
+ struct AST *body_statement;
+ };
+ struct AST_Do_While_Statement
+ {
+ enum AST_Type type;
+ struct AST *body_statement;
+ struct AST *condition;
+ };
+ struct AST_If_Statement
+ {
+ enum AST_Type type;
+ struct AST* condition;
+ struct AST* body_statement;
+ struct AST* else_statement;
+
+ };
+ struct AST_Goto_Statement
+ {
+ enum AST_Type type;
+ struct token *label;
+ };
+ struct AST_Switch_Statement
+ {
+ enum AST_Type type;
+ struct AST* condition;
+ struct AST* body_statement;
+ };
+ struct AST_Return_Statement
+ {
+ enum AST_Type type;
+ struct AST* return_expression;
+
+ };
+ struct AST_Declaration
+ {
+ enum AST_Type type;
+ struct Type_Node* base_type;
+ struct Queue declarators;
+ struct Scope *scope;
+ };
+ struct AST_Function_Definition
+ {
+ enum AST_Type type;
+ struct Type_Node *base_type;
+ struct Declarator *declarator;
+ struct AST *body_statement;
+ struct Scope *scope;
+ };
+ struct AST_Translation_Unit
+ {
+ enum AST_Type type;
+ struct Queue components;
+ struct Scope *scope;
+ };
+
+
+
+
+ struct AST_Error* get_error_tree(struct AST *error);
+ struct AST_Binary_Expression* get_binary_expression_tree(struct AST *left,struct AST *right,enum AST_Type type);
+ struct AST_Conditional_Expression* get_conditional_expression_tree(struct AST *left,struct AST *center,struct AST *right);
+ struct AST_Function_Expression* get_function_expression_tree(struct AST* id,struct Scope *scope);
+ struct AST_Unary_Expression* get_unary_expression_tree(struct AST *operand,enum AST_Type type);
+ struct AST_Rvalue_Expression* get_rvalue_expression_tree(struct token *id);
+ struct AST_Lvalue_Expression* get_lvalue_expression_tree(struct token *id,struct Scope* scope);
+ struct AST_Labeled_Statement* get_labeled_statement_tree(struct token *label,struct AST* statement,struct Scope *scope,enum AST_Type type);
+ struct AST_Compound_Statement* get_compound_statement_tree(struct Scope *parent_scope);
+ struct AST_If_Statement* get_if_statement_tree();
+ struct AST_Switch_Statement* get_switch_statement_tree();
+ struct AST_While_Statement* get_while_statement_tree();
+ struct AST_Do_While_Statement* get_do_while_statement_tree();
+ struct AST_For_Statement* get_for_statement_tree();
+ struct AST_Return_Statement* get_return_statement_tree(struct AST* return_expression);
+ struct AST_Goto_Statement* get_goto_statement_tree(struct token *label,struct Scope *scope);
+ struct AST* get_nop_tree();
+ struct AST_Declaration* get_declaration_tree(struct Scope* scope);
+ struct AST_Function_Definition* get_function_definition_tree(struct Scope *scope);
+ struct AST_Translation_Unit* get_translation_unit_tree(struct Scope* parent_scope);
+
+
+ #define BIN_EXPR_PTR(x) ((struct AST_Binary_Expression*)(x))
+ #define UN_EXPR_PTR(x) ((struct AST_Unary_Expression*)(x))
+ #define LVAL_EXPR_PTR(x) ((struct AST_Lvalue_Expression*)(x))
+ #define RVAL_EXPR_PTR(x) ((struct AST_Rvalue_Expression*)(x))
+ #define DECLR_PTR(x) ((struct AST_Declaration*)(x))
+ #define IF_ST_PTR(s) ((struct AST_If_Statement*)(x))
+
+
+
+ #endif
F diff --git a/chonky.c b/chonky.c new file mode 100644 --- /dev/null +++ b/chonky.c
+ #ifndef GKEYWORDS_MENU_C
+ #define GKEYWORDS_MENU_C GKEYWORDS_MENU_C
+
+ int cmpr[256]={0,0,0,0,0,0,0,0,0,57,57,57,0,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,57,29,30,31,0,32,33,34,37,38,41,42,44,43,45,46,28,28,28,28,28,28,28,28,28,28,47,48,49,51,50,52,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,39,53,40,54,55,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,35,56,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+ int uncmpr[256]={0,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,57,33,34,35,37,38,39,123,125,40,41,91,93,42,43,45,44,46,47,58,59,60,62,61,63,92,94,95,124,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,};
+
+
+ enum KEYWORDS{KW_AUTO,KW_DO,KW_DOUBLE,KW_INT,KW_STRUCT,KW_BREAK,KW_ELSE,KW_LONG,KW_SWITCH,KW_CASE,KW_ENUM,KW_REGISTER,KW_TYPEDEF,KW_CHAR,KW_EXTERN,KW_RETURN,KW_UNION,KW_CONST,KW_FLOAT,KW_SHORT,KW_UNSIGNED,KW_CONTINUE,KW_FOR,KW_SIGNED,KW_VOID,KW_DEFAULT,KW_GOTO,KW_SIZEOF,KW_VOLATILE,KW_IF,KW_STATIC,KW_WHILE,KW_EXCLAMATION,KW_BACK_SLASH,KW_PERCENT,KW_AND,KW_AND_AND,KW_QUOTE,KW_OPEN_NORMAL,KW_CLOSE_NORMAL,KW_STAR,KW_PLUS,KW_COMMA,KW_MINUS,KW_DOT,KW_ARROW,KW_COLUMN,KW_SEMI_COLUMN,KW_LESS,KW_EQ,KW_EQEQ,KW_MORE,KW_QUESTION,KW_OPEN_SQUARE,KW_CLOSE_SQUARE,KW_HAT,KW_FLOOR,KW_OPEN_CURLY,KW_CLOSE_CURLY,KW_PIPE,KW_PIPE_PIPE,KW_TILDE,KW_PLUSPLUS,KW_MINUSMINUS,KW_SHIFT_RIGHT,KW_SHIFT_LEFT,KW_LESS_EQ,KW_MORE_EQ,KW_NOT_EQ,KW_PLUS_EQ,KW_MINUS_EQ,KW_STAR_EQ,KW_PERCENT_EQ,KW_SHIFT_LEFT_EQ,KW_SHIFT_RIGHT_EQ,KW_AND_EQ,KW_HAT_EQ,KW_PIPE_EQ,KW_DIV_EQ,KW_FORWARD_SLASH,KW_NOTYPE,KW_NUMBER,KW_COMMENT,KW_ID,KW_STRING,PKW_IF,PKW_INCLUDE,PKW_DEFINE,PKW_UNDEF,PKW_PRAGMA,PKW_ENDIF,PKW_IFNDEF,PKW_IFDEF,PKW_ELIF,PKW_ERROR,PKW_COMMENT,PKW_NOTYPE};
+
+
+ struct automata_entry
+ {
+ unsigned char is_final;
+ enum KEYWORDS type;
+ struct automata_entry* delta[58];
+ };
+
+
+ struct automata_entry chonky[]={
+
+ {0,KW_NOTYPE,{NULL,&(chonky[2]),&(chonky[10]),&(chonky[11]),&(chonky[12]),&(chonky[13]),&(chonky[14]),&(chonky[15]),&(chonky[16]),&(chonky[2]),&(chonky[17]),&(chonky[2]),&(chonky[2]),&(chonky[18]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[19]),&(chonky[20]),&(chonky[21]),&(chonky[22]),&(chonky[23]),&(chonky[24]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[1]),&(chonky[25]),&(chonky[3]),NULL,&(chonky[26]),&(chonky[27]),&(chonky[28]),&(chonky[29]),&(chonky[30]),&(chonky[31]),&(chonky[32]),&(chonky[33]),&(chonky[34]),&(chonky[35]),&(chonky[36]),&(chonky[37]),&(chonky[38]),&(chonky[39]),&(chonky[5]),&(chonky[40]),&(chonky[41]),&(chonky[42]),&(chonky[43]),&(chonky[44]),&(chonky[45]),&(chonky[46]),&(chonky[47]),&(chonky[48]),&(chonky[49]),NULL,} },
+ {1,KW_NUMBER,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[1]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {0,KW_NOTYPE,{&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[4]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),&(chonky[3]),} },
+ {1,KW_STRING,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_FORWARD_SLASH,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[6]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[9]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,KW_NOTYPE,{&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[7]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),} },
+ {0,KW_NOTYPE,{&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[8]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),&(chonky[6]),} },
+ {1,KW_COMMENT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_DIV_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[50]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[51]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[52]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[53]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[54]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[55]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[56]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[57]),&(chonky[2]),&(chonky[58]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[59]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[60]),&(chonky[2]),&(chonky[2]),&(chonky[61]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[62]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[63]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[64]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[65]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[66]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[67]),&(chonky[68]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[69]),&(chonky[2]),&(chonky[2]),&(chonky[70]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[71]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[72]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[73]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[74]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_EXCLAMATION,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[75]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PERCENT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[76]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_AND,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[77]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[78]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_QUOTE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_OPEN_CURLY,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_CLOSE_CURLY,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_OPEN_NORMAL,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_CLOSE_NORMAL,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_OPEN_SQUARE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_CLOSE_SQUARE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_STAR,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[79]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PLUS,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[80]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[81]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_MINUS,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[82]),NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[83]),&(chonky[84]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_COMMA,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_DOT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_COLUMN,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_SEMI_COLUMN,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_LESS,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[85]),NULL,&(chonky[86]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_MORE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[87]),&(chonky[88]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[89]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_QUESTION,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_BACK_SLASH,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_HAT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[90]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_FLOOR,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_PIPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[91]),NULL,NULL,NULL,NULL,&(chonky[92]),NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[93]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[94]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[95]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[96]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[97]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[98]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_DO,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[99]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[100]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[101]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[102]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[103]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[104]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[105]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_IF,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[106]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[107]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[108]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[109]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[110]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[111]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[112]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[113]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[114]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[115]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[116]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[117]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[118]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[119]),&(chonky[2]),&(chonky[2]),&(chonky[120]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[121]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_NOT_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PERCENT_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_AND_AND,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_AND_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_STAR_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PLUSPLUS,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PLUS_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_MINUSMINUS,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_ARROW,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_MINUS_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_SHIFT_LEFT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[122]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_LESS_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_SHIFT_RIGHT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[123]),NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_MORE_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_EQEQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_HAT_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PIPE_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_PIPE_PIPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[124]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[125]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[126]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[127]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[128]),&(chonky[129]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[130]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[131]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[132]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[133]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[134]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[135]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_FOR,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[136]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_INT,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[137]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[138]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[139]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[140]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[141]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[142]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[143]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[144]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[145]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[146]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[147]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[148]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[149]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[150]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[151]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_SHIFT_LEFT_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_SHIFT_RIGHT_EQ,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,KW_AUTO,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[152]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_CASE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_CHAR,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[153]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[154]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[155]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[156]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ELSE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ENUM,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[157]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[158]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_GOTO,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_LONG,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[159]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[160]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[161]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[162]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[163]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[164]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[165]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[166]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[167]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[168]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[169]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_VOID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[170]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[171]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_BREAK,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_CONST,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[172]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[173]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[174]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[175]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_FLOAT,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[176]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[177]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_SHORT,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[178]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[179]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[180]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[181]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[182]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[183]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_UNION,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[184]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[185]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_WHILE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[186]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[187]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_DOUBLE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_EXTERN,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[188]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_RETURN,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_SIGNED,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_SIZEOF,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_STATIC,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_STRUCT,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_SWITCH,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[189]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[190]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[191]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[192]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_DEFAULT,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[193]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_TYPEDEF,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[194]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_ID,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[195]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_CONTINUE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_REGISTER,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_UNSIGNED,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },
+ {1,KW_VOLATILE,{NULL,&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),&(chonky[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky[2]),NULL,NULL,} },};
+
+ #endif /*#ifndef GKEYWORDS_MENU_C*/
F diff --git a/chonky_jr.c b/chonky_jr.c new file mode 100644 --- /dev/null +++ b/chonky_jr.c
+ #ifndef GPREPROCESSING_KEYWORDS_MENU_C
+ #define GPREPROCESSING_KEYWORDS_MENU_C GPREPROCESSING_KEYWORDS_MENU_C
+ #include"chonky.c"
+
+
+ struct automata_entry chonky_jr[]={
+
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[5]),&(chonky_jr[6]),NULL,NULL,NULL,&(chonky_jr[7]),NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[8]),NULL,NULL,NULL,NULL,&(chonky_jr[9]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[1]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[2]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[3]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),} },
+ {0,PKW_NOTYPE,{&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[4]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),&(chonky_jr[2]),} },
+ {1,PKW_COMMENT,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[10]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[11]),NULL,&(chonky_jr[12]),NULL,NULL,NULL,&(chonky_jr[13]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[14]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[15]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[16]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[17]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[18]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[19]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[20]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[21]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_IF,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[22]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[23]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,&(chonky_jr[24]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,&(chonky_jr[25]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[26]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[27]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[28]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[29]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[30]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[31]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[32]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[33]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[34]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[35]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[36]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_ELIF,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[37]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[38]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[39]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[40]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[41]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[42]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[43]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[44]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_ENDIF,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_ERROR,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_IFDEF,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[45]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,&(chonky_jr[46]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,&(chonky_jr[47]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_UNDEF,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_DEFINE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_IFNDEF,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {0,PKW_NOTYPE,{NULL,NULL,NULL,NULL,NULL,NULL,&(chonky_jr[48]),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_PRAGMA,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },
+ {1,PKW_INCLUDE,{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,} },};
+
+ #endif /*#ifndef GPREPROCESSING_KEYWORDS_MENU_C*/
F diff --git a/compile.c b/compile.c new file mode 100644 --- /dev/null +++ b/compile.c
+ #ifndef GCC_COMPILE_C
+ #define GCC_COMPILE_C GCC_COMPILE_C
+
+ #endif
F diff --git a/context.c b/context.c new file mode 100644 --- /dev/null +++ b/context.c
+ #ifndef GCC_CONTEXT
+ #define GCC_CONTEXT GCC_CONTEXT
+ #include"map.c"
+ #include<assert.h>
+
+
+ struct Scope
+ {
+ unsigned used_types;
+ unsigned used_vars;
+ Map *types;
+ Map *variables;
+ }
+
+ /*use a different function for global scope*/
+ struct Scope get_scope(struct Scope *upper_scope)
+ {
+ struct Scope ret;
+ assert(upper_scope==NULL);
+
+ ret.used_types=upper_scope->used_types;
+ ret.used_vars=upper_scope->used_vars;
+
+ ret.types=upper_scope->types;
+ ret.variables=upper_scope->variables;
+
+ return ret;
+ }
+
+
+ #endif
F diff --git a/lexer.c b/lexer.c new file mode 100644 --- /dev/null +++ b/lexer.c
+ #ifndef LEXER_C
+ #define LEXER_C LEXER_C
+ #include "lexer.h"
+
+
+
+ struct Queue* lex(struct Source_File *src,struct Program *prog)
+ {
+
+
+ struct token *current_token;
+ struct Queue *tokens;
+
+ tokens=malloc(sizeof(struct Queue));
+ Queue_Init(tokens);
+ while(src->src[src->where_in_src]!='\0')
+ {
+ /*ignore leading spaces and tabs and check for double slash comment*/
+ while(src->src[src->where_in_src]==' ' || src->src[src->where_in_src]=='\n' || src->src[src->where_in_src]=='\t')
+ {
+ if(src->src[src->where_in_src]=='\n')
+ {
+ src->which_column=0;
+ ++src->which_row;
+ }else if(src->src[src->where_in_src]=='\t')
+ {
+ src->which_row+=5;
+ }
+ ++src->where_in_src;
+ }
+ if(src->src[src->where_in_src]=='\0')
+ break;
+
+ if(src->which_column==0 && src->src[src->where_in_src]=='#')
+ {
+ /*todo preprocesing*/
+ ++src->where_in_src;
+ ++src->which_column;
+ do_preproc_stuff(src,prog);
+ }else
+ {
+ current_token=get_next_token(src,prog,&chonky[0]);
+ Queue_Push(tokens,current_token);
+ }
+ }
+
+
+ return tokens;
+
+ }
+
+ /*we have skipped the leading #*/
+ /*
+ #include string
+ #include <qchar>
+ #define [ id(list) replacement
+ #line number [string]
+ #if
+ #ifdef
+ #ifndef
+ #pragma
+ #error
+ #
+
+ these should be seperated from the ifs
+ #elif
+ #else
+ #endif
+
+
+ */
+ void do_preproc_stuff(struct Source_File *src,struct Program *prog)
+ {
+ struct token *hold;
+ hold=get_next_token(src,prog,&chonky_jr[0]);
+ switch(hold->type)
+ {
+ case PKW_INCLUDE:
+ free(hold);
+ do_include_stuff(src,prog);
+ return;
+ case PKW_DEFINE:
+ free(hold);
+ do_define_stuff(src,prog);
+
+
+ default:
+ return;
+ /*TODO error*/
+
+ }
+ }
+
+ void do_include_stuff(struct Source_File *src,struct Program *prog)
+ {
+ struct token *hold;
+ hold=get_next_token(src,prog,&chonky[0]);
+ if(hold->type==KW_STRING)
+ {
+ hold->data[hold->data_size-1]='\0';
+ hold->data_size-=2;
+ ++hold->data;
+ handle_splicing(hold);
+ lex_program(hold->data,prog);
+ free(hold);
+ }else if(hold->type==KW_LESS)/*hack*/
+ {
+ ++hold->data;
+ while(src->src[src->where_in_src]!='>')
+ {
+ ++src->where_in_src;
+ ++hold->data_size;
+ }
+ /*skip the >*/
+ ++src->where_in_src;
+ hold->data[hold->data_size-1]='\0';
+ handle_splicing(hold);
+
+ lex_program(hold->data,prog);
+ free(hold);
+
+ }else
+ {
+ /*TODO error*/
+ return;
+ }
+ }
+ struct define_directive* get_define_directive(struct token* macro_name)
+ {
+ struct define_directive* ret;
+ ret=malloc(sizeof(struct define_directive));
+ ret->macro_name=macro_name;
+
+ Queue_Init(&ret->replacement_list);
+ Queue_Init(&ret->id_list);
+ ret->number_of_arguments=0;
+ Map_Init(&ret->arguments);
+ return ret;
+ }
+ /*
+ id[(list)] tokens \n
+ */
+ void do_define_stuff(struct Source_File *src,struct Program *prog)
+ {
+ struct token *hold;
+ struct define_directive *macro;
+ hold=get_next_token(src,prog,&chonky[0]);
+ if(hold->type==KW_ID)
+ {
+ macro=get_define_directive(hold);
+ Map_Push(&prog->defines,hold->data,hold->data_size,macro);
+ hold=get_next_token(src,prog,&chonky[0]);
+ }else
+ {
+ /*TODO error*/
+ return;
+ }
+ }
+
+
+
+ /*hack*/
+ void handle_splicing(struct token *word)
+ {
+ size_t back;
+ size_t front;
+ front=0;
+ for(front;front<word->data_size-1;++front)
+ {
+ if(word->data[front]=='\\' && word->data[front+1]=='\n')
+ {
+ front+=2;
+ break;
+ }
+ }
+ if(front==word->data_size-1)
+ return;
+
+ for(back=front-2;front<word->data_size-1;)
+ {
+ if(word->data[front]=='\\' && word->data[front+1]=='\n')
+ {
+ front+=2;
+ }else
+ {
+ word->data[back]=word->data[front];
+ ++front;
+ ++back;
+ }
+ }
+ word->data[back]=word->data[front];
+ }
+ struct token_vector Lex_Queue_Condense(struct Queue *tokens)
+ {
+ size_t i;
+ struct token_vector ret;
+ struct token *hold;
+
+ ret.tokens=malloc(sizeof(struct token)*tokens->size);
+ ret.size=tokens->size;
+
+ for(i=0;tokens->size>0;++i)
+ {
+ hold=Queue_Pop(tokens);
+ ret.tokens[i]=*hold;
+ free(hold);
+ }
+
+ Queue_Destroy(tokens);
+
+ return ret;
+ }
+
+ char check(struct Queue *tokens,enum KEYWORDS kw,size_t ahead)
+ {
+ size_t i;
+ struct Queue_Node *current;
+ if(tokens->size<=ahead)
+ {
+ return 0;
+ }else
+ {
+ for(i=0,current=tokens->first;i<ahead;++i,current=current->prev);
+
+ if( ((struct token*)(current->data))->type == kw )
+ {
+ return 1;
+ }else
+ {
+ return 0;
+ }
+ }
+ }
+ char get_and_check(struct Queue *tokens,enum KEYWORDS kw)
+ {
+ struct token *hold_token;
+ if(tokens->size==0)
+ {
+ return 0;
+ }else
+ {
+ hold_token=tokens->first->data;
+ if(hold_token->type!=kw)
+ {
+ return 0;
+ }else
+ {
+ hold_token=Queue_Pop(tokens);
+ free(hold_token);
+ return 1;
+ }
+ }
+ }
+ char get_and_check_unsafe(struct Queue *tokens,enum KEYWORDS kw)
+ {
+ struct token *hold_token;
+ hold_token=tokens->first->data;
+ if(hold_token->type!=kw)
+ {
+ return 0;
+ }else
+ {
+ hold_token=Queue_Pop(tokens);
+ free(hold_token);
+ return 1;
+ }
+ }
+ void chomp(struct Queue *tokens)
+ {
+ free(Queue_Pop(tokens));
+ }
+
+ enum KEYWORDS kw_get(struct Queue *tokens)
+ {
+ if(tokens->size==0)
+ return KW_NOTYPE;
+ return ((struct token*)(tokens->first->data))->type;
+
+ }
+
+ struct token* get_next_token(struct Source_File *src,struct Program *prog,struct automata_entry *start_state)
+ {
+ int temp;
+ size_t current_size;
+
+ struct token *ret;
+ struct automata_entry *current_state;
+ struct automata_entry *best_state;
+
+ current_size=0;
+ best_state=current_state=start_state;
+
+ /*check for double slash comment*/
+ if(src->where_in_src<src->src_size-1 && src->src[src->where_in_src]=='/' && src->src[src->where_in_src+1]=='/')
+ {
+ ret=malloc(sizeof(struct token));
+ ret->type=KW_COMMENT;
+ ret->data=src->src + src->where_in_src;
+ src->where_in_src+=2;
+ while(src->where_in_src!=src->src_size && src->src[src->where_in_src]!='\n')
+ {
+ if(src->where_in_src<src->src_size-1 && src->src[src->where_in_src]=='\\' && src->src[src->where_in_src+1]=='\n')
+ {
+ src->where_in_src+=2;
+ }else
+ {
+ ++src->where_in_src;
+ }
+ }
+
+ }
+
+ while(src->src[src->where_in_src]!='\0')
+ {
+
+ if(src->where_in_src<src->src_size-1 && src->src[src->where_in_src]=='\\' && src->src[src->where_in_src+1]=='\n')
+ {
+ src->where_in_src+=2;
+ current_size+=2;
+ }
+
+ current_state=current_state->delta[cmpr[src->src[src->where_in_src]]];
+ if(current_state==NULL)
+ {
+ if(best_state->type==KW_COMMENT || best_state->type==PKW_COMMENT)
+ {
+ current_size=0;
+ best_state=current_state=start_state;
+ }else
+ {
+ ret=malloc(sizeof(struct token));
+ ret->type=best_state->type;
+ ret->data_size=current_size;
+ ret->column=src->which_column;
+ ret->line=src->which_row;
+ ret->data=src->src+(src->where_in_src-current_size);
+ handle_splicing(ret);
+ return ret;
+ }
+
+ }else
+ {
+ if(current_state->is_final)
+ {
+ best_state=current_state;
+ }
+ ++current_size;
+ ++src->where_in_src;
+ ++src->which_column;
+ }
+ }
+ ret=malloc(sizeof(struct token));
+ ret->type=KW_NOTYPE;
+ return ret;
+ }
+ #endif
F diff --git a/lexer.h b/lexer.h new file mode 100644 --- /dev/null +++ b/lexer.h
+ #ifndef LEXER_H
+ #define LEXER_H LEXER_H
+ #include<stdio.h>
+ #include"chonky.c"
+ #include"chonky_jr.c"
+ #include"queue.c"
+ #include "program.h"
+
+ struct token
+ {
+ enum KEYWORDS type;
+ size_t data_size;
+ char *data;
+ size_t line,column;
+ };
+
+ struct token_vector
+ {
+ struct token *tokens;
+ size_t size;
+ };
+
+ struct define_directive
+ {
+ struct token *macro_name;
+ struct Queue replacement_list;
+ /*the tokens of the macro (contains a special token)*/
+ struct Queue id_list;
+
+ struct Map arguments;
+ size_t number_of_arguments;
+ /*put arguments here*/
+ struct token **argument_list;
+ };
+
+ struct Queue* lex(struct Source_File *src,struct Program *prog);
+ struct token* get_next_token(struct Source_File *src,struct Program *prog,struct automata_entry *start_state);
+ struct token_vector Lex_Queue_Condense(struct Queue *tokens);
+ char check(struct Queue *tokens,enum KEYWORDS kw,size_t ahead);
+ char get_and_check(struct Queue *tokens,enum KEYWORDS kw);
+ char get_and_check_unsafe(struct Queue *tokens,enum KEYWORDS kw);
+ void chomp(struct Queue *tokens);
+ enum KEYWORDS kw_get(struct Queue *tokens);
+
+
+ /*I know, i know*/
+ void do_preproc_stuff(struct Source_File *src,struct Program *prog);
+ void do_include_stuff(struct Source_File *src,struct Program *prog);
+ void do_define_stuff(struct Source_File *src,struct Program *prog);
+ void handle_splicing(struct token *word);
+ struct define_directive* get_define_directive(struct token* macro_name);
+ #endif
F diff --git a/main.c b/main.c new file mode 100644 --- /dev/null +++ b/main.c
+ #include<stdio.h>
+ #include<stdlib.h>
+ #include "all.h"
+
+
+
+
+ int id(int a)
+ {
+ return a;
+ }
+ int (*test(int (*a)(int)))(int)
+ {
+ return a;
+ }
+
+ int main(int argc,char **argv)
+ {
+ /*
+ int (*k)(int a,char** b)=main;
+ FILE *in;
+ char *src;
+ struct Queue tokens;
+ struct AST* test_expression;
+ struct AST* test_declaration;
+ struct AST* test_translation_unit;
+ struct Type* test_typename;
+ struct Scope *global_scope;
+ const const const volatile typedef const int const volatile * const index;
+ int typedef kek;
+
+ //printf("%i",test(id)(1));
+
+ in=fopen(argv[1],"r");
+ if(in==NULL)
+ {
+ return -1;
+ }
+ src=get_src(in);
+
+ tokens=lex(src);
+ // print_tokens(stdout,&tokens);
+ // printf("\n---------------------------\n");
+
+ global_scope=get_scope(NULL);
+ test_translation_unit=parse_translation_unit(&tokens,global_scope);
+ print_ast(stdout,(struct AST*)test_translation_unit);
+ // test_typename=parse_type_name(&tokens);
+ // test_expression=parse_statement(&tokens);
+ // print_expression(test_expression,stdout,0);
+
+ */
+ if(argv[1]==NULL)
+ {
+ printf("Give me a file!\n");
+ return -1;
+ }
+ struct Program *program;
+ program=get_program();
+ lex_program(argv[1],program);
+ print_program_tokens(stdout,program);
+ parse_program(program);
+ print_program_ast(stdout,program);
+
+
+
+ return 0;
+ }
+
+
+
+ /*
+
+ int const index=111+222;
+ kek test;
+ if(1)
+ {
+ while(2)
+ {
+ (kek)-1+2;
+ }
+ 1?a,b:1?2:3*1;
+ }else
+ {
+ do
+ {
+ {
+ --a;
+ }
+ }while(a>b?1:0);
+ for(;;);
+ switch(a)
+ {
+ case b:
+ return 0;
+ break;
+ default:
+ return 1;
+ return a=b=c=a->b->c->d;
+ }
+ goto error;
+ }
+ */
F diff --git a/makefile b/makefile new file mode 100644 --- /dev/null +++ b/makefile
+ install:
+ gcc -g main.c -o main.exe
+ run: install
+ ./main.exe
+ clear:
+ rm ./*.exe &
+ rm ./*.temp &
+ rm ./*.out
+ debug:
+ gcc -g main.c
+ gdbtui a.out
+ rm: run
+ rn: run
+ fuzz: install
+ fuzz ./main.exe
F diff --git a/map.c b/map.c new file mode 100644 --- /dev/null +++ b/map.c
+ #ifndef GMAP
+ #define GMAP GMAP
+ #include<stdlib.h>
+ #include<stdio.h>
+ #include"stack.c"
+ #include"queue.c"
+ //#include"../Queue/unique_queue.c"
+
+
+ typedef struct Map Map;
+
+
+ void Map_Init(Map *tree);
+ void Map_Scour(Map *tree,void *str,size_t size,size_t *where,Map **final_node);
+ void Map_Push(Map *tree,void *str,size_t size,void *id);
+ void* Map_Check(Map *tree, void *str,size_t size);
+ void Map_Remove(Map *tree, void *str,size_t size);
+ void Map_Map(Map *tree,void (*map)(void*));
+ void Map_Destroy(Map *tree);
+ struct Condensed_Map* Map_Condense(Map* tree);
+
+
+ /*
+ * A looples automata with things attached to the nodes
+ * */
+ struct Map
+ {
+ char is_final;
+ Map *delta[256];
+ /*ID cannot point to itself ( this is used in the deletion of the map ) */
+ void *ID; //I have integer ids in mind but can be a translation for exmpl.
+ };
+
+
+ /*
+ * ID and residue and all of delta is assigned to NULL
+ * */
+ void Map_Init(Map *tree)
+ {
+ tree->is_final=0;
+ for(int i=0;i<256;++i)tree->delta[i] = NULL;
+ tree->ID = NULL;
+ }
+
+ void Map_Scour(Map *tree,void *str,size_t size,size_t *where,Map **final_node)
+ {
+ for(where[0]=0,final_node[0]=tree;where[0]<size && final_node[0]->delta[((unsigned char*)str)[ where[0] ]]!=NULL;++where[0])
+ {
+ (*final_node) = (*final_node)->delta[((unsigned char*)str)[*where]];
+ }
+ }
+
+
+
+ /*
+ * tree must not be null
+ * */
+ void Map_Push(Map *tree,void *str,size_t size,void *id)
+ {
+ size_t temp;
+ Map_Scour(tree,str,size,&temp,&tree);
+
+ if(temp == size)
+ {
+ if(tree->ID!=NULL)tree->ID=id;
+ tree->is_final=1;
+ return;
+ }
+ for(temp;temp<size;++temp)
+ {
+ Map_Init(tree=tree->delta[((unsigned char*)str)[temp]]=malloc(sizeof(Map)));
+ }
+
+ tree->ID=id;
+ tree->is_final=1;
+
+ }
+
+
+ /*
+ * scours the tree and returns the id of the node that recognises the str
+ * returns NULL if the string is not recognised
+ * */
+ void* Map_Check(Map *tree, void *str,size_t size)
+ {
+ size_t temp;
+ Map_Scour(tree,str,size,&temp,&tree);
+
+ if(temp<size)
+ {
+ return NULL;
+ }else
+ {
+ return tree->ID; //this has been set to be the last reached node
+ }
+ }
+
+ void Map_Remove(Map *tree, void *str,size_t size)
+ {
+ Stack stk;
+ Stack_Init(&stk);
+ size_t where;
+ char what_to_null=((char*)str)[0];
+
+ Stack_Push(&stk,tree);
+
+ for(where=0;where<size-1 && tree->delta[((unsigned char*)str)[where]]!=NULL;++where)
+ {
+ tree = tree->delta[((unsigned char*)str)[where]];
+ if(tree->is_final==1)
+ {
+ while(stk.size>0)Stack_Pop(&stk);
+ what_to_null=((char*)str)[where+1];
+ }
+ Stack_Push(&stk,tree);
+ }
+ if(tree->delta[((unsigned char*)str)[where]] == NULL)return;
+ free(tree->delta[((unsigned char*)str)[where]]);
+ while(stk.size>1)free(Stack_Pop(&stk));
+ tree=(Map*)Stack_Pop(&stk);
+ tree->delta[(unsigned char)what_to_null]=NULL;
+
+ }
+ /*This function especially requires that the map has no loops*/
+ void Map_Map(Map *tree,void (*map)(void*))
+ {
+ if(tree->is_final==1)map(tree->ID);
+ for(int i=0;i<256;++i)
+ {
+ if(tree->delta[i]!=NULL)
+ {
+ Map_Map(tree->delta[i],map);
+ }
+ }
+ }
+
+
+
+ /*this does not destroy(free) any memory pointed to by a node in the Map. This does not free() the root (Map *tree) */
+ /*This function especially does not require that the map has no loop ( for example after grepification )*/
+ void Map_Destroy(Map *tree)
+ {
+ Stack path;
+ Stack nodes;
+ Map *current_node;
+ unsigned int i;
+
+
+ Stack_Init(&path);
+ Stack_Init(&nodes);
+
+ Stack_Push(&path,tree);
+ Stack_Push(&nodes,tree);
+
+ /*
+ using DFS we fill up the nodes stack with all the used
+ (accessible) nodes.
+ */
+ while(path.size>0)
+ {
+ current_node=Stack_Pop(&path);
+ current_node->ID=&(current_node->ID);/*mark the node*/
+ for(i=0;i<256;++i)
+ {
+ if(current_node->delta[i]!=NULL && current_node->delta[i]->ID != &(current_node->delta[i]->ID) )
+ {
+ Stack_Push(&path,current_node->delta[i]);
+
+
+ /*we mark the unmarked child of the current_node*/
+ current_node->delta[i]->ID=&(current_node->delta[i]->ID);
+ /*every node in nodes continues to be marked*/
+ Stack_Push(&nodes,current_node->delta[i]);
+ }
+ }
+
+ }
+ /*
+ There should not be any duplicates in here
+ */
+ while(nodes.size>1)
+ {
+ current_node=Stack_Pop(&nodes);
+ /*Again the things that ID points to is not freed ( this structure is used to map the structure of data )
+ deletion of it is up to you.
+ */
+ free(current_node);
+ }
+
+
+ }
+
+ /*this isn't c++ i promise :)*/
+ /*requres that cpy has no loops*/
+ Map* Map_Copy(Map *cpy)
+ {
+ short i;
+ Map *ret;
+
+ if(cpy==NULL)
+ {
+ return NULL;
+ }
+
+ ret=malloc(sizeof(Map));
+ ret->is_final=cpy->is_final;
+ ret->ID=cpy->ID;
+
+ for(i=0;i<256;++i)
+ {
+ ret->delta[i]=Map_Copy(cpy->delta[i]);
+ }
+ return ret;
+ }
+
+
+ #endif //#ifndef GMAP
F diff --git a/parse.c b/parse.c new file mode 100644 --- /dev/null +++ b/parse.c
+ #ifndef GCC_PARSE_C
+ #define GCC_PARSE_C GCC_PARSE_C
+
+ #include "parse_expression.h"
+ #include "parse_statement.h"
+ #include "parse_declaration.h"
+ #include "parse_translation_unit.h"
+
+
+ #include "parse_expression.c"
+ #include "parse_statement.c"
+ #include "parse_declaration.c"
+ #include "parse_translation_unit.c"
+
+
+
+
+ #endif
F diff --git a/parse_declaration.c b/parse_declaration.c new file mode 100644 --- /dev/null +++ b/parse_declaration.c
+ #ifndef GCC_PARSE_DECLARATION_CCOMMA
+ #define GCC_PARSE_DECLARATION_C GCC_PARSE_DECLARATION_C
+ #include"parse_declaration.h"
+
+
+
+
+ /*
+ declaration-specifiers:
+ storage-class-specifier [ declaration-specifiers ]
+ type-specifier [ declaration-specifiers ]
+ type-qualifier [ declaration-specifiers ]
+ function-spedifier [ declaration-specifiers ]
+ alignment-specifier [ declaration-specifiers ]
+
+ */
+ struct Type_Node* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope)
+ {
+ struct Type_Node *base;
+ struct Type *hold_type;
+ struct Type_Node *hold;
+ enum KEYWORDS kw;
+ base=get_node();
+
+ for(kw=kw_get(tokens);tokens->size>0;chomp(tokens),kw=kw_get(tokens))
+ {
+ switch(kw)
+ {
+ case KW_CONST:
+ base->is_const=1;
+ break;
+ case KW_VOLATILE:
+ base->is_volatile=1;
+ break;
+ case KW_STATIC:
+ base->is_static=1;
+ break;
+ case KW_EXTERN:
+ base->is_extern=1;
+ break;
+ case KW_INT:
+ if(base->type_specifier!=TS_NONE)
+ {
+ base->error=1;
+ return base;
+ }
+ base->type_specifier=TS_INT;
+ break;
+ case KW_CHAR:
+ if(base->type_specifier!=TS_NONE)
+ {
+ base->error=1;
+ return base;
+ }
+ base->type_specifier=TS_CHAR;
+ break;
+ case KW_VOID:
+ if(base->type_specifier!=TS_NONE)
+ {
+ base->error=1;
+ return base;
+ }
+ base->type_specifier=TS_VOID;
+ break;
+ case KW_DOUBLE:
+ if(base->type_specifier!=TS_NONE)
+ {
+ base->error=1;
+ return base;
+ }
+ base->type_specifier=TS_DOUBLE;
+ break;
+ case KW_FLOAT:
+ if(base->type_specifier!=TS_NONE)
+ {
+ base->error=1;
+ return base;
+ }
+ base->type_specifier=TS_FLOAT;
+ break;
+ case KW_UNION:
+ case KW_STRUCT:
+ if(check(tokens,KW_ID,1) )
+ {
+ /*this struct might already have been defined*/
+
+ hold_type=check_tag(scope,tokens->first->prev->data);
+ if(hold_type!=NULL)
+ {
+ return check_first_type_component(hold_type);
+ }
+ hold=parse_struct_union_specifier(tokens,scope);
+ merge_type_nodes(base,hold);
+ return base;
+
+ }else if(check(tokens,KW_OPEN_CURLY,1))
+ {
+ /*this is a definition of an anonymous struct*/
+ hold=parse_struct_union_specifier(tokens,scope);
+ merge_type_nodes(base,hold);
+ return base;
+ }else
+ {
+ base->error=1;
+ return base;
+ }
+ case KW_TYPEDEF:
+ base->is_typedef=1;
+ break;
+ case KW_ID:
+ if(base->type_specifier==TS_NONE && check_if_typedefed(scope,tokens->first->data))
+ {
+ base->type_def=check_ordinary(scope,tokens->first->data);
+ merge_type_nodes(base,check_base_type_component(base->type_def));
+ break;
+ }else
+ {
+ return base;
+ }
+ default:
+ return base;
+ }
+ }
+ }
+
+
+
+ /*
+ pointer:
+ * type-qualifier-list&lt;opt&gt;
+ * type-qualifier-list&lt;opt&gt; pointer
+ */
+ void parse_pointer(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)
+ {
+ struct Type_Node *temp;
+ while(get_and_check(tokens,KW_STAR))
+ {
+ temp=parse_declaration_specifiers(tokens,scope);
+ Queue_Push_Front(&(upper->type->components),temp);
+ if(temp->type_specifier!=TS_NONE || temp->is_extern!=0 || temp->is_static!=0 || temp->is_signed!=0)
+ {
+ /*TODO error*/
+ temp->error=1;
+ upper->initialiser=(struct AST*)get_error_tree(NULL);
+ return;
+ }else
+ {
+ temp->type_specifier=TS_POINTER;
+ }
+ }
+ }
+
+ /*
+ paramenter-list:
+ parameter-declaration
+ parameter-list, prameter-declaration
+ */
+ void parse_parameter_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)
+ {
+ assert(function_base->type_specifier==TS_FUNC);
+ do
+ {
+ parse_parameter_declaration(tokens,function_base,scope);
+ }while(get_and_check(tokens,KW_COMMA));
+
+ }
+ /*
+ ?
+ parameter-type-list
+ parameter-list , ...
+ */
+ void parse_parameter_type_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)
+ {
+ parse_parameter_list(tokens,function_base,scope);
+ }
+ struct AST* parse_initialiser(struct Queue *tokens,struct Scope *scope)
+ {
+ return parse_assignment_expression(tokens,scope);
+ }
+ /*
+ init-declarator:
+ declarator = initialiser
+ */
+ struct Declarator* parse_init_declarator(struct Queue *tokens,struct Type_Node *base,struct Scope *scope)
+ {
+ struct Declarator *ret;
+ ret=get_declarator(base);
+ parse_declarator(tokens,ret,scope);
+ if(get_and_check(tokens,KW_EQ))
+ {
+ ret->initialiser=parse_initialiser(tokens,scope);
+ }
+ return ret;
+ }
+ /*
+ declarator:
+ pointer
+ [ pointer ] direct-declarator
+ */
+ void parse_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)
+ {
+ parse_pointer(tokens,base,scope);
+ parse_direct_declarator(tokens,base,scope);
+ }
+
+ /*
+ direct-declarator-finish:
+ ( direct-declarator-finish-step )*
+ */
+ void parse_direct_declarator_finish(struct Queue *tokens,struct Type *upper,struct Scope *scope)
+ {
+ while(parse_direct_declarator_finish_step(tokens,upper,scope));
+ upper->size=size_of(upper);
+ }
+
+ /*
+ direct-declarator-finish-step:
+ \[ constant-expression \]
+ \[ \]
+ \[ * \]
+ \( parameter-type-list \)
+ */
+ char parse_direct_declarator_finish_step(struct Queue *tokens,struct Type *upper,struct Scope *scope)
+ {
+ struct Type_Node *temp;
+ if(get_and_check(tokens,KW_OPEN_SQUARE))
+ {
+ temp=get_node();
+ temp->type_specifier=TS_ARRAY;
+ temp->type_constraints=TC_NONE;
+ temp->specifics.arr.number_of_elements_expr=NULL;
+
+ if(get_and_check(tokens,KW_CLOSE_SQUARE))
+ {
+ Queue_Push_Front(&upper->components,temp);
+ return 1;
+ }
+ if(check(tokens,KW_STAR,0) && check(tokens,KW_CLOSE_SQUARE,1))
+ {
+ chomp(tokens);
+ chomp(tokens);
+ Queue_Push_Front(&upper->components,temp);
+ return 1;
+ }
+ temp->specifics.arr.number_of_elements=evaluate_const_expression_integer(
+ temp->specifics.arr.number_of_elements_expr=parse_const_expression(tokens,scope)
+ );
+
+ if(!get_and_check(tokens,KW_CLOSE_SQUARE) || temp->specifics.arr.number_of_elements_expr<=0)
+ {
+ temp->error=1;
+ Queue_Push_Front(&upper->components,temp);
+ return 0;
+ }
+ Queue_Push_Front(&upper->components,temp);
+ return 1;
+ }else if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ temp=get_node();
+ temp->type_specifier=TS_FUNC;
+ temp->type_constraints=TC_NONE;
+ Queue_Init(&temp->specifics.arg_types);
+
+ parse_parameter_list(tokens,temp,scope);
+
+
+ if(!get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ temp->error=1;
+ Queue_Push_Front(&upper->components,temp);
+ return 0;
+ }
+ Queue_Push_Front(&upper->components,temp);
+ return 1;
+ }else
+ {
+ return 0;
+ }
+ }
+
+
+ /*
+ direct-declarator:
+ id direct-declarator-finish
+ ( declarator ) direct-declarator-finish
+ */
+ void parse_direct_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)
+ {
+ struct Type_Node *temp;
+ struct Type *hold_type;
+ struct Type *swap_type;
+
+ if(check(tokens,KW_ID,0))
+ {
+ upper->id=Queue_Pop(tokens);
+ parse_direct_declarator_finish(tokens,upper->type,scope);
+ }else if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+
+ hold_type=upper->type;
+
+ upper->type=malloc(sizeof(struct Type));
+ Queue_Init(&(upper->type->components));
+ parse_declarator(tokens,upper,scope);
+
+ swap_type=hold_type;
+ hold_type=upper->type;
+ upper->type=swap_type;
+
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ parse_direct_declarator_finish(tokens,upper->type,scope);
+ Queue_Append(&hold_type->components,&upper->type->components);
+
+ free(upper->type);
+
+ upper->type=hold_type;
+ }else
+ {
+ /*error*/
+ temp=malloc(sizeof(struct Type_Node));
+ temp->type_specifier=TS_ERROR;
+ temp->error=1;
+ Queue_Push_Front(&hold_type->components,temp);
+
+ Queue_Append(&hold_type->components,&upper->type->components);
+
+ free(upper->type);
+
+ upper->type=hold_type;
+ }
+ }else
+ {
+ temp=malloc(sizeof(struct Type_Node));
+ temp->type_specifier=TS_ERROR;
+ temp->error=1;
+ Queue_Push_Front(&upper->type->components,temp);
+ }
+ }
+
+
+ /*
+ delcaration:
+ declaration-specifiers [ init-declarator-list ] ;
+ */
+
+ struct AST* parse_declaration(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST_Declaration *ret;
+ struct Declarator *hold;
+ ret=get_declaration_tree(scope);
+ ret->base_type=parse_declaration_specifiers(tokens,scope);
+
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return (struct AST*)ret;
+ }
+ do
+ {
+ hold=parse_init_declarator(tokens,ret->base_type,scope);
+ Queue_Push(&ret->declarators,hold);
+ if(hold->id==NULL || !Scope_Push(scope,hold))
+ return (struct AST*)get_error_tree((struct AST*)ret);
+
+ }while(get_and_check(tokens,KW_COMMA));
+
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+
+
+ }
+ /*
+ abstract-declarator:
+ pointer
+ [ pointer ] direct-abstract-declarator
+ */
+ void parse_abstract_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)
+ {
+ parse_pointer(tokens,base,scope);
+ parse_direct_abstract_declarator(tokens,base,scope);
+ }
+ /*
+
+ direct-abstract-declarator:
+ direct-declarator-finish
+ ( abstract-declarator ) direct-declarator-finish
+ */
+ void parse_direct_abstract_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope)
+ {
+ struct Type_Node *temp;
+ struct Type *hold_type;
+ struct Type *swap_type;
+
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+
+ hold_type=upper->type;
+
+ upper->type=malloc(sizeof(struct Type));
+ Queue_Init(&(upper->type->components));
+ parse_abstract_declarator(tokens,upper,scope);
+
+ swap_type=hold_type;
+ hold_type=upper->type;
+ upper->type=swap_type;
+
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ parse_direct_declarator_finish(tokens,upper->type,scope);
+ Queue_Append(&hold_type->components,&upper->type->components);
+
+ free(upper->type);
+
+ upper->type=hold_type;
+ }else
+ {
+ /*error*/
+ temp=malloc(sizeof(struct Type_Node));
+ temp->type_specifier=TS_ERROR;
+ temp->error=1;
+ Queue_Push_Front(&hold_type->components,temp);
+
+ Queue_Append(&hold_type->components,&upper->type->components);
+
+ free(upper->type);
+
+ upper->type=hold_type;
+ }
+ }else
+ {
+ parse_direct_declarator_finish(tokens,upper->type,scope);
+ }
+ }
+ /*
+ declaration-specifiers declarator
+ declaration-specifiers [ abstract declaration ]
+ */
+ void parse_parameter_declaration(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope)
+ {
+ struct Type_Node *base;
+ struct Declarator *hold;
+ assert(function_base->type_specifier==TS_FUNC);
+ base=parse_declaration_specifiers(tokens,scope);
+ hold=get_declarator(base);
+ parse_declarator(tokens,hold,scope);
+ Queue_Push(&function_base->specifics.arg_types,hold);
+ }
+ struct Type_Node* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope)
+ {
+ struct Type_Node *ret;
+ ret=parse_declaration_specifiers(tokens,scope);
+ if(ret->type_specifier==TS_NONE || ret->is_extern==1 || ret->is_static==1 || ret->is_signed==1)
+ {
+ ret->error=1;
+ }
+ return ret;
+ }
+ /*
+ type-name:
+ specifier-qualifier-list abstract-declarator;
+
+ */
+ struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope)
+ {
+ struct Declarator *declarator;
+ struct Type *ret;
+ struct Type_Node *base;
+
+ declarator=malloc(sizeof(struct Declarator));
+ declarator->type=malloc(sizeof(struct Type));
+ declarator->id=NULL;
+ Queue_Init(&declarator->type->components);
+
+ base=parse_specifier_qualifier_list(tokens,scope);
+ Queue_Push(&declarator->type->components,base);
+ if(base->error)
+ {
+ ret=declarator->type;
+ free(declarator);
+ return ret;
+ }
+ parse_abstract_declarator(tokens,declarator,scope);
+
+ if(declarator->id!=NULL)
+ {
+ base->error=1;
+ }
+ ret=declarator->type;
+ free(declarator);
+ return ret;
+
+ }
+
+ /*
+ struct-declarator:
+ declarator
+ [ declarator ] : constant-expression
+
+ */
+ void parse_struct_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope)
+ {
+ struct Type_Node *hold;
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ hold=get_node();
+ hold->is_bit_field=1;
+ hold->specifics.bit_field_length=parse_const_expression(tokens,scope);
+ Queue_Push(&base->type->components,hold);
+ }else
+ {
+ parse_declarator(tokens,base,scope);
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ hold=get_node();
+ hold->is_bit_field=1;
+ hold->specifics.bit_field_length=parse_const_expression(tokens,scope);
+ Queue_Push(&base->type->components,hold);
+ }
+ }
+ }
+ /*
+ struct-declarator-list:
+ struct-declarator (,struct-declarator)*
+ */
+ void parse_struct_declarator_list(struct Queue *tokens,struct Queue *declarators,struct Type_Node *base_type,struct Scope *scope)
+ {
+ struct Declarator *struct_declaration;
+ do
+ {
+ struct_declaration=get_declarator(base_type);
+ parse_struct_declarator(tokens,struct_declaration,scope);
+ Queue_Push(declarators,struct_declaration);
+ }while(get_and_check(tokens,KW_COMMA));
+ }
+
+ /*
+ struct-declaration:
+ spedifier-qualifier-list [ struct-declarator-list ] ;
+ */
+ void parse_struct_declaration(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope)
+ {
+ struct AST_Declaration *hold;
+ hold=get_declaration_tree(scope);
+
+ hold->base_type=parse_specifier_qualifier_list(tokens,scope);
+ parse_struct_declarator_list(tokens,&hold->declarators,hold->base_type,scope);
+
+ Queue_Push(&struct_union_base->specifics.struct_union->declarations,hold);
+
+ if(!get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ struct_union_base->error=1;
+ }
+
+ }
+ void parse_struct_declaration_list(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope)
+ {
+ do
+ {
+ parse_struct_declaration(tokens,struct_union_base,scope);
+ }while(!( check(tokens,KW_CLOSE_CURLY,0) || struct_union_base->error));
+ }
+
+ /*
+ struct-or-union-specifier:
+ struct-or-union [ identifier ] { struct-declaration-list }
+ struct-or-union identifier
+ */
+ struct Type_Node* parse_struct_union_specifier(struct Queue *tokens,struct Scope *scope)
+ {
+ struct Type_Node *hold;
+ hold=get_node();
+ if(get_and_check(tokens,KW_STRUCT))
+ {
+ hold->type_specifier=TS_STRUCT;
+ }else if(get_and_check(tokens,KW_UNION))
+ {
+ hold->type_specifier=TS_UNION;
+ }else
+ {
+ hold->type_specifier=TS_NONE;
+ hold->error=1;
+ return hold;
+ }
+
+ hold->specifics.struct_union=get_struct_union();
+ if(check(tokens,KW_ID,0))
+ {
+ hold->specifics.struct_union->id=Queue_Pop(tokens);
+ }
+ if(get_and_check(tokens,KW_OPEN_CURLY))
+ {
+ parse_struct_declaration_list(tokens,hold,scope);
+ if(get_and_check(tokens,KW_CLOSE_CURLY))
+ {
+ return hold;
+ }else
+ {
+ hold->error=1;
+ return hold;
+ }
+ }else
+ {
+
+ hold->error=1;
+ return hold;
+ }
+ }
+ struct Struct_Union* get_struct_union()
+ {
+ struct Struct_Union* ret;
+ ret=malloc(sizeof(struct Struct_Union));
+ Queue_Init(&ret->declarations);
+ Map_Init(&ret->inner_namespace);
+ ret->id=NULL;
+ return ret;
+ }
+ char is_type(struct Queue *tokens,struct Scope *scope)
+ {
+
+ enum KEYWORDS kw;
+ kw=kw_get(tokens);
+ switch(kw)
+ {
+ case KW_CONST:
+ case KW_VOLATILE:
+ case KW_STATIC:
+ case KW_TYPEDEF:
+ case KW_EXTERN:
+ case KW_INT:
+ case KW_CHAR:
+ case KW_VOID:
+ case KW_DOUBLE:
+ case KW_FLOAT:
+ case KW_UNION:
+ case KW_STRUCT:
+ case KW_ENUM:
+ return 1;
+ case KW_ID:
+ return check_if_typedefed(scope,tokens->first->data);
+ default:
+ return 0;
+ }
+ }
+
+ struct Declarator* get_declarator(struct Type_Node *base_type)
+ {
+ struct Declarator *ret;
+ ret=malloc(sizeof(struct Declarator));
+ ret->id=NULL;
+ ret->initialiser=NULL;
+ ret->type=malloc(sizeof(struct Type));
+ Queue_Init(&ret->type->components);
+ Queue_Push(&ret->type->components,base_type);
+ ret->location=NULL;
+
+ return ret;
+ }
+ #endif
F diff --git a/parse_declaration.h b/parse_declaration.h new file mode 100644 --- /dev/null +++ b/parse_declaration.h
+ #ifndef GCC_PARSE_DECLARATION_H
+ #define GCC_PARSE_DECLARATION_H GCC_PARSE_DECLARATION_H
+ #include "ast.h"
+ #include "parse_expression.h"
+ #include "type.h"
+ #include "scope.h"
+ #include "queue.c"
+ #include "map.c"
+ #include "lexer.h"
+ #include <assert.h>
+
+ struct Declarator
+ {
+ struct Type *type;
+ struct AST *initialiser;
+ struct token *id;
+ struct Location *location;
+ };
+
+ struct AST* parse_declaration(struct Queue *tokens,struct Scope *scope);
+ void parse_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope);
+ void parse_direct_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope);
+ void parse_abstract_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope);
+ void parse_direct_abstract_declarator(struct Queue *tokens,struct Declarator *upper,struct Scope *scope);
+ void parse_pointer(struct Queue *tokens,struct Declarator *upper,struct Scope *scope);
+ struct Declarator* parse_init_declarator(struct Queue *tokens,struct Type_Node *base,struct Scope *scope);
+ struct AST* parse_initialiser(struct Queue *tokens,struct Scope *scope);
+ struct Type_Node* parse_declaration_specifiers(struct Queue *tokens,struct Scope *scope);
+ struct Type_Node* parse_specifier_qualifier_list(struct Queue *tokens,struct Scope *scope);
+ void parse_parameter_type_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);
+ void parse_parameter_list(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);
+ void parse_parameter_declaration(struct Queue *tokens,struct Type_Node *function_base,struct Scope *scope);
+ void parse_direct_declarator_finish(struct Queue *tokens,struct Type *upper,struct Scope *scope);
+ char parse_direct_declarator_finish_step(struct Queue *tokens,struct Type *upper,struct Scope *scope);
+ struct Type* parse_type_name(struct Queue *tokens,struct Scope *scope);
+
+
+ void parse_struct_declarator(struct Queue *tokens,struct Declarator *base,struct Scope *scope);
+ void parse_struct_declarator_list(struct Queue *tokens,struct Queue *declarators,struct Type_Node *base_type,struct Scope *scope);
+ void parse_struct_declaration(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope);
+ void parse_struct_declaration_list(struct Queue *tokens,struct Type_Node *struct_union_base,struct Scope *scope);
+ struct Type_Node* parse_struct_union_specifier(struct Queue *tokens,struct Scope *scope);
+
+ char is_type(struct Queue *tokens,struct Scope *scope);
+ struct Type_Node* get_node();
+ struct Type* get_type();
+ struct Declarator* get_declarator(struct Type_Node *base_type);
+
+ #endif
F diff --git a/parse_expression.c b/parse_expression.c new file mode 100644 --- /dev/null +++ b/parse_expression.c
+ #ifndef GCC_PARSE_EXPR_C
+ #define GCC_PARSE_EXPR_C GCC_PARSE_EXPR_C
+ #include "parse_expression.h"
+
+
+
+ struct AST* parse_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ return parse_comma_expression(tokens,scope);
+ }
+
+ struct AST* parse_const_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ return parse_comma_expression(tokens,scope);
+ }
+ /*
+ primary-expression:
+ number
+ string
+ id
+ (e)
+ generic-selection
+
+ */
+ struct AST* parse_primary_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct token *hold_token;
+ struct AST *hold;
+
+ if(tokens->size==0)
+ {
+ /*TODO error*/
+ return (struct AST*)get_error_tree(NULL);
+ }
+ hold_token=Queue_Pop(tokens);
+ switch(hold_token->type)
+ {
+ case KW_NUMBER:
+ case KW_STRING:
+ return (struct AST*)get_rvalue_expression_tree(hold_token);
+ case KW_ID:
+ return (struct AST*)get_lvalue_expression_tree(hold_token,scope);
+ case KW_OPEN_NORMAL:
+ hold=parse_expression(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ return (struct AST*)hold;
+ }else
+ {
+ /*TODO error*/
+ return (struct AST*)get_error_tree(hold);
+ }
+ default:
+ /*TODO error*/
+ return (struct AST*)get_error_tree(NULL);
+ }
+
+ /*just in case*/
+ return (struct AST*)get_error_tree(NULL);
+
+ }
+
+
+ /*
+ arglist:
+ (e)*\)
+
+ */
+ struct AST_Function_Expression* parse_arglist(struct Queue *tokens,struct Scope *scope,struct AST* id)
+ {
+ struct AST_Function_Expression *ret;
+ ret=get_function_expression_tree(id,scope);
+ ret->id=id;
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ return ret;
+ }
+ do
+ {
+ Queue_Push(&ret->arguments,parse_assignment_expression(tokens,scope));
+ } while(get_and_check(tokens,KW_COMMA));
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ return ret;
+ }else
+ {
+ return (struct AST_Function_Expression*)get_error_tree((struct AST*)ret);
+ }
+
+ }
+
+ /*
+ postfix_expression:
+ postfix_expression ++
+ postfix_expression --
+ postfix_expression [ expression ]
+ postfix_expression.id
+ postfix_expression->id
+ postfix_expression ( arglist )
+
+
+ primary_expression
+ postfix_expression:
+ primary_expression ( ++ | -- | \[ expression \] | .id | ->id | \( arglist \) )*
+
+ */
+ struct AST* parse_postfix_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ struct AST *hold_expr;
+
+
+ hold=parse_primary_expression(tokens,scope);
+
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_PLUSPLUS:
+ chomp(tokens);
+ hold=(struct AST*)get_unary_expression_tree(hold,OP_POSTFIX_INC);
+ break;
+ case KW_MINUSMINUS:
+ chomp(tokens);
+ hold=(struct AST*)get_unary_expression_tree(hold,OP_POSTFIX_DEC);
+ break;
+ case KW_DOT:
+ chomp(tokens);
+ if(check(tokens,KW_ID,0))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(tokens),scope),OP_MEMBER);
+ }
+ break;
+ case KW_ARROW:
+ chomp(tokens);
+ if(check(tokens,KW_ID,0))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,(struct AST*)get_lvalue_expression_tree(Queue_Pop(tokens),scope),OP_MEMBER_TROUGH_PTR);
+ }
+ break;
+ case KW_OPEN_SQUARE:
+
+ chomp(tokens);
+ if(get_and_check(tokens,KW_CLOSE_SQUARE))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,NULL,OP_ARR_SUBSCRIPT);
+ }else
+ {
+ hold_expr=parse_expression(tokens,scope);
+ hold=(struct AST*)get_binary_expression_tree(hold,hold_expr,OP_ARR_SUBSCRIPT);
+ if(!get_and_check(tokens,KW_CLOSE_SQUARE))
+ {
+ return (struct AST*)get_error_tree(hold);
+ }
+ }
+ break;
+ case KW_OPEN_NORMAL:
+ chomp(tokens);
+ return (struct AST*)parse_arglist(tokens,scope,hold);
+ break;
+
+ default:
+ return hold;
+ }
+ }
+
+ return hold;
+ }
+
+ /*
+ cast-expression:
+ unary-expression
+ (type)cast-expression
+ */
+ struct AST* parse_cast_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST_Unary_Expression *ret;
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ if(is_type(tokens,scope))
+ {
+ ret=get_unary_expression_tree(NULL,OP_CAST);
+ ret->value_type=parse_type_name(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ ret->operand=parse_cast_expression(tokens,scope);
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+
+ }
+
+ }else
+ {
+ return (struct AST*)parse_unary_expression(tokens,scope);
+ }
+ }else
+ {
+
+ return parse_unary_expression(tokens,scope);
+ }
+ }
+ /*
+ unary-expression:
+ ++unary-expression
+ --unary-expression
+ +unary-expression
+ -unary-expression
+ !cast-expression
+ ~cast-expression
+ *cast-expression
+ &cast-expression
+ sizeof ( typename )
+ sizeof unary-expression
+ postfix-expression
+
+ */
+
+ struct AST* parse_unary_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST_Unary_Expression *hold;
+
+ if(tokens->size==0)
+ {
+ /*TODO error*/
+ return (struct AST*)get_error_tree(NULL);
+ }
+
+ /*TODO make it iterative*/
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_PLUSPLUS:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_PREFIX_INC);
+ case KW_MINUSMINUS:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_PREFIX_DEC);
+ case KW_PLUS:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_UNARY_PLUS);
+ case KW_MINUS:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_UNARY_MINUS);
+ case KW_EXCLAMATION:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_LOGICAL_NOT);
+ case KW_TILDE:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_BITWISE_NOT);
+ case KW_STAR:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_DEREFERENCE);
+ case KW_AND:
+ chomp(tokens);
+ return (struct AST*)get_unary_expression_tree(parse_cast_expression(tokens,scope),OP_ADDR_OF);
+ case KW_SIZEOF:
+ chomp(tokens);
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ hold=get_unary_expression_tree(NULL,OP_CAST);
+ hold->value_type=parse_type_name(tokens,scope);
+ hold->operand=parse_unary_expression(tokens,scope);
+ return (struct AST*)hold;
+ }else
+ {
+ return (struct AST*)get_unary_expression_tree(parse_unary_expression(tokens,scope),OP_SIZEOF);
+ }
+ default:
+ return parse_postfix_expression(tokens,scope);
+ }
+
+ }
+ /*
+ multiplicative-expression:
+ cast-expression ( ( * | / | % ) cast-expression )*
+ */
+ struct AST* parse_multiplicative_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ hold=parse_cast_expression(tokens,scope);
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_STAR:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_MUL);
+ break;
+ case KW_FORWARD_SLASH:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_DIV);
+ break;
+ case KW_PERCENT:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_cast_expression(tokens,scope),OP_REMAINDER);
+ break;
+ default:
+ return hold;
+ }
+ }
+
+ return hold;
+ }
+ /*
+ additive-expression:
+ multiplicative-expression ( ( + | - ) multiplicative )*
+ */
+ struct AST* parse_additive_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_multiplicative_expression(tokens,scope);
+
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_PLUS:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(tokens,scope),OP_ADDITION);
+ break;
+ case KW_MINUS:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_multiplicative_expression(tokens,scope),OP_SUBTRACTION);
+ break;
+ default:
+ return hold;
+ }
+ }
+
+ return hold;
+ }
+ /*
+ bitwise-shift:
+ additive-expression ( ( << | >> ) additive-expression)*
+ */
+ struct AST* parse_shift_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_additive_expression(tokens,scope);
+
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_SHIFT_LEFT:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(tokens,scope),OP_SHIFT_LEFT);
+ break;
+ case KW_SHIFT_RIGHT:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_additive_expression(tokens,scope),OP_SHIFT_RIGHT);
+ break;
+ default:
+ return hold;
+ }
+ }
+ return hold;
+ }
+
+ /*
+ relational-expression:
+ shift-expression ( ( < | > | <= | >= ) shift-expression )*
+ */
+
+ struct AST* parse_relational_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ hold=parse_shift_expression(tokens,scope);
+
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_LESS:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_LESS);
+ break;
+ case KW_LESS_EQ:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_LESS_EQ);
+ break;
+ case KW_MORE:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_GREATER);
+ break;
+ case KW_MORE_EQ:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_shift_expression(tokens,scope),OP_GREATER_EQ);
+ break;
+ default:
+ return hold;
+ }
+ }
+ return hold;
+ }
+
+
+ /*
+ equality-expression:
+ realtional-expression ( ( == | != ) relational-expression )*
+ */
+ struct AST* parse_equality_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ hold=parse_relational_expression(tokens,scope);
+
+ while(tokens->size!=0)
+ {
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_EQEQ:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(tokens,scope),OP_EQUAL);
+ break;
+ case KW_NOT_EQ:
+ chomp(tokens);
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_relational_expression(tokens,scope),OP_NOT_EQUAL);
+ break;
+ default:
+ return hold;
+ }
+ }
+ return hold;
+ }
+ /*
+ and-expression:
+ equality-expression ( & equality-expression ) *
+ */
+ struct AST* parse_and_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_equality_expression(tokens,scope);
+ while(get_and_check(tokens,KW_AND))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_equality_expression(tokens,scope),OP_BITWISE_AND);
+ }
+ return hold;
+ }
+ /*
+ exclusive-or-expression:
+ and-expression (^ and-expression)*
+
+ */
+ struct AST* parse_exclusive_or_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ hold=parse_and_expression(tokens,scope);
+ while(get_and_check(tokens,KW_HAT))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_and_expression(tokens,scope),OP_BITWISE_XOR);
+ }
+ return hold;
+
+ }
+ /*
+ inclusive-or-expression:
+ exclusive-or-expression (|exclusive-or-expression)*
+ */
+ struct AST* parse_inclusive_or_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_exclusive_or_expression(tokens,scope);
+ while(get_and_check(tokens,KW_PIPE))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_exclusive_or_expression(tokens,scope),OP_BITWISE_OR);
+ }
+ return hold;
+ }
+ /*
+ logical-and-expression:
+ inclusive-or-expression(&&inclusive-or-expression)*
+ */
+ struct AST* parse_logical_and_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_inclusive_or_expression(tokens,scope);
+ while(get_and_check(tokens,KW_AND_AND))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_inclusive_or_expression(tokens,scope),OP_LOGICAL_AND);
+ }
+ return hold;
+ }
+ /*
+ logical-or-expression:
+ logical-and-expression ( || logical-and-expression )*
+ */
+ struct AST* parse_logical_or_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_logical_and_expression(tokens,scope);
+ while(get_and_check(tokens,KW_AND_AND))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_logical_and_expression(tokens,scope),OP_LOGICAL_OR);
+ }
+ return hold;
+ }
+
+ /*
+ conditional-expression:
+ logical-or-expression
+ logical-or-expression?expression:conditional-expression
+ */
+ struct AST* parse_conditional_expression(struct Queue *tokens,struct Scope *scope)
+ {
+
+ struct AST *hold;
+ hold=parse_logical_or_expression(tokens,scope);
+ if(get_and_check(tokens,KW_QUESTION))
+ {
+ hold=(struct AST*)get_conditional_expression_tree(hold,parse_expression(tokens,scope),NULL);
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ ((struct AST_Conditional_Expression*)hold)->right=parse_conditional_expression(tokens,scope);
+ return hold;
+ }else
+ {
+ return (struct AST*)get_error_tree(hold);
+ }
+ }else
+ {
+ return hold;
+ }
+ }
+ /*
+ assignment-expression:
+ conditional-expression
+ unary-expression ( ( = | += | -= | %= | /= | *= | >>= | <<= | &= | |= | ^= ) assignment-expression
+ */
+ struct AST* parse_assignment_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+
+ if(tokens->size==0)
+ {
+ /*TODO error*/
+ return (struct AST*)get_error_tree(NULL);
+ }
+
+ hold=parse_conditional_expression(tokens,scope);
+ if(tokens->size==0)
+ return hold;
+ /*TODO make it iterative*/
+ switch(((struct token*)tokens->first->data)->type)
+ {
+ case KW_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_ASSIGN);
+ case KW_PLUS_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_ADD_ASSIGN);
+ case KW_MINUS_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SUBTRACT_ASSIGN);
+ case KW_PERCENT_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_REMAINDER_ASSIGN);
+ case KW_DIV_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_DIV_ASSIGN);
+ case KW_STAR_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_MULTIPLY_ASSIGN);
+ case KW_SHIFT_RIGHT_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SHIFT_RIGHT_ASSIGN);
+ case KW_SHIFT_LEFT_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_SHIFT_LEFT_ASSIGN);
+ case KW_AND_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_AND_ASSIGN);
+ case KW_PIPE_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_PIPE_ASSIGN);
+ case KW_HAT_EQ:
+ chomp(tokens);
+ return (struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_XOR_ASSIGN);
+ default:
+ return hold;
+ }
+
+ }
+ /*
+ comma-expression:
+ assignment-expression(,assignment-expression)*
+ */
+ struct AST* parse_comma_expression(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ hold=parse_assignment_expression(tokens,scope);
+ while(get_and_check(tokens,KW_COMMA))
+ {
+ hold=(struct AST*)get_binary_expression_tree(hold,parse_assignment_expression(tokens,scope),OP_COMMA);
+ }
+ return hold;
+ }
+
+ #endif
F diff --git a/parse_expression.h b/parse_expression.h new file mode 100644 --- /dev/null +++ b/parse_expression.h
+ #ifndef GCC_PARSE_EXPR_H
+ #define GCC_PARSE_EXPR_H GCC_PARSE_EXPR_H
+ #include"chonky.c"
+ #include"queue.c"
+ #include"lexer.h"
+ #include"parse_declaration.h"
+ #include"ast.h"
+ #include<limits.h>
+
+
+ struct AST* parse_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_const_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_primary_expression(struct Queue *tokens,struct Scope *scope);
+
+
+ struct AST_Function_Expression* parse_arglist(struct Queue *tokens,struct Scope *scope,struct AST* id);
+ struct AST* parse_postfix_expression(struct Queue *tokens,struct Scope *scope);
+
+ struct AST* parse_cast_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_unary_expression(struct Queue *tokens,struct Scope *scope);
+
+ struct AST* parse_multiplicative_expression(struct Queue *tokens,struct Scope *scope);
+
+ struct AST* parse_additive_expression(struct Queue *tokens,struct Scope *scope);
+
+ struct AST* parse_shift_expression(struct Queue *tokens,struct Scope *scope);
+
+
+ struct AST* parse_relational_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_equality_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_and_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_exclusive_or_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_inclusive_or_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_logical_and_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_logical_or_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_conditional_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_assignment_expression(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_comma_expression(struct Queue *tokens,struct Scope *scope);
+
+
+
+
+
+ /*
+
+ expression:
+ e15
+ comma-expression:
+ assignment-expression(,assignment-expression)*
+
+ assignment-expression:
+ unary-expression ( ( = | += | -= | %= | /= | *= | >>= | <<= | &= | |= | ^= ) assignment-expression
+
+ conditional-expression:
+ logical-or-expression
+ logical-or-expression?expression:conditional-expression
+ logical-or-expression:
+ logical-and-expression ( || logical-and-expression )*
+ logical-and-expression:
+ inclusive-or-expression(&&inclusive-or-expression)*
+ inclusive-or-expression:
+ exclusive-or-expression (|exclusive-or-expression)*
+ exclusive-or-expression:
+ and-expression (^ and-expression)*
+ and-expression:
+ equality-expression ( & equality-expression ) *
+ equality-expression:
+ realtional-expression ( ( == | != ) relational-expression )*
+ relational-expression:
+ shift-expression ( ( < | > | <= | >= ) shift-expression )*
+
+ shift-expression:
+ additive-expression ( ( << | >> ) additive-expression)*
+
+ additive-expression:
+ multiplicative-expression ( ( + | - ) multiplicative-expression )*
+
+ multiplicative-expression:
+ cast-expression ( ( * | / | % ) cast-expression )*
+
+ unary-expression:
+ ++unary-expression
+ --unary-expression
+ +unary-expression
+ -unary-expression
+ !cast-expression
+ ~cast-expression
+ *cast-expression
+ &cast-expression
+ sizeof ( typename )
+ sizeof unary-expression
+ postfix-expression
+
+ cast-expression:
+ unary-expression
+ (type)cast-expression
+
+
+ arglist:
+ epsilon
+ assignment-expression-list(,assignment-expression-list)*
+ postfix_expression:
+ postfix_expression ++
+ postfix_expression --
+ postfix_expression [ expression ]
+ postfix_expression.id
+ postfix_expression->id
+ postfix_expression ( arglist )
+
+
+ primary_expression
+
+ primary-expression:
+ number
+ string
+ id
+ (e)
+
+ */
+
+
+ #endif
F diff --git a/parse_statement.c b/parse_statement.c new file mode 100644 --- /dev/null +++ b/parse_statement.c
+ #ifndef PARSE_GCC_STATEMENT_C
+ #define PARSE_GCC_STATEMENT_C PARSE_GCC_STATEMENT_C
+ #include "parse_statement.h"
+ #include "parse_declaration.h"
+
+
+ struct AST* parse_statement(struct Queue* tokens,struct Scope *scope)
+ {
+
+ if(tokens->size==0)
+ return NULL;
+
+
+
+ switch(kw_get(tokens))
+ {
+ case KW_NOTYPE:
+ return (struct AST*)get_error_tree(NULL);
+
+ case KW_OPEN_CURLY:
+ chomp(tokens);
+ return parse_finish_compound_statement(tokens,scope);
+ case KW_IF:
+ chomp(tokens);
+ return parse_finish_if_statement(tokens,scope);
+ case KW_SWITCH:
+ chomp(tokens);
+ return parse_finish_switch_statement(tokens,scope);
+ case KW_WHILE:
+ chomp(tokens);
+ return parse_finish_while_statement(tokens,scope);
+ case KW_DO:
+ chomp(tokens);
+ return parse_finish_do_while_statement(tokens,scope);
+ case KW_FOR:
+ chomp(tokens);
+ return parse_finish_for_statement(tokens,scope);
+ case KW_GOTO:
+ chomp(tokens);
+ return parse_finish_goto_statement(tokens,scope);
+ case KW_CASE:
+ chomp(tokens);
+ return parse_finish_labeled_statement(tokens,scope,ST_CASE);
+ case KW_DEFAULT:
+ chomp(tokens);
+ return parse_finish_default_statement(tokens,scope);
+ case KW_ID:
+ /*TODO check if id is in function scope*/
+ if(0)
+ {
+ return parse_finish_labeled_statement(tokens,scope,ST_LABEL);
+ }else
+ {
+ return parse_expression_statement(tokens,scope);
+ }
+ case KW_CONTINUE:
+ chomp(tokens);
+ return parse_finish_continue_statement(tokens);
+ case KW_BREAK:
+ chomp(tokens);
+ return parse_finish_break_statement(tokens);
+ case KW_RETURN:
+ chomp(tokens);
+ return parse_finish_return_statement(tokens,scope);
+ default:
+ return parse_expression_statement(tokens,scope);
+
+ }
+
+ }
+ /*
+ ( declaration | statement )* }
+ */
+ struct AST* parse_finish_compound_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_Compound_Statement *hold;
+ hold=get_compound_statement_tree(scope);
+ while(!get_and_check(tokens,KW_CLOSE_CURLY))
+ {
+ if(is_type(tokens,scope))
+ {
+ Queue_Push(&hold->components,parse_declaration(tokens,hold->scope));
+ }else
+ {
+ Queue_Push(&hold->components,parse_statement(tokens,hold->scope));
+ }
+ }
+
+ return (struct AST*)hold;
+ }
+ /*
+ ( expression ) statement
+ ( expression ) statement else statement
+ */
+ struct AST* parse_finish_if_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_If_Statement *hold;
+ hold=get_if_statement_tree();
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ hold->condition=parse_expression(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ hold->body_statement=parse_statement(tokens,scope);
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ if(get_and_check(tokens,KW_ELSE))
+ {
+ hold->else_statement=parse_statement(tokens,scope);
+ return (struct AST*)hold;
+ }else
+ {
+ hold->else_statement=NULL;
+ return (struct AST*)hold;
+ }
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ return (struct AST*)hold;
+ }
+ /*
+ ( expression ) statement
+ */
+ struct AST* parse_finish_switch_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_Switch_Statement *hold;
+ hold=get_switch_statement_tree();
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ hold->condition=parse_expression(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ hold->body_statement=parse_statement(tokens,scope);
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+
+ return (struct AST*)hold;
+ }
+ /*
+ ( expression ) statement
+
+ */
+ struct AST* parse_finish_while_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_While_Statement *hold;
+ hold=get_while_statement_tree();
+ if(get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ hold->condition=parse_expression(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ hold->body_statement=parse_statement(tokens,scope);
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+
+ return (struct AST*)hold;
+ }
+ /*
+ statement while ( expression ) ;
+ */
+ struct AST* parse_finish_do_while_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_Do_While_Statement *hold;
+ hold=get_do_while_statement_tree();
+ hold->body_statement=parse_statement(tokens,scope);
+ if(get_and_check(tokens,KW_WHILE) && get_and_check(tokens,KW_OPEN_NORMAL))
+ {
+ hold->condition=parse_expression(tokens,scope);
+
+ if(get_and_check(tokens,KW_CLOSE_NORMAL) && get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return (struct AST*)hold;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+
+ }
+ /*
+ ( [ expression ] ; [ expression ] ; [ expression ] ) statement
+ */
+ struct AST* parse_finish_for_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_For_Statement *hold;
+ hold=get_for_statement_tree();
+ if(!get_and_check(tokens,KW_OPEN_NORMAL))
+ return (struct AST*)get_error_tree((struct AST*)hold);
+
+ hold->initialisation=parse_expression_statement(tokens,scope);
+ hold->condition=parse_expression_statement(tokens,scope);
+ if(get_and_check(tokens,KW_CLOSE_NORMAL))
+ {
+ hold->update=get_nop_tree();
+ }else
+ {
+ hold->update=parse_expression(tokens,scope);
+ if(!get_and_check(tokens,KW_CLOSE_NORMAL))
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ hold->body_statement=parse_statement(tokens,scope);
+ return (struct AST*)hold;
+ }
+ /*
+ id ;
+ */
+ struct AST* parse_finish_goto_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST* ret;
+
+ if(check(tokens,KW_ID,0))
+ {
+ ret=(struct AST*)get_goto_statement_tree(Queue_Pop(tokens),scope);
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return ret;
+ }else
+ {
+ return (struct AST*)get_error_tree(ret);
+ }
+ }
+ else
+ {
+ return (struct AST*)get_error_tree((struct AST*)get_goto_statement_tree(NULL,NULL));
+ }
+
+ }
+ /*
+ ;
+ */
+ struct AST* parse_finish_continue_statement(struct Queue* tokens)
+ {
+ struct AST *hold;
+ hold=malloc(sizeof(struct AST));
+ hold->type=ST_CONTINUE;
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return hold;
+ }else
+ {
+ return (struct AST*)get_error_tree(hold);
+ }
+ }
+ /*
+ ;
+ */
+ struct AST* parse_finish_break_statement(struct Queue* tokens)
+ {
+ struct AST *hold;
+ hold=malloc(sizeof(struct AST));
+ hold->type=ST_BREAK;
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return hold;
+ }else
+ {
+ return (struct AST*)get_error_tree(hold);
+ }
+ }
+ /*
+ id:
+ statement
+ */
+ struct AST* parse_finish_labeled_statement(struct Queue* tokens,struct Scope *scope,enum AST_Type type)
+ {
+ struct AST_Labeled_Statement *ret;
+ if(check(tokens,KW_ID,0))
+ {
+ ret=get_labeled_statement_tree(Queue_Pop(tokens),NULL,scope,type);
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ ret->statement=parse_statement(tokens,scope);
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+ }else
+ {
+ return (struct AST*)get_error_tree(NULL);
+ }
+ }
+ /*
+ :
+ statement
+ */
+ struct AST* parse_finish_default_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_Labeled_Statement *ret;
+ ret=get_labeled_statement_tree(NULL,NULL,scope,ST_DEFAULT);
+ if(get_and_check(tokens,KW_COLUMN))
+ {
+ ret->statement=parse_statement(tokens,scope);
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+ }
+ /*
+ [ expression ] ;
+
+ */
+ struct AST* parse_finish_return_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST_Return_Statement *hold;
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ hold=get_return_statement_tree(get_nop_tree());
+ return (struct AST*)hold;
+ }
+
+
+ hold=get_return_statement_tree(parse_expression(tokens,scope));
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return (struct AST*)hold;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+ }
+ /*
+
+ [ expression ] ;
+
+ */
+ struct AST* parse_expression_statement(struct Queue* tokens,struct Scope *scope)
+ {
+ struct AST *hold;
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ hold=get_nop_tree();
+ return (struct AST*)hold;
+ }
+ hold=parse_expression(tokens,scope);
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return hold;
+ }else
+ {
+ return (struct AST*)get_error_tree(hold);
+ }
+ }
+ #endif
F diff --git a/parse_statement.h b/parse_statement.h new file mode 100644 --- /dev/null +++ b/parse_statement.h
+ #ifndef PARSE_GCC_STATEMENT_H
+ #define PARSE_GCC_STATEMENT_H PARSE_GCC_STATEMENT_H
+ #include"lexer.c"
+ #include"ast.h"
+ #include "scope.h"
+ #include"parse_expression.h"
+
+
+ struct AST* parse_finish_compound_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_op_e_cl_st(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_if_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_switch_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_do_while_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_while_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_for_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_goto_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_continue_statement(struct Queue* tokens);
+ struct AST* parse_finish_break_statement(struct Queue* tokens);
+ struct AST* parse_finish_return_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_expression_statement(struct Queue* tokens,struct Scope *scope);
+ struct AST* parse_finish_labeled_statement(struct Queue* tokens,struct Scope *scope,enum AST_Type type);
+ struct AST* parse_finish_default_statement(struct Queue* tokens,struct Scope *scope);
+
+
+
+ #endif
F diff --git a/parse_translation_unit.c b/parse_translation_unit.c new file mode 100644 --- /dev/null +++ b/parse_translation_unit.c
+ #ifndef GCC_PARSE_TRANSLATION_C
+ #define GCC_PARSE_TRANSLATION_C GCC_PARSE_TRANSLATION_C
+ #include "parse_declaration.h"
+ #include "parse_statement.h"
+ /*
+
+ function-definition:
+ [ declaration-specifiers ] declarator
+ [ declaration-list ] compound-statement
+ */
+
+ struct AST* parse_function_definition(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST_Function_Definition *ret;
+ ret=get_function_definition_tree(scope);
+
+ if(is_type(tokens,scope))
+ ret->base_type=parse_declaration_specifiers(tokens,scope);
+ else
+ ret->base_type=NULL;
+
+
+ ret->declarator=get_declarator(ret->base_type);
+ parse_declarator(tokens,ret->declarator,scope);
+ /*TODO*/
+ //[ declaration-list ] compound-statement
+ if(get_and_check(tokens,KW_OPEN_CURLY))
+ {
+ ret->body_statement=parse_finish_compound_statement(tokens,scope);
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+
+ return (struct AST*)ret;
+ }
+
+ /*
+ translation_unit_step:
+ declaration
+ function-definition
+
+ delcaration:
+ declaration-specifiers [ init-declarator-list ] ;
+
+ */
+ struct AST* parse_translation_unit_step(struct Queue *tokens,struct Scope *scope)
+ {
+ struct Type_Node *base_type;
+ struct Declarator *declarator;
+
+ if(!is_type(tokens,scope))
+ {
+ /*this is a function definition with default base_type of int*/
+ return (struct AST*)parse_function_definition(tokens,scope);
+ }
+ base_type=parse_declaration_specifiers(tokens,scope);
+ declarator=get_declarator(base_type);
+ parse_declarator(tokens,declarator,scope);
+ if(get_and_check(tokens,KW_COMMA))
+ {
+ /*this is a declaration*/
+ struct AST_Declaration *ret;
+ ret=get_declaration_tree(scope);
+ ret->base_type=base_type;
+ Queue_Push(&ret->declarators,declarator);
+ Scope_Push(scope,declarator);
+
+ do
+ {
+ parse_declarator(tokens,declarator,scope);
+ Queue_Push(&ret->declarators,declarator);
+ Scope_Push(scope,declarator);
+ }while(get_and_check(tokens,KW_COMMA));
+
+ if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+
+ }else if(get_and_check(tokens,KW_SEMI_COLUMN))
+ {
+ struct AST_Declaration *ret;
+ ret=get_declaration_tree(scope);
+ ret->base_type=base_type;
+ Queue_Push(&ret->declarators,declarator);
+ Scope_Push(scope,declarator);
+ return (struct AST*)ret;
+
+ }else
+ {
+ /*this is a function call*/
+ struct AST_Function_Definition *ret;
+ ret=get_function_definition_tree(scope);
+ ret->base_type=base_type;
+ ret->declarator=declarator;
+ if(get_and_check(tokens,KW_OPEN_CURLY))
+ {
+ ret->body_statement=parse_finish_compound_statement(tokens,scope);
+ ret->scope=scope;
+ return (struct AST*)ret;
+ }else
+ {
+ return (struct AST*)get_error_tree((struct AST*)ret);
+ }
+
+ }
+
+
+ }
+
+ /*
+ translation-unit:
+ declaration [ translation-unit ]
+ function-definition [ translation-unit ]
+ */
+ struct AST* parse_translation_unit(struct Queue *tokens,struct Scope *scope)
+ {
+ struct AST_Translation_Unit *hold;
+ struct AST *temp;
+ hold=get_translation_unit_tree(scope);
+ while(tokens->size>0)
+ {
+ temp=parse_translation_unit_step(tokens,hold->scope);
+ Queue_Push(&hold->components,temp);
+ if(temp->type==ERROR)
+ {
+ return (struct AST*)get_error_tree((struct AST*)hold);
+ }
+
+ }
+ return (struct AST*)hold;
+
+ }
+
+ #endif
F diff --git a/parse_translation_unit.h b/parse_translation_unit.h new file mode 100644 --- /dev/null +++ b/parse_translation_unit.h
+ #ifndef GCC_PARSE_TRANSLATION_H
+ #define GCC_PARSE_TRANSLATION_H GCC_PARSE_TRANSLATION_H
+
+ struct AST* parse_translation_unit_step(struct Queue *tokens,struct Scope *scope);
+ struct AST* parse_translation_unit(struct Queue *tokens,struct Scope *scope);
+
+ #endif
F diff --git a/preprocessing.c b/preprocessing.c new file mode 100644 --- /dev/null +++ b/preprocessing.c
+ #ifndef GCC_PREPROCESSING_C
+ #define GCC_PREPROCESSING_C GCC_PREPROCESSING_C
+ #include "preprocessing.h"
+
+
+ #endif
F diff --git a/preprocessing.h b/preprocessing.h new file mode 100644 --- /dev/null +++ b/preprocessing.h
+ #ifndef GCC_PREPROCESSING_C
+ #define GCC_PREPROCESSING_C GCC_PREPROCESSING_C
+
+
+
+ #endif
F diff --git a/print.c b/print.c new file mode 100644 --- /dev/null +++ b/print.c
+ #ifndef GCC_PRINT
+ #define GCC_PRINT GCC_PRINT
+ #include<stdio.h>
+ #include<assert.h>
+ #include "all.h"
+
+
+ #define INDENT for(int j=0;j<indent;++j) fprintf(out," ");
+ #define TOK(s) ((struct token*)(s))
+ #define ASTPTR(s) ((struct AST*)(s))
+
+ int indent;
+
+
+ void print_ast(FILE *out,struct AST* tree);
+ void print_type_giberish(FILE* out,struct Type* type);
+ void print_keyword_enum(FILE *out,enum KEYWORDS kw);
+
+ void print_token(FILE *out,struct token *token)
+ {
+ size_t i;
+ // fprintf(out,"[");
+ for(i=0;i<token->data_size;++i)
+ {
+ fprintf(out,"%c",token->data[i]);
+ }
+ // fprintf(out,"]");
+ }
+
+ void print_tokens(FILE *out,struct Queue *tokens)
+ {
+ struct Queue_Node *it;
+ for( it=tokens->first;
+ it!=tokens->last;
+ it=it->prev)
+ {
+ fprintf(out,"[");
+ print_keyword_enum(out,((struct token*)(it->data))->type);
+ print_token(out,(struct token*)(it->data));
+ fprintf(out,"] ");
+ }
+ if(it!=NULL)
+ {
+ print_token(out,(struct token*)(it->data));
+ }
+ }
+
+ void print_declarators(FILE *out,struct Queue *declarators)
+ {
+ struct Queue_Node *it;
+ struct Declarator *dec;
+ for(it=declarators->first;NULL;it=it->prev)
+ {
+ dec=(struct Declarator*)(it->data);
+ print_type_giberish(out,dec->type);
+ fprintf(out,",");
+ }
+ }
+ void print_struct_union_node(FILE *out,struct Type_Node *type)
+ {
+ struct Queue_Node *it;
+ struct AST *dec;
+ assert(type->type_specifier==TS_UNION || type->type_specifier==TS_STRUCT);
+ if(type->specifics.struct_union->id!=NULL)
+ {
+ print_token(out,type->specifics.struct_union->id);
+ fprintf(out,"\n{");
+ }
+ for(it=type->specifics.struct_union->declarations.first;it!=NULL;it=it->prev)
+ {
+ dec=(struct AST*)(it->data);
+ print_ast(out,dec);
+ fprintf(out,";\n");
+ }
+
+ }
+
+ void print_type_node(FILE* out,struct Type_Node* type)
+ {
+ short i;
+ struct Queue_Node *it;
+ struct Declarator *dec;
+
+ if(type->type_def)
+ {
+ print_type_giberish(out,type->type_def);
+ return;
+ }
+
+ if(type->is_const)
+ fprintf(out,"CONSTANT ");
+ if(type->is_volatile)
+ fprintf(out,"VOLATILE ");
+
+ switch(type->type_specifier)
+ {
+ case TS_VOID:
+ fprintf(out,"VOID");break;
+ case TS_CHAR:
+ fprintf(out,"CHAR");break;
+ case TS_INT:
+ fprintf(out,"INT");break;
+ case TS_FLOAT:
+ fprintf(out,"FLOAT");break;
+ case TS_DOUBLE:
+ fprintf(out,"DOUBLE");break;
+ case TS_STRUCT:
+ fprintf(out,"\nstruct ");
+ print_struct_union_node(out,type);
+ fprintf(out,"\n}\n");
+ break;
+ case TS_UNION:
+ fprintf(out,"\nunion ");
+ print_struct_union_node(out,type);
+ fprintf(out,"\n}\n");
+ break;
+ case TS_ENUM:
+ fprintf(out,"ENUM");
+ break;
+ case TS_TYPEDEF:
+ fprintf(out,"TYPEDEF");break;
+ case TS_POINTER:
+ fprintf(out,"POINTER to ");
+ break;
+ case TS_ARRAY:
+ fprintf(out,"ARRAY[");
+ if(type->specifics.arr.number_of_elements_expr!=NULL)
+ //print_ast(out,type->specifics.number_of_elements);
+ fprintf(out,"%i",type->specifics.arr.number_of_elements);
+ fprintf(out,"] of ");
+ break;
+ case TS_FUNC:
+ fprintf(out,"FUNC taking argumens (");
+ for(it=type->specifics.arg_types.first;it!=type->specifics.arg_types.last;it=it->prev)
+ {
+ dec=(struct Declarator*)(it->data);
+ print_type_giberish(out,dec->type);
+ fprintf(out,",");
+ }
+ if(it!=NULL)
+ {
+ dec=(struct Declarator*)(it->data);
+ print_type_giberish(out,dec->type);
+ fprintf(out,",");
+ }
+ fprintf(out,") returning ");
+ break;
+ case TS_NONE:
+ fprintf(out,"NONE");break;
+ case TS_PTR_ERROR:
+ fprintf(out,"PTR_ERROR");break;
+ case TS_ARR_ERROR:
+ fprintf(out,"ARR_ERROR");break;
+ case TS_FUNC_ERROR:
+ fprintf(out,"FUNC_ERROR");break;
+ case TS_GROUP_ERROR:
+ fprintf(out,"GROUP_ERROR");break;
+ }
+ }
+ void print_type_giberish(FILE* out,struct Type* type)
+ {
+ if(type!=NULL)
+ {
+ struct Queue_Node *it;
+ for(it=type->components.first;it!=NULL;it=it->prev)
+ {
+ print_type_node(out,(struct Type_Node*)(it->data));
+ }
+ fprintf(out," SIZE=%zu",type->size);
+ }
+ }
+ void print_ast_enum(FILE *out,enum AST_Type op)
+ {
+ switch(op)
+ {
+ case OP_COMMA:
+ fprintf(out,",");break;
+ case OP_ADDITION:
+ fprintf(out,"+");break;
+ case OP_SUBTRACTION:
+ fprintf(out,"-");break;
+ case OP_MUL:
+ fprintf(out,"*");break;
+ case OP_DIV:
+ fprintf(out,"/");break;
+ case OP_REMAINDER:
+ fprintf(out,"%");break;
+ case OP_COND:
+ fprintf(out,"CONDITIONAL");break;
+ case OP_FUNCTION:
+ fprintf(out,"FUNCTION_CALL");break;
+ case OP_ASSIGN:
+ fprintf(out,"=");break;
+ case OP_ADD_ASSIGN:
+ fprintf(out,"&=");break;
+ case OP_SUBTRACT_ASSIGN:
+ fprintf(out,"-=");break;
+ case OP_MULTIPLY_ASSIGN:
+ fprintf(out,"*=");break;
+ case OP_REMAINDER_ASSIGN:
+ fprintf(out,"%=");break;
+ case OP_DIV_ASSIGN:
+ fprintf(out,"/=");break;
+ case OP_SHIFT_LEFT_ASSIGN:
+ fprintf(out,">>=");break;
+ case OP_SHIFT_RIGHT_ASSIGN:
+ fprintf(out,"<<=");break;
+ case OP_AND_ASSIGN:
+ fprintf(out,"&=");break;
+ case OP_XOR_ASSIGN:
+ fprintf(out,"^=");break;
+ case OP_PIPE_ASSIGN:
+ fprintf(out,"|=");break;
+ case OP_NOP:
+ fprintf(out,"NOP");break;
+ case OP_LOGICAL_OR:
+ fprintf(out,"||");break;
+ case OP_LOGICAL_AND:
+ fprintf(out,"&&");break;
+ case OP_LOGICAL_NOT:
+ fprintf(out,"!");break;
+ case OP_BITWISE_OR:
+ fprintf(out,"|");break;
+ case OP_BITWISE_AND:
+ fprintf(out,"&");break;
+ case OP_BITWISE_XOR:
+ fprintf(out,"^");break;
+ case OP_BITWISE_NOT:
+ fprintf(out,"~");break;
+ case OP_ADDR_OF:
+ fprintf(out,"&");break;
+ case OP_DEREFERENCE:
+ fprintf(out,"*");break;
+ case OP_MEMBER_TROUGH_PTR:
+ fprintf(out,"->");break;
+ case OP_MEMBER:
+ fprintf(out,".");break;
+ case OP_ARR_SUBSCRIPT:
+ fprintf(out,"ARR_SUBSCRIPT");break;
+ case OP_POSTFIX_INC:
+ fprintf(out,"++");break;
+ case OP_POSTFIX_DEC:
+ fprintf(out,"--");break;
+ case OP_PREFIX_INC:
+ fprintf(out,"++");break;
+ case OP_PREFIX_DEC:
+ fprintf(out,"--");break;
+ case OP_UNARY_PLUS:
+ fprintf(out,"+");break;
+ case OP_UNARY_MINUS:
+ fprintf(out,"-");break;
+ case OP_CAST:
+ fprintf(out,"CAST");break;
+ case OP_SIZEOF:
+ fprintf(out,"sizeof");break;
+ case OP_SHIFT_LEFT:
+ fprintf(out,"<<");break;
+ case OP_SHIFT_RIGHT:
+ fprintf(out,">>");break;
+ case OP_LESS_EQ:
+ fprintf(out,"<=");break;
+ case OP_GREATER_EQ:
+ fprintf(out,">=");break;
+ case OP_LESS:
+ fprintf(out,"<");break;
+ case OP_GREATER:
+ fprintf(out,">");break;
+ case OP_EQUAL:
+ fprintf(out,"==");break;
+ case OP_NOT_EQUAL:
+ fprintf(out,"!=");break;
+ case OP_LVALUE:
+ fprintf(out,"LVALUE");break;
+ case OP_RVALUE:
+ fprintf(out,"RVALUE");break;
+ case ST_COMPOUND:
+ fprintf(out,"COMPOUND");break;
+ case ST_EXPRESSION:
+ fprintf(out,"EXPRESSION");break;
+ case ST_SWITCH:
+ fprintf(out,"switch");break;
+ case ST_IF:
+ fprintf(out,"if");break;
+ case ST_WHILE:
+ fprintf(out,"while");break;
+ case ST_DO_WHILE:
+ fprintf(out,"do_while");break;
+ case ST_GOTO:
+ fprintf(out,"goto");break;
+ case ST_LABEL:
+ fprintf(out,"LABEL");break;
+ case ST_CASE:
+ fprintf(out,"case");break;
+ case ST_DEFAULT:
+ fprintf(out,"default");break;
+ case ST_CONTINUE:
+ fprintf(out,"continue");break;
+ case ST_BREAK:
+ fprintf(out,"break");break;
+ case ST_RETURN:
+ fprintf(out,"return");break;
+ case ST_FOR:
+ fprintf(out,"for");break;
+ case ST_DECLARATION:
+ fprintf(out,"DECLARATION");break;
+ case ST_FUNCTION_DEFINITION:
+ fprintf(out,"FUNCTION_DEFINITION");break;
+ case TRANSLATION_UNIT:
+ fprintf(out,"TRANSLATION_UNIT");break;
+ case ERROR:
+ fprintf(out,"ERROR");break;
+ default:
+ fprintf(out,"NOT_POSSIBLE");break;
+ }
+ }
+
+ void print_error_tree(FILE *out,struct AST_Error *error)
+ {
+ fprintf(out,"ERROR");
+ if(error->error!=NULL)
+ {
+ if(error->error->type==ST_DECLARATION)
+ {
+ fprintf(out,"ST_DECLARATION");
+ }else
+ {
+ print_ast(out,error->error);
+ }
+ }
+ }
+ void print_binary_expression_tree(FILE *out,struct AST_Binary_Expression *bin)
+ {
+ if(bin->type==OP_ARR_SUBSCRIPT)
+ {
+ print_ast(out,bin->left);
+ fprintf(out,"[");
+ print_ast(out,bin->right);
+ fprintf(out,"]");
+ }else
+ {
+ fprintf(out,"(");
+ print_ast(out,bin->left);
+ print_ast_enum(out,bin->type);
+ print_ast(out,bin->right);
+ fprintf(out,")");
+ }
+ }
+ void print_conditional_expression_tree(FILE *out,struct AST_Conditional_Expression *cond)
+ {
+ fprintf(out,"(");
+ print_ast(out,cond->left);
+ fprintf(out,"?");
+ print_ast(out,cond->center);
+ fprintf(out,":");
+ print_ast(out,cond->right);
+ fprintf(out,")");
+ }
+ void print_function_expression_tree(FILE *out,struct AST_Function_Expression *function_call)
+ {
+ struct Queue_Node *it;
+ print_ast(out,function_call->id);
+ fprintf(out,"(");
+ if(function_call->arguments.size>0)
+ {
+ fprintf(out,"\n");
+ for(it=function_call->arguments.first;it!=function_call->arguments.last;it=it->prev)
+ {
+ print_ast(out,(struct AST*)(it->data));
+ fprintf(out,",\n");
+ }
+ if(it!=NULL)
+ {
+ print_ast(out,(struct AST*)(it->data));
+ }
+
+ }
+ fprintf(out,")");
+ }
+ void print_unary_expression_tree(FILE *out,struct AST_Unary_Expression *unary_expression)
+ {
+ print_ast_enum(out,unary_expression->type);
+ if(unary_expression->type==OP_CAST)
+ {
+ fprintf(out,"(");
+ print_type_giberish(out,unary_expression->value_type);
+ fprintf(out,")");
+ }
+ print_ast(out,unary_expression->operand);
+ }
+ void print_rvalue_expression_tree(FILE *out,struct AST_Rvalue_Expression *rval)
+ {
+ print_token(out,rval->id);
+ }
+ void print_lvalue_expression_tree(FILE *out,struct AST_Lvalue_Expression *lval)
+ {
+ print_token(out,lval->id);
+ }
+ void print_labeled_statement_tree(FILE *out,struct AST_Labeled_Statement *lab)
+ {
+ if(lab->type!=ST_LABEL)
+ print_ast_enum(out,lab->type);
+ if(lab->label!=NULL)
+ print_token(out,lab->label);
+ fprintf(out,":\n");
+ print_ast(out,lab->statement);
+ }
+ void print_compound_statement_tree(FILE *out,struct AST_Compound_Statement *comp)
+ {
+ struct Queue_Node *it;
+ fprintf(out,"{\n");
+ for(it=comp->components.first;it!=NULL;it=it->prev)
+ {
+ print_ast(out,(struct AST*)(it->data));
+ fprintf(out,";\n");
+ }
+ fprintf(out,"}\n");
+ }
+ void print_if_statement_tree(FILE *out,struct AST_If_Statement *ifs)
+ {
+ fprintf(out,"if(");
+ print_ast(out,ifs->condition);
+ fprintf(out,")\n");
+ print_ast(out,ifs->body_statement);
+
+ if(ifs->else_statement!=NULL)
+ {
+ fprintf(out,"\nelse");
+ print_ast(out,ifs->else_statement);
+ }
+
+ }
+ void print_switch_statement_tree(FILE *out,struct AST_Switch_Statement *swi)
+ {
+ fprintf(out,"switch(");
+ print_ast(out,swi->condition);
+ fprintf(out,")\n");
+ print_ast(out,swi->body_statement);
+ }
+ void print_while_statement_tree(FILE *out,struct AST_While_Statement *whi)
+ {
+ fprintf(out,"while(");
+ print_ast(out,whi->condition);
+ fprintf(out,")\n");
+ print_ast(out,whi->body_statement);
+ }
+ void print_do_while_statement_tree(FILE *out,struct AST_Do_While_Statement *whi)
+ {
+ fprintf(out,"do\n");
+ print_ast(out,whi->body_statement);
+ fprintf(out,"while(");
+ print_ast(out,whi->condition);
+ fprintf(out,")\n");
+ }
+ void print_for_statement_tree(FILE *out,struct AST_For_Statement *fo)
+ {
+ fprintf(out,"for(\n");
+ print_ast(out,fo->initialisation);
+ fprintf(out,";\n");
+ print_ast(out,fo->condition);
+ fprintf(out,";\n");
+ print_ast(out,fo->update);
+ fprintf(out,")\n");
+ print_ast(out,fo->body_statement);
+ }
+ void print_return_statement_tree(FILE *out,struct AST_Return_Statement *return_expression)
+ {
+ fprintf(out,"return ");
+ print_ast(out,return_expression->return_expression);
+ }
+ void print_goto_statement_tree(FILE *out,struct AST_Goto_Statement *got)
+ {
+ fprintf(out,"goto ");
+ print_token(out,got->label);
+ }
+ void print_declaration_tree(FILE *out,struct AST_Declaration *declaration)
+ {
+ struct Queue_Node *it;
+ struct Declarator *hold;
+ fprintf(out,"DECLARATION {[\n");
+ for(it=declaration->declarators.first;it!=NULL;it=it->prev)
+ {
+ hold=(struct Declarator*)(it->data);
+ if(hold->id!=NULL)
+ {
+ print_token(out,hold->id);
+ fprintf(out," IS a/an ");
+ }
+ print_type_giberish(out,hold->type);
+
+ fprintf(out,"\n");
+ if(hold->initialiser!=NULL)
+ {
+ fprintf(out,"\tINITIALISED WITH ");
+ print_ast(out,hold->initialiser);
+ fprintf(out,"\n");
+ }
+ }
+ fprintf(out,"END DECLARATION]}\n");
+ }
+ void print_function_definition_tree(FILE *out,struct AST_Function_Definition *def)
+ {
+ fprintf(out,"FUNCTION DEFINITION:\n");
+
+ print_token(out,def->declarator->id);
+ print_type_giberish(out,def->declarator->type);
+ print_ast(out,def->body_statement);
+ }
+ void print_translation_unit_tree(FILE *out,struct AST_Translation_Unit *unit)
+ {
+ struct Queue_Node *it;
+ struct AST* hold;
+ for(it=unit->components.first;it!=NULL;it=it->prev)
+ {
+ hold=(struct AST*)(it->data);
+ print_ast(out,hold);
+ if(hold->type==ST_DECLARATION)
+ {
+ fprintf(out,";\n");
+ }
+ }
+ }
+ void print_ast(FILE *out,struct AST* tree)
+ {
+ switch(tree->type)
+ {
+ case OP_MEMBER_TROUGH_PTR:
+ case OP_MEMBER:
+ case OP_BITWISE_AND:
+ case OP_BITWISE_XOR:
+ case OP_BITWISE_NOT:
+ case OP_LOGICAL_AND:
+ case OP_LOGICAL_OR:
+ case OP_XOR_ASSIGN:
+ case OP_PIPE_ASSIGN:
+ case OP_SHIFT_RIGHT_ASSIGN:
+ case OP_ADD_ASSIGN:
+ case OP_SUBTRACT_ASSIGN:
+ case OP_MULTIPLY_ASSIGN:
+ case OP_REMAINDER_ASSIGN:
+ case OP_DIV_ASSIGN:
+ case OP_SUBTRACTION:
+ case OP_MUL:
+ case OP_DIV:
+ case OP_REMAINDER:
+ case OP_EQUAL:
+ case OP_LESS:
+ case OP_LESS_EQ:
+ case OP_SHIFT_LEFT:
+ case OP_BITWISE_OR:
+ case OP_AND_ASSIGN:
+ case OP_ARR_SUBSCRIPT:
+ case OP_SHIFT_LEFT_ASSIGN:
+ case OP_ASSIGN:
+ case OP_ADDITION:
+ case OP_COMMA:
+ case OP_SHIFT_RIGHT:
+ case OP_GREATER_EQ:
+ case OP_GREATER:
+ case OP_NOT_EQUAL:
+ print_binary_expression_tree(out,(struct AST_Binary_Expression*)tree);
+ break;
+ case OP_COND:
+ print_conditional_expression_tree(out,(struct AST_Conditional_Expression*)tree);
+ break;
+ case OP_FUNCTION:
+ print_function_expression_tree(out,(struct AST_Function_Expression*)tree);
+ break;
+ case OP_LOGICAL_NOT:
+ case OP_UNARY_MINUS:
+ case OP_SIZEOF:
+ case OP_ADDR_OF:
+ case OP_DEREFERENCE:
+ case OP_POSTFIX_INC:
+ case OP_PREFIX_INC:
+ case OP_UNARY_PLUS:
+ case OP_POSTFIX_DEC:
+ case OP_PREFIX_DEC:
+ case OP_CAST:
+ print_unary_expression_tree(out,(struct AST_Unary_Expression*)tree);
+ break;
+ case OP_LVALUE:
+ print_lvalue_expression_tree(out,(struct AST_Lvalue_Expression*)tree);
+ break;
+ case OP_RVALUE:
+ print_rvalue_expression_tree(out,(struct AST_Rvalue_Expression*)tree);
+ break;
+ case OP_NOP:
+ fprintf(out,"NOP");
+ break;
+
+ case ST_SWITCH:
+ print_switch_statement_tree(out,(struct AST_Switch_Statement*)tree);
+ break;
+ case ST_IF:
+ print_if_statement_tree(out,(struct AST_If_Statement*)tree);
+ break;
+ case ST_WHILE:
+ print_while_statement_tree(out,(struct AST_While_Statement*)tree);
+ break;
+ case ST_DO_WHILE:
+ print_do_while_statement_tree(out,(struct AST_Do_While_Statement*)tree);
+ break;
+ case ST_GOTO:
+ print_goto_statement_tree(out,(struct AST_Goto_Statement*)tree);
+ break;
+ case ST_DEFAULT:
+ case ST_LABEL:
+ case ST_CASE:
+ print_labeled_statement_tree(out,(struct AST_Labeled_Statement*)tree);
+ break;
+ case ST_CONTINUE:
+ fprintf(out,"continue");
+ break;
+ case ST_BREAK:
+ fprintf(out,"break");
+ break;
+ case ST_RETURN:
+ print_return_statement_tree(out,(struct AST_Return_Statement*)tree);
+ break;
+ case ST_FOR:
+ print_for_statement_tree(out,(struct AST_For_Statement*)tree);
+ break;
+ case ST_COMPOUND:
+ print_compound_statement_tree(out,(struct AST_Compound_Statement*)tree);
+ break;
+ case ST_DECLARATION:
+ print_declaration_tree(out,(struct AST_Declaration*)tree);
+ break;
+ case ST_FUNCTION_DEFINITION:
+ print_function_definition_tree(out,(struct AST_Function_Definition*)tree);
+ break;
+ case TRANSLATION_UNIT:
+ print_translation_unit_tree(out,(struct AST_Translation_Unit*)tree);
+ break;
+ case ERROR:
+ print_error_tree(out,(struct AST_Error*)tree);
+ break;
+ default:
+ fprintf(out,"NOT_POSSIBLE");break;
+ }
+
+ }
+ void print_program_tokens(FILE *out,struct Program *program)
+ {
+ struct Queue_Node *it;
+ struct Queue_Node *it2;
+ it=program->source_files.first;
+ it2=program->translation_units_tokens.first;
+ for(;it!=NULL && it2!=NULL;it=it->prev,it2=it2->prev)
+ {
+ fprintf(out,"TOKENS for %s\n{\n",((struct Source_File*)(it->data))->src_name);
+ print_tokens(out,it2->data);
+ fprintf(out,"TOKENS_END for %s\n}\n",((struct Source_File*)(it->data))->src_name);
+ }
+ }
+ void print_program_ast(FILE *out,struct Program *program)
+ {
+ size_t i;
+ struct Queue_Node *it;
+ it=program->source_files.first;
+ for( i=0; (i<program->number_of_translation_units) && it!=NULL;++i,it=it->prev)
+ {
+ fprintf(out,"TRANSLATION_UNIT for %s\n{\n",((struct Source_File*)(it->data))->src_name);
+ print_ast(out,program->translation_units[i]);
+ fprintf(out,"TRANSLATION_UNIT_END for %s\n}\n",((struct Source_File*)(it->data))->src_name);
+ }
+ }
+ void print_keyword_enum(FILE *out,enum KEYWORDS kw)
+ {
+ switch(kw)
+ {
+ case KW_AUTO :
+ fprintf(out," KW_AUTO ");break;
+ case KW_DO :
+ fprintf(out," KW_DO ");break;
+ case KW_DOUBLE :
+ fprintf(out," KW_DOUBLE ");break;
+ case KW_INT :
+ fprintf(out," KW_INT ");break;
+ case KW_STRUCT :
+ fprintf(out," KW_STRUCT ");break;
+ case KW_BREAK :
+ fprintf(out," KW_BREAK ");break;
+ case KW_ELSE :
+ fprintf(out," KW_ELSE ");break;
+ case KW_LONG :
+ fprintf(out," KW_LONG ");break;
+ case KW_SWITCH :
+ fprintf(out," KW_SWITCH ");break;
+ case KW_CASE :
+ fprintf(out," KW_CASE ");break;
+ case KW_ENUM :
+ fprintf(out," KW_ENUM ");break;
+ case KW_REGISTER :
+ fprintf(out," KW_REGISTER ");break;
+ case KW_TYPEDEF :
+ fprintf(out," KW_TYPEDEF ");break;
+ case KW_CHAR :
+ fprintf(out," KW_CHAR ");break;
+ case KW_EXTERN :
+ fprintf(out," KW_EXTERN ");break;
+ case KW_RETURN :
+ fprintf(out," KW_RETURN ");break;
+ case KW_UNION :
+ fprintf(out," KW_UNION ");break;
+ case KW_CONST :
+ fprintf(out," KW_CONST ");break;
+ case KW_FLOAT :
+ fprintf(out," KW_FLOAT ");break;
+ case KW_SHORT :
+ fprintf(out," KW_SHORT ");break;
+ case KW_UNSIGNED :
+ fprintf(out," KW_UNSIGNED ");break;
+ case KW_CONTINUE :
+ fprintf(out," KW_CONTINUE ");break;
+ case KW_FOR :
+ fprintf(out," KW_FOR ");break;
+ case KW_SIGNED :
+ fprintf(out," KW_SIGNED ");break;
+ case KW_VOID :
+ fprintf(out," KW_VOID ");break;
+ case KW_DEFAULT :
+ fprintf(out," KW_DEFAULT ");break;
+ case KW_GOTO :
+ fprintf(out," KW_GOTO ");break;
+ case KW_SIZEOF :
+ fprintf(out," KW_SIZEOF ");break;
+ case KW_VOLATILE :
+ fprintf(out," KW_VOLATILE ");break;
+ case KW_IF :
+ fprintf(out," KW_IF ");break;
+ case KW_STATIC :
+ fprintf(out," KW_STATIC ");break;
+ case KW_WHILE :
+ fprintf(out," KW_WHILE ");break;
+ case KW_EXCLAMATION :
+ fprintf(out," KW_EXCLAMATION ");break;
+ case KW_BACK_SLASH :
+ fprintf(out," KW_BACK_SLASH ");break;
+ case KW_PERCENT :
+ fprintf(out," KW_PERCENT ");break;
+ case KW_AND :
+ fprintf(out," KW_AND ");break;
+ case KW_AND_AND :
+ fprintf(out," KW_AND_AND ");break;
+ case KW_QUOTE :
+ fprintf(out," KW_QUOTE ");break;
+ case KW_OPEN_NORMAL :
+ fprintf(out," KW_OPEN_NORMAL ");break;
+ case KW_CLOSE_NORMAL :
+ fprintf(out," KW_CLOSE_NORMAL ");break;
+ case KW_STAR :
+ fprintf(out," KW_STAR ");break;
+ case KW_PLUS :
+ fprintf(out," KW_PLUS ");break;
+ case KW_COMMA :
+ fprintf(out," KW_COMMA ");break;
+ case KW_MINUS :
+ fprintf(out," KW_MINUS ");break;
+ case KW_DOT :
+ fprintf(out," KW_DOT ");break;
+ case KW_ARROW :
+ fprintf(out," KW_ARROW ");break;
+ case KW_COLUMN :
+ fprintf(out," KW_COLUMN ");break;
+ case KW_SEMI_COLUMN :
+ fprintf(out," KW_SEMI_COLUMN ");break;
+ case KW_LESS :
+ fprintf(out," KW_LESS ");break;
+ case KW_EQ :
+ fprintf(out," KW_EQ ");break;
+ case KW_EQEQ :
+ fprintf(out," KW_EQEQ ");break;
+ case KW_MORE :
+ fprintf(out," KW_MORE ");break;
+ case KW_QUESTION :
+ fprintf(out," KW_QUESTION ");break;
+ case KW_OPEN_SQUARE :
+ fprintf(out," KW_OPEN_SQUARE ");break;
+ case KW_CLOSE_SQUARE :
+ fprintf(out," KW_CLOSE_SQUARE ");break;
+ case KW_HAT :
+ fprintf(out," KW_HAT ");break;
+ case KW_FLOOR :
+ fprintf(out," KW_FLOOR ");break;
+ case KW_OPEN_CURLY :
+ fprintf(out," KW_OPEN_CURLY ");break;
+ case KW_CLOSE_CURLY :
+ fprintf(out," KW_CLOSE_CURLY ");break;
+ case KW_PIPE :
+ fprintf(out," KW_PIPE ");break;
+ case KW_PIPE_PIPE :
+ fprintf(out," KW_PIPE_PIPE ");break;
+ case KW_TILDE :
+ fprintf(out," KW_TILDE ");break;
+ case KW_PLUSPLUS :
+ fprintf(out," KW_PLUSPLUS ");break;
+ case KW_MINUSMINUS :
+ fprintf(out," KW_MINUSMINUS ");break;
+ case KW_SHIFT_RIGHT :
+ fprintf(out," KW_SHIFT_RIGHT ");break;
+ case KW_SHIFT_LEFT :
+ fprintf(out," KW_SHIFT_LEFT ");break;
+ case KW_LESS_EQ :
+ fprintf(out," KW_LESS_EQ ");break;
+ case KW_MORE_EQ :
+ fprintf(out," KW_MORE_EQ ");break;
+ case KW_NOT_EQ :
+ fprintf(out," KW_NOT_EQ ");break;
+ case KW_PLUS_EQ :
+ fprintf(out," KW_PLUS_EQ ");break;
+ case KW_MINUS_EQ :
+ fprintf(out," KW_MINUS_EQ ");break;
+ case KW_STAR_EQ :
+ fprintf(out," KW_STAR_EQ ");break;
+ case KW_PERCENT_EQ :
+ fprintf(out," KW_PERCENT_EQ ");break;
+ case KW_SHIFT_LEFT_EQ :
+ fprintf(out," KW_SHIFT_LEFT_EQ ");break;
+ case KW_SHIFT_RIGHT_EQ :
+ fprintf(out," KW_SHIFT_RIGHT_EQ ");break;
+ case KW_AND_EQ :
+ fprintf(out," KW_AND_EQ ");break;
+ case KW_HAT_EQ :
+ fprintf(out," KW_HAT_EQ ");break;
+ case KW_PIPE_EQ :
+ fprintf(out," KW_PIPE_EQ ");break;
+ case KW_DIV_EQ :
+ fprintf(out," KW_DIV_EQ ");break;
+ case KW_FORWARD_SLASH :
+ fprintf(out," KW_FORWARD_SLASH ");break;
+ case KW_NOTYPE :
+ fprintf(out," KW_NOTYPE ");break;
+ case KW_NUMBER :
+ fprintf(out," KW_NUMBER ");break;
+ case KW_COMMENT :
+ fprintf(out," KW_COMMENT ");break;
+ case KW_ID :
+ fprintf(out," KW_ID ");break;
+ case KW_STRING :
+ fprintf(out," KW_STRING ");break;
+ }
+ }
+ #undef TOK
+ #undef INDENT
+
+ #endif
F diff --git a/program.c b/program.c new file mode 100644 --- /dev/null +++ b/program.c
+ #ifndef GCC_PROGRAM_C
+ #define GCC_PROGRAM_C GCC_PROGRAM_C
+ #/*Don't mind me*/include/*When I grow up I want to be a new line*/"program.h"
+ #include"parse_translation_unit.h"
+
+
+ struct Program* get_program()
+ {
+ struct Program *ret;
+ ret=malloc(sizeof(struct Program));
+ Queue_Init(&ret->translation_units_tokens);
+ Queue_Init(&ret->source_files);
+ Map_Init(&ret->defines);
+ ret->global_scope=get_scope(NULL);
+
+ ret->number_of_translation_units=0;
+ ret->translation_units=NULL;
+
+ return ret;
+ }
+ struct Source_File* get_source_file(char *name_of_file)
+ {
+ FILE *in;
+ size_t file_size;
+ struct Source_File *src;
+
+ in=fopen(name_of_file,"r");
+ if(in==NULL)
+ {
+ /*error*/
+ return NULL;
+ }
+
+ fseek(in,0,SEEK_END);
+ file_size=ftell(in);
+ rewind(in);
+
+ src=malloc(sizeof(struct Source_File));
+ src->src_name=name_of_file;
+ src->src=malloc(file_size+1);
+ src->src_size=file_size;
+ src->where_in_src=0;
+ src->which_column=0;
+ src->which_row=0;
+ src->src[file_size]='\0';
+
+ fread(src->src,1,file_size,in);
+ fclose(in);
+ return src;
+ }
+ struct Queue* lex_source_file(char *name_of_file,struct Program* program)
+ {
+ struct Source_File *src;
+ src=get_source_file(name_of_file);
+
+ Queue_Push(&program->translation_units_tokens,lex(src,program));
+ Queue_Push(&program->source_files,src);
+ }
+ void lex_program(char *name_of_file,struct Program *program)
+ {
+ lex_source_file(name_of_file,program);
+ }
+
+ void parse_program(struct Program *program)
+ {
+ size_t i;
+ program->translation_units=malloc(sizeof(struct AST*) * program->translation_units_tokens.size);
+ program->number_of_translation_units=program->translation_units_tokens.size;
+ for(i=0;i<program->number_of_translation_units;++i)
+ {
+ program->translation_units[i]=parse_translation_unit(
+ Queue_Pop(&program->translation_units_tokens),
+ program->global_scope
+ );
+ }
+ }
+ #endif
F diff --git a/program.h b/program.h new file mode 100644 --- /dev/null +++ b/program.h
+ #ifndef GCC_PROGRAM_H
+ #define GCC_PROGRAM_H GCC_PROGRAM_H
+ #include "queue.c"
+ #include "scope.h"
+ #include "lexer.h"
+
+ struct Source_File
+ {
+ char *src;
+ char *src_name;
+ size_t src_size;
+
+ size_t where_in_src;
+ size_t which_column;
+ size_t which_row;
+ };
+
+
+ struct Program
+ {
+
+ struct Queue translation_units_tokens;
+ struct Queue source_files;
+ struct Map defines;
+
+ size_t number_of_translation_units;
+ struct AST **translation_units;
+
+ struct Scope *global_scope;
+ };
+
+ struct Program* get_program();
+ struct Source_File* get_source_file(char *name_of_file);
+ struct Queue* lex_source_file(char *name_of_file,struct Program *program);
+ void lex_program(char *name_of_file,struct Program *program);
+ void parse_program(struct Program *program);
+
+
+ #endif
F diff --git a/queue.c b/queue.c new file mode 100644 --- /dev/null +++ b/queue.c
+ #ifndef GQUEUE_C
+ #define GQUEUE_C GQUEUE_C
+ #include<stdlib.h>//malloc free
+ #include<assert.h>
+
+ typedef struct Queue Queue;
+
+ struct Queue
+ {
+ struct Queue_Node
+ {
+ void *data;
+ struct Queue_Node *prev;
+ }*first,*last;
+
+ size_t size;
+
+ };
+
+ void Queue_Init(Queue *q)
+ {
+ q->first=q->last=NULL;
+ q->size=0;
+ }
+ void Queue_Push(Queue *q,void *data)
+ {
+ if(q==NULL)return;
+ if(q->first==NULL)
+ {
+ q->first=q->last=malloc(sizeof(struct Queue_Node));
+
+ q->first->data=data;
+ q->last->prev=NULL;
+
+ ++q->size;
+ return;
+ }else
+ {
+ struct Queue_Node *temp=malloc(sizeof(struct Queue_Node));
+ q->last->prev=temp;
+ temp->data=data;
+ temp->prev=NULL;
+
+ q->last=temp;
+ ++q->size;
+ }
+
+ }
+ /*max queueiness*/
+ void Queue_Push_Front(struct Queue *q,void *data)
+ {
+ if(q==NULL)return;
+ if(q->first==NULL)
+ {
+ q->first=q->last=malloc(sizeof(struct Queue_Node));
+
+ q->first->data=data;
+ q->last->prev=NULL;
+
+ ++q->size;
+ }else
+ {
+ struct Queue_Node *temp=malloc(sizeof(struct Queue_Node));
+ temp->prev=q->first;
+ temp->data=data;
+
+ q->first=temp;
+ ++q->size;
+ }
+
+ }
+ void* Queue_Pop(Queue *q)
+ {
+ if(q==NULL)return NULL;
+ if(q->size==0)return NULL;
+
+ void *return_value=q->first->data;
+
+ if(q->size==1)
+ {
+ free(q->last);
+ q->first=q->last=NULL;
+ q->size=0;
+ }else
+ {
+ struct Queue_Node *temp_first=q->first;
+ q->first=q->first->prev;
+ free(temp_first);
+ --q->size;
+ }
+ return return_value;
+ }
+ void Queue_Append(struct Queue *lead,struct Queue *follower)
+ {
+ assert(lead!=NULL);
+ lead->last->prev=follower->first;
+ lead->last=follower->last;
+
+ lead->size+=follower->size;
+ }
+
+ void Queue_Destroy(Queue *q)
+ {
+
+ struct Queue_Node *temp_first;
+ while(q->first!=NULL)
+ {
+ temp_first=q->first;
+ q->first=q->first->prev;
+ free(temp_first->data);
+ free(temp_first);
+ }
+
+ }
+ /*
+ Fits a new Queue on top of q. It uses its elements as its own
+ Do not destroy
+ last element ->prev is may not be null
+ */
+ struct Queue Queue_Fit(struct Queue *q,size_t offset)
+ {
+ assert(q->size>offset && offset>0);
+
+ struct Queue ret;
+ size_t i;
+
+ ret.size=q->size-offset;
+ ret.first=q->first;
+ ret.last=q->last;
+
+ for(i=0;i<offset;++i)
+ {
+ ret.first=ret.first->prev;
+ }
+ return ret;
+
+ }
+ #endif //#ifndef GQUEUE_C
F diff --git a/scope.c b/scope.c new file mode 100644 --- /dev/null +++ b/scope.c
+ #ifndef GCC_SCOPE_C
+ #define GCC_SCOPE_C GCC_SCOPE_C
+ #include "scope.h"
+
+
+ struct Scope* get_scope(struct Scope *parent)
+ {
+ struct Scope *ret;
+ ret=malloc(sizeof(struct Scope));
+ Map_Init(&ret->labels);
+ Map_Init(&ret->tags);
+ Map_Init(&ret->ordinary);
+ ret->parent=parent;
+ return ret;
+ }
+
+ void* check_label(struct Scope *current,struct token *id)
+ {
+ void *hold;
+ hold=NULL;
+ while(current!=NULL && hold==NULL)
+ {
+ hold=Map_Check(&current->labels,id->data,id->data_size);
+ current=current->parent;
+ }
+ return hold;
+ }
+
+ void* check_tag(struct Scope *current,struct token *id)
+ {
+ void *hold;
+ hold=NULL;
+ while(current!=NULL && hold==NULL)
+ {
+ hold=Map_Check(&current->tags,id->data,id->data_size);
+ current=current->parent;
+ }
+ return hold;
+ }
+ void* check_ordinary(struct Scope *current,struct token *id)
+ {
+ void *hold;
+ hold=NULL;
+ while(current!=NULL && hold==NULL)
+ {
+ hold=Map_Check(&current->ordinary,id->data,id->data_size);
+ current=current->parent;
+ }
+ return hold;
+ }
+
+ char Scope_Push(struct Scope *scope,struct Declarator *declarator)
+ {
+ struct Type_Node *hold;
+ hold=declarator->type->components.last->data;
+ if(hold->is_typedef)
+ {
+
+ if(Map_Check(&scope->ordinary,declarator->id->data,declarator->id->data_size))
+ {
+ return 0;
+ }else
+ {
+ Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);
+ return 1;
+ }
+ }
+
+ hold=declarator->type->components.first->data;
+
+ switch(hold->type_specifier)
+ {
+ case TS_INT:
+ case TS_CHAR:
+ case TS_FLOAT:
+ case TS_DOUBLE:
+ case TS_ARRAY:
+ case TS_POINTER:
+ if(Map_Check(&scope->ordinary,declarator->id->data,declarator->id->data_size))
+ {
+ return 0;
+ }else
+ {
+ Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);
+ return 1;
+ }
+ case TS_STRUCT:
+ case TS_UNION:
+ if(Map_Check(&scope->tags,declarator->id->data,declarator->id->data_size))
+ {
+ return 0;
+ }else
+ {
+ Map_Push(&scope->ordinary,declarator->id->data,declarator->id->data_size,declarator->type);
+ Map_Push(&scope->tags,kkkkkkk
+ return 1;
+ }
+ }
+ //shouldnt be able to go here
+ return 0;
+ }
+ char check_if_typedefed(struct Scope* scope,struct token *id)
+ {
+ struct Type *hold;
+ hold=check_ordinary(scope,id);
+ if(hold)
+ {
+ return (((struct Type_Node*)(hold->components.last->data))->is_typedef);
+ }else
+ {
+ return 0;
+ }
+
+ }
+ #endif
F diff --git a/scope.h b/scope.h new file mode 100644 --- /dev/null +++ b/scope.h
+ #ifndef GCC_SCOPE_H
+ #define GCC_SCOPE_H GCC_SCOPE_H
+ #include "map.c"
+ #include "parse_declaration.h"
+
+ struct Scope
+ {
+ Map labels;
+ Map tags;
+ Map ordinary;
+ struct Scope *parent;
+ };
+
+
+ struct Scope* get_scope(struct Scope *parent);
+ void* check_label(struct Scope *current,struct token *id);
+ void* check_tag(struct Scope *current,struct token *id);
+ void* check_ordinary(struct Scope *current,struct token *id);
+ char Scope_Push(struct Scope *scope,struct Declarator *declarator);
+ char check_if_typedefed(struct Scope* scope,struct token *id);
+ #endif
F diff --git a/semantics.c b/semantics.c new file mode 100644 --- /dev/null +++ b/semantics.c
+ #ifndef GCC_SEMANTICS_C
+ #define GCC_SEMANTICS_C GCC_SEMANTICS_C
+
+
+
+ long long int evaluate_const_expression_integer(struct AST *expression)
+ {
+ switch(expression->type)
+ {
+ case OP_ADDITION:
+ return
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)
+ +
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);
+ break;
+ case OP_SUBTRACTION:
+ return
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)
+ -
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);
+ break;
+ case OP_DIV:
+ return
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)
+ /
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);
+ break;
+ case OP_MUL:
+ return
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->left)
+ *
+ evaluate_const_expression_integer(BIN_EXPR_PTR(expression)->right);
+ break;
+ case OP_RVALUE:
+ if(RVAL_EXPR_PTR(expression)->id->type==KW_NUMBER)
+ {
+ return evaluate_literal_integer_dec(RVAL_EXPR_PTR(expression)->id);
+ }
+ break;
+ }
+
+ }
+
+ long long int evaluate_literal_integer_dec(struct token *token)
+ {
+ long long int accumulate=0;
+ size_t i;
+ for(i=0;i<token->data_size;++i)
+ {
+ accumulate*=10;
+ accumulate+=token->data[i]-'0';
+ }
+ return accumulate;
+
+ }
+
+
+ #endif
F diff --git a/semantics.h b/semantics.h new file mode 100644 --- /dev/null +++ b/semantics.h
+ #ifndef GCC_SEMANTICS_H
+ #define GCC_SEMANTICS_H GCC_SEMANTICS_H
+ #include "semantics.h"
+
+ enum Location_Type
+ {
+ LT_ON_STACK,
+ LT_RAW,
+ LT_LABEL
+ };
+ struct Location
+ {
+ enum Location_Type type;
+ union
+ {
+ size_t offset;
+ struct token *label;
+ }specifics;
+ };
+ struct Object
+ {
+ struct Type *type;
+ struct Location location;
+ };
+
+
+ long long int evaluate_const_expression_integer(struct AST *expression);
+ long long int evaluate_literal_integer_dec(struct token *token);
+ #endif
F diff --git a/stack.c b/stack.c new file mode 100644 --- /dev/null +++ b/stack.c
+ #ifndef GSTACK_C
+ #define GSTACK_C GSTACK_C
+ #include<stdlib.h>//malloc free et alii
+
+
+ typedef struct Stack Stack;
+
+ struct Stack
+ {
+ struct Stack_Node
+ {
+ struct Stack_Node *next;
+ void *data;
+ }*first;
+ size_t size;
+ };
+
+ void Stack_Init(Stack *stack)
+ {
+ stack->size=0;
+ stack->first=NULL;
+ }
+ void Stack_Push(Stack *stack,void* data)
+ {
+ struct Stack_Node *temp_node=malloc(sizeof(struct Stack_Node));
+ temp_node->data=data;
+ temp_node->next=stack->first;
+ stack->first=temp_node;
+ ++stack->size;
+ }
+ void* Stack_Pop(Stack *stack)
+ {
+ void* return_value=NULL;
+ if(stack->first!=NULL)
+ {
+ struct Stack_Node *temp_first=stack->first;
+ return_value=stack->first->data;
+
+ --stack->size;
+ stack->first=stack->first->next;
+ free(temp_first);
+ }
+
+ return return_value;
+ }
+
+ #endif//#ifndef GSTACK_C
+
F diff --git a/test.c b/test.c new file mode 100644 --- /dev/null +++ b/test.c
+ #/*asdf*/include/*asd*/<tes\
+ t2.c>
+ int main()
+ {
+
+ struct ke asdf;
+ return 0;
+ }
F diff --git a/test2.c b/test2.c new file mode 100644 --- /dev/null +++ b/test2.c
+ int/*kek*/kek;
+ struct ke
+ {
+ int s;
+ };
F diff --git a/type.c b/type.c new file mode 100644 --- /dev/null +++ b/type.c
+ #ifndef GCC_TYPE_C
+ #define GCC_TYPE_C GCC_TYPE_C
+ #include "type.h"
+
+
+ void merge_type_nodes(struct Type_Node *consumer,struct Type_Node *source)
+ {
+ if(source->is_signed)
+ consumer->is_signed=1;
+ if(source->is_const)
+ consumer->is_const=1;
+ if(source->is_volatile)
+ consumer->is_volatile=1;
+ if(source->is_extern)
+ consumer->is_extern=1;
+ if(source->is_static)
+ consumer->is_static=1;
+ if(source->is_bit_field)
+ consumer->is_bit_field=1;
+ /*
+ if(source->is_typedef)
+ consumer->is_typedef=1;
+ */
+ if(source->error)
+ consumer->error=1;
+ if(consumer->type_specifier==TS_NONE)
+ {
+ consumer->type_specifier=source->type_specifier;
+ }else
+ {
+ consumer->error=1;
+ }
+ if(consumer->type_constraints==TC_NONE)
+ {
+ consumer->type_constraints=source->type_constraints;
+ }
+ if(consumer->type_constraints!=source->type_constraints)
+ {
+ consumer->error=1;
+ }
+ consumer->specifics=source->specifics;
+ }
+ struct Type_Node* check_first_type_component(struct Type *type)
+ {
+ return ((struct Type_Node*)type->components.first->data);
+ }
+ struct Type_Node* check_base_type_component(struct Type *type)
+ {
+ return ((struct Type_Node*)type->components.last->data);
+ }
+ size_t size_of(struct Type *type)
+ {
+ struct Type_Node *hold;
+ size_t size;
+
+ hold=type->components.first->data;
+
+ switch(hold->type_specifier)
+ {
+ case TS_INT:
+ size=INT_SIZE;
+ break;
+ case TS_CHAR:
+ size=CHAR_SIZE;
+ break;
+ case TS_FLOAT:
+ size=FLOAT_SIZE;
+ break;
+ case TS_DOUBLE:
+ size=DOUBLE_SIZE;
+ break;
+ case TS_ARRAY:
+ return size_of_array(type);
+ case TS_STRUCT:
+ return size_of_struct(type);
+ case TS_UNION:
+ return size_of_union(type);
+ case TS_POINTER:
+ return PTR_SIZE;
+ default:
+ size=0;
+ }
+ switch(hold->type_constraints)
+ {
+ case TC_LONG:
+ return size<<1;
+ break;
+ case TC_LONG_LONG:
+ return size<<2;
+ break;
+ case TC_SHORT:
+ return size>>1;
+ break;
+ default:
+ return size;
+ }
+
+ }
+
+ size_t size_of_array(struct Type *type)
+ {
+ struct Type temp;
+ struct Type_Node *hold;
+ size_t size;
+
+ hold=type->components.first->data;
+ assert(hold->type_specifier==TS_ARRAY);
+ temp.components=Queue_Fit(&type->components,1);
+ size=hold->specifics.arr.number_of_elements*size_of(&temp);
+ return size;
+
+
+ }
+ size_t size_of_struct(struct Type *type)
+ {
+ struct Queue_Node *it;
+ struct Queue_Node *it2;
+ struct Type_Node *hold;
+ size_t size=0;
+ size_t i;
+
+ hold=type->components.first->data;
+ assert(hold->type_specifier==TS_STRUCT);
+
+ if(hold->specifics.struct_union->declarations.size==0)
+ return 0;
+
+
+ for(it=hold->specifics.struct_union->declarations.first;it!=hold->specifics.struct_union->declarations.last->prev; it=it->prev)
+ {
+ if(DECLR_PTR(it->data)->declarators.size!=0)
+ {
+ for(it2=DECLR_PTR(it->data)->declarators.first;DECLR_PTR(it->data)->declarators.last->prev;it2=it2->prev)
+ {
+ size+=size_of(((struct Declarator*)(it2->data))->type);
+ }
+ }
+ }
+
+ return size;
+ }
+ size_t size_of_union(struct Type *type)
+ {
+ struct Queue_Node *it;
+ struct Queue_Node *it2;
+ struct Type_Node *hold;
+ size_t size=0;
+ size_t hold_size;
+ size_t i;
+
+ hold=type->components.first->data;
+ assert(hold->type_specifier==TS_STRUCT);
+
+ if(hold->specifics.struct_union->declarations.size==0)
+ return 0;
+
+
+ for(it=hold->specifics.struct_union->declarations.first;it!=hold->specifics.struct_union->declarations.last->prev; it=it->prev)
+ {
+ if(DECLR_PTR(it->data)->declarators.size!=0)
+ {
+ for(it2=DECLR_PTR(it->data)->declarators.first;DECLR_PTR(it->data)->declarators.last->prev;it2=it2->prev)
+ {
+ if(hold_size>size)
+ {
+ size=hold_size;
+ }
+ }
+ }
+ }
+ return size;
+ }
+
+ struct Type* get_type()
+ {
+ struct Type *hold;
+ hold=malloc(sizeof(struct Type));
+ Queue_Init(&hold->components);
+ return hold;
+
+ }
+
+ struct Type_Node* get_node()
+ {
+ struct Type_Node *temp;
+ temp=malloc(sizeof(struct Type_Node));
+ temp->type_specifier=TS_NONE;
+ temp->type_constraints=TC_NONE;
+ temp->type_def=NULL;
+ temp->is_typedef=temp->error=temp->is_const=temp->is_signed=temp->is_volatile=temp->is_extern=temp->is_static=temp->is_bit_field=0;
+ return temp;
+ }
+ #endif
F diff --git a/type.h b/type.h new file mode 100644 --- /dev/null +++ b/type.h
+ #ifndef GCC_TYPE_H
+ #define GCC_TYPE_H GCC_TYPE_H
+ #include "queue.c"
+ #include "map.c"
+ #include <limits.h>
+
+ #define PTR_SIZE 4
+
+ #define INT_SIZE 4
+
+ #define CHAR_SIZE 1
+
+ #define FLOAT_SIZE 4
+ #define DOUBLE_SIZE 8
+
+
+
+
+ enum Type_Specifier
+ {
+ TS_VOID,
+ TS_CHAR,
+ TS_INT,
+ TS_FLOAT,
+ TS_DOUBLE,
+ TS_STRUCT,
+ TS_ENUM,
+ TS_UNION,
+ TS_TYPEDEF,
+ TS_POINTER,
+ TS_ARRAY,
+ TS_FUNC,
+ TS_NONE,
+ TS_PTR_ERROR,
+ TS_ARR_ERROR,
+ TS_FUNC_ERROR,
+ TS_GROUP_ERROR,
+ TS_ID_ERROR,
+ TS_ERROR
+ };
+ enum Type_Constraint
+ {
+ TC_LONG,
+ TC_LONG_LONG,
+ TC_SHORT,
+ TC_NONE
+ };
+ struct Struct_Union
+ {
+ struct Map inner_namespace;
+ struct Queue declarations;
+ struct token* id;
+ };
+ struct Type_Node
+ {
+ enum Type_Specifier type_specifier;
+ enum Type_Constraint type_constraints;
+ char is_signed:1;
+ char is_const:1;
+ char is_volatile:1;
+ char is_extern:1;
+ char is_static:1;
+ char is_bit_field:1;
+ char is_typedef:1;
+ char error:1;
+
+ union
+ {
+ struct Queue arg_types;
+ struct {
+ struct AST *number_of_elements_expr;
+ size_t number_of_elements;
+ }arr;
+ struct Struct_Union *struct_union;
+ struct AST* bit_field_length;
+ void *error;
+ }specifics;
+ struct Type *type_def;
+
+ };
+ struct Type
+ {
+ struct Queue components;
+ size_t size;
+ };
+
+ struct Type_Node* check_first_type_component(struct Type *type);
+ struct Type_Node* check_base_type_component(struct Type *type);
+ size_t size_of(struct Type *type);
+ size_t size_of_array(struct Type *type);
+ size_t size_of_struct(struct Type *type);
+ size_t size_of_union(struct Type *type);
+ struct Type_Node* get_node();
+ struct Struct_Union* get_struct_union();
+ void merge_type_nodes(struct Type_Node *consumer,struct Type_Node *source);
+ #endif